diff --git a/src/crypto.c b/src/crypto.c index 07ea046b..dc5a01c9 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -94,8 +94,14 @@ typedef struct { uint8_t der_signature[73]; } __attribute__((packed)) signature_t; -void sha256(const uint8_t *message, uint16_t messageLen, uint8_t message_digest[CX_SHA256_SIZE]) { - cx_hash_sha256(message, messageLen, message_digest, CX_SHA256_SIZE); +zxerr_t sha256(const uint8_t *message, + uint16_t messageLen, + uint8_t message_digest[CX_SHA256_SIZE]) { + cx_err_t cx_err = cx_hash_sha256(message, messageLen, message_digest, CX_SHA256_SIZE); + if (cx_err != CX_OK) { + return zxerr_invalid_crypto_settings; + } + return zxerr_ok; } zxerr_t digest_message(const uint8_t *message, @@ -132,7 +138,7 @@ 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"); @@ -185,7 +191,17 @@ zxerr_t crypto_sign(const hd_path_t path, sizeof(messageDigest), &messageDigestSize)); - if (messageDigestSize != CX_SHA256_SIZE) { + if (cx_hash_kind != HASH_SHA2_256 && cx_hash_kind != HASH_SHA3_256) { + zemu_log_stack("crypto_sign: zxerr_out_of_bounds"); + return zxerr_out_of_bounds; + } + + 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; } diff --git a/src/crypto.h b/src/crypto.h index 722652ee..ea6842ae 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -30,12 +30,13 @@ typedef enum { HASH_UNKNOWN, HASH_SHA2_256, HASH_SHA3_256 } digest_type_e; typedef enum { CURVE_UNKNOWN, CURVE_SECP256K1, CURVE_SECP256R1 } curve_e; -#if defined(TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) +#if defined(TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) || defined(TARGET_STAX) #else -#define CX_SHA256_SIZE 32 +#define CX_SHA256_SIZE 32 +#define CX_SHA3_256_SIZE 32 #endif -void sha256(const uint8_t *message, uint16_t messageLen, uint8_t message_digest[CX_SHA256_SIZE]); +zxerr_t sha256(const uint8_t *message, uint16_t messageLen, uint8_t message_digest[CX_SHA256_SIZE]); zxerr_t crypto_extractPublicKey(const hd_path_t path, const uint16_t options, diff --git a/src/message.c b/src/message.c index 66c2d35c..f472c637 100644 --- a/src/message.c +++ b/src/message.c @@ -45,7 +45,7 @@ zxerr_t message_parse() { } } - sha256(messageData.message, messageData.length, messageData.hash); + CHECK_ZXERR(sha256(messageData.message, messageData.length, messageData.hash)); messageData.canBeDisplayed = false; if (messageData.length <= MAX_MESSAGE_SHOW_LENGTH) { @@ -88,6 +88,9 @@ zxerr_t message_getItem(int8_t displayIdx, pageCount); return zxerr_ok; } else { + if (!app_mode_expert()) { + return zxerr_unknown; + } snprintf(outKey, outKeyLen, "Message too long,"); snprintf(outVal, outValLen, "validate hash on a secure device."); return zxerr_ok; @@ -97,6 +100,9 @@ zxerr_t message_getItem(int8_t displayIdx, displayIdx -= 2; if (displayIdx == 0 && !messageData.canBeDisplayed) { + if (!app_mode_expert()) { + return zxerr_unknown; + } snprintf(outKey, outKeyLen, "Message hash"); pageStringHex(outVal, outValLen, diff --git a/src/parser_impl.c b/src/parser_impl.c index 24abcde7..e08985ed 100644 --- a/src/parser_impl.c +++ b/src/parser_impl.c @@ -348,7 +348,10 @@ parser_error_t _readScript(parser_context_t *c, flow_script_hash_t *s) { CHECK_KIND(kind, RLP_KIND_STRING) MEMZERO(s->digest, sizeof(s->digest)); - sha256(script.buffer, script.bufferLen, s->digest); + zxerr_t err = sha256(script.buffer, script.bufferLen, s->digest); + if (err != zxerr_ok) { + return PARSER_UNEXPECTED_ERROR; + } return PARSER_OK; } diff --git a/src/tx_metadata.c b/src/tx_metadata.c index 2ab85d1e..a392b48a 100644 --- a/src/tx_metadata.c +++ b/src/tx_metadata.c @@ -72,9 +72,13 @@ parser_error_t storeTxMetadata(const uint8_t *txMetadata, uint16_t txMetadataLen txMetadataState.metadataLength = txMetadataLength; // calculate the Merkle tree leaf hash - sha256(txMetadataState.buffer, - txMetadataState.metadataLength, - txMetadataState.metadataMerkleTreeValidationHash); + zxerr_t err = sha256(txMetadataState.buffer, + txMetadataState.metadataLength, + txMetadataState.metadataMerkleTreeValidationHash); + if (err != zxerr_ok) { + return PARSER_UNEXPECTED_ERROR; + } + txMetadataState.metadataMerkleTreeValidationLevel = 1; return PARSER_OK; @@ -110,7 +114,11 @@ parser_error_t validateStoredTxMetadataMerkleTreeLevel(const uint8_t *hashes, si } // calculate new hash of this node and store it - sha256(hashes, hashesLen, txMetadataState.metadataMerkleTreeValidationHash); + zxerr_t err = sha256(hashes, hashesLen, txMetadataState.metadataMerkleTreeValidationHash); + if (err != zxerr_ok) { + return PARSER_UNEXPECTED_ERROR; + } + txMetadataState.metadataMerkleTreeValidationLevel += 1; return PARSER_OK; }