Skip to content

Commit 769714f

Browse files
committed
firmware: stronger recovery state machine checks
1 parent b222c66 commit 769714f

1 file changed

Lines changed: 28 additions & 2 deletions

File tree

lib/firmware/recovery_cipher.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#define MAX_UNCYPHERED_WORDS (3)
3838

39+
static bool recovery_started = false;
3940
static bool enforce_wordlist;
4041
static bool dry_run;
4142
static bool awaiting_character;
@@ -56,6 +57,7 @@ static void recovery_abort(void) {
5657
storage_reset();
5758
}
5859

60+
recovery_started = false;
5961
awaiting_character = false;
6062
memzero(mnemonic, sizeof(mnemonic));
6163
memzero(cipher, sizeof(cipher));
@@ -270,6 +272,7 @@ void recovery_cipher_init(bool passphrase_protection, bool pin_protection,
270272

271273
/* Set to recovery cipher mode and generate and show next cipher */
272274
awaiting_character = true;
275+
recovery_started = true;
273276
next_character();
274277
}
275278

@@ -283,6 +286,13 @@ void recovery_cipher_init(bool passphrase_protection, bool pin_protection,
283286
*/
284287
void next_character(void)
285288
{
289+
if (!recovery_started) {
290+
recovery_abort();
291+
fsm_sendFailure(FailureType_Failure_UnexpectedMessage, "Not in Recovery mode");
292+
layoutHome();
293+
return;
294+
}
295+
286296
/* Scramble cipher */
287297
strlcpy(cipher, english_alphabet, ENGLISH_ALPHABET_BUF);
288298
random_permute_char(cipher, strlen(cipher));
@@ -341,7 +351,7 @@ void next_character(void)
341351
*/
342352
void recovery_character(const char *character)
343353
{
344-
if (!awaiting_character) {
354+
if (!awaiting_character || !recovery_started) {
345355
recovery_abort();
346356
fsm_sendFailure(FailureType_Failure_UnexpectedMessage, "Not in Recovery mode");
347357
layoutHome();
@@ -430,6 +440,13 @@ void recovery_character(const char *character)
430440
*/
431441
void recovery_delete_character(void)
432442
{
443+
if (!recovery_started) {
444+
recovery_abort();
445+
fsm_sendFailure(FailureType_Failure_UnexpectedMessage, "Not in Recovery mode");
446+
layoutHome();
447+
return;
448+
}
449+
433450
if(strlen(mnemonic) > 0)
434451
{
435452
mnemonic[strlen(mnemonic) - 1] = '\0';
@@ -448,6 +465,13 @@ void recovery_delete_character(void)
448465
*/
449466
void recovery_cipher_finalize(void)
450467
{
468+
if (!recovery_started) {
469+
recovery_abort();
470+
fsm_sendFailure(FailureType_Failure_UnexpectedMessage, "Not in Recovery mode");
471+
layoutHome();
472+
return;
473+
}
474+
451475
static char CONFIDENTIAL new_mnemonic[MNEMONIC_BUF] = "";
452476
static char CONFIDENTIAL temp_word[CURRENT_WORD_BUF];
453477
volatile bool auto_completed = true;
@@ -479,7 +503,7 @@ void recovery_cipher_finalize(void)
479503
}
480504

481505
/* Truncate additional space at the end */
482-
new_mnemonic[strlen(new_mnemonic) - 1] = '\0';
506+
new_mnemonic[MAX(0u, strnlen(new_mnemonic, sizeof(new_mnemonic)) - 1)] = '\0';
483507

484508
if (!dry_run && (!enforce_wordlist || mnemonic_check(new_mnemonic))) {
485509
storage_setMnemonic(new_mnemonic);
@@ -532,6 +556,8 @@ void recovery_cipher_finalize(void)
532556
*/
533557
bool recovery_cipher_abort(void)
534558
{
559+
recovery_started = false;
560+
535561
if (awaiting_character) {
536562
awaiting_character = false;
537563
return true;

0 commit comments

Comments
 (0)