Skip to content

Commit

Permalink
Also support derivation paths of length 3.
Browse files Browse the repository at this point in the history
  • Loading branch information
murisi committed Aug 29, 2024
1 parent 6e0ac0f commit e6d3686
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 20 deletions.
2 changes: 1 addition & 1 deletion app/src/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
16 changes: 3 additions & 13 deletions app/src/apdu_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions app/src/coin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 6 additions & 3 deletions app/src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions app/src/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
33 changes: 33 additions & 0 deletions app/src/crypto_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/crypto_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions app/src/review_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit e6d3686

Please sign in to comment.