diff --git a/firmware/protect.c b/firmware/protect.c index d0ef4a8ffe..713881e397 100644 --- a/firmware/protect.c +++ b/firmware/protect.c @@ -161,7 +161,7 @@ bool protectPin(bool use_cached) return true; } uint32_t fails = storage_getPinFailsOffset(); - uint32_t wait = ~*(const uint32_t*)FLASH_PTR(fails); + uint32_t wait = storage_getPinWait(fails); protectCheckMaxTry(wait); usbTiny(1); while (wait > 0) { @@ -206,7 +206,7 @@ bool protectPin(bool use_cached) storage_resetPinFails(fails); return true; } else { - protectCheckMaxTry(~*(const uint32_t*)FLASH_PTR(fails)); + protectCheckMaxTry(storage_getPinWait(fails)); fsm_sendFailure(FailureType_Failure_PinInvalid, NULL); return false; } diff --git a/firmware/storage.c b/firmware/storage.c index 2167b8a407..bfa7467adb 100644 --- a/firmware/storage.c +++ b/firmware/storage.c @@ -797,6 +797,13 @@ bool storage_increasePinFails(uint32_t flash_pinfails) return *(const uint32_t*)FLASH_PTR(flash_pinfails) == newctr; } +uint32_t storage_getPinWait(uint32_t flash_pinfails) +{ + // The pin failure word is the inverted wait time in seconds. + // It's inverted because flash allows changing 1 to 0 but not vice versa. + return ~*(const uint32_t*)FLASH_PTR(flash_pinfails); +} + uint32_t storage_getPinFailsOffset(void) { uint32_t flash_pinfails = FLASH_STORAGE_PINAREA; diff --git a/firmware/storage.h b/firmware/storage.h index 945ca135c8..3a8a16ebc6 100644 --- a/firmware/storage.h +++ b/firmware/storage.h @@ -124,6 +124,7 @@ bool session_isPinCached(void); void storage_clearPinArea(void); void storage_resetPinFails(uint32_t flash_pinfails); bool storage_increasePinFails(uint32_t flash_pinfails); +uint32_t storage_getPinWait(uint32_t flash_pinfails); uint32_t storage_getPinFailsOffset(void); uint32_t storage_nextU2FCounter(void);