From ed89215a79c1edc5036d44ea406ae058afba50b5 Mon Sep 17 00:00:00 2001 From: matejcik Date: Fri, 15 Mar 2024 11:53:04 +0100 Subject: [PATCH] feat(core): expose StorageMessage to micropython [no changelog] --- .../extmod/modtrezorconfig/modtrezorconfig.c | 24 ++++++++++++++-- core/embed/rust/src/trezorhal/storage.rs | 28 +++++++++++++++---- core/mocks/generated/trezorconfig.pyi | 13 ++++++++- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/core/embed/extmod/modtrezorconfig/modtrezorconfig.c b/core/embed/extmod/modtrezorconfig/modtrezorconfig.c index 1078cd923a..8bd5212e6d 100644 --- a/core/embed/extmod/modtrezorconfig/modtrezorconfig.c +++ b/core/embed/extmod/modtrezorconfig/modtrezorconfig.c @@ -32,12 +32,12 @@ #include "storage.h" static secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress, - const char *message) { + enum storage_ui_message_t message) { if (mp_obj_is_callable(MP_STATE_VM(trezorconfig_ui_wait_callback))) { mp_obj_t args[3] = {0}; args[0] = mp_obj_new_int(wait); args[1] = mp_obj_new_int(progress); - args[2] = mp_obj_new_str(message, strlen(message)); + args[2] = mp_obj_new_int(message); if (mp_call_function_n_kw(MP_STATE_VM(trezorconfig_ui_wait_callback), 3, 0, args) == mp_const_true) { return sectrue; @@ -47,7 +47,8 @@ static secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress, } /// def init( -/// ui_wait_callback: Callable[[int, int, str], bool] | None = None +/// ui_wait_callback: Callable[[int, int, StorageMessage], bool] | None = +/// None /// ) -> None: /// """ /// Initializes the storage. Must be called before any other method is @@ -409,6 +410,21 @@ STATIC mp_obj_t mod_trezorconfig_wipe(void) { STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_wipe_obj, mod_trezorconfig_wipe); +/// from enum import IntEnum +/// class StorageMessage(IntEnum): +/// NO_MSG = 0 +/// VERIFYING_PIN_MSG = 1 +/// PROCESSING_MSG = 2 +/// STARTING_MSG = 3 +/// WRONG_PIN_MSG = 4 +STATIC const qstr mod_trezorconfig_StorageMessage_fields[] = { + MP_QSTR_NO_MSG, MP_QSTR_VERIFYING_PIN_MSG, MP_QSTR_PROCESSING_MSG, + MP_QSTR_STARTING_MSG, MP_QSTR_WRONG_PIN_MSG}; +STATIC MP_DEFINE_ATTRTUPLE( + mod_trezorconfig_StorageMessage_obj, mod_trezorconfig_StorageMessage_fields, + (sizeof(mod_trezorconfig_StorageMessage_fields) / sizeof(qstr)), + MP_ROM_INT(0), MP_ROM_INT(1), MP_ROM_INT(2), MP_ROM_INT(3), MP_ROM_INT(4)); + STATIC const mp_rom_map_elem_t mp_module_trezorconfig_globals_table[] = { {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorconfig)}, {MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&mod_trezorconfig_init_obj)}, @@ -437,6 +453,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorconfig_globals_table[] = { {MP_ROM_QSTR(MP_QSTR_next_counter), MP_ROM_PTR(&mod_trezorconfig_next_counter_obj)}, {MP_ROM_QSTR(MP_QSTR_wipe), MP_ROM_PTR(&mod_trezorconfig_wipe_obj)}, + {MP_ROM_QSTR(MP_QSTR_StorageMessage), + MP_ROM_PTR(&mod_trezorconfig_StorageMessage_obj)}, }; STATIC MP_DEFINE_CONST_DICT(mp_module_trezorconfig_globals, mp_module_trezorconfig_globals_table); diff --git a/core/embed/rust/src/trezorhal/storage.rs b/core/embed/rust/src/trezorhal/storage.rs index 8266acce8d..3013a009d4 100644 --- a/core/embed/rust/src/trezorhal/storage.rs +++ b/core/embed/rust/src/trezorhal/storage.rs @@ -3,7 +3,8 @@ use super::ffi; use crate::error::Error; use core::ptr; -use cstr_core::CStr; + +use num_traits::FromPrimitive; /// Result of PIN delay callback. #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -14,13 +15,23 @@ pub enum PinCallbackResult { Abort, } +#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive)] +pub enum PinCallbackMessage { + None, + VerifyingPIN, + Processing, + Starting, + WrongPIN, +} + /// PIN delay callback function type. /// The storage layer will call this function while the PIN timeout is in /// progress. This is useful for showing UI progress bar. /// `wait` is the total number of seconds waiting. /// `progress` is a value between 0 and 1000, where 1000 indicates 100%. /// `message` is a message to show to the user. -pub type PinDelayCallback = fn(wait: u32, progress: u32, message: &str) -> PinCallbackResult; +pub type PinDelayCallback = + fn(wait: u32, progress: u32, message: PinCallbackMessage) -> PinCallbackResult; pub type ExternalSalt = [u8; ffi::EXTERNAL_SALT_SIZE as usize]; @@ -31,12 +42,17 @@ static mut PIN_UI_CALLBACK: Option = None; unsafe extern "C" fn callback_wrapper( wait: u32, progress: u32, - message: *const cty::c_char, + message: ffi::storage_ui_message_t, ) -> ffi::secbool { - let message = unsafe { CStr::from_ptr(message as _) }; let result = unsafe { PIN_UI_CALLBACK - .map(|c| c(wait, progress, message.to_str().unwrap_or(""))) + .map(|c| { + c( + wait, + progress, + PinCallbackMessage::from_u32(message).unwrap_or(PinCallbackMessage::None), + ) + }) .unwrap_or(PinCallbackResult::Continue) }; if matches!(result, PinCallbackResult::Abort) { @@ -266,7 +282,7 @@ mod tests { static mut PIN_CALLBACK_CALLED: bool = false; - fn pin_callback(_wait: u32, _progress: u32, _message: &str) -> PinCallbackResult { + fn pin_callback(_wait: u32, _progress: u32, _message: PinCallbackMessage) -> PinCallbackResult { unsafe { PIN_CALLBACK_CALLED = true; } diff --git a/core/mocks/generated/trezorconfig.pyi b/core/mocks/generated/trezorconfig.pyi index 5b4291549b..14d59a7a15 100644 --- a/core/mocks/generated/trezorconfig.pyi +++ b/core/mocks/generated/trezorconfig.pyi @@ -3,7 +3,8 @@ from typing import * # extmod/modtrezorconfig/modtrezorconfig.c def init( - ui_wait_callback: Callable[[int, int, str], bool] | None = None + ui_wait_callback: Callable[[int, int, StorageMessage], bool] | None = + None ) -> None: """ Initializes the storage. Must be called before any other method is @@ -141,3 +142,13 @@ def wipe() -> None: """ Erases the whole config. Use with caution! """ +from enum import IntEnum + + +# extmod/modtrezorconfig/modtrezorconfig.c +class StorageMessage(IntEnum): + NO_MSG = 0 + VERIFYING_PIN_MSG = 1 + PROCESSING_MSG = 2 + STARTING_MSG = 3 + WRONG_PIN_MSG = 4