From 9556b8f18d0dab6fc84e20f31bad8ba707737562 Mon Sep 17 00:00:00 2001 From: Martin Novak Date: Thu, 8 Dec 2022 15:29:28 +0100 Subject: [PATCH] feat(legacy): code improvements --- legacy/firmware/ethereum.c | 54 ++--- legacy/firmware/ethereum.h | 2 +- legacy/firmware/ethereum_definitions.c | 201 ++++++++---------- legacy/firmware/ethereum_definitions.h | 9 +- .../ethereum_definitions_constants.h.mako | 5 +- legacy/firmware/ethereum_networks.c.mako | 3 +- legacy/firmware/ethereum_networks.h | 2 +- legacy/firmware/fsm.c | 1 + legacy/firmware/fsm_msg_ethereum.h | 155 ++++++-------- tests/ui_tests/fixtures.json | 24 +-- 10 files changed, 206 insertions(+), 250 deletions(-) diff --git a/legacy/firmware/ethereum.c b/legacy/firmware/ethereum.c index c88547196..d00c92b43 100644 --- a/legacy/firmware/ethereum.c +++ b/legacy/firmware/ethereum.c @@ -322,10 +322,7 @@ static void ethereumFormatAmount(const bignum256 *amnt, bn_read_uint32(1000000000, &bn1e9); const char *suffix = NULL; int decimals = 18; - if (is_UnknownToken(token)) { - strlcpy(buf, "Unknown token value", buflen); - return; - } else if (token != NULL) { + if (token) { suffix = token->symbol; decimals = token->decimals; } else if (bn_is_less(amnt, &bn1e9)) { @@ -556,7 +553,7 @@ static bool ethereum_signing_init_common(struct signing_params *params) { } static void ethereum_signing_handle_erc20( - struct signing_params *params, const EthereumDefinitionsDecoded *defs) { + struct signing_params *params, const EthereumTokenInfo *token) { if (params->has_to && ethereum_parse(params->to, params->pubkeyhash)) { params->pubkeyhash_set = true; } else { @@ -570,7 +567,7 @@ static void ethereum_signing_handle_erc20( memcmp(params->data_initial_chunk_bytes, "\xa9\x05\x9c\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) { - params->token = defs ? &defs->token : UnknownToken; + params->token = token; } } @@ -603,9 +600,8 @@ static bool ethereum_signing_confirm_common( void ethereum_signing_init(const EthereumSignTx *msg, const HDNode *node, const EthereumDefinitionsDecoded *defs) { struct signing_params params = { - .chain_id = defs ? defs->network.chain_id : msg->chain_id, - .chain_suffix = - defs ? defs->network.shortcut : get_ethereum_suffix(msg->chain_id), + .chain_id = msg->chain_id, + .chain_suffix = defs->network.shortcut, .data_length = msg->data_length, .data_initial_chunk_size = msg->data_initial_chunk.size, .data_initial_chunk_bytes = msg->data_initial_chunk.bytes, @@ -642,7 +638,7 @@ void ethereum_signing_init(const EthereumSignTx *msg, const HDNode *node, } } - ethereum_signing_handle_erc20(¶ms, defs); + ethereum_signing_handle_erc20(¶ms, &defs->token); if (!ethereum_signing_confirm_common(¶ms)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); @@ -710,10 +706,14 @@ void ethereum_signing_init(const EthereumSignTx *msg, const HDNode *node, void ethereum_signing_init_eip1559(const EthereumSignTxEIP1559 *msg, const HDNode *node, const EthereumDefinitionsDecoded *defs) { + if (!defs) { + ethereum_signing_abort(); + return; + } + struct signing_params params = { - .chain_id = defs ? defs->network.chain_id : msg->chain_id, - .chain_suffix = - defs ? defs->network.shortcut : get_ethereum_suffix(msg->chain_id), + .chain_id = msg->chain_id, + .chain_suffix = defs->network.shortcut, .data_length = msg->data_length, .data_initial_chunk_size = msg->data_initial_chunk.size, @@ -740,7 +740,7 @@ void ethereum_signing_init_eip1559(const EthereumSignTxEIP1559 *msg, return; } - ethereum_signing_handle_erc20(¶ms, defs); + ethereum_signing_handle_erc20(¶ms, &defs->token); if (!ethereum_signing_confirm_common(¶ms)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); @@ -1053,7 +1053,11 @@ bool ethereum_parse(const char *address, uint8_t pubkeyhash[20]) { bool ethereum_path_check(uint32_t address_n_count, const uint32_t *address_n, bool pubkey_export, - const EthereumDefinitionsDecoded *defs) { + const EthereumNetworkInfo *network) { + if (!network) { + return false; + } + bool valid = (address_n_count >= 3); valid = valid && (address_n[0] == (PATH_HARDENED | 44)); valid = valid && (address_n[1] & PATH_HARDENED); @@ -1061,19 +1065,15 @@ bool ethereum_path_check(uint32_t address_n_count, const uint32_t *address_n, valid = valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT); uint32_t path_slip44 = address_n[1] & PATH_UNHARDEN_MASK; - if (!defs || defs->network.chain_id == CHAIN_ID_UNKNOWN) { - valid = valid && (is_ethereum_slip44(path_slip44)); + if (network->slip44 == SLIP44_UNKNOWN) { + // Allow Ethereum or testnet paths for unknown networks. + valid = valid && (path_slip44 == 60 || path_slip44 == 1); + } else if (network->slip44 != 60 && network->slip44 != 1) { + // Allow cross-signing with Ethereum unless it's testnet. + valid = + valid && (path_slip44 == network->slip44 || path_slip44 == 60); } else { - if (defs->network.slip44 == SLIP44_UNKNOWN) { - // Allow Ethereum or testnet paths for unknown networks. - valid = valid && (path_slip44 == 60 || path_slip44 == 1); - } else if (defs->network.slip44 != 60 && defs->network.slip44 != 1) { - // Allow cross-signing with Ethereum unless it's testnet. - valid = - valid && (path_slip44 == defs->network.slip44 || path_slip44 == 60); - } else { - valid = valid && (path_slip44 == defs->network.slip44); - } + valid = valid && (path_slip44 == network->slip44); } if (pubkey_export) { diff --git a/legacy/firmware/ethereum.h b/legacy/firmware/ethereum.h index ff5d869d8..aa6373213 100644 --- a/legacy/firmware/ethereum.h +++ b/legacy/firmware/ethereum.h @@ -46,5 +46,5 @@ bool ethereum_parse(const char *address, uint8_t pubkeyhash[20]); bool ethereum_path_check(uint32_t address_n_count, const uint32_t *address_n, bool pubkey_export, - const EthereumDefinitionsDecoded *defs); + const EthereumNetworkInfo *network); #endif diff --git a/legacy/firmware/ethereum_definitions.c b/legacy/firmware/ethereum_definitions.c index f5b1fa56b..3ea7214a1 100644 --- a/legacy/firmware/ethereum_definitions.c +++ b/legacy/firmware/ethereum_definitions.c @@ -35,142 +35,131 @@ #include "trezor.h" // because of the "VERSTR" macro used in "fsm_sendFailureDebug" function #include "util.h" -typedef struct { +typedef pb_byte_t proof_entry[SHA256_DIGEST_LENGTH]; +typedef struct _ParsedEncodedEthereumDefinitions { // prefix - pb_size_t format_version_start; + pb_byte_t format_version[FORMAT_VERSION_LENGTH]; uint8_t definition_type; uint32_t data_version; - uint16_t payload_length_in_bytes; + uint16_t payload_length; // payload - pb_size_t payload_start; + const pb_byte_t *payload; // suffix uint8_t proof_length; - pb_size_t proof_start; + const proof_entry* proof; - ed25519_signature signed_root_hash; + const ed25519_signature* signed_root_hash; } ParsedEncodedEthereumDefinitions; -const ParsedEncodedEthereumDefinitions *_parse_encoded_EthereumDefinitions( - const pb_size_t size, const pb_byte_t *bytes) { - static ParsedEncodedEthereumDefinitions parsed; - +bool _parse_encoded_EthereumDefinitions( + ParsedEncodedEthereumDefinitions* const result, const pb_size_t size, const pb_byte_t *bytes) { // format version + definition type + data version + payload length + payload // (at least 1B) + proof length + signed Merkle tree root hash if (size < (FORMAT_VERSION_LENGTH + 1 + 4 + 2 + 1 + 1 + MERKLE_TREE_SIGNED_ROOT_SIZE)) { - return (const ParsedEncodedEthereumDefinitions *const)NULL; + return false; } - pb_size_t current_position = 0; - parsed.format_version_start = current_position; - current_position += FORMAT_VERSION_LENGTH; + const pb_byte_t *cursor = bytes; + memcpy(result->format_version, cursor, FORMAT_VERSION_LENGTH); + cursor += FORMAT_VERSION_LENGTH; - parsed.definition_type = bytes[current_position]; - current_position += 1; + result->definition_type = *cursor; + cursor += 1; - parsed.data_version = read_be(&bytes[current_position]); - current_position += 4; + result->data_version = read_be(cursor); + cursor += 4; - parsed.payload_length_in_bytes = (((uint16_t)bytes[current_position]) << 8) | - (((uint16_t)bytes[current_position + 1])); - current_position += 2; + result->payload_length = (((uint16_t)*cursor << 8) | + ((uint16_t)*(cursor + 1))); + cursor += 2; - if (size < current_position - 1) { - return (const ParsedEncodedEthereumDefinitions *const)NULL; - } - parsed.payload_start = current_position; - current_position += parsed.payload_length_in_bytes; + result->payload = cursor; + cursor += result->payload_length; - if (size < current_position - 1) { - return (const ParsedEncodedEthereumDefinitions *const)NULL; + if (size < cursor - bytes) { + return false; } - parsed.proof_length = bytes[current_position]; - current_position += 1; + result->proof_length = *cursor; + cursor += 1; - if (size < current_position - 1) { - return (const ParsedEncodedEthereumDefinitions *const)NULL; + // check the whole size of incoming bytes array + if (size != (cursor - bytes) + result->proof_length * sizeof(proof_entry) + MERKLE_TREE_SIGNED_ROOT_SIZE) { + return false; } - parsed.proof_start = current_position; - current_position += parsed.proof_length * SHA256_DIGEST_LENGTH; + result->proof = (proof_entry*) cursor; + cursor += result->proof_length * sizeof(proof_entry); - if (size < current_position + MERKLE_TREE_SIGNED_ROOT_SIZE - 1) { - return (const ParsedEncodedEthereumDefinitions *const)NULL; - } - memcpy(&parsed.signed_root_hash, &bytes[current_position], - MERKLE_TREE_SIGNED_ROOT_SIZE); + result->signed_root_hash = (ed25519_signature*) cursor; - return (const ParsedEncodedEthereumDefinitions *const)&parsed; + return true; } bool _decode_definition(const pb_size_t size, const pb_byte_t *bytes, const EthereumDefinitionType expected_type, void *definition) { // parse received definition - const ParsedEncodedEthereumDefinitions *parsed_def = - _parse_encoded_EthereumDefinitions(size, bytes); - if (!parsed_def) { + static ParsedEncodedEthereumDefinitions parsed_def; + if (!_parse_encoded_EthereumDefinitions(&parsed_def, size, bytes)) { fsm_sendFailure(FailureType_Failure_DataError, _("Invalid Ethereum definition")); return false; } // check definition fields - if (memcmp(FORMAT_VERSION, &bytes[parsed_def->format_version_start], + if (memcmp(FORMAT_VERSION, parsed_def.format_version, FORMAT_VERSION_LENGTH)) { fsm_sendFailure(FailureType_Failure_DataError, _("Invalid definition format")); return false; } - if (expected_type != parsed_def->definition_type) { + if (expected_type != parsed_def.definition_type) { fsm_sendFailure(FailureType_Failure_DataError, _("Definition type mismatch")); return false; } - if (MIN_DATA_VERSION > parsed_def->data_version) { + if (MIN_DATA_VERSION > parsed_def.data_version) { fsm_sendFailure(FailureType_Failure_DataError, _("Definition is outdated")); return false; } // compute Merkle tree root hash from proof uint8_t hash[SHA256_DIGEST_LENGTH] = {0}; - uint8_t hash_data[HASH_DATA_BUFFER_SIZE]; - memzero(hash_data, HASH_DATA_BUFFER_SIZE); + uint8_t hash_prefix = '\x00'; + SHA256_CTX context = {0}; + sha256_Init(&context); // leaf hash = sha256('\x00' + leaf data) - memcpy(&hash_data[1], bytes, - parsed_def->payload_start + parsed_def->payload_length_in_bytes); - sha256_Raw( - hash_data, - 1 + parsed_def->payload_start + parsed_def->payload_length_in_bytes, - hash); - - pb_size_t index = parsed_def->proof_start; + sha256_Update(&context, &hash_prefix, 1); + sha256_Update(&context, bytes, (parsed_def.payload - bytes) + parsed_def.payload_length); + sha256_Final(&context, hash); + int cmp = 0; const void *min, *max; - for (uint8_t i = 0; i < parsed_def->proof_length; i++) { - memzero(hash_data, HASH_DATA_BUFFER_SIZE); + hash_prefix = '\x01'; + for (uint8_t i = 0; i < parsed_def.proof_length; i++) { + sha256_Init(&context); // node hash = sha256('\x01' + min(hash, next_proof) + max(hash, // next_proof)) - hash_data[0] = '\x01'; - cmp = memcmp(hash, &bytes[index], SHA256_DIGEST_LENGTH); - min = cmp < 1 ? hash : &bytes[index]; - max = cmp > 0 ? hash : &bytes[index]; - memcpy(&hash_data[1], min, SHA256_DIGEST_LENGTH); - memcpy(&hash_data[1 + SHA256_DIGEST_LENGTH], max, SHA256_DIGEST_LENGTH); - sha256_Raw(hash_data, 1 + SHA256_DIGEST_LENGTH * 2, hash); - index += SHA256_DIGEST_LENGTH; + sha256_Update(&context, &hash_prefix, 1); + cmp = memcmp(hash, parsed_def.proof + i, SHA256_DIGEST_LENGTH); + min = cmp < 1 ? hash : (void*) (parsed_def.proof + i); + max = cmp > 0 ? hash : (void*) (parsed_def.proof + i); + sha256_Update(&context, min, SHA256_DIGEST_LENGTH); + sha256_Update(&context, max, SHA256_DIGEST_LENGTH); + sha256_Final(&context, hash); } // and verify its signature if (ed25519_sign_open(hash, SHA256_DIGEST_LENGTH, DEFINITIONS_PUBLIC_KEY, - parsed_def->signed_root_hash) != 0 + *(parsed_def.signed_root_hash)) != 0 #if DEBUG_LINK && ed25519_sign_open(hash, SHA256_DIGEST_LENGTH, DEFINITIONS_DEV_PUBLIC_KEY, - parsed_def->signed_root_hash) != 0 + *(parsed_def.signed_root_hash)) != 0 #endif ) { // invalid signature @@ -183,9 +172,8 @@ bool _decode_definition(const pb_size_t size, const pb_byte_t *bytes, const pb_msgdesc_t *fields = (expected_type == EthereumDefinitionType_NETWORK ? EthereumNetworkInfo_fields : EthereumTokenInfo_fields); - memzero(definition, sizeof(definition)); pb_istream_t stream = pb_istream_from_buffer( - &bytes[parsed_def->payload_start], parsed_def->payload_length_in_bytes); + parsed_def.payload, parsed_def.payload_length); bool status = pb_decode(&stream, fields, definition); if (!status) { // invalid message @@ -196,10 +184,15 @@ bool _decode_definition(const pb_size_t size, const pb_byte_t *bytes, return true; } -void _set_EthereumNetworkInfo_to_builtin(const uint64_t ref_chain_id, +void _set_EthereumNetworkInfo_to_builtin(const uint64_t ref_chain_id, const uint32_t ref_slip44, EthereumNetworkInfo *network) { + if (ref_chain_id == CHAIN_ID_UNKNOWN) { + // we don't know chain id so we can use only slip44 + network->slip44 = is_ethereum_slip44(ref_slip44) ? ref_slip44 : SLIP44_UNKNOWN; + } else { + network->slip44 = ethereum_slip44_by_chain_id(ref_chain_id); + } network->chain_id = ref_chain_id; - network->slip44 = ethereum_slip44_by_chain_id(ref_chain_id); memzero(network->shortcut, sizeof(network->shortcut)); const char *sc = get_ethereum_suffix(ref_chain_id); strncpy(network->shortcut, sc, sizeof(network->shortcut) - 1); @@ -207,64 +200,45 @@ void _set_EthereumNetworkInfo_to_builtin(const uint64_t ref_chain_id, } bool _get_EthereumNetworkInfo( - const EthereumDefinitions_encoded_network_t *encoded_network, - const uint64_t ref_chain_id, EthereumNetworkInfo *network) { + const EncodedNetwork *encoded_network, + const uint64_t ref_chain_id, const uint32_t ref_slip44, EthereumNetworkInfo *network) { // try to get built-in definition - _set_EthereumNetworkInfo_to_builtin(ref_chain_id, network); + _set_EthereumNetworkInfo_to_builtin(ref_chain_id, ref_slip44, network); // if we still do not have any network definition try to decode the received // one - if (strncmp(network->shortcut, UNKNOWN_NETWORK_SHORTCUT, - sizeof(network->shortcut)) == 0 && - encoded_network != NULL) { + if (network->slip44 == SLIP44_UNKNOWN && encoded_network != NULL) { if (_decode_definition(encoded_network->size, encoded_network->bytes, - EthereumDefinitionType_NETWORK, (void *)network)) { + EthereumDefinitionType_NETWORK, network)) { if (ref_chain_id != CHAIN_ID_UNKNOWN && network->chain_id != ref_chain_id) { // chain_id mismatch - error and reset definition fsm_sendFailure(FailureType_Failure_DataError, _("Network definition mismatch")); - _set_EthereumNetworkInfo_to_builtin(CHAIN_ID_UNKNOWN, network); return false; + } else if (ref_slip44 != SLIP44_UNKNOWN && network->slip44 != ref_slip44) { + // slip44 mismatch - reset network definition + _set_EthereumNetworkInfo_to_builtin(CHAIN_ID_UNKNOWN, SLIP44_UNKNOWN, network); } else { // chain_id does match the reference one (if provided) so prepend one // space character to symbol, terminate it (encoded definitions does not // have space prefix) and return the decoded data - memmove(&network->shortcut[1], &network->shortcut, + memmove(network->shortcut + 1, network->shortcut, sizeof(network->shortcut) - 2); network->shortcut[0] = ' '; network->shortcut[sizeof(network->shortcut) - 1] = 0; } } else { // decoding failed - reset network definition - _set_EthereumNetworkInfo_to_builtin(CHAIN_ID_UNKNOWN, network); + _set_EthereumNetworkInfo_to_builtin(CHAIN_ID_UNKNOWN, SLIP44_UNKNOWN, network); } } return true; } -void _set_EthereumTokenInfo(const EthereumTokenInfo *ref_token, - EthereumTokenInfo *token) { - // reset - memzero(token->symbol, sizeof(token->symbol)); - token->decimals = 0; - memzero(token->address.bytes, sizeof(token->address.bytes)); - token->address.size = 0; - token->chain_id = CHAIN_ID_UNKNOWN; - memzero(token->name, sizeof(token->name)); - - // copy data to token definition - strncpy(token->symbol, ref_token->symbol, sizeof(token->symbol) - 1); - token->decimals = ref_token->decimals; - memcpy(token->address.bytes, ref_token->address.bytes, - sizeof(token->address.bytes)); - token->address.size = sizeof(token->address.bytes); - token->chain_id = ref_token->chain_id; -} - bool _get_EthereumTokenInfo( - const EthereumDefinitions_encoded_token_t *encoded_token, + const EncodedToken *encoded_token, const uint64_t ref_chain_id, const char *ref_address, EthereumTokenInfo *token) { EthereumTokenInfo_address_t ref_address_bytes; @@ -282,7 +256,7 @@ bool _get_EthereumTokenInfo( // if we do not have any token definition try to decode the received one if (builtin == UnknownToken && encoded_token != NULL) { if (_decode_definition(encoded_token->size, encoded_token->bytes, - EthereumDefinitionType_TOKEN, (void *)token)) { + EthereumDefinitionType_TOKEN, token)) { if ((ref_chain_id == CHAIN_ID_UNKNOWN || token->chain_id == ref_chain_id) && (!address_parsed || @@ -291,7 +265,7 @@ bool _get_EthereumTokenInfo( // chain_id and/or address does match the reference ones (if provided) // so prepend one space character to symbol, terminate it (encoded // definitions does not have space prefix) and return the decoded data - memmove(&token->symbol[1], &token->symbol, sizeof(token->symbol) - 2); + memmove(token->symbol + 1, token->symbol, sizeof(token->symbol) - 2); token->symbol[0] = ' '; token->symbol[sizeof(token->symbol) - 1] = 0; return true; @@ -303,37 +277,36 @@ bool _get_EthereumTokenInfo( // decoding failed or token definition has different // chain_id and/or address - _set_EthereumTokenInfo(UnknownToken, token); return false; } // copy result - _set_EthereumTokenInfo(builtin, token); + *token = *builtin; return true; } const EthereumDefinitionsDecoded *get_EthereumDefinitionsDecoded( - const EthereumDefinitions_encoded_network_t *encoded_network, - const EthereumDefinitions_encoded_token_t *encoded_token, - const uint64_t ref_chain_id, const char *ref_address) { + const EncodedNetwork *encoded_network, + const EncodedToken *encoded_token, + const uint64_t ref_chain_id, const uint32_t ref_slip44, const char *ref_address) { static EthereumDefinitionsDecoded defs; + memzero(&defs, sizeof(defs)); - if (!_get_EthereumNetworkInfo(encoded_network, ref_chain_id, &defs.network)) { + if (!_get_EthereumNetworkInfo(encoded_network, ref_chain_id, ref_slip44, &defs.network)) { // error while decoding - chain IDs mismatch return NULL; } - if (strncmp(defs.network.shortcut, UNKNOWN_NETWORK_SHORTCUT, - sizeof(defs.network.shortcut)) != 0) { + if (defs.network.slip44 != SLIP44_UNKNOWN && defs.network.chain_id != CHAIN_ID_UNKNOWN) { // we have found network definition, we can try to load token definition - if (!_get_EthereumTokenInfo(encoded_token, ref_chain_id, ref_address, + if (!_get_EthereumTokenInfo(encoded_token, defs.network.chain_id, ref_address, &defs.token)) { return NULL; } } else { // if we did not find any network definition, set token definition to // unknown token - _set_EthereumTokenInfo(UnknownToken, &defs.token); + defs.token = *UnknownToken; } return &defs; } diff --git a/legacy/firmware/ethereum_definitions.h b/legacy/firmware/ethereum_definitions.h index cc390e1f0..0c6d9faa1 100644 --- a/legacy/firmware/ethereum_definitions.h +++ b/legacy/firmware/ethereum_definitions.h @@ -22,14 +22,17 @@ #include "messages-ethereum-definitions.pb.h" +typedef EthereumDefinitions_encoded_network_t EncodedNetwork; +typedef EthereumDefinitions_encoded_token_t EncodedToken; + typedef struct { EthereumNetworkInfo network; EthereumTokenInfo token; } EthereumDefinitionsDecoded; const EthereumDefinitionsDecoded *get_EthereumDefinitionsDecoded( - const EthereumDefinitions_encoded_network_t *encoded_network, - const EthereumDefinitions_encoded_token_t *encoded_token, - const uint64_t ref_chain_id, const char *ref_address); + const EncodedNetwork *encoded_network, + const EncodedToken *encoded_token, + const uint64_t ref_chain_id, const uint32_t ref_slip44, const char *ref_address); #endif diff --git a/legacy/firmware/ethereum_definitions_constants.h.mako b/legacy/firmware/ethereum_definitions_constants.h.mako index 7cd41962d..1a2a28c65 100644 --- a/legacy/firmware/ethereum_definitions_constants.h.mako +++ b/legacy/firmware/ethereum_definitions_constants.h.mako @@ -21,9 +21,6 @@ static const uint8_t DEFINITIONS_DEV_PUBLIC_KEY[] = #define MIN_DATA_VERSION ${ethereum_defs_timestamp} #define FORMAT_VERSION_LENGTH 5 #define FORMAT_VERSION (const pb_byte_t *)"trzd1" -#define MERKLE_TREE_SIGNED_ROOT_SIZE 64 - -#define HASH_DATA_BUFFER_SIZE \ - (1 + MAX(EthereumDefinitions_size / 2, 2 * SHA256_DIGEST_LENGTH)) +#define MERKLE_TREE_SIGNED_ROOT_SIZE sizeof(ed25519_signature) #endif diff --git a/legacy/firmware/ethereum_networks.c.mako b/legacy/firmware/ethereum_networks.c.mako index 3c76452fa..e22cfb35b 100644 --- a/legacy/firmware/ethereum_networks.c.mako +++ b/legacy/firmware/ethereum_networks.c.mako @@ -34,7 +34,6 @@ const char *get_ethereum_suffix(uint64_t chain_id) { } } -// TODO: do we need this functions? bool is_ethereum_slip44(uint32_t slip44) { switch (slip44) { % for slip44 in sorted(set(n.slip44 for n in networks)): @@ -46,7 +45,7 @@ bool is_ethereum_slip44(uint32_t slip44) { } } -int32_t ethereum_slip44_by_chain_id(uint64_t chain_id) { +uint32_t ethereum_slip44_by_chain_id(uint64_t chain_id) { switch (chain_id) { % for n in networks: case ${align_chain_id(n)}: return ${align_slip44(n)}; /* ${n.name} */ diff --git a/legacy/firmware/ethereum_networks.h b/legacy/firmware/ethereum_networks.h index 00490f907..e4f9bbb68 100644 --- a/legacy/firmware/ethereum_networks.h +++ b/legacy/firmware/ethereum_networks.h @@ -28,6 +28,6 @@ const char *get_ethereum_suffix(uint64_t chain_id); bool is_ethereum_slip44(uint32_t slip44); -int32_t ethereum_slip44_by_chain_id(uint64_t chain_id); +uint32_t ethereum_slip44_by_chain_id(uint64_t chain_id); #endif diff --git a/legacy/firmware/fsm.c b/legacy/firmware/fsm.c index 02ac94fa0..a4535f112 100644 --- a/legacy/firmware/fsm.c +++ b/legacy/firmware/fsm.c @@ -56,6 +56,7 @@ #if !BITCOIN_ONLY #include "ethereum.h" #include "ethereum_definitions.h" +#include "ethereum_networks.h" #include "nem.h" #include "nem2.h" #include "stellar.h" diff --git a/legacy/firmware/fsm_msg_ethereum.h b/legacy/firmware/fsm_msg_ethereum.h index d2f99c084..4466a30b8 100644 --- a/legacy/firmware/fsm_msg_ethereum.h +++ b/legacy/firmware/fsm_msg_ethereum.h @@ -19,8 +19,12 @@ static bool fsm_ethereumCheckPath(uint32_t address_n_count, const uint32_t *address_n, bool pubkey_export, - const EthereumDefinitionsDecoded *defs) { - if (ethereum_path_check(address_n_count, address_n, pubkey_export, defs)) { + const EthereumNetworkInfo *network) { + if (!network) { + return false; + } + + if (ethereum_path_check(address_n_count, address_n, pubkey_export, network)) { return true; } @@ -32,6 +36,35 @@ static bool fsm_ethereumCheckPath(uint32_t address_n_count, return fsm_layoutPathWarning(); } +static const EthereumDefinitionsDecoded* get_definitions(bool has_definitions, const EthereumDefinitions* definitions, uint64_t chain_id, const char* to) { + const EncodedNetwork *encoded_network = NULL; + const EncodedToken *encoded_token = NULL; + if (has_definitions && definitions) { + if (definitions->has_encoded_network) { + encoded_network = &definitions->encoded_network; + } + if (definitions->has_encoded_token) { + encoded_token = &definitions->encoded_token; + } + } + + return get_EthereumDefinitionsDecoded( + encoded_network, encoded_token, chain_id, SLIP44_UNKNOWN, + to); +} + +static const EthereumNetworkInfo* get_network_definition_only(bool has_encoded_network, const EncodedNetwork* encoded_network, const uint32_t slip44) { + const EncodedNetwork *en = NULL; + if (has_encoded_network) { + en = (const EncodedNetwork*) encoded_network; + } + + const EthereumDefinitionsDecoded* defs = get_EthereumDefinitionsDecoded( + en, NULL, CHAIN_ID_UNKNOWN, slip44, NULL); + + return defs ? &defs->network : NULL; +} + void fsm_msgEthereumGetPublicKey(const EthereumGetPublicKey *msg) { RESP_INIT(EthereumPublicKey); @@ -43,12 +76,6 @@ void fsm_msgEthereumGetPublicKey(const EthereumGetPublicKey *msg) { const CoinInfo *coin = fsm_getCoin(true, "Bitcoin"); if (!coin) return; - if (!fsm_ethereumCheckPath(msg->address_n_count, msg->address_n, true, - NULL)) { - layoutHome(); - return; - } - const char *curve = coin->curve_name; uint32_t fingerprint; HDNode *node = fsm_getDerivedNode(curve, msg->address_n, msg->address_n_count, @@ -92,25 +119,12 @@ void fsm_msgEthereumSignTx(const EthereumSignTx *msg) { CHECK_PIN - const EthereumDefinitions_encoded_network_t *encoded_network = NULL; - const EthereumDefinitions_encoded_token_t *encoded_token = NULL; - if (msg->has_definitions) { - if (msg->definitions.has_encoded_network) { - encoded_network = (const EthereumDefinitions_encoded_network_t *)&msg - ->definitions.encoded_network; - } - if (msg->definitions.has_encoded_token) { - encoded_token = (const EthereumDefinitions_encoded_token_t *)&msg - ->definitions.encoded_token; - } - } - - const EthereumDefinitionsDecoded *defs = get_EthereumDefinitionsDecoded( - encoded_network, encoded_token, msg->chain_id, + const EthereumDefinitionsDecoded *defs = get_definitions( + msg->has_definitions, &msg->definitions, msg->chain_id, msg->has_to ? msg->to : NULL); if (!defs || !fsm_ethereumCheckPath(msg->address_n_count, msg->address_n, - false, defs)) { + false, &defs->network)) { layoutHome(); return; } @@ -127,25 +141,12 @@ void fsm_msgEthereumSignTxEIP1559(const EthereumSignTxEIP1559 *msg) { CHECK_PIN - const EthereumDefinitions_encoded_network_t *encoded_network = NULL; - const EthereumDefinitions_encoded_token_t *encoded_token = NULL; - if (msg->has_definitions) { - if (msg->definitions.has_encoded_network) { - encoded_network = (const EthereumDefinitions_encoded_network_t *)&msg - ->definitions.encoded_network; - } - if (msg->definitions.has_encoded_token) { - encoded_token = (const EthereumDefinitions_encoded_token_t *)&msg - ->definitions.encoded_token; - } - } - - const EthereumDefinitionsDecoded *defs = get_EthereumDefinitionsDecoded( - encoded_network, encoded_token, msg->chain_id, + const EthereumDefinitionsDecoded *defs = get_definitions( + msg->has_definitions, &msg->definitions, msg->chain_id, msg->has_to ? msg->to : NULL); if (!defs || !fsm_ethereumCheckPath(msg->address_n_count, msg->address_n, - false, defs)) { + false, &defs->network)) { layoutHome(); return; } @@ -170,17 +171,14 @@ void fsm_msgEthereumGetAddress(const EthereumGetAddress *msg) { CHECK_PIN - const EthereumDefinitions_encoded_network_t *encoded_network = NULL; - if (msg->has_encoded_network) { - encoded_network = - (const EthereumDefinitions_encoded_network_t *)&msg->encoded_network; - } + uint32_t slip44 = + (msg->address_n_count > 1) ? (msg->address_n[1] & PATH_UNHARDEN_MASK) : 0; - const EthereumDefinitionsDecoded *defs = get_EthereumDefinitionsDecoded( - encoded_network, NULL, CHAIN_ID_UNKNOWN, NULL); + const EthereumNetworkInfo *network = get_network_definition_only( + msg->has_encoded_network, (const EncodedNetwork*) &msg->encoded_network, slip44); - if (!defs || !fsm_ethereumCheckPath(msg->address_n_count, msg->address_n, - false, defs)) { + if (!fsm_ethereumCheckPath(msg->address_n_count, msg->address_n, + false, network)) { layoutHome(); return; } @@ -195,27 +193,18 @@ void fsm_msgEthereumGetAddress(const EthereumGetAddress *msg) { layoutHome(); return; } - - uint32_t slip44 = - (msg->address_n_count > 1) ? (msg->address_n[1] & PATH_UNHARDEN_MASK) : 0; bool rskip60 = false; uint64_t chain_id = 0; - - if (defs->network.chain_id != CHAIN_ID_UNKNOWN && - defs->network.slip44 == slip44) { - chain_id = defs->network.chain_id; - } else { - // constants from trezor-common/defs/ethereum/networks.json - switch (slip44) { - case 137: - rskip60 = true; - chain_id = 30; - break; - case 37310: - rskip60 = true; - chain_id = 31; - break; - } + // constants from trezor-common/defs/ethereum/networks.json + switch (slip44) { + case 137: + rskip60 = true; + chain_id = 30; + break; + case 37310: + rskip60 = true; + chain_id = 31; + break; } resp->has_address = true; @@ -243,17 +232,14 @@ void fsm_msgEthereumSignMessage(const EthereumSignMessage *msg) { CHECK_PIN - const EthereumDefinitions_encoded_network_t *encoded_network = NULL; - if (msg->has_encoded_network) { - encoded_network = - (const EthereumDefinitions_encoded_network_t *)&msg->encoded_network; - } + uint32_t slip44 = + (msg->address_n_count > 1) ? (msg->address_n[1] & PATH_UNHARDEN_MASK) : 0; - const EthereumDefinitionsDecoded *defs = get_EthereumDefinitionsDecoded( - encoded_network, NULL, CHAIN_ID_UNKNOWN, NULL); + const EthereumNetworkInfo *network = get_network_definition_only( + msg->has_encoded_network, (const EncodedNetwork*) &msg->encoded_network, slip44); - if (!defs || !fsm_ethereumCheckPath(msg->address_n_count, msg->address_n, - false, defs)) { + if (!fsm_ethereumCheckPath(msg->address_n_count, msg->address_n, + false, network)) { layoutHome(); return; } @@ -339,17 +325,14 @@ void fsm_msgEthereumSignTypedHash(const EthereumSignTypedHash *msg) { return; } - const EthereumDefinitions_encoded_network_t *encoded_network = NULL; - if (msg->has_encoded_network) { - encoded_network = - (const EthereumDefinitions_encoded_network_t *)&msg->encoded_network; - } + uint32_t slip44 = + (msg->address_n_count > 1) ? (msg->address_n[1] & PATH_UNHARDEN_MASK) : 0; - const EthereumDefinitionsDecoded *defs = get_EthereumDefinitionsDecoded( - encoded_network, NULL, CHAIN_ID_UNKNOWN, NULL); + const EthereumNetworkInfo *network = get_network_definition_only( + msg->has_encoded_network, (const EncodedNetwork*) &msg->encoded_network, slip44); - if (!defs || !fsm_ethereumCheckPath(msg->address_n_count, msg->address_n, - false, defs)) { + if (!fsm_ethereumCheckPath(msg->address_n_count, msg->address_n, + false, network)) { layoutHome(); return; } diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index 38eb4bba6..6b004124f 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -401,13 +401,13 @@ "T1_ethereum-test_signtx.py::test_signtx[builtin_Ethereum_builtin_Tether_send_nothing]": "2ad8d58e1c04bfde465902c6edd2308a392a4afeffbeaf5e32e0ef22380acf75", "T1_ethereum-test_signtx.py::test_signtx[builtin_Ethereum_builtin_Tether_send_token]": "2ad8d58e1c04bfde465902c6edd2308a392a4afeffbeaf5e32e0ef22380acf75", "T1_ethereum-test_signtx.py::test_signtx[builtin_Ethereum_builtin_Tether_wrong_network]": "2ad8d58e1c04bfde465902c6edd2308a392a4afeffbeaf5e32e0ef22380acf75", -"T1_ethereum-test_signtx.py::test_signtx[builtin_Ethereum_extern_adChain_send_network]": "0143f7c4273964eb5eb8113c7e63674c033bebeca7ae619270b7ca77bb6aed66", +"T1_ethereum-test_signtx.py::test_signtx[builtin_Ethereum_extern_adChain_send_network]": "54fca1212bbee09bcbc2207528d6f92bed486efc35bfe2361194887ad7d86f9c", "T1_ethereum-test_signtx.py::test_signtx[builtin_Ethereum_extern_adChain_send_network_token]": "08e9da493a8ac1f4e7f05bbb8f7c2b2fd97481421899a170ac0ead26b0764a21", -"T1_ethereum-test_signtx.py::test_signtx[builtin_Ethereum_extern_adChain_send_nothing]": "0143f7c4273964eb5eb8113c7e63674c033bebeca7ae619270b7ca77bb6aed66", +"T1_ethereum-test_signtx.py::test_signtx[builtin_Ethereum_extern_adChain_send_nothing]": "54fca1212bbee09bcbc2207528d6f92bed486efc35bfe2361194887ad7d86f9c", "T1_ethereum-test_signtx.py::test_signtx[builtin_Ethereum_extern_adChain_send_token]": "08e9da493a8ac1f4e7f05bbb8f7c2b2fd97481421899a170ac0ead26b0764a21", "T1_ethereum-test_signtx.py::test_signtx[data_1]": "8b432aba21bc4344814cceaf693e114b9d3e3d6ceb83c3a6af7c3ed0f9b37449", "T1_ethereum-test_signtx.py::test_signtx[data_2_bigdata]": "445286b7501ca67dd16dafd7ea09c57cc4a37a642ae50f0c812d74353c37c017", -"T1_ethereum-test_signtx.py::test_signtx[extern_Ubiq_extern_Sphere_send_network]": "0143f7c4273964eb5eb8113c7e63674c033bebeca7ae619270b7ca77bb6aed66", +"T1_ethereum-test_signtx.py::test_signtx[extern_Ubiq_extern_Sphere_send_network]": "54fca1212bbee09bcbc2207528d6f92bed486efc35bfe2361194887ad7d86f9c", "T1_ethereum-test_signtx.py::test_signtx[extern_Ubiq_extern_Sphere_send_network_token]": "6f7c7fa6f3c59a653f068f1c63238d15178513d99575cd6ce5c6608c7d1baed2", "T1_ethereum-test_signtx.py::test_signtx[known_erc20_token]": "7ef8d3bbf6e299b41522769a893f72b04571fc7176bc93e5c1701a2b5721fb20", "T1_ethereum-test_signtx.py::test_signtx[max_chain_id]": "a6e6d63cba839c897e80dc0b7cf5c2263be8ff64a5281a43fca992380cca872b", @@ -416,25 +416,25 @@ "T1_ethereum-test_signtx.py::test_signtx[newcontract]": "a7efa7f690d1448dc48f642f69688e8b266417901cc014e5930c94c9087b3e08", "T1_ethereum-test_signtx.py::test_signtx[nodata_1]": "6bd90f2c98122de19159e60fd4dcf9f4b16a600407ac84ea1e447d561ea9decb", "T1_ethereum-test_signtx.py::test_signtx[nodata_2_bigvalue]": "538f7be885ce6ea3a6dc842ef10797fa45184d7737f6f179c42d36fe92fadd45", -"T1_ethereum-test_signtx.py::test_signtx[unknown_erc20_token]": "df41efe4c5336fc188d3f754d2fe0b830588e57eaa32c98607b0bc4057851fcc", +"T1_ethereum-test_signtx.py::test_signtx[unknown_erc20_token]": "911121dafe31a079fe736782373cfe9d1d329fcd8f2916b7bf052ce89da380c1", "T1_ethereum-test_signtx.py::test_signtx[wanchain]": "37aa64fbab44b89757833df6ee78e302c97fe24c4cb74175f1843f635cb2dbec", "T1_ethereum-test_signtx.py::test_signtx_eip1559[Ledger Live legacy path]": "5b008a081b4ef9e7b47c9d0c1fc4bb24d729d77841193694232bd2da4a386515", "T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_builtin_Tether_send_network]": "267527c7713363820da9ec21c0c4c3202c5d257886500a2c3f60c0f4fc078d90", "T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_builtin_Tether_send_network_token]": "267527c7713363820da9ec21c0c4c3202c5d257886500a2c3f60c0f4fc078d90", "T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_builtin_Tether_send_nothing]": "267527c7713363820da9ec21c0c4c3202c5d257886500a2c3f60c0f4fc078d90", "T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_builtin_Tether_send_token]": "267527c7713363820da9ec21c0c4c3202c5d257886500a2c3f60c0f4fc078d90", -"T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_extern_adChain_send_network]": "3ecdb8fe6a70e4cd8ca9829156927a997154ce6a8062bd8564731abc7d1cda0f", +"T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_extern_adChain_send_network]": "2c11cc7946fd87485bc10f9ba5ceeb8571f8c5244d0ff7c6669e4554615f44f9", "T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_extern_adChain_send_network_token]": "9eac799b87d0705f2c254e9de44a25b98272eca2ed9be12d41ee8b47e839cbf0", -"T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_extern_adChain_send_nothing]": "3ecdb8fe6a70e4cd8ca9829156927a997154ce6a8062bd8564731abc7d1cda0f", +"T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_extern_adChain_send_nothing]": "2c11cc7946fd87485bc10f9ba5ceeb8571f8c5244d0ff7c6669e4554615f44f9", "T1_ethereum-test_signtx.py::test_signtx_eip1559[builtin_Ethereum_extern_adChain_send_token]": "9eac799b87d0705f2c254e9de44a25b98272eca2ed9be12d41ee8b47e839cbf0", "T1_ethereum-test_signtx.py::test_signtx_eip1559[data_1]": "171ffadf61a2520274bedf6a8543127f23a8948c2689e034f996e170289b1822", "T1_ethereum-test_signtx.py::test_signtx_eip1559[data_2_bigdata]": "28d2a0d397b4e9865ca8286cc1a3669c3a7d34bb31b430662354bf3ec69d1cc5", -"T1_ethereum-test_signtx.py::test_signtx_eip1559[extern_Ubiq_extern_Sphere_send_network]": "3ecdb8fe6a70e4cd8ca9829156927a997154ce6a8062bd8564731abc7d1cda0f", +"T1_ethereum-test_signtx.py::test_signtx_eip1559[extern_Ubiq_extern_Sphere_send_network]": "2c11cc7946fd87485bc10f9ba5ceeb8571f8c5244d0ff7c6669e4554615f44f9", "T1_ethereum-test_signtx.py::test_signtx_eip1559[extern_Ubiq_extern_Sphere_send_network_token]": "b1e9a28be3f74d1bd2311a6cd089f4aa467df986cc7fe195f1f1184b9078214a", "T1_ethereum-test_signtx.py::test_signtx_eip1559[known_erc20]": "b8e205a40711e377f2185cec6e085fa2f6a4d5bbc6a03d9cf2758058b6c1e17b", "T1_ethereum-test_signtx.py::test_signtx_eip1559[large_chainid]": "5b008a081b4ef9e7b47c9d0c1fc4bb24d729d77841193694232bd2da4a386515", "T1_ethereum-test_signtx.py::test_signtx_eip1559[nodata]": "5b008a081b4ef9e7b47c9d0c1fc4bb24d729d77841193694232bd2da4a386515", -"T1_ethereum-test_signtx.py::test_signtx_eip1559[unknown_erc20]": "548c1f22918351e9cbcc1e16d8ba67bc2e7460b9a92cfc6c8bfa0a2b063e68da", +"T1_ethereum-test_signtx.py::test_signtx_eip1559[unknown_erc20]": "4165cdb71da00d7cc20d4b8e1f348943dccc0d7400e232d832875ae806359be3", "T1_ethereum-test_signtx.py::test_signtx_eip1559_access_list": "f6c5f398d4e80fc8f93cf70e9b10de24b9a968db04dc6ea21b28d1a273f04ca1", "T1_ethereum-test_signtx.py::test_signtx_eip1559_access_list_larger": "f6c5f398d4e80fc8f93cf70e9b10de24b9a968db04dc6ea21b28d1a273f04ca1", "T1_ethereum-test_signtx.py::test_signtx_eip1559_failed[extern_Ubiq_extern_Sphere_missing_network]": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", @@ -465,13 +465,13 @@ "T1_ethereum-test_signtx.py::test_signtx_online_definitions[builtin_Ethereum_builtin_Tether_send_token]": "2ad8d58e1c04bfde465902c6edd2308a392a4afeffbeaf5e32e0ef22380acf75", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[builtin_Ethereum_builtin_Tether_wro-d290218e": "2ad8d58e1c04bfde465902c6edd2308a392a4afeffbeaf5e32e0ef22380acf75", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[builtin_Ethereum_extern_adChain_sen-67be0845": "08e9da493a8ac1f4e7f05bbb8f7c2b2fd97481421899a170ac0ead26b0764a21", -"T1_ethereum-test_signtx.py::test_signtx_online_definitions[builtin_Ethereum_extern_adChain_sen-82ca1e91": "0143f7c4273964eb5eb8113c7e63674c033bebeca7ae619270b7ca77bb6aed66", -"T1_ethereum-test_signtx.py::test_signtx_online_definitions[builtin_Ethereum_extern_adChain_sen-9f73b317": "0143f7c4273964eb5eb8113c7e63674c033bebeca7ae619270b7ca77bb6aed66", +"T1_ethereum-test_signtx.py::test_signtx_online_definitions[builtin_Ethereum_extern_adChain_sen-82ca1e91": "54fca1212bbee09bcbc2207528d6f92bed486efc35bfe2361194887ad7d86f9c", +"T1_ethereum-test_signtx.py::test_signtx_online_definitions[builtin_Ethereum_extern_adChain_sen-9f73b317": "54fca1212bbee09bcbc2207528d6f92bed486efc35bfe2361194887ad7d86f9c", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[builtin_Ethereum_extern_adChain_send_token]": "08e9da493a8ac1f4e7f05bbb8f7c2b2fd97481421899a170ac0ead26b0764a21", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[data_1]": "8b432aba21bc4344814cceaf693e114b9d3e3d6ceb83c3a6af7c3ed0f9b37449", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[data_2_bigdata]": "445286b7501ca67dd16dafd7ea09c57cc4a37a642ae50f0c812d74353c37c017", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[extern_Ubiq_extern_Sphere_send_netw-eaee9424": "6f7c7fa6f3c59a653f068f1c63238d15178513d99575cd6ce5c6608c7d1baed2", -"T1_ethereum-test_signtx.py::test_signtx_online_definitions[extern_Ubiq_extern_Sphere_send_network]": "0143f7c4273964eb5eb8113c7e63674c033bebeca7ae619270b7ca77bb6aed66", +"T1_ethereum-test_signtx.py::test_signtx_online_definitions[extern_Ubiq_extern_Sphere_send_network]": "54fca1212bbee09bcbc2207528d6f92bed486efc35bfe2361194887ad7d86f9c", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[known_erc20_token]": "7ef8d3bbf6e299b41522769a893f72b04571fc7176bc93e5c1701a2b5721fb20", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[max_chain_id]": "a6e6d63cba839c897e80dc0b7cf5c2263be8ff64a5281a43fca992380cca872b", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[max_chain_plus_one]": "a6e6d63cba839c897e80dc0b7cf5c2263be8ff64a5281a43fca992380cca872b", @@ -479,7 +479,7 @@ "T1_ethereum-test_signtx.py::test_signtx_online_definitions[newcontract]": "a7efa7f690d1448dc48f642f69688e8b266417901cc014e5930c94c9087b3e08", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[nodata_1]": "6bd90f2c98122de19159e60fd4dcf9f4b16a600407ac84ea1e447d561ea9decb", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[nodata_2_bigvalue]": "538f7be885ce6ea3a6dc842ef10797fa45184d7737f6f179c42d36fe92fadd45", -"T1_ethereum-test_signtx.py::test_signtx_online_definitions[unknown_erc20_token]": "df41efe4c5336fc188d3f754d2fe0b830588e57eaa32c98607b0bc4057851fcc", +"T1_ethereum-test_signtx.py::test_signtx_online_definitions[unknown_erc20_token]": "911121dafe31a079fe736782373cfe9d1d329fcd8f2916b7bf052ce89da380c1", "T1_ethereum-test_signtx.py::test_signtx_online_definitions[wanchain]": "37aa64fbab44b89757833df6ee78e302c97fe24c4cb74175f1843f635cb2dbec", "T1_misc-test_cosi.py::test_cosi_nonce": "6990c238036b79368fea1dc1e3e8871d7788322bbee7425d14c53623bc8182e8", "T1_misc-test_cosi.py::test_cosi_pubkey": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",