fix: add ltc native xpub to parse context
What changed, and why it matters
This commit fixes a bug in the Keystone 3 hardware wallet firmware where Litecoin (LTC) transactions using the newer Native SegWit address format (path m/84'/2'/0') could not be properly parsed or verified. The fix adds the missing LTC Native SegWit extended public key (xpub) to the list of keys used when decoding transaction data. Without this key, the device might fail to recognize the user's own addresses in a transaction, which could lead to incorrect display, signing failures, or in a worst-case scenario, tricking the user about where funds are going. The change is small and appears to be a straightforward missing-key fix rather than a full security patch.
Review the declared size of the public_keys/keys array to ensure it has room for the new LTC Native SegWit entry and that no buffer overflow or truncation occurs. Verify that the Rust parser consumes all entries correctly and that no other BIP44/BIP49/BIP84/BIP86 paths for LTC or other coins are missing. Test signing and display of LTC Native SegWit transactions end-to-end, including change output detection. Consider whether this fix should be treated as a security-relevant firmware update and communicated to users who rely on LTC Native SegWit.
Security signals we found
Missing extended public key for a supported coin/derivation path in transaction parsing context
Potential address ownership misidentification for LTC Native SegWit (BIP84) transactions
UI/display layer dependency on incomplete key list for transaction verification
No explicit bounds check visible in the diff; patch assumes array has capacity for the extra element
Evidence from the diff
In src/ui/gui_chain/gui_btc.c, the PreparePublicKeys() function builds a CSliceFFI_ExtendedPublicKey array used by the Rust/C FFI transaction parser to map scriptPubKeys/addresses to the wallet’s own keys. The previous array only included LTC’s legacy wrapped-SegWit path (m/49’/2’/0’, XPUB_TYPE_LTC) but omitted the native SegWit path (m/84’/2’/0’, XPUB_TYPE_LTC_NATIVE_SEGWIT). The patch inserts that missing entry and shifts DASH and BCH indices up by one. The parser likely uses these xpubs to derive child public keys and identify change/receive outputs. Missing the native SegWit xpub means the parser cannot derive native SegWit LTC addresses, so it may treat them as external addresses, fail path validation, or present incomplete transaction info to the signing UI.
Changed components
src/ui/gui_chain/gui_btc.cLitecoin (LTC) Native SegWit transaction parsing and displayPreparePublicKeys() functionCSliceFFI_ExtendedPublicKey public key list passed to Rust transaction parserInspect captured patch +6 / −4
diff --git a/src/ui/gui_chain/gui_btc.c b/src/ui/gui_chain/gui_btc.c
index b8e2a1e..f53c2d8 100644
--- a/src/ui/gui_chain/gui_btc.c
+++ b/src/ui/gui_chain/gui_btc.c
@@ -359,10 +359,12 @@ static void PreparePublicKeys(PtrT_CSliceFFI_ExtendedPublicKey public_keys, Exte
// ltc、dash、bch
keys[6].path = "m/49'/2'/0'";
keys[6].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_LTC);
- keys[7].path = "m/44'/5'/0'";
- keys[7].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_DASH);
- keys[8].path = "m/44'/145'/0'";
- keys[8].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_BCH);
+ keys[7].path = "m/84'/2'/0'";
+ keys[7].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_LTC_NATIVE_SEGWIT);
+ keys[8].path = "m/44'/5'/0'";
+ keys[8].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_DASH);
+ keys[9].path = "m/44'/145'/0'";
+ keys[9].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_BCH);
#endif
#endif
}
Why this scored 34/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.