mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-26 17:38:39 +00:00
Only compute pubkey on demand.
Changed all hdnode callers to call hdnode_fill_public_key if they need the public key.
This commit is contained in:
parent
c6309ff93c
commit
ae4dff6e5f
@ -85,13 +85,13 @@ uint32_t deser_length(const uint8_t *in, uint32_t *out)
|
||||
return 1 + 8;
|
||||
}
|
||||
|
||||
int sshMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
int sshMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
{
|
||||
signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes
|
||||
return hdnode_sign(node, message, message_len, signature + 1, NULL);
|
||||
}
|
||||
|
||||
int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
{
|
||||
// GPG should sign a SHA256 digest of the original message.
|
||||
if (message_len != 32) {
|
||||
@ -120,7 +120,7 @@ int cryptoGetECDHSessionKey(const HDNode *node, const uint8_t *peer_public_key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cryptoMessageSign(const CoinType *coin, const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
int cryptoMessageSign(const CoinType *coin, HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
sha256_Init(&ctx);
|
||||
@ -294,7 +294,7 @@ uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath)
|
||||
{
|
||||
if (!hdnodepath->node.has_public_key || hdnodepath->node.public_key.size != 33) return 0;
|
||||
static HDNode node;
|
||||
if (hdnode_from_xpub(hdnodepath->node.depth, hdnodepath->node.fingerprint, hdnodepath->node.child_num, hdnodepath->node.chain_code.bytes, hdnodepath->node.public_key.bytes, SECP256K1_NAME, &node) == 0) {
|
||||
if (hdnode_from_xpub(hdnodepath->node.depth, hdnodepath->node.child_num, hdnodepath->node.chain_code.bytes, hdnodepath->node.public_key.bytes, SECP256K1_NAME, &node) == 0) {
|
||||
return 0;
|
||||
}
|
||||
layoutProgressUpdate(true);
|
||||
|
@ -33,14 +33,14 @@ uint32_t ser_length(uint32_t len, uint8_t *out);
|
||||
|
||||
uint32_t ser_length_hash(SHA256_CTX *ctx, uint32_t len);
|
||||
|
||||
int sshMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
int sshMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
|
||||
int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
|
||||
int cryptoGetECDHSessionKey(const HDNode *node, const uint8_t *peer_public_key, uint8_t *session_key);
|
||||
|
||||
|
||||
int cryptoMessageSign(const CoinType *coin, const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
int cryptoMessageSign(const CoinType *coin, HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
|
||||
int cryptoMessageVerify(const CoinType *coin, const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature);
|
||||
|
||||
|
@ -94,7 +94,7 @@ const CoinType *fsm_getCoin(const char *name)
|
||||
return coin;
|
||||
}
|
||||
|
||||
const HDNode *fsm_getDerivedNode(const char *curve, uint32_t *address_n, size_t address_n_count)
|
||||
HDNode *fsm_getDerivedNode(const char *curve, uint32_t *address_n, size_t address_n_count)
|
||||
{
|
||||
static HDNode node;
|
||||
if (!storage_getRootNode(&node, curve, true)) {
|
||||
@ -298,8 +298,21 @@ void fsm_msgGetPublicKey(GetPublicKey *msg)
|
||||
if (msg->has_ecdsa_curve_name) {
|
||||
curve = msg->ecdsa_curve_name;
|
||||
}
|
||||
const HDNode *node = fsm_getDerivedNode(curve, msg->address_n, msg->address_n_count);
|
||||
uint32_t fpr;
|
||||
HDNode *node;
|
||||
if (msg->address_n_count == 0) {
|
||||
/* get master node */
|
||||
fpr = 0;
|
||||
node = fsm_getDerivedNode(curve, msg->address_n, 0);
|
||||
} else {
|
||||
/* get parent node */
|
||||
node = fsm_getDerivedNode(curve, msg->address_n, msg->address_n_count - 1);
|
||||
if (!node) return;
|
||||
fpr = hdnode_fingerprint(node);
|
||||
/* get child */
|
||||
hdnode_private_ckd(node, msg->address_n[msg->address_n_count - 1]);
|
||||
}
|
||||
hdnode_fill_public_key(node);
|
||||
|
||||
if (msg->has_show_display && msg->show_display) {
|
||||
layoutPublicKey(node->public_key);
|
||||
@ -311,7 +324,7 @@ void fsm_msgGetPublicKey(GetPublicKey *msg)
|
||||
}
|
||||
|
||||
resp->node.depth = node->depth;
|
||||
resp->node.fingerprint = node->fingerprint;
|
||||
resp->node.fingerprint = fpr;
|
||||
resp->node.child_num = node->child_num;
|
||||
resp->node.chain_code.size = 32;
|
||||
memcpy(resp->node.chain_code.bytes, node->chain_code, 32);
|
||||
@ -319,8 +332,12 @@ void fsm_msgGetPublicKey(GetPublicKey *msg)
|
||||
resp->node.has_public_key = true;
|
||||
resp->node.public_key.size = 33;
|
||||
memcpy(resp->node.public_key.bytes, node->public_key, 33);
|
||||
if (node->public_key[0] == 1) {
|
||||
/* ed25519 public key */
|
||||
resp->node.public_key.bytes[0] = 0;
|
||||
}
|
||||
resp->has_xpub = true;
|
||||
hdnode_serialize_public(node, resp->xpub, sizeof(resp->xpub));
|
||||
hdnode_serialize_public(node, fpr, resp->xpub, sizeof(resp->xpub));
|
||||
msg_write(MessageType_MessageType_PublicKey, resp);
|
||||
layoutHome();
|
||||
}
|
||||
@ -561,8 +578,9 @@ void fsm_msgGetAddress(GetAddress *msg)
|
||||
|
||||
const CoinType *coin = fsm_getCoin(msg->coin_name);
|
||||
if (!coin) return;
|
||||
const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
|
||||
HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
|
||||
if (!node) return;
|
||||
hdnode_fill_public_key(node);
|
||||
|
||||
if (msg->has_multisig) {
|
||||
layoutProgressSwipe("Preparing", 0);
|
||||
@ -641,14 +659,14 @@ void fsm_msgSignMessage(SignMessage *msg)
|
||||
|
||||
const CoinType *coin = fsm_getCoin(msg->coin_name);
|
||||
if (!coin) return;
|
||||
const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
|
||||
HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
|
||||
if (!node) return;
|
||||
|
||||
layoutProgressSwipe("Signing", 0);
|
||||
if (cryptoMessageSign(coin, node, msg->message.bytes, msg->message.size, resp->signature.bytes) == 0) {
|
||||
resp->has_address = true;
|
||||
uint8_t addr_raw[21];
|
||||
ecdsa_get_address_raw(node->public_key, coin->address_type, addr_raw);
|
||||
hdnode_get_address_raw(node, coin->address_type, addr_raw);
|
||||
base58_encode_check(addr_raw, 21, resp->address, sizeof(resp->address));
|
||||
resp->has_signature = true;
|
||||
resp->signature.size = 65;
|
||||
@ -735,7 +753,7 @@ void fsm_msgSignIdentity(SignIdentity *msg)
|
||||
if (msg->has_ecdsa_curve_name) {
|
||||
curve = msg->ecdsa_curve_name;
|
||||
}
|
||||
const HDNode *node = fsm_getDerivedNode(curve, address_n, 5);
|
||||
HDNode *node = fsm_getDerivedNode(curve, address_n, 5);
|
||||
if (!node) return;
|
||||
|
||||
bool sign_ssh = msg->identity.has_proto && (strcmp(msg->identity.proto, "ssh") == 0);
|
||||
@ -755,17 +773,22 @@ void fsm_msgSignIdentity(SignIdentity *msg)
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
hdnode_fill_public_key(node);
|
||||
if (strcmp(curve, SECP256K1_NAME) != 0) {
|
||||
resp->has_address = false;
|
||||
} else {
|
||||
resp->has_address = true;
|
||||
uint8_t addr_raw[21];
|
||||
ecdsa_get_address_raw(node->public_key, 0x00, addr_raw); // hardcoded Bitcoin address type
|
||||
hdnode_get_address_raw(node, 0x00, addr_raw); // hardcoded Bitcoin address type
|
||||
base58_encode_check(addr_raw, 21, resp->address, sizeof(resp->address));
|
||||
}
|
||||
resp->has_public_key = true;
|
||||
resp->public_key.size = 33;
|
||||
memcpy(resp->public_key.bytes, node->public_key, 33);
|
||||
if (node->public_key[0] == 1) {
|
||||
/* ed25519 public key */
|
||||
resp->public_key.bytes[0] = 0;
|
||||
}
|
||||
resp->has_signature = true;
|
||||
resp->signature.size = 65;
|
||||
msg_write(MessageType_MessageType_SignedIdentity, resp);
|
||||
@ -859,9 +882,7 @@ void fsm_msgEncryptMessage(EncryptMessage *msg)
|
||||
}
|
||||
node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
|
||||
if (!node) return;
|
||||
uint8_t public_key[33];
|
||||
ecdsa_get_public_key33(&secp256k1, node->private_key, public_key);
|
||||
ecdsa_get_address_raw(public_key, coin->address_type, address_raw);
|
||||
hdnode_get_address_raw(node, coin->address_type, address_raw);
|
||||
}
|
||||
layoutEncryptMessage(msg->message.bytes, msg->message.size, signing);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) {
|
||||
|
@ -471,6 +471,7 @@ void signing_txack(TransactionType *tx)
|
||||
signing_abort();
|
||||
return;
|
||||
}
|
||||
hdnode_fill_public_key(&node);
|
||||
if (tx->inputs[0].script_type == InputScriptType_SPENDMULTISIG) {
|
||||
if (!tx->inputs[0].has_multisig) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Multisig info not provided");
|
||||
|
@ -361,7 +361,7 @@ bool storage_getRootNode(HDNode *node, const char *curve, bool usePassphrase)
|
||||
if (!protectPassphrase()) {
|
||||
return false;
|
||||
}
|
||||
if (hdnode_from_xprv(storage.node.depth, storage.node.fingerprint, storage.node.child_num, storage.node.chain_code.bytes, storage.node.private_key.bytes, curve, node) == 0) {
|
||||
if (hdnode_from_xprv(storage.node.depth, storage.node.child_num, storage.node.chain_code.bytes, storage.node.private_key.bytes, curve, node) == 0) {
|
||||
return false;
|
||||
}
|
||||
if (storage.has_passphrase_protection && storage.passphrase_protection && sessionPassphraseCached && strlen(sessionPassphrase) > 0) {
|
||||
|
@ -71,7 +71,7 @@ int compile_output(const CoinType *coin, const HDNode *root, TxOutputType *in, T
|
||||
return 0;
|
||||
}
|
||||
layoutProgressUpdate(true);
|
||||
ecdsa_get_address_raw(node.public_key, coin->address_type, addr_raw);
|
||||
hdnode_get_address_raw(&node, coin->address_type, addr_raw);
|
||||
} else
|
||||
if (in->has_address) { // address provided -> regular output
|
||||
if (needs_confirm) {
|
||||
|
2
vendor/trezor-crypto
vendored
2
vendor/trezor-crypto
vendored
@ -1 +1 @@
|
||||
Subproject commit 16f477787d7e59a37e0f05807182cef8aeb1e2d5
|
||||
Subproject commit 3390fcf89e5502d6087a8b0d182fc9db05bbd759
|
Loading…
Reference in New Issue
Block a user