Skip to content

Commit 179794f

Browse files
authored
separate error codes in crypto.* functions (#41)
* separate error codes in crypto.* functions * update dependencies * update hash used in RFC6979 * bumping version number
1 parent 0c94895 commit 179794f

File tree

26 files changed

+322
-145
lines changed

26 files changed

+322
-145
lines changed

app/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ endif
4848

4949
APPVERSION_M=0
5050
APPVERSION_N=7
51-
APPVERSION_P=2
51+
APPVERSION_P=3
5252

5353
$(info COIN = [$(COIN)])
5454
ifeq ($(COIN),FLOW)

app/src/common/actions.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717

1818
#include "actions.h"
1919

20-
uint8_t action_addr_len;
20+
uint16_t action_addr_len;

app/src/common/actions.h

+11-12
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,21 @@
2222
#include <os_io_seproxyhal.h>
2323
#include "coin.h"
2424

25-
extern uint8_t action_addr_len;
25+
extern uint16_t action_addr_len;
2626

2727
__Z_INLINE void app_sign() {
2828
const uint8_t *message = tx_get_buffer();
2929
const uint16_t messageLength = tx_get_buffer_length();
30-
const uint8_t replyLen = crypto_sign(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, message, messageLength);
3130

32-
if (replyLen > 0) {
33-
set_code(G_io_apdu_buffer, replyLen, APDU_CODE_OK);
34-
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, replyLen + 2);
35-
} else {
31+
uint16_t replyLen = 0;
32+
zxerr_t err = crypto_sign(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, message, messageLength, &replyLen);
33+
34+
if (err != zxerr_ok || replyLen == 0) {
3635
set_code(G_io_apdu_buffer, 0, APDU_CODE_SIGN_VERIFY_ERROR);
3736
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
37+
} else {
38+
set_code(G_io_apdu_buffer, replyLen, APDU_CODE_OK);
39+
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, replyLen + 2);
3840
}
3941
}
4042

@@ -46,14 +48,11 @@ __Z_INLINE void app_reject() {
4648
__Z_INLINE uint8_t app_fill_address() {
4749
// Put data directly in the apdu buffer
4850
MEMZERO(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE);
49-
action_addr_len = crypto_fillAddress(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 2);
5051

51-
char buffer[100];
52-
snprintf(buffer, 100, "???? %d", action_addr_len);
53-
zemu_log_stack(buffer);
52+
action_addr_len = 0;
53+
zxerr_t err = crypto_fillAddress(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 2, &action_addr_len);
5454

55-
if (action_addr_len == 0) {
56-
zemu_log_stack("crypto_fillAddress");
55+
if (err != zxerr_ok || action_addr_len == 0) {
5756
THROW(APDU_CODE_EXECUTION_ERROR);
5857
}
5958

app/src/crypto.c

+47-23
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,21 @@ __Z_INLINE enum cx_md_e get_cx_hash_kind() {
7272
}
7373
}
7474

75-
uint8_t crypto_extractPublicKey(const uint32_t path[HDPATH_LEN_DEFAULT], uint8_t *pubKey, uint16_t pubKeyLen) {
75+
zxerr_t crypto_extractPublicKey(const uint32_t path[HDPATH_LEN_DEFAULT], uint8_t *pubKey, uint16_t pubKeyLen) {
76+
zemu_log_stack("crypto_extractPublicKey");
7677
MEMZERO(pubKey, pubKeyLen);
78+
7779
cx_curve_t curve = get_cx_curve();
78-
if (curve==CX_CURVE_NONE) {
79-
return 0;
80+
if (curve!=CX_CURVE_SECP256K1 && curve!=CX_CURVE_SECP256R1 ) {
81+
zemu_log_stack("extractPublicKey: invalid_crypto_settings");
82+
return zxerr_invalid_crypto_settings;
8083
}
8184

8285
const uint32_t domainSize = 32;
8386
const uint32_t pkSize = 1 + 2 * domainSize;
8487
if (pubKeyLen < pkSize) {
85-
return 0;
88+
zemu_log_stack("extractPublicKey: zxerr_buffer_too_small");
89+
return zxerr_buffer_too_small;
8690
}
8791

8892
cx_ecfp_public_key_t cx_publicKey;
@@ -92,13 +96,17 @@ uint8_t crypto_extractPublicKey(const uint32_t path[HDPATH_LEN_DEFAULT], uint8_t
9296
BEGIN_TRY
9397
{
9498
TRY {
99+
zemu_log_stack("extractPublicKey: derive_node_bip32");
95100
os_perso_derive_node_bip32(curve,
96101
path,
97102
HDPATH_LEN_DEFAULT,
98103
privateKeyData, NULL);
99104

105+
zemu_log_stack("extractPublicKey: cx_ecfp_init_private_key");
100106
cx_ecfp_init_private_key(curve, privateKeyData, 32, &cx_privateKey);
101107
cx_ecfp_init_public_key(curve, NULL, 0, &cx_publicKey);
108+
109+
zemu_log_stack("extractPublicKey: cx_ecfp_generate_pair");
102110
cx_ecfp_generate_pair(curve, &cx_publicKey, &cx_privateKey, 1);
103111
}
104112
FINALLY {
@@ -109,7 +117,7 @@ uint8_t crypto_extractPublicKey(const uint32_t path[HDPATH_LEN_DEFAULT], uint8_t
109117
END_TRY;
110118

111119
memcpy(pubKey, cx_publicKey.W, pkSize);
112-
return pkSize;
120+
return zxerr_ok;
113121
}
114122

115123
typedef struct {
@@ -131,14 +139,15 @@ uint16_t digest_message(uint8_t *digest, uint16_t digestMax, const uint8_t *mess
131139
case sha2_256: {
132140
zemu_log_stack("sha2_256");
133141
if (digestMax < CX_SHA256_SIZE) {
134-
return 0;
142+
zemu_log_stack("digest_message: zxerr_buffer_too_small");
143+
return zxerr_buffer_too_small;
135144
}
136145
sha256(message, messageLen, digest);
137146
return CX_SHA256_SIZE;
138147
}
139148
case sha3_256: {
140149
if (digestMax < 32) {
141-
return 0;
150+
return zxerr_buffer_too_small;
142151
}
143152
zemu_log_stack("sha3_256");
144153
cx_sha3_t sha3;
@@ -147,24 +156,35 @@ uint16_t digest_message(uint8_t *digest, uint16_t digestMax, const uint8_t *mess
147156
zemu_log_stack("sha3_256 ready");
148157
return 32;
149158
}
150-
default:
151-
return 0;
159+
default: {
160+
zemu_log_stack("digest_message: zxerr_invalid_crypto_settings");
161+
return zxerr_invalid_crypto_settings;
162+
}
152163
}
153164
}
154165

155-
uint16_t crypto_sign(uint8_t *buffer, uint16_t signatureMaxlen, const uint8_t *message, uint16_t messageLen) {
166+
zxerr_t crypto_sign(uint8_t *buffer, uint16_t signatureMaxlen, const uint8_t *message, uint16_t messageLen, uint16_t *sigSize) {
167+
zemu_log_stack("crypto_sign");
168+
156169
cx_curve_t curve = get_cx_curve();
157-
if (curve==CX_CURVE_NONE) {
158-
return 0;
170+
if (curve!=CX_CURVE_SECP256K1 && curve!=CX_CURVE_SECP256R1 ) {
171+
zemu_log_stack("crypto_sign: invalid_crypto_settings");
172+
return zxerr_invalid_crypto_settings;
159173
}
160174

161175
const uint32_t domainSize = 32;
162-
uint8_t messageDigest[128];
176+
uint8_t messageDigest[32];
163177

164178
const enum cx_md_e cxhash_kind = get_cx_hash_kind();
165179
const uint16_t messageDigestSize = digest_message(messageDigest, sizeof(messageDigest), message, messageLen );
166-
if (cxhash_kind == CX_NONE || messageDigestSize == 0) {
167-
return 0;
180+
if (messageDigestSize != 32) {
181+
zemu_log_stack("crypto_sign: zxerr_out_of_bounds");
182+
return zxerr_out_of_bounds;
183+
}
184+
185+
if (cxhash_kind != CX_SHA256 && cxhash_kind != CX_SHA3) {
186+
zemu_log_stack("crypto_sign: zxerr_invalid_crypto_settings");
187+
return zxerr_invalid_crypto_settings;
168188
}
169189

170190
cx_ecfp_private_key_t cx_privateKey;
@@ -191,7 +211,7 @@ uint16_t crypto_sign(uint8_t *buffer, uint16_t signatureMaxlen, const uint8_t *m
191211
zemu_log_stack("cx_ecdsa_sign");
192212
signatureLength = cx_ecdsa_sign(&cx_privateKey,
193213
CX_RND_RFC6979 | CX_LAST,
194-
cxhash_kind,
214+
CX_SHA256,
195215
messageDigest,
196216
messageDigestSize,
197217
signature->der_signature,
@@ -209,11 +229,12 @@ uint16_t crypto_sign(uint8_t *buffer, uint16_t signatureMaxlen, const uint8_t *m
209229
err_convert_e err = convertDERtoRSV(signature->der_signature, info, signature->r, signature->s, &signature->v);
210230
if (err != no_error) {
211231
// Error while converting so return length 0
212-
return 0;
232+
return zxerr_invalid_crypto_settings;
213233
}
214234

215235
// return actual size using value from signatureLength
216-
return sizeof_field(signature_t, r) + sizeof_field(signature_t, s) + sizeof_field(signature_t, v) + signatureLength;
236+
*sigSize = sizeof_field(signature_t, r) + sizeof_field(signature_t, s) + sizeof_field(signature_t, v) + signatureLength;
237+
return zxerr_ok;
217238
}
218239

219240
typedef struct {
@@ -222,22 +243,25 @@ typedef struct {
222243
uint8_t padding[4];
223244
} __attribute__((packed)) answer_t;
224245

225-
uint16_t crypto_fillAddress(uint8_t *buffer, uint16_t buffer_len) {
246+
zxerr_t crypto_fillAddress(uint8_t *buffer, uint16_t buffer_len, uint16_t *addrLen) {
226247
MEMZERO(buffer, buffer_len);
227248

228249
if (buffer_len < sizeof(answer_t)) {
229-
return 0;
250+
zemu_log_stack("crypto_fillAddress: zxerr_buffer_too_small");
251+
return zxerr_buffer_too_small;
230252
}
231253

232254
answer_t *const answer = (answer_t *) buffer;
233255

234-
if (crypto_extractPublicKey(hdPath, answer->publicKey, sizeof_field(answer_t, publicKey)) == 0 ) {
235-
return 0;
256+
zxerr_t err = crypto_extractPublicKey(hdPath, answer->publicKey, sizeof_field(answer_t, publicKey));
257+
if ( err != zxerr_ok ) {
258+
return err;
236259
}
237260

238261
array_to_hexstr(answer->addrStr, sizeof_field(answer_t, addrStr) + 2, answer->publicKey, sizeof_field(answer_t, publicKey) );
239262

240-
return sizeof(answer_t) - sizeof_field(answer_t, padding);
263+
*addrLen = sizeof(answer_t) - sizeof_field(answer_t, padding);
264+
return zxerr_ok;
241265
}
242266

243267
#endif

app/src/crypto.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern "C" {
2424
#include "coin.h"
2525
#include <stdbool.h>
2626
#include <sigutils.h>
27+
#include <zxerror.h>
2728

2829
typedef enum {
2930
hash_unknown,
@@ -48,14 +49,15 @@ extern uint32_t hdPath[HDPATH_LEN_DEFAULT];
4849

4950
bool isTestnet();
5051

51-
uint8_t crypto_extractPublicKey(const uint32_t path[HDPATH_LEN_DEFAULT], uint8_t *pubKey, uint16_t pubKeyLen);
52+
zxerr_t crypto_extractPublicKey(const uint32_t path[HDPATH_LEN_DEFAULT], uint8_t *pubKey, uint16_t pubKeyLen);
5253

53-
uint16_t crypto_fillAddress(uint8_t *buffer, uint16_t bufferLen);
54+
zxerr_t crypto_fillAddress(uint8_t *buffer, uint16_t bufferLen, uint16_t *addrLen);
5455

55-
uint16_t crypto_sign(uint8_t *signature,
56+
zxerr_t crypto_sign(uint8_t *signature,
5657
uint16_t signatureMaxlen,
5758
const uint8_t *message,
58-
uint16_t messageLen);
59+
uint16_t messageLen,
60+
uint16_t *sigSize);
5961

6062
#ifdef __cplusplus
6163
}

app/src/rlp.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ parser_error_t rlp_readUInt64(const parser_context_t *ctx,
124124

125125
// handle case when string is a single byte
126126
if (ctx->bufferLen == 1) {
127-
uint8_t tmp;
127+
uint8_t tmp = 0;
128128
CHECK_PARSER_ERR(rlp_readByte(ctx, kind, &tmp))
129129
*value = tmp;
130130
return parser_ok;

deps/ledger-zxlib/include/zxerror.h

+40-6
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,48 @@ extern "C" {
2525
if (err!=zxerr_ok) return err;}
2626

2727
typedef enum {
28-
zxerr_ok,
29-
zxerr_no_data,
30-
zxerr_buffer_too_small,
31-
zxerr_out_of_bounds,
32-
zxerr_encoding_failed,
33-
zxerr_unknown
28+
zxerr_unknown = 0b00000000,
29+
zxerr_ok = 0b00000011,
30+
zxerr_no_data = 0b00000101,
31+
zxerr_buffer_too_small = 0b00000110,
32+
zxerr_out_of_bounds = 0b00001001,
33+
zxerr_encoding_failed = 0b00001010,
34+
zxerr_invalid_crypto_settings = 0b00001100,
3435
} zxerr_t;
3536

37+
//0b00000000
38+
//0b00000011
39+
//0b00000101
40+
//0b00000110
41+
//0b00001001
42+
//0b00001010
43+
//0b00001100
44+
//0b00001111
45+
//0b00010001
46+
//0b00010010
47+
//0b00010100
48+
//0b00010111
49+
//0b00011000
50+
//0b00011011
51+
//0b00011101
52+
//0b00011110
53+
//0b00100001
54+
//0b00100010
55+
//0b00100100
56+
//0b00100111
57+
//0b00101000
58+
//0b00101011
59+
//0b00101101
60+
//0b00101110
61+
//0b00110000
62+
//0b00110011
63+
//0b00110101
64+
//0b00110110
65+
//0b00111001
66+
//0b00111010
67+
//0b00111100
68+
//0b00111111
69+
3670
#ifdef __cplusplus
3771
}
3872
#endif

deps/ledger-zxlib/include/zxversion.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
#pragma once
1717

1818
#define ZXLIB_MAJOR 5
19-
#define ZXLIB_MINOR 0
20-
#define ZXLIB_PATCH 1
19+
#define ZXLIB_MINOR 1
20+
#define ZXLIB_PATCH 0

tests_zemu/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
],
1818
"dependencies": {
1919
"@zondax/ledger-flow": "^0.0.1",
20-
"@zondax/zemu": "^0.6.0"
20+
"@zondax/zemu": "^0.7.0"
2121
},
2222
"devDependencies": {
2323
"@babel/cli": "^7.11.6",
@@ -32,7 +32,7 @@
3232
"eslint-config-airbnb-base": "^14.2.0",
3333
"eslint-config-prettier": "^6.11.0",
3434
"eslint-plugin-import": "^2.22.0",
35-
"eslint-plugin-jest": "^23.20.0",
35+
"eslint-plugin-jest": "^24.0.0",
3636
"eslint-plugin-prettier": "^3.1.4",
3737
"jest": "26.4.2",
3838
"jest-serial-runner": "^1.1.0",
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

tests_zemu/tests/test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ describe('Basic checks', function () {
495495
// Wait until we are not in the main menu
496496
await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot());
497497

498-
await sim.compareSnapshotsAndAccept(".", "sign_secp256k1_basic_verify_addNewKey_sha3_256", 14);
498+
await sim.compareSnapshotsAndAccept(".", "sign_secp256k1_basic_verify_addNewKey_sha2_256", 14);
499499

500500
let resp = await signatureRequest;
501501
console.log(resp);

0 commit comments

Comments
 (0)