feat: hide zcash on slip39 wallet for keystone
What changed, and why it matters
This commit changes the Keystone hardware wallet firmware so that Zcash features are hidden or blocked when the wallet was created using a SLIP39 seed (a type of multi-share recovery phrase). The code now returns an 'unsupported' error for Zcash transaction checks on SLIP39 wallets and swaps in a wallet-list image that does not show Zcash. There is no evidence in the commit of a vulnerability being fixed; it reads as a product-level feature restriction.
No security patch action is required. Treat this as a normal feature/limitation commit. If Zcash support for SLIP39 is desired in the future, the gating logic and UI asset selection should be revisited through the normal product roadmap.
Security signals we found
Feature gating: Zcash transaction validation is explicitly disabled for SLIP39 wallets
UI hiding: Zcash icon removed from Keystone wallet list when SLIP39 is active
Error path returns a controlled error message rather than crashing or default-allowing
No input parsing, buffer handling, or privilege changes are present in the diff
Evidence from the diff
The patch adds a disabled boolean parameter to check_zcash_tx_multi_coins in rust/rust_c/src/zcash/mod.rs. When disabled is true, the function immediately returns RustCError::UnsupportedTransaction("zcash is not supported for slip39 and passphrase wallet now"). The C caller in src/ui/gui_chain/multi/gui_zcash.c passes mnemonicType == MNEMONIC_TYPE_SLIP39 for that flag. The UI wallet-list code in gui_connect_wallet_widgets.c switches the Keystone wallet entry to a SLIP39-specific coin icon array (g_keystoneWalletCoinArraySlip39) with a count of 7 instead of 8, and a new PNG asset is added. The image hash file is updated accordingly. No cryptographic, memory-safety, or authorization bug is visible in the diff.
Changed components
rust/rust_c/src/zcash/mod.rssrc/ui/gui_chain/multi/gui_zcash.csrc/ui/gui_widgets/multi/web3/gui_connect_wallet_widgets.csrc/ui/gui_assets/images_hash.txtimages/walletList/walletListKeystoneSlip39.pngInspect captured patch +16 / −4
diff --git a/images/walletList/walletListKeystoneSlip39.png b/images/walletList/walletListKeystoneSlip39.png
new file mode 100644
index 0000000..2cefec2
Binary files /dev/null and b/images/walletList/walletListKeystoneSlip39.png differ
diff --git a/rust/rust_c/src/zcash/mod.rs b/rust/rust_c/src/zcash/mod.rs
index e775032..530e46a 100644
--- a/rust/rust_c/src/zcash/mod.rs
+++ b/rust/rust_c/src/zcash/mod.rs
@@ -107,7 +107,14 @@ pub unsafe extern "C" fn check_zcash_tx_multi_coins(
xpub: PtrString,
seed_fingerprint: PtrBytes,
account_index: u32,
+ disabled: bool,
) -> *mut TransactionCheckResult {
+ if disabled {
+ return TransactionCheckResult::from(RustCError::UnsupportedTransaction(
+ "zcash is not supported for slip39 and passphrase wallet now".to_string(),
+ ))
+ .c_ptr();
+ }
let pczt = extract_ptr_with_type!(tx, ZcashPczt);
let xpub_text = unsafe { recover_c_char(xpub) };
let seed_fingerprint = extract_array!(seed_fingerprint, u8, 32);
diff --git a/src/ui/gui_assets/images_hash.txt b/src/ui/gui_assets/images_hash.txt
index 4c1e4e1..c9150c1 100644
--- a/src/ui/gui_assets/images_hash.txt
+++ b/src/ui/gui_assets/images_hash.txt
@@ -1 +1 @@
-42a71ce01bbaebf57a21b3c79dd8fa67
+192f997af26b8b0e7c2420a5d0379bb0
\ No newline at end of file
diff --git a/src/ui/gui_chain/multi/gui_zcash.c b/src/ui/gui_chain/multi/gui_zcash.c
index 21c45c6..122f0d8 100644
--- a/src/ui/gui_chain/multi/gui_zcash.c
+++ b/src/ui/gui_chain/multi/gui_zcash.c
@@ -313,7 +313,7 @@ PtrT_TransactionCheckResult GuiGetZcashCheckResult(void)
#ifdef WEB3_VERSION
char *xpub = GetCurrentAccountPublicKey(XPUB_TYPE_ZEC_TRANSPARENT_LEGACY);
- return check_zcash_tx_multi_coins(data, xpub, sfp, zcash_account_index);
+ return check_zcash_tx_multi_coins(data, xpub, sfp, zcash_account_index, mnemonicType == MNEMONIC_TYPE_SLIP39);
#endif
#ifdef CYPHERPUNK_VERSION
char ufvk[ZCASH_UFVK_MAX_LEN + 1] = {0};
diff --git a/src/ui/gui_widgets/multi/web3/gui_connect_wallet_widgets.c b/src/ui/gui_widgets/multi/web3/gui_connect_wallet_widgets.c
index 898b52e..fd96d0d 100644
--- a/src/ui/gui_widgets/multi/web3/gui_connect_wallet_widgets.c
+++ b/src/ui/gui_widgets/multi/web3/gui_connect_wallet_widgets.c
@@ -201,7 +201,7 @@ static CoinState_t g_defaultFewchaState[FEWCHA_COINS_BUTT] = {
};
WalletListItem_t g_walletListArray[] = {
- {WALLET_LIST_KEYSTONE, &walletKeystone, "Keystone Nexus", g_keystoneWalletCoinArray, 6, false, WALLET_FILTER_BTC | WALLET_FILTER_ETH | WALLET_FILTER_OTHER},
+ {WALLET_LIST_KEYSTONE, &walletKeystone, "Keystone Nexus", g_keystoneWalletCoinArray, 8, false, WALLET_FILTER_BTC | WALLET_FILTER_ETH | WALLET_FILTER_OTHER},
{WALLET_LIST_OKX, &walletOkx, "OKX Wallet", g_okxWalletCoinArray, 7, true, WALLET_FILTER_BTC | WALLET_FILTER_ETH | WALLET_FILTER_OTHER},
{WALLET_LIST_METAMASK, &walletMetamask, "MetaMask", g_metaMaskCoinArray, 5, true, WALLET_FILTER_ETH},
{WALLET_LIST_BACKPACK, &walletBackpack, "Backpack", g_backpackWalletCoinArray, 3, true, WALLET_FILTER_ETH | WALLET_FILTER_SOL | WALLET_FILTER_OTHER},
@@ -242,7 +242,6 @@ WalletListItem_t g_walletListArray[] = {
{WALLET_LIST_SUSHISWAP, &walletSushi, "SushiSwap", g_ethWalletCoinArray, 4, true, WALLET_FILTER_ETH},
};
-
typedef struct {
const char *accountType;
const char *path;
@@ -338,6 +337,12 @@ static void GuiInitWalletListArray()
for (size_t i = 0; i < NUMBER_OF_ARRAYS(g_walletListArray); i++) {
bool enable = true;
int index = g_walletListArray[i].index;
+ if (isSLIP39) {
+ if (index == WALLET_LIST_KEYSTONE) {
+ g_walletListArray[i].coinIcons = g_keystoneWalletCoinArraySlip39;
+ g_walletListArray[i].coinCount = 7;
+ }
+ }
if (isTON) {
enable = (index == WALLET_LIST_TONKEEPER);
Why this scored 19/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.