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:
parent
cc02e8892c
commit
b61b4cac04
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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."""
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user