From b2172e462764cb68f98633dc33df865952a8df0a Mon Sep 17 00:00:00 2001 From: pscott Date: Thu, 26 Aug 2021 13:02:07 +0200 Subject: [PATCH] Use uint64_t for chainID --- src/chainConfig.h | 2 +- src/utils.c | 22 ++++++-------- src/utils.h | 2 +- src_common/network.c | 13 ++++---- src_common/network.h | 4 +-- src_features/signTx/logic_signTx.c | 42 +++++++++++++++++++------- src_features/signTx/ui_common_signTx.c | 2 +- src_features/signTx/ui_flow_signTx.c | 3 +- 8 files changed, 54 insertions(+), 36 deletions(-) diff --git a/src/chainConfig.h b/src/chainConfig.h index a845018..907ba28 100644 --- a/src/chainConfig.h +++ b/src/chainConfig.h @@ -60,7 +60,7 @@ typedef enum chain_kind_e { typedef struct chain_config_s { char coinName[10]; // ticker - uint32_t chainId; + uint64_t chainId; chain_kind_t kind; } chain_config_t; diff --git a/src/utils.c b/src/utils.c index e3e04c6..5048119 100644 --- a/src/utils.c +++ b/src/utils.c @@ -54,19 +54,17 @@ int local_strchr(char *string, char ch) { return -1; } -uint32_t u32_from_BE(uint8_t *in, uint8_t size) { - switch (size) { - case 0: - return 0; - case 1: - return in[0]; - case 2: - return (in[0] << 8) | in[1]; - case 3: - return (in[0] << 16) | (in[1] << 8) | in[2]; - default: - return (in[0] << 24) | (in[1] << 16) | (in[2] << 8) | in[3]; +uint64_t u64_from_BE(uint8_t *in, uint8_t size) { + uint8_t i = 0; + uint64_t res = 0; + + while (i < size && i < sizeof(res)) { + res <<= 8; + res |= in[i]; + i++; } + + return res; } bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len) { diff --git a/src/utils.h b/src/utils.h index f10ac19..6ee5d45 100644 --- a/src/utils.h +++ b/src/utils.h @@ -28,7 +28,7 @@ void convertUint256BE(uint8_t* data, uint32_t length, uint256_t* target); int local_strchr(char* string, char ch); -uint32_t u32_from_BE(uint8_t* in, uint8_t size); +uint64_t u64_from_BE(uint8_t* in, uint8_t size); bool uint256_to_decimal(const uint8_t* value, size_t value_len, char* out, size_t out_len); diff --git a/src_common/network.c b/src_common/network.c index f1181b8..e2739b5 100644 --- a/src_common/network.c +++ b/src_common/network.c @@ -19,18 +19,19 @@ const network_info_t NETWORK_MAPPING[] = { {.chain_id = 100, .name = "xDai", .ticker = "xDAI "}, {.chain_id = 137, .name = "Polygon", .ticker = "MATIC "}, {.chain_id = 250, .name = "Fantom", .ticker = "FTM "}, - {.chain_id = 43114, .name = "Avalanche", .ticker = "AVAX "}}; + {.chain_id = 43114, .name = "Avalanche", .ticker = "AVAX "}, + {.chain_id = 11297108099, .name = "Palm", .ticker = "PALM "}}; -uint32_t get_chain_id(void) { - uint32_t chain_id = 0; +uint64_t get_chain_id(void) { + uint64_t chain_id = 0; switch (txContext.txType) { case LEGACY: - chain_id = u32_from_BE(txContext.content->v, txContext.content->vLength); + chain_id = u64_from_BE(txContext.content->v, txContext.content->vLength); break; case EIP2930: case EIP1559: - chain_id = u32_from_BE(tmpContent.txContent.chainID.value, + chain_id = u64_from_BE(tmpContent.txContent.chainID.value, tmpContent.txContent.chainID.length); break; default: @@ -42,7 +43,7 @@ uint32_t get_chain_id(void) { } network_info_t *get_network(void) { - uint32_t chain_id = get_chain_id(); + uint64_t chain_id = get_chain_id(); for (uint8_t i = 0; i < sizeof(NETWORK_MAPPING) / sizeof(*NETWORK_MAPPING); i++) { if (NETWORK_MAPPING[i].chain_id == chain_id) { return (network_info_t *) PIC(&NETWORK_MAPPING[i]); diff --git a/src_common/network.h b/src_common/network.h index e8c4f7a..b19d851 100644 --- a/src_common/network.h +++ b/src_common/network.h @@ -6,11 +6,11 @@ typedef struct network_info_s { const char name[NETWORK_STRING_MAX_SIZE]; const char ticker[MAX_TICKER_LEN]; - uint32_t chain_id; + uint64_t chain_id; } network_info_t; // Returns the current chain id. Defaults to 0 if txType was not found. -uint32_t get_chain_id(void); +uint64_t get_chain_id(void); // Returns a pointer to the network struct, or NULL if there is none. network_info_t *get_network(void); // Returns a pointer to the network name, or NULL if there is none. diff --git a/src_features/signTx/logic_signTx.c b/src_features/signTx/logic_signTx.c index 47960af..ae310c4 100644 --- a/src_features/signTx/logic_signTx.c +++ b/src_features/signTx/logic_signTx.c @@ -257,20 +257,40 @@ void prepareFeeDisplay() { sizeof(strings.common.maxFee)); } +static void u64_to_string(uint64_t src, char *dst, uint8_t dst_size) { + // Copy the numbers in ASCII format. + uint8_t i = 0; + do { + // Checking `i + 1` to make sure we have enough space for '\0'. + if (i + 1 >= dst_size) { + THROW(0x6502); + } + dst[i] = src % 10 + '0'; + src /= 10; + i++; + } while (src); + + // Null terminate string + dst[i] = '\0'; + + // Revert the string + i--; + uint8_t j = 0; + while (j < i) { + char tmp = dst[i]; + dst[i] = dst[j]; + dst[j] = tmp; + i--; + j++; + } +} + void prepareNetworkDisplay() { char *name = get_network_name(); if (name == NULL) { // No network name found so simply copy the chain ID as the network name. - uint32_t chain_id = get_chain_id(); - uint8_t res = snprintf(strings.common.network_name, - sizeof(strings.common.network_name), - "%d", - chain_id); - if (res >= sizeof(strings.common.network_name)) { - // If the return value is higher or equal to the size passed in as parameter, then - // the output was truncated. Return the appropriate error code. - THROW(0x6502); - } + uint64_t chain_id = get_chain_id(); + u64_to_string(chain_id, strings.common.network_name, sizeof(strings.common.network_name)); } else { // Network name found, simply copy it. strlcpy(strings.common.network_name, name, sizeof(strings.common.network_name)); @@ -308,7 +328,7 @@ void finalizeParsing(bool direct) { // Verify the chain if (chainConfig->chainId != ETHEREUM_MAINNET_CHAINID) { // TODO: Could we remove above check? - uint32_t id = get_chain_id(); + uint64_t id = get_chain_id(); if (chainConfig->chainId != id) { PRINTF("Invalid chainID %u expected %u\n", id, chainConfig->chainId); diff --git a/src_features/signTx/ui_common_signTx.c b/src_features/signTx/ui_common_signTx.c index 360f883..e535410 100644 --- a/src_features/signTx/ui_common_signTx.c +++ b/src_features/signTx/ui_common_signTx.c @@ -7,7 +7,6 @@ unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_elemen uint8_t signature[100]; cx_ecfp_private_key_t privateKey; uint32_t tx = 0; - uint32_t v = u32_from_BE(tmpContent.txContent.v, tmpContent.txContent.vLength); io_seproxyhal_io_heartbeat(); os_perso_derive_node_bip32(CX_CURVE_256K1, tmpCtx.transactionContext.bip32Path, @@ -41,6 +40,7 @@ unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_elemen } else { // New API // Note that this is wrong for a large v, but the client can always recover + uint64_t v = u64_from_BE(tmpContent.txContent.v, tmpContent.txContent.vLength); G_io_apdu_buffer[0] = (v * 2) + 35; } if (info & CX_ECCINFO_PARITY_ODD) { diff --git a/src_features/signTx/ui_flow_signTx.c b/src_features/signTx/ui_flow_signTx.c index aee22f5..b508ee5 100644 --- a/src_features/signTx/ui_flow_signTx.c +++ b/src_features/signTx/ui_flow_signTx.c @@ -222,9 +222,8 @@ void ux_approve_tx(bool fromPlugin) { ux_approval_tx_flow[step++] = &ux_approval_nonce_step; } - uint32_t chain_id = get_chain_id(); + uint64_t chain_id = get_chain_id(); if (chainConfig->chainId == ETHEREUM_MAINNET_CHAINID && chain_id != chainConfig->chainId) { - // TODO: do we need the `&&` above? ux_approval_tx_flow[step++] = &ux_approval_network_step; }