1

I'm confused by the proposed solution posted in the blog regarding the recent vulnerability https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd?gi=504a17ecca1c

The fix is straightforward — we need to deal with Segwit transactions in the very same manner as we do with non-Segwit transactions. That means we need to require and validate the previous transactions’ UTXO amounts. That is exactly what we are introducing in firmware versions 2.3.1 and 1.9.1.

I thought the value was already required to sign a raw segwit transaction... Since the change to segwit the full value of the input was needed in order to sign the raw transaction whereas before with legacy addresses you can simply sign without the input value amount.

They basically state the same thing in the article:

This is defined in BIP-143 and one of the changes was that the amount of the UTXO is present in the signed data. This helps significantly; if the attacker lies about the UTXO’s amount, the signature is simply not valid in the Bitcoin network.

I guess I need it explained to me like a child because I don't get it, what are they checking and validating, how are they validating? Are they going back two transactions now?

1

The way I understand it, the important part is that for BIP-143 each signature is only calculated for the amount that it's own input spends. For the other inputs only their outpoints (txid+txidx) are used for the signature digest.

Let's assume you have two UTXOs, one with 15 BTC at outpoint txid0:txidx0 and another with 20 BTC at outpoint txid1:txidx1.

Then the trick works as follows:

  • Create a "template" PSBT that contains the correct outpoints in the inputs, so input0: txid0:txidx0 and input1: txid1:txidx1; and an output that sends an amount equal the greatest value of UTXO you have, so e.g. 20 BTC.

  • Now when you feed this template to your (offline) hardware device, you give the correct UTXO information for e.g. input0 (hence 15BTC+scriptPubkey1), but fake the UTXO amount of input1 so that it adds up to the amount you send + fees (hence 5.000001BTC+scriptPubKey2).

  • This will leave you with a valid signature for input0, which however is worthless as long as you do not also produce a valid signature for input1 (the one we could have got now for input1 is invalid as the amount was incorrect).

  • We therefore now repeat the steps, but this time faking the amount of input0 (hence 0.000001BTC+scriptPubKey1), while adding the correct amount for input1 (hence 20BTC+scriptPubKey2). The idea is that it looks similar and the user will simply sign again. This gives you a valid signature for input1.

  • Lastly, you simply use your "template" PSBT and add for each input the valid signatures you produced. The resulting valid and signed tx then uses inputs of 15 + 20 = 45 BTC, but have as output only 20 BTC, so paying a fee of 15(!) BTC.

// Edit: The fix of adding to each PSBT input the complete transaction containing an outpoint being spend enables the hardware device to check if the amount are correct (otherwise the txid would be wrong).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.