1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-24 07:28:34 +00:00

WIP - autolock_delay

This commit is contained in:
grdddj 2022-03-16 14:48:34 +01:00
parent cc02e8892c
commit b61b4cac04
6 changed files with 114 additions and 17 deletions

View File

@ -45,6 +45,8 @@ static void _librust_qstrs(void) {
MP_QSTR_set_slip39_identifier;
MP_QSTR_get_slip39_iteration_exponent;
MP_QSTR_set_slip39_iteration_exponent;
MP_QSTR_get_autolock_delay_ms;
MP_QSTR_set_autolock_delay_ms;
MP_QSTR_set_timer_fn;
MP_QSTR_touch_event;

View File

@ -55,6 +55,18 @@ const INITIALIZED: u8 = 0x13;
const _SAFETY_CHECK_LEVEL: u8 = 0x14;
const _EXPERIMENTAL_FEATURES: u8 = 0x15;
// TODO: somehow determine the DEBUG_MODE value
const DEBUG_MODE: bool = true;
const AUTOLOCK_DELAY_DEFAULT: u32 = 10 * 60 * 1000; // 10 minutes
const AUTOLOCK_DELAY_MINIMUM: u32 = if DEBUG_MODE {
10 * 1000 // 10 seconds
} else {
60 * 1000 // 1 minute
};
// autolock intervals larger than AUTOLOCK_DELAY_MAXIMUM cause issues in the
// scheduler
const AUTOLOCK_DELAY_MAXIMUM: u32 = 0x2000_0000; // ~6 days
extern "C" {
// storage.h
fn storage_has(key: u16) -> secbool::Secbool;
@ -334,6 +346,28 @@ extern "C" fn storagedevice_set_slip39_iteration_exponent(exponent: Obj) -> Obj
unsafe { util::try_or_raise(block) }
}
extern "C" fn storagedevice_get_autolock_delay_ms() -> Obj {
let block = || {
let key = _get_appkey(_AUTOLOCK_DELAY_MS, false);
match storagedevice_storage_get_u32(key) {
// TODO: strange that u8 and u16 have .into(), but u32 needs .try_into()
Some(delay) => _normalize_autolock_delay(delay).try_into(),
None => AUTOLOCK_DELAY_DEFAULT.try_into(),
}
};
unsafe { util::try_or_raise(block) }
}
extern "C" fn storagedevice_set_autolock_delay_ms(delay_ms: Obj) -> Obj {
let block = || {
let delay_ms = u32::try_from(delay_ms)?;
let key = _get_appkey(_AUTOLOCK_DELAY_MS, false);
Ok(storagedevice_storage_set_u32(key, delay_ms).into())
};
unsafe { util::try_or_raise(block) }
}
pub fn storagedevice_storage_get(key: u16) -> Vec<u8, MAX_LEN> {
let mut buf: [u8; MAX_LEN] = [0; MAX_LEN];
let mut len: u16 = 0;
@ -382,7 +416,18 @@ pub fn storagedevice_storage_get_bool(key: u16) -> bool {
result.len() == 1 && result[0] == _TRUE_BYTE
}
// TODO: can we somehow generalize this for u16 and u8?
// TODO: can we somehow generalize this for all uint types?
pub fn storagedevice_storage_get_u32(key: u16) -> Option<u32> {
let result = storagedevice_storage_get(key);
if result.len() == 4 {
Some(u32::from_be_bytes([
result[0], result[1], result[2], result[3],
]))
} else {
None
}
}
pub fn storagedevice_storage_get_u16(key: u16) -> Option<u16> {
let result = storagedevice_storage_get(key);
if result.len() == 2 {
@ -418,6 +463,10 @@ pub fn storagedevice_storage_set_u16(key: u16, val: u16) -> bool {
storagedevice_storage_set(key, &val.to_be_bytes() as *const _, 2)
}
pub fn storagedevice_storage_set_u32(key: u16, val: u32) -> bool {
storagedevice_storage_set(key, &val.to_be_bytes() as *const _, 4)
}
pub fn storagedevice_storage_has(key: u16) -> bool {
matches!(unsafe { storage_has(key) }, secbool::TRUE)
}
@ -437,6 +486,16 @@ fn _get_appkey(key: u8, is_public: bool) -> u16 {
((app as u16) << 8) | key as u16
}
fn _normalize_autolock_delay(delay_ms: u32) -> u32 {
if delay_ms < AUTOLOCK_DELAY_MINIMUM {
AUTOLOCK_DELAY_MINIMUM
} else if delay_ms > AUTOLOCK_DELAY_MAXIMUM {
AUTOLOCK_DELAY_MAXIMUM
} else {
delay_ms
}
}
#[no_mangle]
pub static mp_module_trezorstoragedevice: Module = obj_module! {
Qstr::MP_QSTR___name_storage__ => Qstr::MP_QSTR_trezorstoragedevice.to_obj(),
@ -552,6 +611,14 @@ pub static mp_module_trezorstoragedevice: Module = obj_module! {
/// the recovery process and it is copied here upon success.
/// """
Qstr::MP_QSTR_set_slip39_iteration_exponent => obj_fn_1!(storagedevice_set_slip39_iteration_exponent).as_obj(),
/// def get_autolock_delay_ms() -> int:
/// """Get autolock delay."""
Qstr::MP_QSTR_get_autolock_delay_ms => obj_fn_0!(storagedevice_get_autolock_delay_ms).as_obj(),
/// def set_autolock_delay_ms(delay_ms: int) -> bool:
/// """Set autolock delay."""
Qstr::MP_QSTR_set_autolock_delay_ms => obj_fn_1!(storagedevice_set_autolock_delay_ms).as_obj(),
};
#[cfg(test)]
@ -569,4 +636,22 @@ mod tests {
let result = _get_appkey(0x11, true);
assert_eq!(result, 0x8111);
}
#[test]
fn normalize_autolock_delay_small() {
let result = _normalize_autolock_delay(123);
assert_eq!(result, AUTOLOCK_DELAY_MINIMUM);
}
#[test]
fn normalize_autolock_delay_big() {
let result = _normalize_autolock_delay(u32::MAX);
assert_eq!(result, AUTOLOCK_DELAY_MAXIMUM);
}
#[test]
fn normalize_autolock_delay_normal() {
let result = _normalize_autolock_delay(1_000_000);
assert_eq!(result, 1_000_000);
}
}

View File

@ -132,3 +132,13 @@ def set_slip39_iteration_exponent(exponent: int) -> bool:
Not to be confused with recovery.iteration_exponent, which is stored only during
the recovery process and it is copied here upon success.
"""
# rust/src/storagedevice/storage_device.rs
def get_autolock_delay_ms() -> int:
"""Get autolock delay."""
# rust/src/storagedevice/storage_device.rs
def set_autolock_delay_ms(delay_ms: int) -> bool:
"""Set autolock delay."""

View File

@ -92,7 +92,7 @@ def get_features() -> Features:
f.wipe_code_protection = config.has_wipe_code()
f.passphrase_always_on_device = storagedevice.get_passphrase_always_on_device()
f.safety_checks = safety_checks.read_setting()
f.auto_lock_delay_ms = storage.device.get_autolock_delay_ms()
f.auto_lock_delay_ms = storagedevice.get_autolock_delay_ms()
f.display_rotation = storagedevice.get_rotation()
f.experimental_features = storage.device.get_experimental_features()
@ -275,7 +275,7 @@ def reload_settings_from_storage() -> None:
from trezor import ui
workflow.idle_timer.set(
storage.device.get_autolock_delay_ms(), lock_device_if_unlocked
storagedevice.get_autolock_delay_ms(), lock_device_if_unlocked
)
wire.experimental_enabled = storage.device.get_experimental_features()
ui.display.orientation(storagedevice.get_rotation())

View File

@ -80,7 +80,7 @@ async def apply_settings(ctx: wire.Context, msg: ApplySettings) -> Success:
if msg.auto_lock_delay_ms > storage.device.AUTOLOCK_DELAY_MAXIMUM:
raise wire.ProcessError("Auto-lock delay too long")
await require_confirm_change_autolock_delay(ctx, msg.auto_lock_delay_ms)
storage.device.set_autolock_delay_ms(msg.auto_lock_delay_ms)
storagedevice.set_autolock_delay_ms(msg.auto_lock_delay_ms)
if msg.safety_checks is not None:
await require_confirm_safety_checks(ctx, msg.safety_checks)

View File

@ -226,23 +226,23 @@ def set_flags(flags: int) -> None:
common.set(_NAMESPACE, _FLAGS, flags.to_bytes(4, "big"))
def _normalize_autolock_delay(delay_ms: int) -> int:
delay_ms = max(delay_ms, AUTOLOCK_DELAY_MINIMUM)
delay_ms = min(delay_ms, AUTOLOCK_DELAY_MAXIMUM)
return delay_ms
# def _normalize_autolock_delay(delay_ms: int) -> int:
# delay_ms = max(delay_ms, AUTOLOCK_DELAY_MINIMUM)
# delay_ms = min(delay_ms, AUTOLOCK_DELAY_MAXIMUM)
# return delay_ms
def get_autolock_delay_ms() -> int:
b = common.get(_NAMESPACE, _AUTOLOCK_DELAY_MS)
if b is None:
return AUTOLOCK_DELAY_DEFAULT
else:
return _normalize_autolock_delay(int.from_bytes(b, "big"))
# def get_autolock_delay_ms() -> int:
# b = common.get(_NAMESPACE, _AUTOLOCK_DELAY_MS)
# if b is None:
# return AUTOLOCK_DELAY_DEFAULT
# else:
# return _normalize_autolock_delay(int.from_bytes(b, "big"))
def set_autolock_delay_ms(delay_ms: int) -> None:
delay_ms = _normalize_autolock_delay(delay_ms)
common.set(_NAMESPACE, _AUTOLOCK_DELAY_MS, delay_ms.to_bytes(4, "big"))
# def set_autolock_delay_ms(delay_ms: int) -> None:
# delay_ms = _normalize_autolock_delay(delay_ms)
# common.set(_NAMESPACE, _AUTOLOCK_DELAY_MS, delay_ms.to_bytes(4, "big"))
def next_u2f_counter() -> int: