From 568da981991652786fd795944203b4686f5893df Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Tue, 4 Aug 2020 18:51:19 +0200 Subject: [PATCH] legacy: refactor path_mismatched function and revert its logic --- legacy/firmware/crypto.c | 99 ++++++++++++++++++++++++++++++++++ legacy/firmware/crypto.h | 4 ++ legacy/firmware/fsm_msg_coin.h | 81 +--------------------------- legacy/firmware/signing.c | 4 ++ 4 files changed, 109 insertions(+), 79 deletions(-) diff --git a/legacy/firmware/crypto.c b/legacy/firmware/crypto.c index 9122447357..5e64266228 100644 --- a/legacy/firmware/crypto.c +++ b/legacy/firmware/crypto.c @@ -507,3 +507,102 @@ int cryptoIdentityFingerprint(const IdentityType *identity, uint8_t *hash) { sha256_Final(&ctx, hash); return 1; } + +bool coin_known_path_check(const CoinInfo *coin, InputScriptType script_type, + uint32_t address_n_count, const uint32_t *address_n, + bool full) { + bool valid = true; + // m/44' : BIP44 Legacy + // m / purpose' / coin_type' / account' / change / address_index + if (address_n_count > 0 && address_n[0] == (0x80000000 + 44)) { + valid &= (script_type == InputScriptType_SPENDADDRESS); + if (full) { + valid &= (address_n_count == 5); + } else { + valid &= (address_n_count >= 2); + } + valid &= (address_n[1] == coin->coin_type); + if (full) { + valid &= (address_n[2] & 0x80000000) == 0x80000000; + valid &= (address_n[3] & 0x80000000) == 0; + valid &= (address_n[4] & 0x80000000) == 0; + } + return valid; + } + + // m/45' - BIP45 Copay Abandoned Multisig P2SH + // m / purpose' / cosigner_index / change / address_index + if (address_n_count > 0 && address_n[0] == (0x80000000 + 45)) { + valid &= (script_type == InputScriptType_SPENDMULTISIG); + if (full) { + valid &= (address_n_count == 4); + valid &= (address_n[1] & 0x80000000) == 0; + valid &= (address_n[2] & 0x80000000) == 0; + valid &= (address_n[3] & 0x80000000) == 0; + } + return valid; + } + + // m/48' - BIP48 Copay Multisig P2SH + // m / purpose' / coin_type' / account' / change / address_index + // Electrum: + // m / purpose' / coin_type' / account' / type' / change / address_index + if (address_n_count > 0 && address_n[0] == (0x80000000 + 48)) { + valid &= (script_type == InputScriptType_SPENDMULTISIG) || + (script_type == InputScriptType_SPENDP2SHWITNESS) || + (script_type == InputScriptType_SPENDWITNESS); + if (full) { + valid &= (address_n_count == 5) || (address_n_count == 6); + } else { + valid &= (address_n_count >= 2); + } + valid &= (address_n[1] == coin->coin_type); + if (full) { + valid &= (address_n[2] & 0x80000000) == 0x80000000; + valid &= (address_n[4] & 0x80000000) == 0; + } + return valid; + } + + // m/49' : BIP49 SegWit + // m / purpose' / coin_type' / account' / change / address_index + if (address_n_count > 0 && address_n[0] == (0x80000000 + 49)) { + valid &= (script_type == InputScriptType_SPENDP2SHWITNESS); + valid &= coin->has_segwit; + if (full) { + valid &= (address_n_count == 5); + } else { + valid &= (address_n_count >= 2); + } + valid &= (address_n[1] == coin->coin_type); + if (full) { + valid &= (address_n[2] & 0x80000000) == 0x80000000; + valid &= (address_n[3] & 0x80000000) == 0; + valid &= (address_n[4] & 0x80000000) == 0; + } + return valid; + } + + // m/84' : BIP84 Native SegWit + // m / purpose' / coin_type' / account' / change / address_index + if (address_n_count > 0 && address_n[0] == (0x80000000 + 84)) { + valid &= (script_type == InputScriptType_SPENDWITNESS); + valid &= coin->has_segwit; + valid &= coin->bech32_prefix != NULL; + if (full) { + valid &= (address_n_count == 5); + } else { + valid &= (address_n_count >= 2); + } + valid &= (address_n[1] == coin->coin_type); + if (full) { + valid &= (address_n[2] & 0x80000000) == 0x80000000; + valid &= (address_n[3] & 0x80000000) == 0; + valid &= (address_n[4] & 0x80000000) == 0; + } + return valid; + } + + // we don't check unknown paths + return true; +} diff --git a/legacy/firmware/crypto.h b/legacy/firmware/crypto.h index ff5648beeb..c889d8962e 100644 --- a/legacy/firmware/crypto.h +++ b/legacy/firmware/crypto.h @@ -82,4 +82,8 @@ int cryptoMultisigFingerprint(const MultisigRedeemScriptType *multisig, int cryptoIdentityFingerprint(const IdentityType *identity, uint8_t *hash); +bool coin_known_path_check(const CoinInfo *coin, InputScriptType script_type, + uint32_t address_n_count, const uint32_t *address_n, + bool full); + #endif diff --git a/legacy/firmware/fsm_msg_coin.h b/legacy/firmware/fsm_msg_coin.h index b3b662019b..17e6642b55 100644 --- a/legacy/firmware/fsm_msg_coin.h +++ b/legacy/firmware/fsm_msg_coin.h @@ -121,82 +121,6 @@ void fsm_msgTxAck(TxAck *msg) { signing_txack(&(msg->tx)); } -static bool path_mismatched(const CoinInfo *coin, const GetAddress *msg) { - bool mismatch = false; - - // m : no path - if (msg->address_n_count == 0) { - return false; - } - - // m/44' : BIP44 Legacy - // m / purpose' / coin_type' / account' / change / address_index - if (msg->address_n[0] == (0x80000000 + 44)) { - mismatch |= (msg->script_type != InputScriptType_SPENDADDRESS); - mismatch |= (msg->address_n_count != 5); - mismatch |= (msg->address_n[1] != coin->coin_type); - mismatch |= (msg->address_n[2] & 0x80000000) == 0; - mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000; - mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000; - return mismatch; - } - - // m/45' - BIP45 Copay Abandoned Multisig P2SH - // m / purpose' / cosigner_index / change / address_index - if (msg->address_n[0] == (0x80000000 + 45)) { - mismatch |= (msg->script_type != InputScriptType_SPENDMULTISIG); - mismatch |= (msg->address_n_count != 4); - mismatch |= (msg->address_n[1] & 0x80000000) == 0x80000000; - mismatch |= (msg->address_n[2] & 0x80000000) == 0x80000000; - mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000; - return mismatch; - } - - // m/48' - BIP48 Copay Multisig P2SH - // m / purpose' / coin_type' / account' / change / address_index - // Electrum: - // m / purpose' / coin_type' / account' / type' / change / address_index - if (msg->address_n[0] == (0x80000000 + 48)) { - mismatch |= (msg->script_type != InputScriptType_SPENDMULTISIG) && - (msg->script_type != InputScriptType_SPENDP2SHWITNESS) && - (msg->script_type != InputScriptType_SPENDWITNESS); - mismatch |= (msg->address_n_count != 5) && (msg->address_n_count != 6); - mismatch |= (msg->address_n[1] != coin->coin_type); - mismatch |= (msg->address_n[2] & 0x80000000) == 0; - mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000; - return mismatch; - } - - // m/49' : BIP49 SegWit - // m / purpose' / coin_type' / account' / change / address_index - if (msg->address_n[0] == (0x80000000 + 49)) { - mismatch |= (msg->script_type != InputScriptType_SPENDP2SHWITNESS); - mismatch |= !coin->has_segwit; - mismatch |= (msg->address_n_count != 5); - mismatch |= (msg->address_n[1] != coin->coin_type); - mismatch |= (msg->address_n[2] & 0x80000000) == 0; - mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000; - mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000; - return mismatch; - } - - // m/84' : BIP84 Native SegWit - // m / purpose' / coin_type' / account' / change / address_index - if (msg->address_n[0] == (0x80000000 + 84)) { - mismatch |= (msg->script_type != InputScriptType_SPENDWITNESS); - mismatch |= !coin->has_segwit; - mismatch |= !coin->bech32_prefix; - mismatch |= (msg->address_n_count != 5); - mismatch |= (msg->address_n[1] != coin->coin_type); - mismatch |= (msg->address_n[2] & 0x80000000) == 0; - mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000; - mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000; - return mismatch; - } - - return false; -} - void fsm_msgGetAddress(const GetAddress *msg) { RESP_INIT(Address); @@ -239,9 +163,8 @@ void fsm_msgGetAddress(const GetAddress *msg) { strlcpy(desc, _("Address:"), sizeof(desc)); } - bool mismatch = path_mismatched(coin, msg); - - if (mismatch) { + if (!coin_known_path_check(coin, msg->script_type, msg->address_n_count, + msg->address_n, true)) { layoutDialogSwipe(&bmp_icon_warning, _("Abort"), _("Continue"), NULL, _("Wrong address path"), _("for selected coin."), NULL, _("Continue at your"), _("own risk!"), NULL); diff --git a/legacy/firmware/signing.c b/legacy/firmware/signing.c index 5bda102ec9..b3550f2e7e 100644 --- a/legacy/firmware/signing.c +++ b/legacy/firmware/signing.c @@ -466,6 +466,10 @@ bool compile_input_script_sig(TxInputType *tinput) { return false; } } + if (!coin_known_path_check(coin, tinput->script_type, tinput->address_n_count, + tinput->address_n, false)) { + return false; + } memcpy(&node, &root, sizeof(HDNode)); if (hdnode_private_ckd_cached(&node, tinput->address_n, tinput->address_n_count, NULL) == 0) {