diff --git a/core/src/apps/common/request_pin.py b/core/src/apps/common/request_pin.py index 8dfe4509a7..da17b91d4e 100644 --- a/core/src/apps/common/request_pin.py +++ b/core/src/apps/common/request_pin.py @@ -1,5 +1,6 @@ import utime +import storage.cache import storage.sd_salt from trezor import config, ui, wire from trezor.messages import ButtonRequestType @@ -14,9 +15,6 @@ if False: from typing import Any, NoReturn -_last_successful_unlock = 0 - - def can_lock_device() -> bool: """Return True if the device has a PIN set or SD-protect enabled.""" return config.has_pin() or storage.sd_salt.is_enabled() @@ -79,6 +77,19 @@ async def request_pin_and_sd_salt( return pin, salt +def _set_last_unlock_time() -> None: + now = utime.ticks_ms() + storage.cache.set( + storage.cache.APP_COMMON_REQUEST_PIN_LAST_UNLOCK, now.to_bytes(4, "big") + ) + + +def _get_last_unlock_time() -> int: + return int.from_bytes( + storage.cache.get(storage.cache.APP_COMMON_REQUEST_PIN_LAST_UNLOCK), "big" + ) + + async def verify_user_pin( ctx: wire.GenericContext = wire.DUMMY_CONTEXT, prompt: str = "Enter your PIN", @@ -86,11 +97,11 @@ async def verify_user_pin( retry: bool = True, cache_time_ms: int = 0, ) -> None: - global _last_successful_unlock + last_unlock = _get_last_unlock_time() if ( cache_time_ms - and _last_successful_unlock - and utime.ticks_ms() - _last_successful_unlock <= cache_time_ms + and last_unlock + and utime.ticks_ms() - last_unlock <= cache_time_ms and config.is_unlocked() ): return @@ -106,7 +117,7 @@ async def verify_user_pin( except SdCardUnavailable: raise wire.PinCancelled("SD salt is unavailable") if config.unlock(pin, salt): - _last_successful_unlock = utime.ticks_ms() + _set_last_unlock_time() return elif not config.has_pin(): raise RuntimeError @@ -116,7 +127,7 @@ async def verify_user_pin( ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel ) if config.unlock(pin, salt): - _last_successful_unlock = utime.ticks_ms() + _set_last_unlock_time() return raise wire.PinInvalid diff --git a/core/src/storage/cache.py b/core/src/storage/cache.py index b0827f1c55..3ea73d2d1d 100644 --- a/core/src/storage/cache.py +++ b/core/src/storage/cache.py @@ -21,6 +21,7 @@ APP_COMMON_AUTHORIZATION_DATA = 4 APP_COMMON_SEED_WITHOUT_PASSPHRASE = 0 | _SESSIONLESS_FLAG APP_COMMON_SAFETY_CHECKS_TEMPORARY = 1 | _SESSIONLESS_FLAG STORAGE_DEVICE_EXPERIMENTAL_FEATURES = 2 | _SESSIONLESS_FLAG +APP_COMMON_REQUEST_PIN_LAST_UNLOCK = 3 | _SESSIONLESS_FLAG # === Homescreen storage === @@ -90,6 +91,7 @@ class SessionlessCache(DataCache): 64, # APP_COMMON_SEED_WITHOUT_PASSPHRASE 1, # APP_COMMON_SAFETY_CHECKS_TEMPORARY 1, # STORAGE_DEVICE_EXPERIMENTAL_FEATURES + 4, # APP_COMMON_REQUEST_PIN_LAST_UNLOCK ) super().__init__()