sign_tx/sign_psbt: extra check for BTC inputs
What changed, and why it matters
This commit adds overflow protection when adding up the total value of Bitcoin transaction inputs in Blockstream Jade's signing code. Previously, the firmware used a plain addition that could silently wrap around if a specially crafted transaction pushed the running total above the maximum 64-bit integer value. The patch now uses a checked addition and rejects the transaction if the total would overflow. The commit message says the check 'should be redundant' because each individual input amount and the number of inputs are already bounded, so this is a defensive hardening change rather than a confirmed exploitable bug.
Treat as a low-risk hardening improvement. No immediate incident response is warranted, but ensure the checked_add_uint64 helper is robust and that test coverage includes boundary cases for total input amount. Review whether similar unchecked accumulations exist elsewhere in the firmware.
Security signals we found
Integer overflow hardening in financial-amount accumulation
Defensive checked_add_uint64() introduced where plain addition existed
Transaction signing path now rejects overflowed input totals
Commit message frames change as redundant/defensive, not as a fix for a known exploit
Evidence from the diff
In sign_tx.c and sign_psbt.c, the firmware accumulates input amounts into a uint64_t variable input_amount to compute total input value (used later for fee calculation). The original code used the += operator, which wraps on overflow. The patch replaces those additions with checked_add_uint64(), which returns false on overflow and now causes the signing request to be rejected with CBOR_RPC_BAD_PARAMETERS and the message ‘Total input amounts exceed maximum’. The commit message notes the check is likely redundant because WALLY_SATOSHI_MAX bounds each amount and MAX_TX_INPUTS bounds input count, but the patch adds the defense anyway.
Changed components
main/process/sign_tx.cmain/process/sign_psbt.cBitcoin transaction signing input-amount accumulationInspect captured patch +15 / −3
### main/process/sign_psbt.c
@@ -808,7 +808,11 @@ int sign_psbt(jade_process_t* process, CborValue* params, const network_t networ
}
if (!for_liquid) {
// Bitcoin: Collect input total for fee calculation
- input_amount += utxo->satoshi;
+ if (!checked_add_uint64(input_amount, utxo->satoshi, &input_amount)) {
+ *errmsg = "Total input amounts exceed maximum";
+ retval = CBOR_RPC_BAD_PARAMETERS;
+ goto cleanup;
+ }
}
if (!key_iter_input_begin_public(psbt, index, &iter)) {
### main/process/sign_tx.c
@@ -11,6 +11,7 @@
#include "../utils/cbor_rpc.h"
#include "../utils/event.h"
#include "../utils/malloc_ext.h"
+#include "../utils/util.h"
#include "../utils/wally_ext.h"
#include "../wallet.h"
@@ -724,7 +725,11 @@ static void sign_tx_impl(jade_process_t* process, const bool for_liquid)
if (res == WALLY_OK) {
res = wally_map_add_integer(&signing_data->amounts, index, (uint8_t*)&txout->satoshi, sizeof(uint64_t));
// Keep a running total
- input_amount += txout->satoshi;
+ if (res == WALLY_OK && !checked_add_uint64(input_amount, txout->satoshi, &input_amount)) {
+ jade_process_reject_message(process, CBOR_RPC_BAD_PARAMETERS, "Total input amounts exceed maximum");
+ JADE_WALLY_VERIFY(wally_tx_free(input_tx));
+ goto cleanup;
+ }
}
if (res != WALLY_OK) {
jade_process_reject_message(process, CBOR_RPC_BAD_PARAMETERS, "Failed to extract prevout");
@@ -752,7 +757,10 @@ static void sign_tx_impl(jade_process_t* process, const bool for_liquid)
if (rpc_get_uint64("satoshi", ¶ms, &satoshi)) {
res = wally_map_add_integer(&signing_data->amounts, index, (uint8_t*)&satoshi, sizeof(uint64_t));
// Keep a running total
- input_amount += satoshi;
+ if (res == WALLY_OK && !checked_add_uint64(input_amount, satoshi, &input_amount)) {
+ jade_process_reject_message(process, CBOR_RPC_BAD_PARAMETERS, "Total input amounts exceed maximum");
+ goto cleanup;
+ }
}
if (res != WALLY_OK) {
jade_process_reject_message(Why this scored 44/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.