diff --git a/src/crypto.c b/src/crypto.c index 07ea046b..1c4b2f97 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -69,7 +69,7 @@ zxerr_t crypto_extractPublicKey(const hd_path_t path, return zxerr_invalid_crypto_settings; } - if (pubKeyLen < 65) { + if (pubKeyLen < PUB_KEY_SIZE) { zemu_log_stack("extractPublicKey: zxerr_buffer_too_small"); return zxerr_buffer_too_small; } @@ -85,13 +85,10 @@ zxerr_t crypto_extractPublicKey(const hd_path_t path, } typedef struct { - uint8_t r[32]; - uint8_t s[32]; + uint8_t r[CURVE_ORDER_SIZE]; + uint8_t s[CURVE_ORDER_SIZE]; uint8_t v; - - // DER signature max size should be 73 - // https://bitcoin.stackexchange.com/questions/77191/what-is-the-maximum-size-of-a-der-encoded-ecdsa-signature#77192 - uint8_t der_signature[73]; + uint8_t der_signature[DER_SIG_MAX_SIZE]; } __attribute__((packed)) signature_t; void sha256(const uint8_t *message, uint16_t messageLen, uint8_t message_digest[CX_SHA256_SIZE]) { @@ -132,18 +129,18 @@ zxerr_t digest_message(const uint8_t *message, return zxerr_ok; } case HASH_SHA3_256: { - if (digestMax < 32) { + if (digestMax < CX_SHA3_256_SIZE) { return zxerr_buffer_too_small; } zemu_log_stack("sha3_256"); cx_sha3_t sha3; - cx_err = cx_sha3_init_no_throw(&sha3, 256); + cx_err = cx_sha3_init_no_throw(&sha3, CX_SHA3_256_SIZE * 8); if (cx_err != CX_OK) return zxerr_invalid_crypto_settings; cx_err = cx_hash_no_throw((cx_hash_t *) &sha3, 0, domainTag, DOMAIN_TAG_LENGTH, NULL, 0); if (cx_err != CX_OK) return zxerr_invalid_crypto_settings; cx_err = - cx_hash_no_throw((cx_hash_t *) &sha3, CX_LAST, message, messageLen, digest, 32); + cx_hash_no_throw((cx_hash_t *) &sha3, CX_LAST, message, messageLen, digest, CX_SHA3_256_SIZE); if (cx_err != CX_OK) return zxerr_invalid_crypto_settings; *digest_size = cx_hash_get_size((cx_hash_t *) &sha3); return zxerr_ok; @@ -174,7 +171,7 @@ zxerr_t crypto_sign(const hd_path_t path, const digest_type_e cx_hash_kind = get_hash_type(options); - uint8_t messageDigest[32]; + uint8_t messageDigest[CURVE_ORDER_SIZE]; uint16_t messageDigestSize = 0; CHECK_ZXERR(digest_message(message, @@ -185,11 +182,26 @@ zxerr_t crypto_sign(const hd_path_t path, sizeof(messageDigest), &messageDigestSize)); - if (messageDigestSize != CX_SHA256_SIZE) { + + // check the message worked properly + if (cx_hash_kind == HASH_SHA2_256 && messageDigestSize != CX_SHA256_SIZE) { zemu_log_stack("crypto_sign: zxerr_out_of_bounds"); return zxerr_out_of_bounds; } + if (cx_hash_kind == HASH_SHA3_256 && messageDigestSize != CX_SHA3_256_SIZE) { + zemu_log_stack("crypto_sign: zxerr_out_of_bounds"); + return zxerr_out_of_bounds; + } + + // check that the hashing choice doesn't reduce the curve security. + // it's enough to check that the digest size is larger or equal to the group order + // but we check the equality to make sure the algos are fully compatible. + if (messageDigestSize != CURVE_ORDER_SIZE) { + zemu_log_stack("crypto_sign: zxerr_invalid_crypto_settings"); + return zxerr_invalid_crypto_settings; + } + size_t signatureLength; uint32_t info = 0; diff --git a/src/crypto.h b/src/crypto.h index 722652ee..ad722857 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -32,7 +32,18 @@ typedef enum { CURVE_UNKNOWN, CURVE_SECP256K1, CURVE_SECP256R1 } curve_e; #if defined(TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) #else +/* output sizes of the supported hash algorithms */ #define CX_SHA256_SIZE 32 +#define CX_SHA3_256_SIZE 32 + +/* constants related to the supported elliptic curves */ +/* the currently supported curves have the same group order byte size and prime field byte size */ +#define CURVE_ORDER_SIZE 32 +#define CURVE_FIELD_SIZE 32 +#define PUB_KEY_SIZE ((2*CURVE_FIELD_SIZE)+1) +// DER signature max size should be 73 +// https://bitcoin.stackexchange.com/questions/77191/what-is-the-maximum-size-of-a-der-encoded-ecdsa-signature#77192 +#define DER_SIG_MAX_SIZE (2*(CURVE_ORDER_SIZE+3)+3) #endif void sha256(const uint8_t *message, uint16_t messageLen, uint8_t message_digest[CX_SHA256_SIZE]);