diff --git a/src/ethUstream.c b/src/ethUstream.c index 3273c65969..42c29fa4e1 100644 --- a/src/ethUstream.c +++ b/src/ethUstream.c @@ -36,7 +36,7 @@ void initTx(txContext_t *context, context->customProcessor = customProcessor; context->extra = extra; context->currentField = RLP_NONE + 1; - cx_keccak_init(context->sha3, 256); + CX_ASSERT(cx_keccak_init_no_throw(context->sha3, 256)); } uint8_t readTxByte(txContext_t *context) { @@ -52,7 +52,7 @@ uint8_t readTxByte(txContext_t *context) { context->currentFieldPos++; } if (!(context->processingField && context->fieldSingleByte)) { - cx_hash((cx_hash_t *) context->sha3, 0, &data, 1, NULL, 0); + CX_ASSERT(cx_hash_no_throw((cx_hash_t *) context->sha3, 0, &data, 1, NULL, 0)); } return data; } @@ -66,7 +66,8 @@ void copyTxData(txContext_t *context, uint8_t *out, uint32_t length) { memmove(out, context->workBuffer, length); } if (!(context->processingField && context->fieldSingleByte)) { - cx_hash((cx_hash_t *) context->sha3, 0, context->workBuffer, length, NULL, 0); + CX_ASSERT( + cx_hash_no_throw((cx_hash_t *) context->sha3, 0, context->workBuffer, length, NULL, 0)); } context->workBuffer += length; context->commandLength -= length; diff --git a/src/handle_check_address.c b/src/handle_check_address.c index 45c8586fae..16b4e0b688 100644 --- a/src/handle_check_address.c +++ b/src/handle_check_address.c @@ -2,6 +2,7 @@ #include "os.h" #include "shared_context.h" #include "string.h" +#include "lib_standard_app/crypto_helpers.h" #define ZERO(x) explicit_bzero(&x, sizeof(x)) @@ -18,17 +19,10 @@ void handle_check_address(check_address_parameters_t* params, chain_config_t* ch const uint8_t* bip32_path_ptr = params->address_parameters; uint8_t bip32PathLength = *(bip32_path_ptr++); cx_sha3_t local_sha3; - - // Common memory is used for locals that are not used concurrently - union group1 { - uint32_t bip32Path[MAX_BIP32_PATH]; - cx_ecfp_private_key_t privateKey; - char address[51]; - } locals_union1; - union group2 { - uint8_t privateKeyData[64]; - cx_ecfp_public_key_t publicKey; - } locals_union2; + uint32_t bip32Path[MAX_BIP32_PATH]; + char address[51]; + cx_ecfp_256_private_key_t priv; + cx_ecfp_256_public_key_t pub; if ((bip32PathLength < 0x01) || (bip32PathLength > MAX_BIP32_PATH) || (bip32PathLength * 4 != params->address_parameters_length - 1)) { @@ -36,58 +30,34 @@ void handle_check_address(check_address_parameters_t* params, chain_config_t* ch return; } for (uint8_t i = 0; i < bip32PathLength; i++) { - locals_union1.bip32Path[i] = U4BE(bip32_path_ptr, 0); + bip32Path[i] = U4BE(bip32_path_ptr, 0); bip32_path_ptr += 4; } - if (os_derive_bip32_no_throw(CX_CURVE_256K1, - locals_union1.bip32Path, - bip32PathLength, - locals_union2.privateKeyData, - NULL) != CX_OK) { - ZERO(locals_union1); - ZERO(locals_union2); - return; - } - - ZERO(locals_union1); - if (cx_ecfp_init_private_key_no_throw(CX_CURVE_256K1, - locals_union2.privateKeyData, - 32, - &locals_union1.privateKey) != CX_OK) { - ZERO(locals_union1); - ZERO(locals_union2); - return; - } - ZERO(locals_union2); - if (cx_ecfp_generate_pair_no_throw(CX_CURVE_256K1, - &locals_union2.publicKey, - &locals_union1.privateKey, - 1) != CX_OK) { - ZERO(locals_union1); - ZERO(locals_union2); - return; - } - ZERO(locals_union1); - if (!getEthAddressStringFromKey(&locals_union2.publicKey, - locals_union1.address, - &local_sha3, - chain_config->chainId)) { - ZERO(locals_union1); - ZERO(locals_union2); + CX_ASSERT(bip32_derive_with_seed_init_privkey_256(HDW_NORMAL, + CX_CURVE_256K1, + bip32Path, + bip32PathLength, + &priv, + NULL, + NULL, + 0)); + if (cx_ecfp_generate_pair_no_throw(CX_CURVE_256K1, &pub, &priv, 1) != CX_OK) { return; } - ZERO(locals_union2); + getEthAddressStringFromRawKey((const uint8_t*) &pub.W, + address, + &local_sha3, + chain_config->chainId); uint8_t offset_0x = 0; if (memcmp(params->address_to_check, "0x", 2) == 0) { offset_0x = 2; } - if (strcmp(locals_union1.address, params->address_to_check + offset_0x) != 0) { + if (strcmp(address, params->address_to_check + offset_0x) != 0) { PRINTF("Addresses don't match\n"); } else { PRINTF("Addresses match\n"); params->result = 1; } - ZERO(locals_union1); } diff --git a/src/handle_swap_sign_transaction.c b/src/handle_swap_sign_transaction.c index fc7167a566..22b3ac1d34 100644 --- a/src/handle_swap_sign_transaction.c +++ b/src/handle_swap_sign_transaction.c @@ -113,4 +113,6 @@ void __attribute__((noreturn)) handle_swap_sign_transaction(chain_config_t* conf BLE_power(1, NULL); #endif // HAVE_BLE app_main(); + // Failsafe + os_sched_exit(-1); } diff --git a/src/hash_bytes.c b/src/hash_bytes.c index e6b6437e3c..4d3eab4038 100644 --- a/src/hash_bytes.c +++ b/src/hash_bytes.c @@ -8,7 +8,7 @@ * @param[in] hash_ctx pointer to the hashing context */ void hash_nbytes(const uint8_t *bytes_ptr, size_t n, cx_hash_t *hash_ctx) { - cx_hash(hash_ctx, 0, bytes_ptr, n, NULL, 0); + CX_ASSERT(cx_hash_no_throw(hash_ctx, 0, bytes_ptr, n, NULL, 0)); } /** diff --git a/src/main.c b/src/main.c index 4f5ce6d7f3..eb2109b309 100644 --- a/src/main.c +++ b/src/main.c @@ -31,6 +31,7 @@ #include "commands_712.h" #include "challenge.h" #include "domain_name.h" +#include "lib_standard_app/crypto_helpers.h" unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; @@ -88,28 +89,6 @@ void io_seproxyhal_send_status(uint32_t sw) { io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); } -void format_signature_out(const uint8_t *signature) { - memset(G_io_apdu_buffer + 1, 0x00, 64); - uint8_t offset = 1; - uint8_t xoffset = 4; // point to r value - // copy r - uint8_t xlength = signature[xoffset - 1]; - if (xlength == 33) { - xlength = 32; - xoffset++; - } - memmove(G_io_apdu_buffer + offset + 32 - xlength, signature + xoffset, xlength); - offset += 32; - xoffset += xlength + 2; // move over rvalue and TagLEn - // copy s value - xlength = signature[xoffset - 1]; - if (xlength == 33) { - xlength = 32; - xoffset++; - } - memmove(G_io_apdu_buffer + offset + 32 - xlength, signature + xoffset, xlength); -} - unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) { switch (channel & ~(IO_FLAGS)) { case CHANNEL_KEYBOARD: @@ -162,11 +141,17 @@ void handleGetWalletId(volatile unsigned int *tx) { unsigned char t[64]; cx_ecfp_256_private_key_t priv; cx_ecfp_256_public_key_t pub; - // seed => priv key - os_perso_derive_node_bip32(CX_CURVE_256K1, U_os_perso_seed_cookie, 2, t, NULL); + // seed => pubkey + CX_ASSERT(bip32_derive_with_seed_init_privkey_256(HDW_NORMAL, + CX_CURVE_256K1, + U_os_perso_seed_cookie, + 2, + &priv, + NULL, + NULL, + 0)); // priv key => pubkey - cx_ecdsa_init_private_key(CX_CURVE_256K1, t, 32, &priv); - cx_ecfp_generate_pair(CX_CURVE_256K1, &pub, &priv, 1); + CX_ASSERT(cx_ecfp_generate_pair_no_throw(CX_CURVE_256K1, &pub, &priv, 1)); // pubkey -> sha512 cx_hash_sha512(pub.W, sizeof(pub.W), t, sizeof(t)); // ! cookie ! @@ -508,9 +493,6 @@ void app_main(void) { } END_TRY; } - - // return_to_dashboard: - return; } // override point, but nothing more to do diff --git a/src/ui_callbacks.h b/src/ui_callbacks.h index 3063400765..da704783a0 100644 --- a/src/ui_callbacks.h +++ b/src/ui_callbacks.h @@ -25,7 +25,6 @@ unsigned int io_seproxyhal_touch_privacy_cancel(const bagl_element_t *e); void ui_warning_contract_data(void); void io_seproxyhal_send_status(uint32_t sw); -void format_signature_out(const uint8_t *signature); void finalizeParsing(bool direct); extraInfo_t *getKnownToken(uint8_t *contractAddress); diff --git a/src/uint256.c b/src/uint256.c index 8829c906df..fb6d236c6a 100644 --- a/src/uint256.c +++ b/src/uint256.c @@ -175,7 +175,7 @@ void mul256(const uint256_t *const number1, write_u64_be(num1 + i * sizeof(uint64_t), number1->elements[i / 2].elements[i % 2]); write_u64_be(num2 + i * sizeof(uint64_t), number2->elements[i / 2].elements[i % 2]); } - cx_math_mult(result, num1, num2, sizeof(num1)); + CX_ASSERT(cx_math_mult_no_throw(result, num1, num2, sizeof(num1))); for (uint8_t i = 0; i < 4; i++) { read_u64_be(result + 32 + i * sizeof(uint64_t), &target->elements[i / 2].elements[i % 2]); } diff --git a/src_common/common_utils.c b/src_common/common_utils.c index 84a424ea06..73c12ed156 100644 --- a/src_common/common_utils.c +++ b/src_common/common_utils.c @@ -214,50 +214,25 @@ bool amountToString(const uint8_t *amount, return true; } -bool getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3_t *sha3Context) { +void getEthAddressFromRawKey(const uint8_t raw_pubkey[static 65], + uint8_t *out, + cx_sha3_t *sha3Context) { uint8_t hashAddress[INT256_LENGTH]; - - if (cx_keccak_init_no_throw(sha3Context, 256) != CX_OK) { - return false; - } - - if (cx_hash_no_throw((cx_hash_t *) sha3Context, - CX_LAST, - publicKey->W + 1, - 64, - hashAddress, - 32) != CX_OK) { - return false; - } - + CX_ASSERT(cx_keccak_init_no_throw(sha3Context, 256)); + CX_ASSERT( + cx_hash_no_throw((cx_hash_t *) sha3Context, CX_LAST, raw_pubkey + 1, 64, hashAddress, 32)); memmove(out, hashAddress + 12, 20); - return true; } -bool getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey, - char *out, - cx_sha3_t *sha3Context, - uint64_t chainId) { +void getEthAddressStringFromRawKey(const uint8_t raw_pubkey[static 65], + char *out, + cx_sha3_t *sha3Context, + uint64_t chainId) { uint8_t hashAddress[INT256_LENGTH]; - - if (cx_keccak_init_no_throw(sha3Context, 256) != CX_OK) { - return false; - } - - if (cx_hash_no_throw((cx_hash_t *) sha3Context, - CX_LAST, - publicKey->W + 1, - 64, - hashAddress, - 32) != CX_OK) { - return false; - } - - if (!getEthAddressStringFromBinary(hashAddress + 12, out, sha3Context, chainId)) { - return false; - } - - return true; + CX_ASSERT(cx_keccak_init_no_throw(sha3Context, 256)); + CX_ASSERT( + cx_hash_no_throw((cx_hash_t *) sha3Context, CX_LAST, raw_pubkey + 1, 64, hashAddress, 32)); + getEthAddressStringFromBinary(hashAddress + 12, out, sha3Context, chainId); } bool getEthAddressStringFromBinary(uint8_t *address, diff --git a/src_common/common_utils.h b/src_common/common_utils.h index fd198d95f8..7c1ef7909a 100644 --- a/src_common/common_utils.h +++ b/src_common/common_utils.h @@ -35,6 +35,10 @@ static const char HEXDIGITS[] = "0123456789abcdef"; #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +extern size_t strlcpy(char *dst, const char *src, size_t size); + +extern size_t strlcat(char *dst, const char *src, size_t size); + void array_hexstr(char *strbuf, const void *bin, unsigned int len); uint64_t u64_from_BE(const uint8_t *in, uint8_t size); @@ -56,12 +60,14 @@ bool adjustDecimals(const char *src, size_t targetLength, uint8_t decimals); -bool getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3_t *sha3Context); +void getEthAddressFromRawKey(const uint8_t raw_pubkey[static 65], + uint8_t *out, + cx_sha3_t *sha3Context); -bool getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey, - char *out, - cx_sha3_t *sha3Context, - uint64_t chainId); +void getEthAddressStringFromRawKey(const uint8_t raw_pubkey[static 65], + char *out, + cx_sha3_t *sha3Context, + uint64_t chainId); bool getEthAddressStringFromBinary(uint8_t *address, char *out, diff --git a/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c b/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c index b1b38d5f12..8ba2bb9cc7 100644 --- a/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c +++ b/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c @@ -13,27 +13,35 @@ static const uint8_t BLS12_381_FIELD_MODULUS[] = { 0x1e, 0xab, 0xff, 0xfe, 0xb1, 0x53, 0xff, 0xff, 0xb9, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xab}; void getEth2PublicKey(uint32_t *bip32Path, uint8_t bip32PathLength, uint8_t *out) { - uint8_t privateKeyData[INT256_LENGTH]; + uint8_t privateKeyData[64]; cx_ecfp_256_extended_private_key_t privateKey; cx_ecfp_384_public_key_t publicKey; uint8_t yFlag = 0; uint8_t tmp[96]; + int diff; io_seproxyhal_io_heartbeat(); - os_perso_derive_eip2333(CX_CURVE_BLS12_381_G1, bip32Path, bip32PathLength, privateKeyData); + CX_ASSERT(os_derive_eip2333_no_throw(CX_CURVE_BLS12_381_G1, + bip32Path, + bip32PathLength, + privateKeyData)); io_seproxyhal_io_heartbeat(); memset(tmp, 0, 48); memmove(tmp + 16, privateKeyData, 32); - cx_ecfp_init_private_key(CX_CURVE_BLS12_381_G1, tmp, 48, (cx_ecfp_private_key_t *) &privateKey); - cx_ecfp_generate_pair(CX_CURVE_BLS12_381_G1, - (cx_ecfp_public_key_t *) &publicKey, - (cx_ecfp_private_key_t *) &privateKey, - 1); + CX_ASSERT(cx_ecfp_init_private_key_no_throw(CX_CURVE_BLS12_381_G1, + tmp, + 48, + (cx_ecfp_private_key_t *) &privateKey)); + CX_ASSERT(cx_ecfp_generate_pair_no_throw(CX_CURVE_BLS12_381_G1, + (cx_ecfp_public_key_t *) &publicKey, + (cx_ecfp_private_key_t *) &privateKey, + 1)); explicit_bzero(tmp, 96); explicit_bzero((void *) &privateKey, sizeof(cx_ecfp_256_extended_private_key_t)); tmp[47] = 2; - cx_math_mult(tmp, publicKey.W + 1 + 48, tmp, 48); - if (cx_math_cmp(tmp + 48, BLS12_381_FIELD_MODULUS, 48) > 0) { + CX_ASSERT(cx_math_mult_no_throw(tmp, publicKey.W + 1 + 48, tmp, 48)); + CX_ASSERT(cx_math_cmp_no_throw(tmp + 48, BLS12_381_FIELD_MODULUS, 48, &diff)); + if (diff > 0) { yFlag = 0x20; } publicKey.W[1] &= 0x1f; diff --git a/src_features/getPublicKey/cmd_getPublicKey.c b/src_features/getPublicKey/cmd_getPublicKey.c index c30addcb6e..3aa681a89b 100644 --- a/src_features/getPublicKey/cmd_getPublicKey.c +++ b/src_features/getPublicKey/cmd_getPublicKey.c @@ -4,6 +4,7 @@ #include "feature_getPublicKey.h" #include "common_ui.h" #include "os_io_seproxyhal.h" +#include "lib_standard_app/crypto_helpers.h" void handleGetPublicKey(uint8_t p1, uint8_t p2, @@ -11,9 +12,7 @@ void handleGetPublicKey(uint8_t p1, uint8_t dataLength, unsigned int *flags, unsigned int *tx) { - uint8_t privateKeyData[INT256_LENGTH]; bip32_path_t bip32; - cx_ecfp_private_key_t privateKey; if (!G_called_from_swap) { reset_app_context(); @@ -35,25 +34,19 @@ void handleGetPublicKey(uint8_t p1, } tmpCtx.publicKeyContext.getChaincode = (p2 == P2_CHAINCODE); - io_seproxyhal_io_heartbeat(); - os_perso_derive_node_bip32( - CX_CURVE_256K1, - bip32.path, - bip32.length, - privateKeyData, - (tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL)); - cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey); - io_seproxyhal_io_heartbeat(); - cx_ecfp_generate_pair(CX_CURVE_256K1, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1); - explicit_bzero(&privateKey, sizeof(privateKey)); - explicit_bzero(privateKeyData, sizeof(privateKeyData)); - io_seproxyhal_io_heartbeat(); - if (!getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey, - tmpCtx.publicKeyContext.address, - &global_sha3, - chainConfig->chainId)) { - THROW(CX_INVALID_PARAMETER); + if (bip32_derive_get_pubkey_256( + CX_CURVE_256K1, + bip32.path, + bip32.length, + tmpCtx.publicKeyContext.publicKey.W, + (tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL), + CX_SHA512) != CX_OK) { + THROW(0x6F00); } + getEthAddressStringFromRawKey(tmpCtx.publicKeyContext.publicKey.W, + tmpCtx.publicKeyContext.address, + &global_sha3, + chainConfig->chainId); uint64_t chain_id = chainConfig->chainId; if (dataLength >= sizeof(chain_id)) { diff --git a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c index c1f0369470..703ec07556 100644 --- a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c +++ b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c @@ -28,7 +28,7 @@ void handlePerformPrivacyOperation(uint8_t p1, uint8_t dataLength, unsigned int *flags, unsigned int *tx) { - uint8_t privateKeyData[INT256_LENGTH]; + uint8_t privateKeyData[64]; uint8_t privateKeyDataSwapped[INT256_LENGTH]; bip32_path_t bip32; cx_err_t status = CX_OK; @@ -53,27 +53,31 @@ void handlePerformPrivacyOperation(uint8_t p1, cx_ecfp_private_key_t privateKey; - os_perso_derive_node_bip32( + CX_ASSERT(os_derive_bip32_no_throw( CX_CURVE_256K1, bip32.path, bip32.length, privateKeyData, - (tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL)); - cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey); - cx_ecfp_generate_pair(CX_CURVE_256K1, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1); - if (!getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey, - tmpCtx.publicKeyContext.address, - &global_sha3, - chainConfig->chainId)) { - THROW(CX_INVALID_PARAMETER); - } + (tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL))); + CX_ASSERT(cx_ecfp_init_private_key_no_throw(CX_CURVE_256K1, privateKeyData, 32, &privateKey)); + CX_ASSERT(cx_ecfp_generate_pair_no_throw(CX_CURVE_256K1, + &tmpCtx.publicKeyContext.publicKey, + &privateKey, + 1)); + getEthAddressStringFromRawKey((const uint8_t *) &tmpCtx.publicKeyContext.publicKey.W, + tmpCtx.publicKeyContext.address, + &global_sha3, + chainConfig->chainId); if (p2 == P2_PUBLIC_ENCRYPTION_KEY) { decodeScalar(privateKeyData, privateKeyDataSwapped); - cx_ecfp_init_private_key(CX_CURVE_Curve25519, privateKeyDataSwapped, 32, &privateKey); - cx_ecfp_generate_pair(CX_CURVE_Curve25519, - &tmpCtx.publicKeyContext.publicKey, - &privateKey, - 1); + CX_ASSERT(cx_ecfp_init_private_key_no_throw(CX_CURVE_Curve25519, + privateKeyDataSwapped, + 32, + &privateKey)); + CX_ASSERT(cx_ecfp_generate_pair_no_throw(CX_CURVE_Curve25519, + &tmpCtx.publicKeyContext.publicKey, + &privateKey, + 1)); explicit_bzero(privateKeyDataSwapped, sizeof(privateKeyDataSwapped)); } else { memmove(tmpCtx.publicKeyContext.publicKey.W + 1, dataBuffer, 32); diff --git a/src_features/provideDomainName/cmd_provide_domain_name.c b/src_features/provideDomainName/cmd_provide_domain_name.c index 3ec5b39d47..dcce5f58c2 100644 --- a/src_features/provideDomainName/cmd_provide_domain_name.c +++ b/src_features/provideDomainName/cmd_provide_domain_name.c @@ -365,36 +365,38 @@ static bool handle_address(const s_tlv_data *data, static bool verify_signature(const s_sig_ctx *sig_ctx) { uint8_t hash[INT256_LENGTH]; cx_ecfp_public_key_t verif_key; + cx_err_t error = CX_INTERNAL_ERROR; - cx_hash((cx_hash_t *) &sig_ctx->hash_ctx, CX_LAST, NULL, 0, hash, INT256_LENGTH); + CX_CHECK( + cx_hash_no_throw((cx_hash_t *) &sig_ctx->hash_ctx, CX_LAST, NULL, 0, hash, INT256_LENGTH)); switch (sig_ctx->key_id) { #ifdef HAVE_DOMAIN_NAME_TEST_KEY case KEY_ID_TEST: #else case KEY_ID_PROD: #endif - cx_ecfp_init_public_key(CX_CURVE_256K1, - DOMAIN_NAME_PUB_KEY, - sizeof(DOMAIN_NAME_PUB_KEY), - &verif_key); + CX_CHECK(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1, + DOMAIN_NAME_PUB_KEY, + sizeof(DOMAIN_NAME_PUB_KEY), + &verif_key)); break; default: PRINTF("Error: Unknown metadata key ID %u\n", sig_ctx->key_id); return false; } - if (!cx_ecdsa_verify(&verif_key, - CX_LAST, - CX_SHA256, - hash, - sizeof(hash), - sig_ctx->input_sig, - sig_ctx->input_sig_size)) { + if (!cx_ecdsa_verify_no_throw(&verif_key, + hash, + sizeof(hash), + sig_ctx->input_sig, + sig_ctx->input_sig_size)) { PRINTF("Domain name signature verification failed!\n"); #ifndef HAVE_BYPASS_SIGNATURES return false; #endif } return true; +end: + return false; } /** diff --git a/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c b/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c index 00665ad7c4..94bf4e241f 100644 --- a/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c +++ b/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c @@ -168,18 +168,14 @@ void handleProvideErc20TokenInformation(uint8_t p1, } if (index < NUM_TOKENS_EXTRA) { PRINTF("Descriptor whitelisted\n"); - } else { - cx_ecfp_init_public_key(CX_CURVE_256K1, - LEDGER_SIGNATURE_PUBLIC_KEY, - sizeof(LEDGER_SIGNATURE_PUBLIC_KEY), - &tokenKey); - if (!cx_ecdsa_verify(&tokenKey, - CX_LAST, - CX_SHA256, - hash, - 32, - workBuffer + offset, - dataLength)) { + } else +#endif + { + CX_ASSERT(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1, + LEDGER_SIGNATURE_PUBLIC_KEY, + sizeof(LEDGER_SIGNATURE_PUBLIC_KEY), + &tokenKey)); + if (!cx_ecdsa_verify_no_throw(&tokenKey, hash, 32, workBuffer + offset, dataLength)) { #ifndef HAVE_BYPASS_SIGNATURES PRINTF("Invalid token signature\n"); THROW(0x6A80); @@ -187,26 +183,6 @@ void handleProvideErc20TokenInformation(uint8_t p1, } } -#else - - cx_ecfp_init_public_key(CX_CURVE_256K1, - LEDGER_SIGNATURE_PUBLIC_KEY, - sizeof(LEDGER_SIGNATURE_PUBLIC_KEY), - &tokenKey); - if (!cx_ecdsa_verify(&tokenKey, - CX_LAST, - CX_SHA256, - hash, - 32, - workBuffer + offset, - dataLength)) { -#ifndef HAVE_BYPASS_SIGNATURES - PRINTF("Invalid token signature\n"); - THROW(0x6A80); -#endif - } -#endif - tmpCtx.transactionContext.tokenSet[tmpCtx.transactionContext.currentItemIndex] = 1; THROW(0x9000); } diff --git a/src_features/provideNFTInformation/cmd_provideNFTInfo.c b/src_features/provideNFTInformation/cmd_provideNFTInfo.c index e59c77b6f2..b53c207748 100644 --- a/src_features/provideNFTInformation/cmd_provideNFTInfo.c +++ b/src_features/provideNFTInformation/cmd_provideNFTInfo.c @@ -159,20 +159,10 @@ void handleProvideNFTInformation(uint8_t p1, uint8_t algorithmId = workBuffer[offset]; PRINTF("Algorithm: %d\n", algorithmId); - cx_curve_t curve; - verificationAlgo *verificationFn; - cx_md_t hashId; - - switch (algorithmId) { - case ALGORITHM_ID_1: - curve = CX_CURVE_256K1; - verificationFn = (verificationAlgo *) cx_ecdsa_verify; - hashId = CX_SHA256; - break; - default: - PRINTF("Incorrect algorithmId %d\n", algorithmId); - THROW(0x6a80); - break; + + if (algorithmId != ALGORITHM_ID_1) { + PRINTF("Incorrect algorithmId %d\n", algorithmId); + THROW(0x6a80); } offset += ALGORITHM_ID_SIZE; PRINTF("hashing: %.*H\n", payloadSize, workBuffer); @@ -199,14 +189,12 @@ void handleProvideNFTInformation(uint8_t p1, THROW(0x6a80); } - cx_ecfp_init_public_key(curve, rawKey, rawKeyLen, &nftKey); - if (!verificationFn(&nftKey, - CX_LAST, - hashId, - hash, - sizeof(hash), - (uint8_t *) workBuffer + offset, - signatureLen)) { + CX_ASSERT(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1, rawKey, rawKeyLen, &nftKey)); + if (!cx_ecdsa_verify_no_throw(&nftKey, + hash, + sizeof(hash), + (uint8_t *) workBuffer + offset, + signatureLen)) { #ifndef HAVE_BYPASS_SIGNATURES PRINTF("Invalid NFT signature\n"); THROW(0x6A80); diff --git a/src_features/setExternalPlugin/cmd_setExternalPlugin.c b/src_features/setExternalPlugin/cmd_setExternalPlugin.c index 13d1faf009..a2ddd71f21 100644 --- a/src_features/setExternalPlugin/cmd_setExternalPlugin.c +++ b/src_features/setExternalPlugin/cmd_setExternalPlugin.c @@ -37,17 +37,15 @@ void handleSetExternalPlugin(uint8_t p1, // check Ledger's signature over the payload cx_hash_sha256(workBuffer, payload_size, hash, sizeof(hash)); - cx_ecfp_init_public_key(CX_CURVE_256K1, - LEDGER_SIGNATURE_PUBLIC_KEY, - sizeof(LEDGER_SIGNATURE_PUBLIC_KEY), - &tokenKey); - if (!cx_ecdsa_verify(&tokenKey, - CX_LAST, - CX_SHA256, - hash, - sizeof(hash), - workBuffer + payload_size, - dataLength - payload_size)) { + CX_ASSERT(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1, + LEDGER_SIGNATURE_PUBLIC_KEY, + sizeof(LEDGER_SIGNATURE_PUBLIC_KEY), + &tokenKey)); + if (!cx_ecdsa_verify_no_throw(&tokenKey, + hash, + sizeof(hash), + workBuffer + payload_size, + dataLength - payload_size)) { #ifndef HAVE_BYPASS_SIGNATURES PRINTF("Invalid plugin signature %.*H\n", dataLength - payload_size, diff --git a/src_features/setPlugin/cmd_setPlugin.c b/src_features/setPlugin/cmd_setPlugin.c index d4eb522c4d..1b80bb524e 100644 --- a/src_features/setPlugin/cmd_setPlugin.c +++ b/src_features/setPlugin/cmd_setPlugin.c @@ -189,20 +189,10 @@ void handleSetPlugin(uint8_t p1, uint8_t algorithmId = workBuffer[offset]; PRINTF("Algorithm: %d\n", algorithmId); - cx_curve_t curve; - verificationAlgo *verificationFn; - cx_md_t hashId; - - switch (algorithmId) { - case ECC_SECG_P256K1__ECDSA_SHA_256: - curve = CX_CURVE_256K1; - verificationFn = (verificationAlgo *) cx_ecdsa_verify; - hashId = CX_SHA256; - break; - default: - PRINTF("Incorrect algorithmId %d\n", algorithmId); - THROW(0x6a80); - break; + + if (algorithmId != ECC_SECG_P256K1__ECDSA_SHA_256) { + PRINTF("Incorrect algorithmId %d\n", algorithmId); + THROW(0x6a80); } offset += ALGORITHM_ID_SIZE; PRINTF("hashing: %.*H\n", payloadSize, workBuffer); @@ -229,14 +219,12 @@ void handleSetPlugin(uint8_t p1, THROW(0x6a80); } - cx_ecfp_init_public_key(curve, rawKey, rawKeyLen, &pluginKey); - if (!verificationFn(&pluginKey, - CX_LAST, - hashId, - hash, - sizeof(hash), - (unsigned char *) (workBuffer + offset), - signatureLen)) { + CX_ASSERT(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1, rawKey, rawKeyLen, &pluginKey)); + if (!cx_ecdsa_verify_no_throw(&pluginKey, + hash, + sizeof(hash), + (unsigned char *) (workBuffer + offset), + signatureLen)) { #ifndef HAVE_BYPASS_SIGNATURES PRINTF("Invalid NFT signature\n"); THROW(0x6A80); diff --git a/src_features/signMessage/cmd_signMessage.c b/src_features/signMessage/cmd_signMessage.c index 6280ca0825..14ea72d6f7 100644 --- a/src_features/signMessage/cmd_signMessage.c +++ b/src_features/signMessage/cmd_signMessage.c @@ -92,6 +92,8 @@ static void reset_ui_buffer(void) { * @return pointer to the start of the start of the message; \ref NULL if it failed */ static const uint8_t *first_apdu_data(const uint8_t *data, uint8_t *length) { + cx_err_t error = CX_INTERNAL_ERROR; + if (appState != APP_STATE_IDLE) { apdu_reply(APDU_RESPONSE_CONDITION_NOT_SATISFIED); } @@ -113,22 +115,29 @@ static const uint8_t *first_apdu_data(const uint8_t *data, uint8_t *length) { *length -= sizeof(uint32_t); // Initialize message header + length - cx_keccak_init(&global_sha3, 256); - cx_hash((cx_hash_t *) &global_sha3, 0, (uint8_t *) SIGN_MAGIC, sizeof(SIGN_MAGIC) - 1, NULL, 0); + CX_CHECK(cx_keccak_init_no_throw(&global_sha3, 256)); + CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3, + 0, + (uint8_t *) SIGN_MAGIC, + sizeof(SIGN_MAGIC) - 1, + NULL, + 0)); snprintf(strings.tmp.tmp2, sizeof(strings.tmp.tmp2), "%u", tmpCtx.messageSigningContext.remainingLength); - cx_hash((cx_hash_t *) &global_sha3, - 0, - (uint8_t *) strings.tmp.tmp2, - strlen(strings.tmp.tmp2), - NULL, - 0); + CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3, + 0, + (uint8_t *) strings.tmp.tmp2, + strlen(strings.tmp.tmp2), + NULL, + 0)); reset_ui_buffer(); states.sign_state = STATE_191_HASH_DISPLAY; states.ui_started = false; return data; +end: + return NULL; } /** @@ -139,6 +148,8 @@ static const uint8_t *first_apdu_data(const uint8_t *data, uint8_t *length) { * @return whether it was successful or not */ static bool feed_hash(const uint8_t *const data, const uint8_t length) { + cx_err_t error = CX_INTERNAL_ERROR; + if (length > tmpCtx.messageSigningContext.remainingLength) { PRINTF("Error: Length mismatch ! (%u > %u)!\n", length, @@ -146,17 +157,19 @@ static bool feed_hash(const uint8_t *const data, const uint8_t length) { apdu_reply(APDU_RESPONSE_INVALID_DATA); return false; } - cx_hash((cx_hash_t *) &global_sha3, 0, data, length, NULL, 0); + CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3, 0, data, length, NULL, 0)); if ((tmpCtx.messageSigningContext.remainingLength -= length) == 0) { // Finalize hash - cx_hash((cx_hash_t *) &global_sha3, - CX_LAST, - NULL, - 0, - tmpCtx.messageSigningContext.hash, - 32); + CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3, + CX_LAST, + NULL, + 0, + tmpCtx.messageSigningContext.hash, + 32)); } return true; +end: + return false; } /** diff --git a/src_features/signMessage/ui_common_signMessage.c b/src_features/signMessage/ui_common_signMessage.c index eb6707d353..1d511fd75c 100644 --- a/src_features/signMessage/ui_common_signMessage.c +++ b/src_features/signMessage/ui_common_signMessage.c @@ -1,31 +1,22 @@ #include "os_io_seproxyhal.h" +#include "lib_standard_app/crypto_helpers.h" #include "common_ui.h" unsigned int io_seproxyhal_touch_signMessage_ok(void) { - uint8_t privateKeyData[INT256_LENGTH]; - uint8_t signature[100]; - cx_ecfp_private_key_t privateKey; uint32_t tx = 0; - io_seproxyhal_io_heartbeat(); - os_perso_derive_node_bip32(CX_CURVE_256K1, - tmpCtx.messageSigningContext.bip32.path, - tmpCtx.messageSigningContext.bip32.length, - privateKeyData, - NULL); - io_seproxyhal_io_heartbeat(); - cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey); - explicit_bzero(privateKeyData, sizeof(privateKeyData)); unsigned int info = 0; - io_seproxyhal_io_heartbeat(); - cx_ecdsa_sign(&privateKey, - CX_RND_RFC6979 | CX_LAST, - CX_SHA256, - tmpCtx.messageSigningContext.hash, - sizeof(tmpCtx.messageSigningContext.hash), - signature, - sizeof(signature), - &info); - explicit_bzero(&privateKey, sizeof(privateKey)); + if (bip32_derive_ecdsa_sign_rs_hash_256(CX_CURVE_256K1, + tmpCtx.messageSigningContext.bip32.path, + tmpCtx.messageSigningContext.bip32.length, + CX_RND_RFC6979 | CX_LAST, + CX_SHA256, + tmpCtx.messageSigningContext.hash, + sizeof(tmpCtx.messageSigningContext.hash), + G_io_apdu_buffer + 1, + G_io_apdu_buffer + 1 + 32, + &info) != CX_OK) { + THROW(0x6F00); + } G_io_apdu_buffer[0] = 27; if (info & CX_ECCINFO_PARITY_ODD) { G_io_apdu_buffer[0]++; @@ -33,7 +24,6 @@ unsigned int io_seproxyhal_touch_signMessage_ok(void) { if (info & CX_ECCINFO_xGTn) { G_io_apdu_buffer[0] += 2; } - format_signature_out(signature); tx = 65; G_io_apdu_buffer[tx++] = 0x90; G_io_apdu_buffer[tx++] = 0x00; diff --git a/src_features/signMessageEIP712/field_hash.c b/src_features/signMessageEIP712/field_hash.c index af89be879f..d97d5ee27d 100644 --- a/src_features/signMessageEIP712/field_hash.c +++ b/src_features/signMessageEIP712/field_hash.c @@ -52,6 +52,7 @@ static const uint8_t *field_hash_prepare(const void *const field_ptr, const uint8_t *data, uint8_t *data_length) { e_type field_type; + cx_err_t error = CX_INTERNAL_ERROR; field_type = struct_field_type(field_ptr); fh->remaining_size = __builtin_bswap16(*(uint16_t *) &data[0]); // network byte order @@ -59,10 +60,12 @@ static const uint8_t *field_hash_prepare(const void *const field_ptr, *data_length -= sizeof(uint16_t); fh->state = FHS_WAITING_FOR_MORE; if (IS_DYN(field_type)) { - cx_keccak_init(&global_sha3, 256); // init hash + CX_CHECK(cx_keccak_init_no_throw(&global_sha3, 256)); ui_712_new_field(field_ptr, data, *data_length); } return data; +end: + return NULL; } /** @@ -120,14 +123,22 @@ static const uint8_t *field_hash_finalize_static(const void *const field_ptr, */ static uint8_t *field_hash_finalize_dynamic(void) { uint8_t *value; + cx_err_t error = CX_INTERNAL_ERROR; if ((value = mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) { apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return NULL; } // copy hash into memory - cx_hash((cx_hash_t *) &global_sha3, CX_LAST, NULL, 0, value, KECCAK256_HASH_BYTESIZE); + CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3, + CX_LAST, + NULL, + 0, + value, + KECCAK256_HASH_BYTESIZE)); return value; +end: + return NULL; } /** diff --git a/src_features/signMessageEIP712/filtering.c b/src_features/signMessageEIP712/filtering.c index ff45a6eb9a..1a24d61521 100644 --- a/src_features/signMessageEIP712/filtering.c +++ b/src_features/signMessageEIP712/filtering.c @@ -63,6 +63,7 @@ static bool verify_filtering_signature(uint8_t dname_length, cx_ecfp_public_key_t verifying_key; cx_sha256_t hash_ctx; uint64_t chain_id; + cx_err_t error = CX_INTERNAL_ERROR; cx_sha256_init(&hash_ctx); @@ -105,13 +106,13 @@ static bool verify_filtering_signature(uint8_t dname_length, hash_nbytes((uint8_t *) dname, sizeof(char) * dname_length, (cx_hash_t *) &hash_ctx); // Finalize hash - cx_hash((cx_hash_t *) &hash_ctx, CX_LAST, NULL, 0, hash, INT256_LENGTH); + CX_CHECK(cx_hash_no_throw((cx_hash_t *) &hash_ctx, CX_LAST, NULL, 0, hash, INT256_LENGTH)); - cx_ecfp_init_public_key(CX_CURVE_256K1, - LEDGER_SIGNATURE_PUBLIC_KEY, - sizeof(LEDGER_SIGNATURE_PUBLIC_KEY), - &verifying_key); - if (!cx_ecdsa_verify(&verifying_key, CX_LAST, CX_SHA256, hash, sizeof(hash), sig, sig_length)) { + CX_CHECK(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1, + LEDGER_SIGNATURE_PUBLIC_KEY, + sizeof(LEDGER_SIGNATURE_PUBLIC_KEY), + &verifying_key)); + if (!cx_ecdsa_verify_no_throw(&verifying_key, hash, sizeof(hash), sig, sig_length)) { #ifndef HAVE_BYPASS_SIGNATURES PRINTF("Invalid EIP-712 filtering signature\n"); apdu_response_code = APDU_RESPONSE_INVALID_DATA; @@ -119,6 +120,8 @@ static bool verify_filtering_signature(uint8_t dname_length, #endif } return true; +end: + return false; } /** diff --git a/src_features/signMessageEIP712/path.c b/src_features/signMessageEIP712/path.c index 3c823c9ce9..fd90a06b4e 100644 --- a/src_features/signMessageEIP712/path.c +++ b/src_features/signMessageEIP712/path.c @@ -147,13 +147,17 @@ static cx_sha3_t *get_last_hash_ctx(void) { static bool finalize_hash_depth(uint8_t *hash) { const cx_sha3_t *hash_ctx; size_t hashed_bytes; + cx_err_t error = CX_INTERNAL_ERROR; hash_ctx = get_last_hash_ctx(); hashed_bytes = hash_ctx->blen; // finalize hash - cx_hash((cx_hash_t *) hash_ctx, CX_LAST, NULL, 0, hash, KECCAK256_HASH_BYTESIZE); + CX_CHECK( + cx_hash_no_throw((cx_hash_t *) hash_ctx, CX_LAST, NULL, 0, hash, KECCAK256_HASH_BYTESIZE)); mem_dealloc(sizeof(*hash_ctx)); // remove hash context return hashed_bytes > 0; +end: + return false; } /** @@ -166,7 +170,7 @@ static void feed_last_hash_depth(const uint8_t *const hash) { hash_ctx = get_last_hash_ctx(); // continue progressive hash with the array hash - cx_hash((cx_hash_t *) hash_ctx, 0, hash, KECCAK256_HASH_BYTESIZE, NULL, 0); + CX_ASSERT(cx_hash_no_throw((cx_hash_t *) hash_ctx, 0, hash, KECCAK256_HASH_BYTESIZE, NULL, 0)); } /** @@ -177,15 +181,18 @@ static void feed_last_hash_depth(const uint8_t *const hash) { */ static bool push_new_hash_depth(bool init) { cx_sha3_t *hash_ctx; + cx_err_t error = CX_INTERNAL_ERROR; // allocate new hash context if ((hash_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*hash_ctx)) == NULL) { return false; } if (init) { - cx_keccak_init(hash_ctx, 256); // initialize it + CX_CHECK(cx_keccak_init_no_throw(hash_ctx, 256)); } return true; +end: + return false; } /** @@ -432,6 +439,7 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) { bool is_custom; uint8_t array_size; uint8_t array_depth_count_bak; + cx_err_t error = CX_INTERNAL_ERROR; if (path_struct == NULL) { apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; @@ -479,9 +487,9 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) { if (array_size > 0) { memcpy(hash_ctx, old_ctx, sizeof(*old_ctx)); } else { - cx_keccak_init(hash_ctx, 256); + CX_CHECK(cx_keccak_init_no_throw(hash_ctx, 256)); } - cx_keccak_init(old_ctx, 256); // init hash + CX_CHECK(cx_keccak_init_no_throw(old_ctx, 256)); } if (array_size == 0) { do { @@ -490,6 +498,8 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) { } return true; +end: + return false; } /** diff --git a/src_features/signMessageEIP712/schema_hash.c b/src_features/signMessageEIP712/schema_hash.c index e47c2eeb34..5b8e1bfb66 100644 --- a/src_features/signMessageEIP712/schema_hash.c +++ b/src_features/signMessageEIP712/schema_hash.c @@ -27,6 +27,7 @@ bool compute_schema_hash(void) { const char *name; uint8_t name_length; cx_sha224_t hash_ctx; + cx_err_t error = CX_INTERNAL_ERROR; cx_sha224_init(&hash_ctx); @@ -61,13 +62,15 @@ bool compute_schema_hash(void) { hash_byte('}', (cx_hash_t *) &hash_ctx); // copy hash into context struct - cx_hash((cx_hash_t *) &hash_ctx, - CX_LAST, - NULL, - 0, - eip712_context->schema_hash, - sizeof(eip712_context->schema_hash)); + CX_CHECK(cx_hash_no_throw((cx_hash_t *) &hash_ctx, + CX_LAST, + NULL, + 0, + eip712_context->schema_hash, + sizeof(eip712_context->schema_hash))); return true; +end: + return false; } #endif // HAVE_EIP712_FULL_SUPPORT diff --git a/src_features/signMessageEIP712/type_hash.c b/src_features/signMessageEIP712/type_hash.c index 7b9515f867..aa2ecfe63e 100644 --- a/src_features/signMessageEIP712/type_hash.c +++ b/src_features/signMessageEIP712/type_hash.c @@ -171,8 +171,9 @@ bool type_hash(const char *const struct_name, const uint8_t struct_name_length, uint8_t deps_count = 0; const void **deps; void *mem_loc_bak = mem_alloc(0); + cx_err_t error = CX_INTERNAL_ERROR; - cx_keccak_init(&global_sha3, 256); // init hash + CX_CHECK(cx_keccak_init_no_throw(&global_sha3, 256)); deps = get_struct_dependencies(&deps_count, NULL, struct_ptr); if ((deps_count > 0) && (deps == NULL)) { return false; @@ -191,8 +192,15 @@ bool type_hash(const char *const struct_name, const uint8_t struct_name_length, mem_dealloc(mem_alloc(0) - mem_loc_bak); // copy hash into memory - cx_hash((cx_hash_t *) &global_sha3, CX_LAST, NULL, 0, hash_buf, KECCAK256_HASH_BYTESIZE); + CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3, + CX_LAST, + NULL, + 0, + hash_buf, + KECCAK256_HASH_BYTESIZE)); return true; +end: + return false; } #endif // HAVE_EIP712_FULL_SUPPORT diff --git a/src_features/signMessageEIP712_common/common_712.c b/src_features/signMessageEIP712_common/common_712.c index 084a528bb1..98b47fc8cd 100644 --- a/src_features/signMessageEIP712_common/common_712.c +++ b/src_features/signMessageEIP712_common/common_712.c @@ -1,5 +1,6 @@ #include "shared_context.h" #include "os_io_seproxyhal.h" +#include "lib_standard_app/crypto_helpers.h" #include "ui_callbacks.h" #include "common_712.h" #include "ui_callbacks.h" @@ -8,54 +9,45 @@ static const uint8_t EIP_712_MAGIC[] = {0x19, 0x01}; unsigned int ui_712_approve_cb(void) { - uint8_t privateKeyData[INT256_LENGTH]; uint8_t hash[INT256_LENGTH]; - uint8_t signature[100]; - cx_ecfp_private_key_t privateKey; uint32_t tx = 0; io_seproxyhal_io_heartbeat(); - cx_keccak_init(&global_sha3, 256); - cx_hash((cx_hash_t *) &global_sha3, - 0, - (uint8_t *) EIP_712_MAGIC, - sizeof(EIP_712_MAGIC), - NULL, - 0); - cx_hash((cx_hash_t *) &global_sha3, - 0, - tmpCtx.messageSigningContext712.domainHash, - sizeof(tmpCtx.messageSigningContext712.domainHash), - NULL, - 0); - cx_hash((cx_hash_t *) &global_sha3, - CX_LAST, - tmpCtx.messageSigningContext712.messageHash, - sizeof(tmpCtx.messageSigningContext712.messageHash), - hash, - sizeof(hash)); + CX_ASSERT(cx_keccak_init_no_throw(&global_sha3, 256)); + CX_ASSERT(cx_hash_no_throw((cx_hash_t *) &global_sha3, + 0, + (uint8_t *) EIP_712_MAGIC, + sizeof(EIP_712_MAGIC), + NULL, + 0)); + CX_ASSERT(cx_hash_no_throw((cx_hash_t *) &global_sha3, + 0, + tmpCtx.messageSigningContext712.domainHash, + sizeof(tmpCtx.messageSigningContext712.domainHash), + NULL, + 0)); + CX_ASSERT(cx_hash_no_throw((cx_hash_t *) &global_sha3, + CX_LAST, + tmpCtx.messageSigningContext712.messageHash, + sizeof(tmpCtx.messageSigningContext712.messageHash), + hash, + sizeof(hash))); PRINTF("EIP712 Domain hash 0x%.*h\n", 32, tmpCtx.messageSigningContext712.domainHash); PRINTF("EIP712 Message hash 0x%.*h\n", 32, tmpCtx.messageSigningContext712.messageHash); - io_seproxyhal_io_heartbeat(); - os_perso_derive_node_bip32(CX_CURVE_256K1, - tmpCtx.messageSigningContext712.bip32.path, - tmpCtx.messageSigningContext712.bip32.length, - privateKeyData, - NULL); - io_seproxyhal_io_heartbeat(); - cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey); - explicit_bzero(privateKeyData, sizeof(privateKeyData)); + unsigned int info = 0; - io_seproxyhal_io_heartbeat(); - cx_ecdsa_sign(&privateKey, - CX_RND_RFC6979 | CX_LAST, - CX_SHA256, - hash, - sizeof(hash), - signature, - sizeof(signature), - &info); - explicit_bzero(&privateKey, sizeof(privateKey)); + if (bip32_derive_ecdsa_sign_rs_hash_256(CX_CURVE_256K1, + tmpCtx.messageSigningContext712.bip32.path, + tmpCtx.messageSigningContext712.bip32.length, + CX_RND_RFC6979 | CX_LAST, + CX_SHA256, + hash, + sizeof(hash), + G_io_apdu_buffer + 1, + G_io_apdu_buffer + 1 + 32, + &info) != CX_OK) { + THROW(0x6F00); + } G_io_apdu_buffer[0] = 27; if (info & CX_ECCINFO_PARITY_ODD) { G_io_apdu_buffer[0]++; @@ -63,7 +55,6 @@ unsigned int ui_712_approve_cb(void) { if (info & CX_ECCINFO_xGTn) { G_io_apdu_buffer[0] += 2; } - format_signature_out(signature); tx = 65; G_io_apdu_buffer[tx++] = 0x90; G_io_apdu_buffer[tx++] = 0x00; diff --git a/src_features/signTx/cmd_signTx.c b/src_features/signTx/cmd_signTx.c index 0eb1d1c43a..8a845387ae 100644 --- a/src_features/signTx/cmd_signTx.c +++ b/src_features/signTx/cmd_signTx.c @@ -43,7 +43,7 @@ void handleSign(uint8_t p1, if (txType >= MIN_TX_TYPE && txType <= MAX_TX_TYPE) { // Enumerate through all supported txTypes here... if (txType == EIP2930 || txType == EIP1559) { - cx_hash((cx_hash_t *) &global_sha3, 0, workBuffer, 1, NULL, 0); + CX_ASSERT(cx_hash_no_throw((cx_hash_t *) &global_sha3, 0, workBuffer, 1, NULL, 0)); txContext.txType = txType; workBuffer++; dataLength--; diff --git a/src_features/signTx/logic_signTx.c b/src_features/signTx/logic_signTx.c index bdacd76847..8620092478 100644 --- a/src_features/signTx/logic_signTx.c +++ b/src_features/signTx/logic_signTx.c @@ -8,6 +8,7 @@ #include "common_ui.h" #include "ui_callbacks.h" #include "apdu_constants.h" +#include "lib_standard_app/crypto_helpers.h" #define ERR_SILENT_MODE_CHECK_FAILED 0x6001 @@ -279,26 +280,21 @@ static void get_network_as_string(char *out, size_t out_size) { } static void get_public_key(uint8_t *out, uint8_t outLength) { - uint8_t privateKeyData[INT256_LENGTH] = {0}; - cx_ecfp_private_key_t privateKey = {0}; - cx_ecfp_public_key_t publicKey = {0}; + uint8_t raw_pubkey[65]; if (outLength < ADDRESS_LENGTH) { return; } - - os_perso_derive_node_bip32(CX_CURVE_256K1, - tmpCtx.transactionContext.bip32.path, - tmpCtx.transactionContext.bip32.length, - privateKeyData, - NULL); - cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey); - cx_ecfp_generate_pair(CX_CURVE_256K1, &publicKey, &privateKey, 1); - explicit_bzero(&privateKey, sizeof(privateKey)); - explicit_bzero(privateKeyData, sizeof(privateKeyData)); - if (!getEthAddressFromKey(&publicKey, out, &global_sha3)) { - THROW(CX_INVALID_PARAMETER); + if (bip32_derive_get_pubkey_256(CX_CURVE_256K1, + tmpCtx.transactionContext.bip32.path, + tmpCtx.transactionContext.bip32.length, + raw_pubkey, + NULL, + CX_SHA512) != CX_OK) { + THROW(0x6F00); } + + getEthAddressFromRawKey(raw_pubkey, out, &global_sha3); } /* Local implmentation of strncasecmp, workaround of the segfaulting base implem @@ -322,6 +318,7 @@ __attribute__((noinline)) static bool finalize_parsing_helper(bool direct, bool uint64_t chain_id = get_tx_chain_id(); const char *ticker = get_displayable_ticker(&chain_id, chainConfig); ethPluginFinalize_t pluginFinalize; + cx_err_t error = CX_INTERNAL_ERROR; // Verify the chain if (chainConfig->chainId != ETHEREUM_MAINNET_CHAINID) { @@ -337,12 +334,12 @@ __attribute__((noinline)) static bool finalize_parsing_helper(bool direct, bool } } // Store the hash - cx_hash((cx_hash_t *) &global_sha3, - CX_LAST, - tmpCtx.transactionContext.hash, - 0, - tmpCtx.transactionContext.hash, - 32); + CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3, + CX_LAST, + tmpCtx.transactionContext.hash, + 0, + tmpCtx.transactionContext.hash, + 32)); // Finalize the plugin handling if (dataContext.tokenContext.pluginStatus >= ETH_PLUGIN_RESULT_SUCCESSFUL) { @@ -529,6 +526,8 @@ __attribute__((noinline)) static bool finalize_parsing_helper(bool direct, bool get_network_as_string(strings.common.network_name, sizeof(strings.common.network_name)); PRINTF("Network: %s\n", strings.common.network_name); return true; +end: + return false; } void finalizeParsing(bool direct) {