feat(legacy): code improvements

marnova/ethereum_defs_from_host-tmp
Martin Novak 1 year ago
parent e89e453152
commit 9556b8f18d

@ -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(&params, defs);
ethereum_signing_handle_erc20(&params, &defs->token);
if (!ethereum_signing_confirm_common(&params)) {
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(&params, defs);
ethereum_signing_handle_erc20(&params, &defs->token);
if (!ethereum_signing_confirm_common(&params)) {
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) {

@ -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

@ -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;
}

@ -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

@ -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

@ -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} */

@ -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

@ -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"

@ -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;
}

@ -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",

Loading…
Cancel
Save