diff --git a/app/src/addr.c b/app/src/addr.c index 769b1db..c24a371 100644 --- a/app/src/addr.c +++ b/app/src/addr.c @@ -55,7 +55,7 @@ zxerr_t addr_getItem(int8_t displayIdx, snprintf(outKey, outKeyLen, "Your Path"); char buffer[300]; - bip32_to_str(buffer, sizeof(buffer), hdPath, HDPATH_LEN_DEFAULT); + bip32_to_str(buffer, sizeof(buffer), hdPath, hdPathLen); pageString(outVal, outValLen, buffer, pageIdx, pageCount); return zxerr_ok; } diff --git a/app/src/apdu_handler.c b/app/src/apdu_handler.c index dab9f89..0029f91 100644 --- a/app/src/apdu_handler.c +++ b/app/src/apdu_handler.c @@ -39,24 +39,14 @@ __Z_INLINE void extractHDPath(uint32_t rx, uint32_t offset) { ZEMU_LOGF(50, "Extract HDPath\n") tx_initialized = false; - const uint8_t pathLength = G_io_apdu_buffer[offset]; + hdPathLen = G_io_apdu_buffer[offset]; offset++; - if (pathLength != HDPATH_LEN_DEFAULT || (rx - offset) != sizeof(uint32_t) * pathLength) { + if ((rx - offset) != sizeof(uint32_t) * hdPathLen) { THROW(APDU_CODE_WRONG_LENGTH); } - memcpy(hdPath, G_io_apdu_buffer + offset, sizeof(uint32_t) * HDPATH_LEN_DEFAULT); - - const bool mainnet = hdPath[0] == HDPATH_0_DEFAULT && - hdPath[1] == HDPATH_1_DEFAULT; - - const bool testnet = hdPath[0] == HDPATH_0_DEFAULT && - hdPath[1] == HDPATH_1_TESTNET; - - if (!mainnet && !testnet) { - THROW(APDU_CODE_DATA_INVALID); - } + memcpy(hdPath, G_io_apdu_buffer + offset, sizeof(uint32_t) * hdPathLen); } __Z_INLINE bool process_chunk(__Z_UNUSED volatile uint32_t *tx, uint32_t rx) { diff --git a/app/src/coin.h b/app/src/coin.h index 39e32a5..e46c05c 100644 --- a/app/src/coin.h +++ b/app/src/coin.h @@ -22,7 +22,9 @@ extern "C" { #define CLA 0x57 #define HDPATH_LEN_DEFAULT 5 +#define IDENTITY_DER_PATH_LEN 3 #define HDPATH_0_DEFAULT (0x80000000u | 0x2cu) //44 +#define HDPATH_0_IDENTITY (0x80000000u | 0x20u) //32 #define HDPATH_1_DEFAULT (0x80000000u | 0x36d) //877 #define HDPATH_1_TESTNET (0x80000000u | 0x01) //1 diff --git a/app/src/crypto.c b/app/src/crypto.c index 061beec..711a7c2 100644 --- a/app/src/crypto.c +++ b/app/src/crypto.c @@ -58,6 +58,7 @@ } while (0) static zxerr_t crypto_extractPublicKey_ed25519(uint8_t *pubKey, uint16_t pubKeyLen) { + CHECK_ZXERR(ensureBip32()); if (pubKey == NULL || pubKeyLen < PK_LEN_25519) { return zxerr_invalid_crypto_settings; } @@ -70,7 +71,7 @@ static zxerr_t crypto_extractPublicKey_ed25519(uint8_t *pubKey, uint16_t pubKeyL CATCH_CXERROR(os_derive_bip32_with_seed_no_throw(HDW_ED25519_SLIP10, CX_CURVE_Ed25519, hdPath, - HDPATH_LEN_DEFAULT, + hdPathLen, privateKeyData, NULL, NULL, @@ -99,6 +100,7 @@ static zxerr_t crypto_extractPublicKey_ed25519(uint8_t *pubKey, uint16_t pubKeyL } static zxerr_t crypto_sign_ed25519(uint8_t *output, uint16_t outputLen, const uint8_t *message, uint16_t messageLen) { + CHECK_ZXERR(ensureBip32()); if (output == NULL || message == NULL || outputLen < ED25519_SIGNATURE_SIZE || messageLen == 0) { return zxerr_unknown; } @@ -111,7 +113,7 @@ static zxerr_t crypto_sign_ed25519(uint8_t *output, uint16_t outputLen, const ui CATCH_CXERROR(os_derive_bip32_with_seed_no_throw(HDW_ED25519_SLIP10, CX_CURVE_Ed25519, hdPath, - HDPATH_LEN_DEFAULT, + hdPathLen, privateKeyData, NULL, NULL, @@ -480,6 +482,7 @@ zxerr_t crypto_sign(const parser_tx_t *txObj, uint8_t *output, uint16_t outputLe // MASP static zxerr_t computeKeys(keys_t * saplingKeys) { + CHECK_ZXERR(ensureZip32()); if (saplingKeys == NULL) { return zxerr_no_data; } @@ -552,7 +555,7 @@ zxerr_t crypto_computeSaplingSeed(uint8_t spendingKey[static KEY_LENGTH]) { CATCH_CXERROR(os_derive_bip32_with_seed_no_throw(HDW_NORMAL, CX_CURVE_Ed25519, hdPath, - HDPATH_LEN_DEFAULT, + hdPathLen, privateKeyData, NULL, NULL, 0)); memcpy(spendingKey, privateKeyData, KEY_LENGTH); diff --git a/app/src/crypto.h b/app/src/crypto.h index 6c859a2..88a07ca 100644 --- a/app/src/crypto.h +++ b/app/src/crypto.h @@ -27,6 +27,7 @@ extern "C" { #include "parser_txdef.h" extern uint32_t hdPath[HDPATH_LEN_DEFAULT]; +extern uint8_t hdPathLen; zxerr_t crypto_fillAddress(signing_key_type_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *cmdResponseLen); zxerr_t crypto_sign(const parser_tx_t *txObj, uint8_t *output, uint16_t outputLen); diff --git a/app/src/crypto_helper.c b/app/src/crypto_helper.c index 97c0559..2174fc5 100644 --- a/app/src/crypto_helper.c +++ b/app/src/crypto_helper.c @@ -52,10 +52,41 @@ #include "blake2.h" uint32_t hdPath[HDPATH_LEN_DEFAULT]; +uint8_t hdPathLen; uint8_t bech32_hrp_len; char bech32_hrp[MAX_BECH32_HRP_LEN + 1]; +// Ensure that we are working on a BIP 32 path +zxerr_t ensureBip32() { + const bool default_mainnet = hdPath[0] == HDPATH_0_DEFAULT && + hdPath[1] == HDPATH_1_DEFAULT; + + const bool default_testnet = hdPath[0] == HDPATH_0_DEFAULT && + hdPath[1] == HDPATH_1_TESTNET; + + if (!default_mainnet && !default_testnet) { + return zxerr_unknown; + } else { + return zxerr_ok; + } +} + +// Ensure that we are working on a ZIP 32 path +zxerr_t ensureZip32() { + const bool identity_mainnet = hdPath[0] == HDPATH_0_IDENTITY && + hdPath[1] == HDPATH_1_DEFAULT; + + const bool identity_testnet = hdPath[0] == HDPATH_0_IDENTITY && + hdPath[1] == HDPATH_1_TESTNET; + + if (!identity_mainnet && !identity_testnet) { + return zxerr_unknown; + } else { + return zxerr_ok; + } +} + static zxerr_t crypto_publicKeyHash_ed25519(uint8_t *publicKeyHash, const uint8_t *pubkey){ if (publicKeyHash == NULL || pubkey == NULL) { return zxerr_no_data; @@ -91,6 +122,7 @@ static zxerr_t crypto_publicKeyHash_ed25519(uint8_t *publicKeyHash, const uint8_ } zxerr_t crypto_encodeRawPubkey(const uint8_t* rawPubkey, uint16_t rawPubkeyLen, uint8_t *output, uint16_t outputLen) { + CHECK_ZXERR(ensureBip32()); if (rawPubkey == NULL || rawPubkeyLen != PK_LEN_25519_PLUS_TAG || output == NULL) { return zxerr_encoding_failed; } @@ -116,6 +148,7 @@ zxerr_t crypto_encodeRawPubkey(const uint8_t* rawPubkey, uint16_t rawPubkeyLen, } zxerr_t crypto_encodeAddress(const uint8_t *pubkey, uint16_t pubkeyLen, uint8_t *output, uint16_t outputLen) { + CHECK_ZXERR(ensureBip32()); if (output == NULL || pubkey == NULL || pubkeyLen != PK_LEN_25519) { return zxerr_encoding_failed; } diff --git a/app/src/crypto_helper.h b/app/src/crypto_helper.h index 8b8f691..f3202e2 100644 --- a/app/src/crypto_helper.h +++ b/app/src/crypto_helper.h @@ -55,6 +55,8 @@ zxerr_t crypto_hashDataSection(const section_t *data, uint8_t *output, uint32_t zxerr_t crypto_hashCodeSection(const section_t *section, uint8_t *output, uint32_t outputLen); zxerr_t crypto_hashExtraDataSection(const section_t *section, uint8_t *output, uint32_t outputLen); +zxerr_t ensureBip32(); +zxerr_t ensureZip32(); // MASP SECTION parser_error_t convertKey(const uint8_t spendingKey[KEY_LENGTH], const uint8_t modifier, uint8_t outputKey[KEY_LENGTH], bool reduceWideByte); diff --git a/app/src/review_keys.c b/app/src/review_keys.c index e8b2d4c..e3a6e0d 100644 --- a/app/src/review_keys.c +++ b/app/src/review_keys.c @@ -51,7 +51,7 @@ zxerr_t getItemPublicAddress(int8_t displayIdx, char *outKey, uint16_t outKeyLen case 1: { snprintf(outKey, outKeyLen, "HD Path"); char buffer[200] = {0}; - bip32_to_str(buffer, sizeof(buffer), hdPath, HDPATH_LEN_DEFAULT); + bip32_to_str(buffer, sizeof(buffer), hdPath, hdPathLen); pageString(outVal, outValLen, buffer, pageIdx, pageCount); break; } @@ -90,7 +90,7 @@ zxerr_t getItemProofGenerationKey(int8_t displayIdx, char *outKey, uint16_t outK case 2: { snprintf(outKey, outKeyLen, "HD Path"); char buffer[200] = {0}; - bip32_to_str(buffer, sizeof(buffer), hdPath, HDPATH_LEN_DEFAULT); + bip32_to_str(buffer, sizeof(buffer), hdPath, hdPathLen); pageString(outVal, outValLen, buffer, pageIdx, pageCount); break; } @@ -135,7 +135,7 @@ zxerr_t getItemViewKey(int8_t displayIdx, char *outKey, uint16_t outKeyLen, char case 3: { snprintf(outKey, outKeyLen, "HD Path"); char buffer[200] = {0}; - bip32_to_str(buffer, sizeof(buffer), hdPath, HDPATH_LEN_DEFAULT); + bip32_to_str(buffer, sizeof(buffer), hdPath, hdPathLen); pageString(outVal, outValLen, buffer, pageIdx, pageCount); break; }