sign_psbt: update input amounts when additional_info is present
What changed, and why it matters
This commit fixes a bug in how Blockstream Jade signs Liquid Bitcoin transactions. When extra data ('additional_info') was provided for a transaction input, the hardware wallet was not updating its internal running totals of input amounts per asset. This could cause the device to miscalculate whether a transaction is balanced—potentially allowing a malicious or buggy host to trick the wallet into approving a transaction that silently moves more value than the user expects. The fix makes the wallet explicitly require and record the input's asset and amount in this code path.
Treat as a security-relevant bug fix. Review whether any prior firmware version allowed signing Liquid PSBTs with additional_info while skipping this balance check, and assess if a security advisory or firmware update notice is warranted for users who sign Liquid transactions with untrusted hosts.
Security signals we found
Fixes missing update of input asset/amount totals during PSBT signing
Adds explicit validation that input amount and asset are present when additional_info is used
Targets Liquid asset-balance verification (in_sums)
Potential consequence: host could present unbalanced PSBT that device would not detect
Evidence from the diff
In main/process/sign_psbt.c, inside sign_psbt(), the loop that identifies inputs belonging to the signer now updates the Liquid asset input-summaries (in_sums) when for_liquid and in_sums are active. Previously, when additional_info was present, the code path apparently skipped or failed to record the input amount into the per-asset running totals used for balance verification. The patch adds a check that the PSBT input has an explicit amount and asset, fetches the asset ID, reverses it in place (noting a TODO about binary ordering), and calls asset_summary_update(). If amount/asset is missing it returns CBOR_RPC_BAD_PARAMETERS with ‘Missing input explicit asset or value’. This is a correctness fix for transaction-balance validation on Liquid.
Changed components
main/process/sign_psbt.cLiquid PSBT signing flowasset_summary_update balance-checking logicInspect captured patch +19 / −0
diff --git a/main/process/sign_psbt.c b/main/process/sign_psbt.c
index 607dd64..528ec77 100644
--- a/main/process/sign_psbt.c
+++ b/main/process/sign_psbt.c
@@ -755,6 +755,25 @@ int sign_psbt(jade_process_t* process, CborValue* params, const network_t networ
// Found our key - we are signing this input
JADE_LOGD("Key %u belongs to this signer, so we will need to sign input %u", iter.key_index, index);
+
+ if (for_liquid && in_sums) {
+ uint8_t asset_id[32];
+ size_t written = 0;
+ if (!input->has_amount
+ || wally_psbt_input_get_asset(input, asset_id, sizeof(asset_id), &written) != WALLY_OK
+ || written != sizeof(asset_id)) {
+ // If additional_info is present, the caller must provide explicit
+ // value/asset along with their proofs (checked during parsing)
+ *errmsg = "Missing input explicit asset or value";
+ retval = CBOR_RPC_BAD_PARAMETERS;
+ goto cleanup;
+ }
+ // TODO: additional_info should store asset_ids in binary order,
+ // so we shouldn't have to reverse_in_place() here
+ reverse_in_place(asset_id, sizeof(asset_id));
+ asset_summary_update(in_sums, num_in_sums, asset_id, sizeof(asset_id), input->amount);
+ }
+
uint32_t sig_type;
JADE_WALLY_VERIFY(wally_psbt_get_input_signature_type(psbt, index, &sig_type));
JADE_ASSERT(sig_type);
Why this scored 59/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.