diff --git a/firmware/protect.c b/firmware/protect.c index 01e44f051..53f5791a9 100644 --- a/firmware/protect.c +++ b/firmware/protect.c @@ -183,7 +183,7 @@ bool protectPin(bool use_cached) fsm_sendFailure(FailureType_Failure_PinCancelled, NULL); return false; } - if (storage_increasePinFails(fails) && storage_isPinCorrect(pin)) { + if (storage_increasePinFails(fails) && storage_containsPin(pin)) { session_cachePin(); storage_resetPinFails(fails); return true; diff --git a/firmware/recovery.c b/firmware/recovery.c index ac08dc63c..878736d37 100644 --- a/firmware/recovery.c +++ b/firmware/recovery.c @@ -126,19 +126,6 @@ static void recovery_request(void) { msg_write(MessageType_MessageType_WordRequest, &resp); } -static bool is_same_mnemonic(const char *new_mnemonic) { - /* The execution time of the following code only depends on the - * (public) input. This avoids timing attacks. - */ - char diff = 0; - uint32_t i = 0; - for (; new_mnemonic[i]; i++) { - diff |= (storage.mnemonic[i] - new_mnemonic[i]); - } - diff |= storage.mnemonic[i]; - return diff == 0; -} - /* Called when the last word was entered. * Check mnemonic and send success/failure. */ @@ -166,7 +153,7 @@ static void recovery_done(void) { fsm_sendSuccess(_("Device recovered")); } else { // Inform the user about new mnemonic correctness (as well as whether it is the same as the current one). - if (is_same_mnemonic(new_mnemonic)) { + if (storage_isInitialized() && storage_containsMnemonic(new_mnemonic)) { layoutDialog(&bmp_icon_ok, NULL, _("Confirm"), NULL, _("The seed is valid"), _("and MATCHES"), diff --git a/firmware/storage.c b/firmware/storage.c index ec85cda4f..0976c44fe 100644 --- a/firmware/storage.c +++ b/firmware/storage.c @@ -427,10 +427,26 @@ const uint8_t *storage_getHomescreen(void) return (storage.has_homescreen && storage.homescreen.size == 1024) ? storage.homescreen.bytes : 0; } -/* Check whether pin matches storage. The pin must be a null-terminated - * string with at most 9 characters. +/* Check whether mnemonic matches storage. The mnemonic must be + * a null-terminated string. */ -bool storage_isPinCorrect(const char *pin) +bool storage_containsMnemonic(const char *mnemonic) { + /* The execution time of the following code only depends on the + * (public) input. This avoids timing attacks. + */ + char diff = 0; + uint32_t i = 0; + for (; mnemonic[i]; i++) { + diff |= (storage.mnemonic[i] - mnemonic[i]); + } + diff |= storage.mnemonic[i]; + return diff == 0; +} + +/* Check whether pin matches storage. The pin must be + * a null-terminated string with at most 9 characters. + */ +bool storage_containsPin(const char *pin) { /* The execution time of the following code only depends on the * (public) input. This avoids timing attacks. diff --git a/firmware/storage.h b/firmware/storage.h index b3680a2bb..89e2cfc4f 100644 --- a/firmware/storage.h +++ b/firmware/storage.h @@ -51,7 +51,9 @@ void storage_setHomescreen(const uint8_t *data, uint32_t size); void session_cachePassphrase(const char *passphrase); bool session_isPassphraseCached(void); -bool storage_isPinCorrect(const char *pin); +bool storage_containsMnemonic(const char *mnemonic); + +bool storage_containsPin(const char *pin); bool storage_hasPin(void); void storage_setPin(const char *pin); void session_cachePin(void);