diff --git a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip32.h b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip32.h index afae08650..ed0794b59 100644 --- a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip32.h +++ b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip32.h @@ -131,8 +131,10 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_make_new(const mp_obj_type_t *type, } if (33 == public_key.len) { memcpy(o->hdnode.public_key, public_key.buf, 33); + o->hdnode.is_public_key_set = true; } else { memzero(o->hdnode.public_key, 33); + o->hdnode.is_public_key_set = false; } o->hdnode.curve = curve; diff --git a/crypto/bip32.c b/crypto/bip32.c index 09723d9fd..741049c43 100644 --- a/crypto/bip32.c +++ b/crypto/bip32.c @@ -103,6 +103,7 @@ int hdnode_from_xpub(uint32_t depth, uint32_t child_num, memzero(out->private_key, 32); memzero(out->private_key_extension, 32); memcpy(out->public_key, public_key, 33); + out->is_public_key_set = true; return 1; } @@ -136,6 +137,7 @@ int hdnode_from_xprv(uint32_t depth, uint32_t child_num, memcpy(out->chain_code, chain_code, 32); memcpy(out->private_key, private_key, 32); memzero(out->public_key, sizeof(out->public_key)); + out->is_public_key_set = false; memzero(out->private_key_extension, sizeof(out->private_key_extension)); return 1; } @@ -174,6 +176,7 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve, memcpy(out->private_key, I, 32); memcpy(out->chain_code, I + 32, 32); memzero(out->public_key, sizeof(out->public_key)); + out->is_public_key_set = false; memzero(I, sizeof(I)); return 1; } @@ -255,6 +258,7 @@ int hdnode_private_ckd_bip32(HDNode *inout, uint32_t i) { inout->depth++; inout->child_num = i; memzero(inout->public_key, sizeof(inout->public_key)); + inout->is_public_key_set = false; // making sure to wipe our memory memzero(&a, sizeof(a)); @@ -329,6 +333,7 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i) { inout->child_num = i; inout->public_key[0] = 0x02 | (child.y.val[0] & 0x01); bn_write_be(&child.x, inout->public_key + 1); + inout->is_public_key_set = true; // Wipe all stack data. memzero(&parent, sizeof(parent)); @@ -468,7 +473,9 @@ int hdnode_get_address(HDNode *node, uint32_t version, char *addr, } int hdnode_fill_public_key(HDNode *node) { - if (node->public_key[0] != 0) return 0; + if (node->is_public_key_set) { + return 0; + } #if USE_BIP32_25519_CURVES if (node->curve->params) { @@ -501,6 +508,7 @@ int hdnode_fill_public_key(HDNode *node) { return 1; } #endif + node->is_public_key_set = true; return 0; } @@ -750,9 +758,11 @@ static int hdnode_deserialize(const char *str, uint32_t version, } memcpy(node->private_key, node_data + 46, 32); memzero(node->public_key, sizeof(node->public_key)); + node->is_public_key_set = false; } else { memzero(node->private_key, sizeof(node->private_key)); memcpy(node->public_key, node_data + 45, 33); + node->is_public_key_set = true; } node->depth = node_data[4]; if (fingerprint) { diff --git a/crypto/bip32.h b/crypto/bip32.h index 4be5c4483..27084719c 100644 --- a/crypto/bip32.h +++ b/crypto/bip32.h @@ -56,6 +56,7 @@ typedef struct { uint8_t private_key_extension[32]; uint8_t public_key[33]; + bool is_public_key_set; const curve_info *curve; } HDNode; diff --git a/crypto/cardano.c b/crypto/cardano.c index 485d6514a..090dfe3ce 100644 --- a/crypto/cardano.c +++ b/crypto/cardano.c @@ -143,6 +143,7 @@ int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index) { inout->depth++; inout->child_num = index; memzero(inout->public_key, sizeof(inout->public_key)); + inout->is_public_key_set = false; // making sure to wipe our memory memzero(z, sizeof(z)); @@ -164,7 +165,7 @@ int hdnode_from_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH], cardano_ed25519_tweak_bits(out->private_key); - out->public_key[0] = 0; + out->is_public_key_set = false; if (hdnode_fill_public_key(out) != 0) { return 0; }