mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-03 03:50:58 +00:00
feat(legacy): Disable prevtx streaming for Taproot.
This commit is contained in:
parent
c9d1ff93f5
commit
7597eb25ab
1
legacy/firmware/.changelog.d/1656.changed
Normal file
1
legacy/firmware/.changelog.d/1656.changed
Normal file
@ -0,0 +1 @@
|
||||
Disable previous transaction streaming in Bitcoin if all internal inputs are Taproot.
|
@ -66,6 +66,7 @@ enum {
|
||||
STAGE_REQUEST_DECRED_WITNESS,
|
||||
#endif
|
||||
} signing_stage;
|
||||
static bool taproot_only; // indicates whether all internal inputs are Taproot
|
||||
static uint32_t idx1; // The index of the input or output in the current tx
|
||||
// which is being processed, signed or serialized.
|
||||
static uint32_t idx2; // The index of the input or output in the original tx
|
||||
@ -237,6 +238,9 @@ foreach O (idx1):
|
||||
Check tx fee
|
||||
Ask for confirmation
|
||||
|
||||
if (taproot_only)
|
||||
Skip to Phase 2.
|
||||
|
||||
foreach I (idx1):
|
||||
Request I STAGE_REQUEST_3_INPUT
|
||||
Request prevhash I, META STAGE_REQUEST_3_PREV_META
|
||||
@ -879,6 +883,7 @@ void signing_init(const SignTx *msg, const CoinInfo *_coin,
|
||||
|
||||
tx_weight = 4 * size;
|
||||
|
||||
taproot_only = true;
|
||||
signatures = 0;
|
||||
idx1 = 0;
|
||||
total_in = 0;
|
||||
@ -1975,8 +1980,25 @@ static void phase1_finish(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (taproot_only) {
|
||||
// All internal inputs are Taproot. We do not need to verify them so we
|
||||
// proceed directly to Phase 2, where the transaction will be signed. We can
|
||||
// trust the amounts and scriptPubKeys, because if an invalid value is
|
||||
// provided then all issued signatures will be invalid.
|
||||
phase2_request_next_input();
|
||||
} else {
|
||||
// There are internal non-Taproot inputs. We need to verify all inputs,
|
||||
// because we can't trust any amounts or scriptPubKeys. If we did, then an
|
||||
// attacker who provides invalid information about amounts, scriptPubKeys
|
||||
// and/or script types may still obtain valid signatures for legacy and
|
||||
// SegWit v0 inputs. These valid signatures could be exploited in subsequent
|
||||
// signing operations to falsely claim externality of the already signed
|
||||
// inputs or to falsely claim that a transaction is a replacement of an
|
||||
// already approved transaction or to construct a valid transaction by
|
||||
// combining signatures obtained in multiple rounds of the attack.
|
||||
send_req_3_input();
|
||||
}
|
||||
}
|
||||
|
||||
static void phase1_request_next_output(void) {
|
||||
if (idx1 < info.outputs_count - 1) {
|
||||
@ -2122,11 +2144,11 @@ static bool signing_sign_bip340(const uint8_t *private_key,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool signing_sign_input(void) {
|
||||
static bool signing_sign_legacy_input(void) {
|
||||
uint8_t hash[32] = {0};
|
||||
hasher_Final(&hasher_check, hash);
|
||||
if (memcmp(hash, info.hash_outputs, 32) != 0) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError,
|
||||
if (memcmp(hash, info.hash_outputs, 32) != 0 || taproot_only) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Transaction has changed during signing"));
|
||||
signing_abort();
|
||||
return false;
|
||||
@ -2170,6 +2192,13 @@ static bool signing_sign_segwit_input(TxInputType *txinput) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (taproot_only) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Transaction has changed during signing"));
|
||||
signing_abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tx_info_check_input(&info, txinput) || !derive_node(txinput) ||
|
||||
!fill_input_script_sig(txinput)) {
|
||||
return false;
|
||||
@ -2293,6 +2322,10 @@ void signing_txack(TransactionType *tx) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tx->inputs[0].script_type != InputScriptType_SPENDTAPROOT) {
|
||||
taproot_only = false;
|
||||
}
|
||||
|
||||
if (tx->inputs[0].script_type == InputScriptType_SPENDMULTISIG ||
|
||||
tx->inputs[0].script_type == InputScriptType_SPENDADDRESS) {
|
||||
#if !ENABLE_SEGWIT_NONSEGWIT_MIXING
|
||||
@ -2713,7 +2746,7 @@ void signing_txack(TransactionType *tx) {
|
||||
idx2++;
|
||||
send_req_4_output();
|
||||
} else {
|
||||
if (!signing_sign_input()) {
|
||||
if (!signing_sign_legacy_input()) {
|
||||
return;
|
||||
}
|
||||
// since this took a longer time, update progress
|
||||
@ -2741,7 +2774,7 @@ void signing_txack(TransactionType *tx) {
|
||||
resp.serialized.has_serialized_tx = true;
|
||||
if (tx->inputs[0].script_type == InputScriptType_SPENDMULTISIG ||
|
||||
tx->inputs[0].script_type == InputScriptType_SPENDADDRESS) {
|
||||
if (!(coin->force_bip143 || coin->overwintered)) {
|
||||
if (!(coin->force_bip143 || coin->overwintered) || taproot_only) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError,
|
||||
_("Transaction has changed during signing"));
|
||||
signing_abort();
|
||||
|
Loading…
Reference in New Issue
Block a user