1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-24 14:20:57 +00:00

fix(core): properly cache last successful unlock time

This commit is contained in:
matejcik 2021-04-21 13:16:35 +02:00 committed by matejcik
parent 959cf7d515
commit ed5c357b78
2 changed files with 21 additions and 8 deletions

View File

@ -1,5 +1,6 @@
import utime import utime
import storage.cache
import storage.sd_salt import storage.sd_salt
from trezor import config, ui, wire from trezor import config, ui, wire
from trezor.messages import ButtonRequestType from trezor.messages import ButtonRequestType
@ -14,9 +15,6 @@ if False:
from typing import Any, NoReturn from typing import Any, NoReturn
_last_successful_unlock = 0
def can_lock_device() -> bool: def can_lock_device() -> bool:
"""Return True if the device has a PIN set or SD-protect enabled.""" """Return True if the device has a PIN set or SD-protect enabled."""
return config.has_pin() or storage.sd_salt.is_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 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( async def verify_user_pin(
ctx: wire.GenericContext = wire.DUMMY_CONTEXT, ctx: wire.GenericContext = wire.DUMMY_CONTEXT,
prompt: str = "Enter your PIN", prompt: str = "Enter your PIN",
@ -86,11 +97,11 @@ async def verify_user_pin(
retry: bool = True, retry: bool = True,
cache_time_ms: int = 0, cache_time_ms: int = 0,
) -> None: ) -> None:
global _last_successful_unlock last_unlock = _get_last_unlock_time()
if ( if (
cache_time_ms cache_time_ms
and _last_successful_unlock and last_unlock
and utime.ticks_ms() - _last_successful_unlock <= cache_time_ms and utime.ticks_ms() - last_unlock <= cache_time_ms
and config.is_unlocked() and config.is_unlocked()
): ):
return return
@ -106,7 +117,7 @@ async def verify_user_pin(
except SdCardUnavailable: except SdCardUnavailable:
raise wire.PinCancelled("SD salt is unavailable") raise wire.PinCancelled("SD salt is unavailable")
if config.unlock(pin, salt): if config.unlock(pin, salt):
_last_successful_unlock = utime.ticks_ms() _set_last_unlock_time()
return return
elif not config.has_pin(): elif not config.has_pin():
raise RuntimeError raise RuntimeError
@ -116,7 +127,7 @@ async def verify_user_pin(
ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel
) )
if config.unlock(pin, salt): if config.unlock(pin, salt):
_last_successful_unlock = utime.ticks_ms() _set_last_unlock_time()
return return
raise wire.PinInvalid raise wire.PinInvalid

View File

@ -21,6 +21,7 @@ APP_COMMON_AUTHORIZATION_DATA = 4
APP_COMMON_SEED_WITHOUT_PASSPHRASE = 0 | _SESSIONLESS_FLAG APP_COMMON_SEED_WITHOUT_PASSPHRASE = 0 | _SESSIONLESS_FLAG
APP_COMMON_SAFETY_CHECKS_TEMPORARY = 1 | _SESSIONLESS_FLAG APP_COMMON_SAFETY_CHECKS_TEMPORARY = 1 | _SESSIONLESS_FLAG
STORAGE_DEVICE_EXPERIMENTAL_FEATURES = 2 | _SESSIONLESS_FLAG STORAGE_DEVICE_EXPERIMENTAL_FEATURES = 2 | _SESSIONLESS_FLAG
APP_COMMON_REQUEST_PIN_LAST_UNLOCK = 3 | _SESSIONLESS_FLAG
# === Homescreen storage === # === Homescreen storage ===
@ -90,6 +91,7 @@ class SessionlessCache(DataCache):
64, # APP_COMMON_SEED_WITHOUT_PASSPHRASE 64, # APP_COMMON_SEED_WITHOUT_PASSPHRASE
1, # APP_COMMON_SAFETY_CHECKS_TEMPORARY 1, # APP_COMMON_SAFETY_CHECKS_TEMPORARY
1, # STORAGE_DEVICE_EXPERIMENTAL_FEATURES 1, # STORAGE_DEVICE_EXPERIMENTAL_FEATURES
4, # APP_COMMON_REQUEST_PIN_LAST_UNLOCK
) )
super().__init__() super().__init__()