From e7703a16fef30c33e9f5fa12ff3f2021da7b8975 Mon Sep 17 00:00:00 2001 From: Saleem Rashid Date: Wed, 20 Dec 2017 16:25:01 +0000 Subject: [PATCH] crypto: Remove hardcoded instances of secp256k1 --- firmware/crypto.c | 10 +++++----- firmware/crypto.h | 4 ++-- firmware/signing.c | 14 +++++++------- firmware/transaction.c | 20 ++++++++++---------- firmware/transaction.h | 6 +++--- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/firmware/crypto.c b/firmware/crypto.c index 349116bef9..4ff322c250 100644 --- a/firmware/crypto.c +++ b/firmware/crypto.c @@ -163,7 +163,7 @@ int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t mes // check if signature verifies the digest and recover the public key uint8_t pubkey[65]; - if (ecdsa_verify_digest_recover(&secp256k1, pubkey, signature + 1, hash, recid) != 0) { + if (ecdsa_verify_digest_recover(coin->curve->params, pubkey, signature + 1, hash, recid) != 0) { return 3; } // convert public key to compressed pubkey if necessary @@ -327,11 +327,11 @@ int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, size_t payload_le } */ -uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath) +uint8_t *cryptoHDNodePathToPubkey(const CoinInfo *coin, 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.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, coin->curve_name, &node) == 0) { return 0; } layoutProgressUpdate(true); @@ -344,10 +344,10 @@ uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath) return node.public_key; } -int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey) +int cryptoMultisigPubkeyIndex(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, const uint8_t *pubkey) { for (size_t i = 0; i < multisig->pubkeys_count; i++) { - const uint8_t *node_pubkey = cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])); + const uint8_t *node_pubkey = cryptoHDNodePathToPubkey(coin, &(multisig->pubkeys[i])); if (node_pubkey && memcmp(node_pubkey, pubkey, 33) == 0) { return i; } diff --git a/firmware/crypto.h b/firmware/crypto.h index 7744c2909d..2f72a48bcf 100644 --- a/firmware/crypto.h +++ b/firmware/crypto.h @@ -51,9 +51,9 @@ int cryptoMessageEncrypt(curve_point *pubkey, const uint8_t *msg, size_t msg_siz int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, size_t payload_len, const uint8_t *hmac, size_t hmac_len, const uint8_t *privkey, uint8_t *msg, size_t *msg_len, bool *display_only, bool *signing, uint8_t *address_raw); */ -uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath); +uint8_t *cryptoHDNodePathToPubkey(const CoinInfo *coin, const HDNodePathType *hdnodepath); -int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey); +int cryptoMultisigPubkeyIndex(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, const uint8_t *pubkey); int cryptoMultisigFingerprint(const MultisigRedeemScriptType *multisig, uint8_t *hash); diff --git a/firmware/signing.c b/firmware/signing.c index 2aff6bd21c..5cccaff4ab 100644 --- a/firmware/signing.c +++ b/firmware/signing.c @@ -460,7 +460,7 @@ bool compile_input_script_sig(TxInputType *tinput) } hdnode_fill_public_key(&node); if (tinput->has_multisig) { - tinput->script_sig.size = compile_script_multisig(&(tinput->multisig), tinput->script_sig.bytes); + tinput->script_sig.size = compile_script_multisig(coin, &(tinput->multisig), tinput->script_sig.bytes); } else { // SPENDADDRESS uint8_t hash[20]; ecdsa_get_pubkeyhash(node.public_key, coin->curve->hasher_type, hash); @@ -759,7 +759,7 @@ static bool signing_sign_hash(TxInputType *txinput, const uint8_t* private_key, resp.serialized.signature_index = idx1; resp.serialized.has_signature = true; resp.serialized.has_serialized_tx = true; - if (ecdsa_sign_digest(&secp256k1, private_key, hash, sig, NULL, NULL) != 0) { + if (ecdsa_sign_digest(coin->curve->params, private_key, hash, sig, NULL, NULL) != 0) { fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed")); signing_abort(); return false; @@ -769,7 +769,7 @@ static bool signing_sign_hash(TxInputType *txinput, const uint8_t* private_key, uint8_t sighash = signing_hash_type() & 0xff; if (txinput->has_multisig) { // fill in the signature - int pubkey_idx = cryptoMultisigPubkeyIndex(&(txinput->multisig), public_key); + int pubkey_idx = cryptoMultisigPubkeyIndex(coin, &(txinput->multisig), public_key); if (pubkey_idx < 0) { fsm_sendFailure(FailureType_Failure_DataError, _("Pubkey not found in multisig script")); signing_abort(); @@ -777,7 +777,7 @@ static bool signing_sign_hash(TxInputType *txinput, const uint8_t* private_key, } memcpy(txinput->multisig.signatures[pubkey_idx].bytes, resp.serialized.signature.bytes, resp.serialized.signature.size); txinput->multisig.signatures[pubkey_idx].size = resp.serialized.signature.size; - txinput->script_sig.size = serialize_script_multisig(&(txinput->multisig), sighash, txinput->script_sig.bytes); + txinput->script_sig.size = serialize_script_multisig(coin, &(txinput->multisig), sighash, txinput->script_sig.bytes); if (txinput->script_sig.size == 0) { fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to serialize multisig script")); signing_abort(); @@ -845,9 +845,9 @@ static bool signing_sign_segwit_input(TxInputType *txinput) { txinput->multisig.signatures[i].bytes[txinput->multisig.signatures[i].size] = sighash; r += tx_serialize_script(txinput->multisig.signatures[i].size + 1, txinput->multisig.signatures[i].bytes, resp.serialized.serialized_tx.bytes + r); } - uint32_t script_len = compile_script_multisig(&txinput->multisig, 0); + uint32_t script_len = compile_script_multisig(coin, &txinput->multisig, 0); r += ser_length(script_len, resp.serialized.serialized_tx.bytes + r); - r += compile_script_multisig(&txinput->multisig, resp.serialized.serialized_tx.bytes + r); + r += compile_script_multisig(coin, &txinput->multisig, resp.serialized.serialized_tx.bytes + r); resp.serialized.serialized_tx.bytes[0] = nwitnesses; resp.serialized.serialized_tx.size = r; } else { // single signature @@ -1207,7 +1207,7 @@ void signing_txack(TransactionType *tx) tx->inputs[0].script_sig.bytes[1] = 0x00; // witness 0 script tx->inputs[0].script_sig.bytes[2] = 0x20; // push 32 bytes (digest) // compute digest of multisig script - if (!compile_script_multisig_hash(&tx->inputs[0].multisig, coin->curve->hasher_type, tx->inputs[0].script_sig.bytes + 3)) { + if (!compile_script_multisig_hash(coin, &tx->inputs[0].multisig, tx->inputs[0].script_sig.bytes + 3)) { fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input")); signing_abort(); return; diff --git a/firmware/transaction.c b/firmware/transaction.c index e99dc75786..cee79124d9 100644 --- a/firmware/transaction.c +++ b/firmware/transaction.c @@ -106,10 +106,10 @@ bool compute_address(const CoinInfo *coin, size_t prelen; if (has_multisig) { - if (cryptoMultisigPubkeyIndex(multisig, node->public_key) < 0) { + if (cryptoMultisigPubkeyIndex(coin, multisig, node->public_key) < 0) { return 0; } - if (compile_script_multisig_hash(multisig, coin->curve->hasher_type, digest) == 0) { + if (compile_script_multisig_hash(coin, multisig, digest) == 0) { return 0; } if (script_type == InputScriptType_SPENDWITNESS) { @@ -294,7 +294,7 @@ uint32_t compile_script_sig(uint32_t address_type, const uint8_t *pubkeyhash, ui } // if out == NULL just compute the length -uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t *out) +uint32_t compile_script_multisig(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, uint8_t *out) { if (!multisig->has_m) return 0; const uint32_t m = multisig->m; @@ -306,7 +306,7 @@ uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8 out[r] = 0x50 + m; r++; for (uint32_t i = 0; i < n; i++) { out[r] = 33; r++; // OP_PUSH 33 - const uint8_t *pubkey = cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])); + const uint8_t *pubkey = cryptoHDNodePathToPubkey(coin, &(multisig->pubkeys[i])); if (!pubkey) return 0; memcpy(out + r, pubkey, 33); r += 33; } @@ -318,7 +318,7 @@ uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8 return r; } -uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig, HasherType hasher_type, uint8_t *hash) +uint32_t compile_script_multisig_hash(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, uint8_t *hash) { if (!multisig->has_m) return 0; const uint32_t m = multisig->m; @@ -327,13 +327,13 @@ uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig, if (n < 1 || n > 15) return 0; Hasher hasher; - hasher_Init(&hasher, hasher_type); + hasher_Init(&hasher, coin->curve->hasher_type); uint8_t d[2]; d[0] = 0x50 + m; hasher_Update(&hasher, d, 1); for (uint32_t i = 0; i < n; i++) { d[0] = 33; hasher_Update(&hasher, d, 1); // OP_PUSH 33 - const uint8_t *pubkey = cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])); + const uint8_t *pubkey = cryptoHDNodePathToPubkey(coin, &(multisig->pubkeys[i])); if (!pubkey) return 0; hasher_Update(&hasher, pubkey, 33); } @@ -357,7 +357,7 @@ uint32_t serialize_script_sig(const uint8_t *signature, uint32_t signature_len, return r; } -uint32_t serialize_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t sighash, uint8_t *out) +uint32_t serialize_script_multisig(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, uint8_t sighash, uint8_t *out) { uint32_t r = 0; out[r] = 0x00; r++; @@ -369,12 +369,12 @@ uint32_t serialize_script_multisig(const MultisigRedeemScriptType *multisig, uin memcpy(out + r, multisig->signatures[i].bytes, multisig->signatures[i].size); r += multisig->signatures[i].size; out[r] = sighash; r++; } - uint32_t script_len = compile_script_multisig(multisig, 0); + uint32_t script_len = compile_script_multisig(coin, multisig, 0); if (script_len == 0) { return 0; } r += op_push(script_len, out + r); - r += compile_script_multisig(multisig, out + r); + r += compile_script_multisig(coin, multisig, out + r); return r; } diff --git a/firmware/transaction.h b/firmware/transaction.h index cd344093ff..8177a9655a 100644 --- a/firmware/transaction.h +++ b/firmware/transaction.h @@ -51,10 +51,10 @@ typedef struct { bool compute_address(const CoinInfo *coin, InputScriptType script_type, const HDNode *node, bool has_multisig, const MultisigRedeemScriptType *multisig, char address[MAX_ADDR_SIZE]); uint32_t compile_script_sig(uint32_t address_type, const uint8_t *pubkeyhash, uint8_t *out); -uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t *out); -uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig, HasherType hasher_type, uint8_t *hash); +uint32_t compile_script_multisig(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, uint8_t *out); +uint32_t compile_script_multisig_hash(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, uint8_t *hash); uint32_t serialize_script_sig(const uint8_t *signature, uint32_t signature_len, const uint8_t *pubkey, uint32_t pubkey_len, uint8_t sighash, uint8_t *out); -uint32_t serialize_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t sighash, uint8_t *out); +uint32_t serialize_script_multisig(const CoinInfo *coin, const MultisigRedeemScriptType *multisig, uint8_t sighash, uint8_t *out); int compile_output(const CoinInfo *coin, const HDNode *root, TxOutputType *in, TxOutputBinType *out, bool needs_confirm); uint32_t tx_prevout_hash(Hasher *hasher, const TxInputType *input);