diff --git a/app/Makefile.version b/app/Makefile.version index 15343385..6f483eb0 100644 --- a/app/Makefile.version +++ b/app/Makefile.version @@ -3,4 +3,4 @@ APPVERSION_M=2 # This is the `spec_version` field of `Runtime` APPVERSION_N=36 # This is the patch version of this release -APPVERSION_P=2 +APPVERSION_P=3 diff --git a/app/src/chain_config.c b/app/src/chain_config.c index 79fe8e39..0b2fcb7b 100644 --- a/app/src/chain_config.c +++ b/app/src/chain_config.c @@ -31,7 +31,11 @@ static const chain_config_t chainConfig[] = { {60, "dym", BECH32_ETH}, {60, "zeta", BECH32_ETH}, {60, "bera", BECH32_ETH}, - {60, "human", BECH32_ETH} + {60, "human", BECH32_ETH}, + {118, "osmos", BECH32_COSMOS}, + {118, "dydx", BECH32_COSMOS}, + {118, "mantra", BECH32_COSMOS}, + {118, "xion", BECH32_COSMOS} }; static const uint32_t chainConfigLen = sizeof(chainConfig) / sizeof(chainConfig[0]); diff --git a/app/src/coin.h b/app/src/coin.h index b938a903..8ae54a97 100644 --- a/app/src/coin.h +++ b/app/src/coin.h @@ -55,6 +55,8 @@ typedef enum { #define APPVERSION_LINE2 ("v" APPVERSION) #define COIN_DEFAULT_CHAINID "cosmoshub-4" +#define OSMOSIS_CHAINID "osmosis-1" +#define DYDX_CHAINID "dydx-mainnet-1" // In non-expert mode, the app will convert from uatom to ATOM #define COIN_DEFAULT_DENOM_BASE "uatom" diff --git a/app/src/crypto.c b/app/src/crypto.c index 15c5f2d9..c42f3b78 100644 --- a/app/src/crypto.c +++ b/app/src/crypto.c @@ -202,6 +202,8 @@ zxerr_t crypto_fillAddress(uint8_t *buffer, uint16_t buffer_len, uint16_t *addrR // Fill address using a hd path coming from check_address_parameters_t zxerr_t crypto_swap_fillAddress(uint32_t *hdPath_swap, uint8_t hdPathLen_swap, + char *hrp, + address_encoding_e encode_type, char *buffer, uint16_t bufferLen, uint16_t *addrResponseLen) { @@ -216,12 +218,27 @@ zxerr_t crypto_swap_fillAddress(uint32_t *hdPath_swap, CHECK_ZXERR(compressPubkey(uncompressedPubkey, sizeof(uncompressedPubkey), compressedPubkey, sizeof(compressedPubkey))); uint8_t hashed1_pk[CX_SHA256_SIZE] = {0}; - cx_hash_sha256(compressedPubkey, PK_LEN_SECP256K1, hashed1_pk, CX_SHA256_SIZE); - - uint8_t hashed2_pk[CX_RIPEMD160_SIZE] = {0}; - CHECK_CX_OK(cx_ripemd160_hash(hashed1_pk, CX_SHA256_SIZE, hashed2_pk)); - // support only cosmos for now we might need to send the hrp as an address parameter - CHECK_ZXERR(bech32EncodeFromBytes(buffer, bufferLen, "cosmos", hashed2_pk, CX_RIPEMD160_SIZE, 1, BECH32_ENCODING_BECH32)); + switch (encode_type) { + case BECH32_COSMOS: { + // Hash it + cx_hash_sha256(compressedPubkey, PK_LEN_SECP256K1, hashed1_pk, CX_SHA256_SIZE); + uint8_t hashed2_pk[CX_RIPEMD160_SIZE] = {0}; + CHECK_CX_OK(cx_ripemd160_hash(hashed1_pk, CX_SHA256_SIZE, hashed2_pk)); + CHECK_ZXERR(bech32EncodeFromBytes(buffer, bufferLen, hrp, hashed2_pk, CX_RIPEMD160_SIZE, 1, BECH32_ENCODING_BECH32)); + break; + } + + case BECH32_ETH: { + CHECK_CX_OK(cx_keccak_256_hash(uncompressedPubkey+1, sizeof(uncompressedPubkey)-1, hashed1_pk)); + CHECK_ZXERR(bech32EncodeFromBytes(buffer, bufferLen, hrp, hashed1_pk + 12, sizeof(hashed1_pk) - 12, 1, BECH32_ENCODING_BECH32)); + break; + } + + default: + *addrResponseLen = 0; + return zxerr_encoding_failed; + } + *addrResponseLen = strnlen(buffer, bufferLen); return zxerr_ok; diff --git a/app/src/crypto.h b/app/src/crypto.h index db877bd6..c2e930b1 100644 --- a/app/src/crypto.h +++ b/app/src/crypto.h @@ -39,6 +39,8 @@ zxerr_t crypto_sign(uint8_t *signature, uint16_t signatureMaxlen, uint16_t *sign zxerr_t crypto_swap_fillAddress(uint32_t *hdPath_swap, uint8_t hdPathLen_swap, + char *hrp, + address_encoding_e encode_type, char *buffer, uint16_t bufferLen, uint16_t *addrResponseLen); diff --git a/app/src/swap/handle_check_address.c b/app/src/swap/handle_check_address.c index aa694e2b..56067edd 100644 --- a/app/src/swap/handle_check_address.c +++ b/app/src/swap/handle_check_address.c @@ -20,6 +20,7 @@ #include "swap.h" #include "zxformat.h" #include "swap_utils.h" +#include "chain_config.h" void handle_check_address(check_address_parameters_t *params) { @@ -31,10 +32,20 @@ void handle_check_address(check_address_parameters_t *params) { params->result = 0; // Address parameters have the following structure - // path length (1 byte) | bip32 path (4 * pathLength bytes) - // Get the path + // hrp length (1 byte) | hrp (hrp length bytes) | bip32 path length (1 byte) | bip32 path (4 * pathLength bytes) + // Get HRP + uint8_t hrp_length = params->address_parameters[0]; + char hrp[MAX_BECH32_HRP_LEN + 1] = {0}; + + if (hrp_length == 0 || hrp_length > MAX_BECH32_HRP_LEN) { + return; + } + memcpy(hrp, params->address_parameters + 1, hrp_length); + hrp[hrp_length] = 0; + + // Get bip32 path + uint8_t bip32_path_length = params->address_parameters[1 + hrp_length]; uint32_t bip32_path[HDPATH_LEN_DEFAULT] = {0}; - uint8_t bip32_path_length = params->address_parameters[0]; if (bip32_path_length != HDPATH_LEN_DEFAULT) { return; @@ -44,11 +55,16 @@ void handle_check_address(check_address_parameters_t *params) { readU32BE(params->address_parameters + 1 + (i * 4), &bip32_path[i]); } + // Check if the chain is supported with the HRP and path + address_encoding_e encode_type = checkChainConfig(bip32_path[1], hrp, hrp_length); + if (encode_type == UNSUPPORTED) { + return; + } + char address_computed[100] = {0}; uint16_t reply_len = 0; - zxerr_t err = crypto_swap_fillAddress(bip32_path, - bip32_path_length, address_computed, sizeof(address_computed), - &reply_len); + zxerr_t err = crypto_swap_fillAddress(bip32_path, bip32_path_length, hrp, encode_type, address_computed, + sizeof(address_computed), &reply_len); if (err != zxerr_ok) { MEMZERO(address_computed, sizeof(address_computed)); return; diff --git a/app/src/swap/handle_sign_transaction.c b/app/src/swap/handle_sign_transaction.c index f528ed5a..9bc0ff5a 100644 --- a/app/src/swap/handle_sign_transaction.c +++ b/app/src/swap/handle_sign_transaction.c @@ -28,6 +28,17 @@ swap_globals_t G_swap_state; // Save the BSS address where we will write the return value when finished static uint8_t *G_swap_sign_return_value_address; +static const char * chain_ids[] = { COIN_DEFAULT_CHAINID, OSMOSIS_CHAINID, DYDX_CHAINID}; + +bool is_allowed_chainid(const char *chainId) { + for (uint32_t i = 0; i < array_length(chain_ids); i++) { + if (strcmp(chainId, chain_ids[i]) == 0) { + return true; + } + } + return false; +} + bool copy_transaction_parameters(create_transaction_parameters_t *sign_transaction_params) { if (sign_transaction_params == NULL) { return false; @@ -135,14 +146,12 @@ parser_error_t check_swap_conditions(parser_context_t *ctx_parsed_tx) { // Cosmos App in normal mode requires that chain id is the default one. If not, it will print expert mode fields // this means if we reach this point and no chain_id is printed, chain_id must be the default one - const char *default_chain_id = "cosmoshub-4"; CHECK_PARSER_ERR(parser_getItem(ctx_parsed_tx, displayIdx, tmpKey, sizeof(tmpKey), tmpValue, sizeof(tmpValue), pageIdx, &pageCount)) // Check if chain_id is printed, expert fields if (strcmp(tmpKey, "Chain ID") == 0) { - // For now allow only default chain id - if (strcmp(tmpValue, default_chain_id) != 0) { - ZEMU_LOGF(200, "Wrong Chain Id. ('%s', should be : '%s').\n", tmpValue, default_chain_id); + if (!is_allowed_chainid(tmpValue)) { + ZEMU_LOGF(200, " Not supported Chain Id\n"); return parser_unexpected_error; } displayIdx += 5; // skip account_number, sequence, source_address, source_coins diff --git a/tests_zemu/snapshots/fl-mainmenu/00004.png b/tests_zemu/snapshots/fl-mainmenu/00004.png index 3de31dcb..389d3fc3 100644 Binary files a/tests_zemu/snapshots/fl-mainmenu/00004.png and b/tests_zemu/snapshots/fl-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/s-mainmenu/00004.png b/tests_zemu/snapshots/s-mainmenu/00004.png index 6c445195..4232c9a0 100644 Binary files a/tests_zemu/snapshots/s-mainmenu/00004.png and b/tests_zemu/snapshots/s-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/s-mainmenu/00010.png b/tests_zemu/snapshots/s-mainmenu/00010.png index 6c445195..4232c9a0 100644 Binary files a/tests_zemu/snapshots/s-mainmenu/00010.png and b/tests_zemu/snapshots/s-mainmenu/00010.png differ diff --git a/tests_zemu/snapshots/sp-mainmenu/00004.png b/tests_zemu/snapshots/sp-mainmenu/00004.png index 5cb641d7..0d0cb470 100644 Binary files a/tests_zemu/snapshots/sp-mainmenu/00004.png and b/tests_zemu/snapshots/sp-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/sp-mainmenu/00010.png b/tests_zemu/snapshots/sp-mainmenu/00010.png index 5cb641d7..0d0cb470 100644 Binary files a/tests_zemu/snapshots/sp-mainmenu/00010.png and b/tests_zemu/snapshots/sp-mainmenu/00010.png differ diff --git a/tests_zemu/snapshots/st-mainmenu/00004.png b/tests_zemu/snapshots/st-mainmenu/00004.png index e8a9c8c9..63752b5f 100644 Binary files a/tests_zemu/snapshots/st-mainmenu/00004.png and b/tests_zemu/snapshots/st-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00004.png b/tests_zemu/snapshots/x-mainmenu/00004.png index 5cb641d7..0d0cb470 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00004.png and b/tests_zemu/snapshots/x-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00010.png b/tests_zemu/snapshots/x-mainmenu/00010.png index 5cb641d7..0d0cb470 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00010.png and b/tests_zemu/snapshots/x-mainmenu/00010.png differ