diff --git a/firmware/recovery.c b/firmware/recovery.c index daa2973fb9..e92fc1d5a3 100644 --- a/firmware/recovery.c +++ b/firmware/recovery.c @@ -139,27 +139,36 @@ void recovery_word(const char *word) strlcpy(words[word_pos - 1], word, sizeof(words[word_pos - 1])); } - if (word_index + 1 == 24) { // last one - uint32_t i; - strlcpy(storage.mnemonic, words[0], sizeof(storage.mnemonic)); - for (i = 1; i < word_count; i++) { - strlcat(storage.mnemonic, " ", sizeof(storage.mnemonic)); - strlcat(storage.mnemonic, words[i], sizeof(storage.mnemonic)); - } - if (!enforce_wordlist || mnemonic_check(storage.mnemonic)) { - storage.has_mnemonic = true; - storage_commit(); - fsm_sendSuccess("Device recovered"); - } else { - storage_reset(); - fsm_sendFailure(FailureType_Failure_SyntaxError, "Invalid mnemonic, are words in correct order?"); - } - awaiting_word = false; - layoutHome(); - } else { + if (word_index + 1 < 24) { // not the last one word_index++; next_word(); + return; } + + // the last one + strlcpy(storage.mnemonic, words[0], sizeof(storage.mnemonic)); + for (uint32_t i = 1; i < word_count; i++) { + strlcat(storage.mnemonic, " ", sizeof(storage.mnemonic)); + strlcat(storage.mnemonic, words[i], sizeof(storage.mnemonic)); + } + + awaiting_word = false; + layoutHome(); + + if (!mnemonic_check(storage.mnemonic)) { + if (enforce_wordlist) { + storage_reset(); + fsm_sendFailure(FailureType_Failure_SyntaxError, "Invalid mnemonic, are words in correct order?"); + return; + } else { // not enforcing => mark storage as imported + storage.has_imported = true; + storage.imported = true; + } + } + + storage.has_mnemonic = true; + storage_commit(); + fsm_sendSuccess("Device recovered"); } void recovery_abort(void) diff --git a/firmware/storage.c b/firmware/storage.c index 5ec381f0ab..8ef55fce77 100644 --- a/firmware/storage.c +++ b/firmware/storage.c @@ -105,7 +105,7 @@ static char sessionPassphrase[51]; void storage_show_error(void) { layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Storage failure", "detected.", NULL, "Please unplug", "the device.", NULL); - for (;;) { } + system_halt(); } void storage_check_flash_errors(void) @@ -353,6 +353,14 @@ const uint8_t *storage_getSeed(bool usePassphrase) if (usePassphrase && !protectPassphrase()) { return NULL; } + // if storage was not imported (i.e. it was properly generated or recovered) + if (!storage.has_imported || !storage.imported) { + // test whether mnemonic is a valid BIP-0039 mnemonic + if (!mnemonic_check(storage.mnemonic)) { + // and if not then halt the device + storage_show_error(); + } + } mnemonic_to_seed(storage.mnemonic, usePassphrase ? sessionPassphrase : "", sessionSeed, get_root_node_callback); // BIP-0039 sessionSeedCached = true; sessionSeedUsesPassphrase = usePassphrase;