What changed, and why it matters
This commit fixes a logic bug in the Keystone hardware wallet's SLIP39 backup phrase handling. The original code used 'OR' instead of 'AND' when checking word counts, which made the validation always fail for valid 20-word and 33-word SLIP39 phrases. This would have shown users an incorrect error notice and blocked legitimate wallet recovery or setup operations. It is a bug fix that improves reliability, but it does not appear to allow theft of funds on its own.
Verify the fix with unit tests covering 20-word and 33-word SLIP39 mnemonics, and audit nearby validation logic for similar boolean-operator mistakes. No urgent security patch is required, but include this fix in the next firmware release to restore SLIP39 usability.
Security signals we found
Logic operator bug in input validation
SLIP39 mnemonic word-count check always evaluated true, rejecting valid mnemonics
Availability impact on wallet recovery/setup
No explicit vendor security framing in commit message
Evidence from the diff
In ModelSlip39WriteEntropy(), the condition guarding allowed SLIP39 mnemonic word counts was written with || instead of &&. Because wordCnt cannot simultaneously equal 20 and 33, the expression wordCnt != 20 || wordCnt != 33 is always true, so every SLIP39 input was rejected with ERR_KEYSTORE_MNEMONIC_INVALID. The patch changes the operator to && so that only word counts other than 20 or 33 are rejected. This is a straightforward boolean-logic defect with denial-of-service/availability impact on SLIP39 workflows.
Changed components
src/ui/gui_model/gui_model.cModelSlip39WriteEntropy()SLIP39 mnemonic validation flowInspect captured patch +1 / −1
diff --git a/src/ui/gui_model/gui_model.c b/src/ui/gui_model/gui_model.c
index 20ebd14..c6c0600 100644
--- a/src/ui/gui_model/gui_model.c
+++ b/src/ui/gui_model/gui_model.c
@@ -821,7 +821,7 @@ static int32_t ModelSlip39WriteEntropy(const void *inData, uint32_t inDataLen)
ie = SecretCacheGetIteration();
MODEL_WRITE_SE_HEAD
- if (wordCnt != SLIP39_MNEMONIC_20_WORDS || wordCnt != SLIP39_MNEMONIC_33_WORDS) {
+ if (wordCnt != SLIP39_MNEMONIC_20_WORDS && wordCnt != SLIP39_MNEMONIC_33_WORDS) {
ret = ERR_KEYSTORE_MNEMONIC_INVALID;
break;
}
Why this scored 48/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.