refactor(core): cleanup storage syscalls, prepare early initialization
What changed, and why it matters
This commit is a code cleanup and refactoring change in Trezor firmware. It replaces the old storage_init() function, which required callers to fetch their own random entropy (salt), with a new storage_setup() helper that fetches entropy internally. It also removes the direct entropy_get() system call from the non-secure kernel interface. There is no direct evidence in the commit that this fixes an active security vulnerability; it appears to be architectural preparation for future initialization changes.
Treat as a routine refactor. Review the follow-up commits in the same branch to confirm that early initialization ordering and secure-world entropy handling are correctly preserved, especially because the entropy_get() syscall removal may require compensating changes elsewhere.
Security signals we found
Removal of entropy_get() from SMCALL and SYSCALL dispatch tables reduces privileged entropy-extraction surface exposed to untrusted code
Addition of probe_execute_access() in syscall verifier enables execute-permission checks on callback pointers
storage_setup() now fetches entropy inside secure mode and memzero()s it, centralizing sensitive buffer handling
Old storage_init__verified() no longer probes caller-supplied salt buffer, eliminating a potential read-access probe path
Evidence from the diff
The patch consolidates storage initialization by introducing embed/sec/storage/storage_setup.c, which calls entropy_get() and then storage_init() inside SECURE_MODE. Callers in Rust, MicroPython, secure-monitor calls (SMCALL), and system calls now use storage_setup(callback) instead of storage_init(callback, salt, salt_len). The SYSCALL_ENTROPY_GET and SMCALL_ENTROPY_GET dispatch entries are removed, and the syscall verifier gains probe_execute_access() so it can validate the UI callback pointer. The change reduces the attack surface exposed to untrusted applets by no longer allowing them to supply or read raw entropy through these interfaces, but the diff itself is a refactor with [no changelog].
Changed components
core/embed/sec/storage/storage_setup.c (new)core/embed/sec/storage/inc/sec/storage.h (new)core/embed/rust/src/trezorhal/storage.rscore/embed/upymod/modtrezorconfig/modtrezorconfig.ccore/embed/sys/syscall/stm32/syscall_dispatch.ccore/embed/sys/syscall/stm32/syscall_verifiers.ccore/embed/sys/syscall/stm32/syscall_probe.ccore/embed/sys/smcall/stm32/smcall_dispatch.ccore/embed/sys/smcall/stm32/smcall_verifiers.cInspect captured patch +152 / −159
diff --git a/core/SConscript.firmware b/core/SConscript.firmware
index 31bdc251..3a513e35 100644
--- a/core/SConscript.firmware
+++ b/core/SConscript.firmware
@@ -471,6 +471,7 @@ ALLPATHS = [
'embed/rtl/inc',
'embed/models',
'embed/gfx/inc',
+ 'embed/sec/storage/inc',
'embed/sys/bsp/inc',
'embed/util/image/inc',
'embed/util/rsod/inc',
diff --git a/core/SConscript.kernel b/core/SConscript.kernel
index cc778330..f3edf085 100644
--- a/core/SConscript.kernel
+++ b/core/SConscript.kernel
@@ -271,10 +271,11 @@ FEATURE_FLAGS["AES_GCM"] = FEATURE_FLAGS["AES_GCM"] or "tropic" in FEATURES_AVAI
if not 'secmon_layout' in FEATURES_AVAILABLE:
SOURCE_MOD += [
+ 'embed/sec/storage/storage_setup.c',
'vendor/trezor-storage/norcow.c',
'vendor/trezor-storage/storage.c',
'vendor/trezor-storage/storage_utils.c',
- ]
+ ]
# AES-GCM
@@ -320,6 +321,7 @@ ALLPATHS = [
'embed/rtl/inc',
'embed/models',
'embed/gfx/inc',
+ 'embed/sec/storage/inc',
'embed/sys/bsp/inc',
'embed/util/image/inc',
'embed/util/rsod/inc',
diff --git a/core/SConscript.secmon b/core/SConscript.secmon
index 70453fd6..4b07d1ed 100644
--- a/core/SConscript.secmon
+++ b/core/SConscript.secmon
@@ -75,6 +75,7 @@ CPPPATH_MOD += [
'vendor/micropython/lib/uzlib',
]
SOURCE_MOD += [
+ 'embed/sec/storage/storage_setup.c',
'vendor/trezor-storage/norcow.c',
'vendor/trezor-storage/storage.c',
'vendor/trezor-storage/storage_utils.c',
@@ -320,6 +321,7 @@ ALLPATHS = [
'embed/rtl/inc',
'embed/models',
'embed/gfx/inc',
+ 'embed/sec/storage/inc',
'embed/sys/bsp/inc',
'embed/util/image/inc',
'embed/util/rsod/inc',
diff --git a/core/SConscript.unix b/core/SConscript.unix
index c39ba896..2ec16ec9 100644
--- a/core/SConscript.unix
+++ b/core/SConscript.unix
@@ -70,6 +70,7 @@ CPPPATH_MOD += [
]
SOURCE_MOD += [
'embed/upymod/modtrezorconfig/modtrezorconfig.c',
+ 'embed/sec/storage/storage_setup.c',
'vendor/trezor-storage/norcow.c',
'vendor/trezor-storage/storage.c',
'vendor/trezor-storage/storage_utils.c',
@@ -485,6 +486,7 @@ ALLPATHS=['.',
'embed/util/rsod/inc',
'embed/util/scm_revision/inc',
'embed/util/translations/inc',
+ 'embed/sec/storage/inc',
'vendor/micropython',
'vendor/micropython/ports/unix',
'vendor/micropython/lib/mp-readline',
diff --git a/core/embed/rust/build.rs b/core/embed/rust/build.rs
index ba88866c..f3b431ff 100644
--- a/core/embed/rust/build.rs
+++ b/core/embed/rust/build.rs
@@ -324,10 +324,6 @@ fn generate_trezorhal_bindings() {
// model
.allowlist_var("MODEL_INTERNAL_NAME")
.allowlist_var("MODEL_FULL_NAME")
- // entropy
- .allowlist_var("ENTROPY_MAX_SIZE")
- .allowlist_type("entropy_data_t")
- .allowlist_function("entropy_get")
// secbool
.allowlist_type("secbool")
.must_use_type("secbool")
@@ -337,7 +333,7 @@ fn generate_trezorhal_bindings() {
.allowlist_function("flash_init")
// storage
.allowlist_var("EXTERNAL_SALT_SIZE")
- .allowlist_function("storage_init")
+ .allowlist_function("storage_setup")
.allowlist_function("storage_wipe")
.allowlist_function("storage_is_unlocked")
.allowlist_function("storage_lock")
diff --git a/core/embed/rust/src/trezorhal/storage.rs b/core/embed/rust/src/trezorhal/storage.rs
index da4ed0d6..1322c616 100644
--- a/core/embed/rust/src/trezorhal/storage.rs
+++ b/core/embed/rust/src/trezorhal/storage.rs
@@ -97,16 +97,7 @@ pub type StorageResult<T> = Result<T, StorageError>;
/// This function must be called before any other storage function.
pub fn init() {
unsafe {
- let mut entropy: ffi::entropy_data_t = ffi::entropy_data_t {
- bytes: [0; ffi::ENTROPY_MAX_SIZE as usize],
- size: 0,
- };
- ffi::entropy_get(&mut entropy);
- ffi::storage_init(
- Some(callback_wrapper),
- entropy.bytes.as_ptr(),
- entropy.size as u16,
- );
+ ffi::storage_setup(Some(callback_wrapper));
}
}
diff --git a/core/embed/rust/trezorhal.h b/core/embed/rust/trezorhal.h
index 6d332330..ed0d0c90 100644
--- a/core/embed/rust/trezorhal.h
+++ b/core/embed/rust/trezorhal.h
@@ -7,14 +7,13 @@
#include <io/display_utils.h>
#include <io/usb.h>
#include <rtl/secbool.h>
-#include <sec/entropy.h>
+#include <sec/storage.h>
#include <sys/irq.h>
#include <sys/sysevent.h>
#include <sys/systick.h>
#include <util/flash.h>
#include <util/translations.h>
#include "rust_types.h"
-#include "storage.h"
#ifdef USE_HW_JPEG_DECODER
#include <gfx/jpegdec.h>
diff --git a/core/embed/sec/optiga/inc/sec/optiga.h b/core/embed/sec/optiga/inc/sec/optiga.h
index b43e338e..2f7f7112 100644
--- a/core/embed/sec/optiga/inc/sec/optiga.h
+++ b/core/embed/sec/optiga/inc/sec/optiga.h
@@ -22,8 +22,9 @@
#include <trezor_types.h>
+#include <sec/storage.h>
+
#include "optiga_common.h"
-#include "storage.h"
#define OPTIGA_DEVICE_CERT_INDEX 1
#define OPTIGA_DEVICE_ECC_KEY_INDEX 0
diff --git a/core/embed/sec/optiga/optiga.c b/core/embed/sec/optiga/optiga.c
index 052d90a7..4ae1e5d6 100644
--- a/core/embed/sec/optiga/optiga.c
+++ b/core/embed/sec/optiga/optiga.c
@@ -25,13 +25,13 @@
#include <sec/optiga_commands.h>
#include <sec/optiga_transport.h>
#include <sec/secret_keys.h>
+#include <sec/storage.h>
#include "ecdsa.h"
#include "hash_to_curve.h"
#include "hmac.h"
#include "memzero.h"
#include "nist256p1.h"
#include "rand.h"
-#include "storage.h"
// Counter-protected PIN secret and reset key for OID_STRETCHED_PIN_CTR (OID
// 0xF1D0).
diff --git a/core/embed/sec/optiga/unix/optiga.c b/core/embed/sec/optiga/unix/optiga.c
index cc387e58..3e0c2996 100644
--- a/core/embed/sec/optiga/unix/optiga.c
+++ b/core/embed/sec/optiga/unix/optiga.c
@@ -21,10 +21,11 @@
#include <sec/optiga.h>
#include <sec/optiga_common.h>
+#include <sec/storage.h>
+
#include "ecdsa.h"
#include "nist256p1.h"
#include "rand.h"
-#include "storage.h"
#if defined(TREZOR_MODEL_T2B1)
#include "certs/T2B1.h"
diff --git a/core/embed/sec/storage/inc/sec/storage.h b/core/embed/sec/storage/inc/sec/storage.h
new file mode 100644
index 00000000..8fffed21
--- /dev/null
+++ b/core/embed/sec/storage/inc/sec/storage.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <vendor/trezor-storage/storage.h>
+
+/**
+ * Initialize storage and optionally register a UI progress callback.
+ *
+ * If storage is already initialized, this call locks it, restoring the
+ * post-initialization state, and replaces the existing callback.
+ *
+ * @param callback Callback invoked during long-term operations (may be NULL).
+ */
+void storage_setup(PIN_UI_WAIT_CALLBACK callback);
diff --git a/core/embed/sec/storage/storage_setup.c b/core/embed/sec/storage/storage_setup.c
new file mode 100644
index 00000000..34532975
--- /dev/null
+++ b/core/embed/sec/storage/storage_setup.c
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef SECURE_MODE
+
+#include <sec/entropy.h>
+#include <sec/storage.h>
+
+#include "memzero.h"
+
+void storage_setup(PIN_UI_WAIT_CALLBACK callback) {
+ entropy_data_t entropy;
+ entropy_get(&entropy);
+ storage_init(callback, entropy.bytes, entropy.size);
+ memzero(&entropy, sizeof(entropy));
+}
+
+#endif // SECURE_MODE
diff --git a/core/embed/sys/smcall/stm32/smcall_dispatch.c b/core/embed/sys/smcall/stm32/smcall_dispatch.c
index 746393af..aee4d153 100644
--- a/core/embed/sys/smcall/stm32/smcall_dispatch.c
+++ b/core/embed/sys/smcall/stm32/smcall_dispatch.c
@@ -21,7 +21,6 @@
#include <trezor_rtl.h>
-#include <sec/entropy.h>
#include <sec/random_delays.h>
#include <sec/rng.h>
#include <sys/bootargs.h>
@@ -189,11 +188,9 @@ __attribute((no_stack_protector)) void smcall_handler(uint32_t *args,
#endif
#endif
- case SMCALL_STORAGE_INIT: {
+ case SMCALL_STORAGE_SETUP: {
PIN_UI_WAIT_CALLBACK callback = (PIN_UI_WAIT_CALLBACK)args[0];
- const uint8_t *salt = (const uint8_t *)args[1];
- uint16_t salt_len = args[2];
- storage_init__verified(callback, salt, salt_len);
+ storage_setup__verified(callback);
} break;
case SMCALL_STORAGE_WIPE: {
@@ -295,11 +292,6 @@ __attribute((no_stack_protector)) void smcall_handler(uint32_t *args,
args[0] = storage_next_counter__verified(key, count);
} break;
- case SMCALL_ENTROPY_GET: {
- entropy_data_t *entropy = (entropy_data_t *)args[0];
- entropy_get__verified(entropy);
- } break;
-
case SMCALL_RNG_GET: {
args[0] = rng_get();
} break;
diff --git a/core/embed/sys/smcall/stm32/smcall_numbers.h b/core/embed/sys/smcall/stm32/smcall_numbers.h
index 9cb0a4b8..e9df21a7 100644
--- a/core/embed/sys/smcall/stm32/smcall_numbers.h
+++ b/core/embed/sys/smcall/stm32/smcall_numbers.h
@@ -63,7 +63,7 @@ typedef enum {
SMCALL_OPTIGA_RANDOM_BUFFER,
SMCALL_OPTIGA_SET_SEC_MAX,
- SMCALL_STORAGE_INIT,
+ SMCALL_STORAGE_SETUP,
SMCALL_STORAGE_WIPE,
SMCALL_STORAGE_IS_UNLOCKED,
SMCALL_STORAGE_LOCK,
@@ -82,8 +82,6 @@ typedef enum {
SMCALL_STORAGE_SET_COUNTER,
SMCALL_STORAGE_NEXT_COUNTER,
- SMCALL_ENTROPY_GET,
-
SMCALL_RNG_GET,
SMCALL_FIRMWARE_GET_VENDOR,
diff --git a/core/embed/sys/smcall/stm32/smcall_stubs.c b/core/embed/sys/smcall/stm32/smcall_stubs.c
index 58155357..ffedfc39 100644
--- a/core/embed/sys/smcall/stm32/smcall_stubs.c
+++ b/core/embed/sys/smcall/stm32/smcall_stubs.c
@@ -204,12 +204,10 @@ void optiga_set_sec_max(void) { smcall_invoke0(SMCALL_OPTIGA_SET_SEC_MAX); }
// storage.h
// =============================================================================
-#include "storage.h"
+#include <sec/storage.h>
-void storage_init(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt,
- const uint16_t salt_len) {
- smcall_invoke3((uint32_t)callback, (uint32_t)salt, salt_len,
- SMCALL_STORAGE_INIT);
+void storage_setup(PIN_UI_WAIT_CALLBACK callback) {
+ smcall_invoke1((uint32_t)callback, SMCALL_STORAGE_SETUP);
}
void storage_wipe(void) { smcall_invoke0(SMCALL_STORAGE_WIPE); }
@@ -290,16 +288,6 @@ secbool storage_next_counter(const uint16_t key, uint32_t *count) {
SMCALL_STORAGE_NEXT_COUNTER);
}
-// =============================================================================
-// entropy.h
-// =============================================================================
-
-#include <sec/entropy.h>
-
-void entropy_get(entropy_data_t *entropy) {
- smcall_invoke1((uint32_t)entropy, SMCALL_ENTROPY_GET);
-}
-
// =============================================================================
// rng.h
// =============================================================================
diff --git a/core/embed/sys/smcall/stm32/smcall_verifiers.c b/core/embed/sys/smcall/stm32/smcall_verifiers.c
index 10bb12fc..66a20343 100644
--- a/core/embed/sys/smcall/stm32/smcall_verifiers.c
+++ b/core/embed/sys/smcall/stm32/smcall_verifiers.c
@@ -225,19 +225,14 @@ static secbool storage_callback_wrapper(uint32_t wait, uint32_t progress,
}
}
-void storage_init__verified(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt,
- const uint16_t salt_len) {
+void storage_setup__verified(PIN_UI_WAIT_CALLBACK callback) {
if (!probe_execute_access(callback)) {
goto access_violation;
}
- if (!probe_read_access(salt, salt_len)) {
- goto access_violation;
- }
-
storage_callback = (ns_storage_callback_t)cmse_nsfptr_create(callback);
+ storage_setup(storage_callback_wrapper);
- storage_init(storage_callback_wrapper, salt, salt_len);
return;
access_violation:
@@ -370,20 +365,6 @@ access_violation:
// ---------------------------------------------------------------------
-void entropy_get__verified(entropy_data_t *entropy) {
- if (!probe_write_access(entropy, sizeof(*entropy))) {
- goto access_violation;
- }
-
- entropy_get(entropy);
- return;
-
-access_violation:
- apptask_access_violation();
-}
-
-// ---------------------------------------------------------------------
-
int firmware_hash_start__verified(const uint8_t *challenge,
size_t challenge_len) {
if (!probe_read_access(challenge, challenge_len)) {
diff --git a/core/embed/sys/smcall/stm32/smcall_verifiers.h b/core/embed/sys/smcall/stm32/smcall_verifiers.h
index 6febef7e..f11e3c3c 100644
--- a/core/embed/sys/smcall/stm32/smcall_verifiers.h
+++ b/core/embed/sys/smcall/stm32/smcall_verifiers.h
@@ -70,10 +70,9 @@ bool __wur optiga_random_buffer__verified(uint8_t *dest, size_t size);
#endif // USE_OPTIGA
// ---------------------------------------------------------------------
-#include "storage.h"
+#include <sec/storage.h>
-void storage_init__verified(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt,
- const uint16_t salt_len);
+void storage_setup__verified(PIN_UI_WAIT_CALLBACK callback);
secbool storage_unlock__verified(const uint8_t *pin, size_t pin_len,
const uint8_t *ext_salt);
@@ -98,11 +97,6 @@ secbool storage_set__verified(const uint16_t key, const void *val,
secbool storage_next_counter__verified(const uint16_t key, uint32_t *count);
-// ---------------------------------------------------------------------
-#include <sec/entropy.h>
-
-void entropy_get__verified(entropy_data_t *entropy);
-
// ---------------------------------------------------------------------
#include <util/fwutils.h>
diff --git a/core/embed/sys/syscall/inc/sys/syscall_numbers.h b/core/embed/sys/syscall/inc/sys/syscall_numbers.h
index dfb8bf22..4d8d1aec 100644
--- a/core/embed/sys/syscall/inc/sys/syscall_numbers.h
+++ b/core/embed/sys/syscall/inc/sys/syscall_numbers.h
@@ -120,8 +120,6 @@ typedef enum {
SYSCALL_OPTIGA_RANDOM_BUFFER,
SYSCALL_OPTIGA_SET_SEC_MAX,
- SYSCALL_ENTROPY_GET,
-
SYSCALL_TRANSLATIONS_WRITE,
SYSCALL_TRANSLATIONS_READ,
SYSCALL_TRANSLATIONS_ERASE,
@@ -181,7 +179,7 @@ typedef enum {
// ------------------------------------------------------
// Following syscalls are executed in kernel thread mode
- SYSCALL_STORAGE_INIT = SYSCALL_THREAD_MODE,
+ SYSCALL_STORAGE_SETUP = SYSCALL_THREAD_MODE,
SYSCALL_STORAGE_WIPE,
SYSCALL_STORAGE_IS_UNLOCKED,
SYSCALL_STORAGE_LOCK,
diff --git a/core/embed/sys/syscall/stm32/syscall_dispatch.c b/core/embed/sys/syscall/stm32/syscall_dispatch.c
index 361a9800..a1904441 100644
--- a/core/embed/sys/syscall/stm32/syscall_dispatch.c
+++ b/core/embed/sys/syscall/stm32/syscall_dispatch.c
@@ -27,7 +27,6 @@
#include <io/usb_hid.h>
#include <io/usb_vcp.h>
#include <io/usb_webusb.h>
-#include <sec/entropy.h>
#include <sec/rng.h>
#include <sec/secret.h>
#include <sys/bootutils.h>
@@ -88,18 +87,6 @@
#include "syscall_internal.h"
#include "syscall_verifiers.h"
-static PIN_UI_WAIT_CALLBACK storage_init_callback = NULL;
-
-static secbool storage_init_callback_wrapper(
- uint32_t wait, uint32_t progress, enum storage_ui_message_t message) {
- secbool result;
-
- applet_t *applet = syscall_get_context();
- result = systask_invoke_callback(&applet->task, wait, progress, message,
- storage_init_callback);
- return result;
-}
-
__attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
uint32_t syscall,
void *applet) {
@@ -545,11 +532,9 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
#endif
#endif
- case SYSCALL_STORAGE_INIT: {
- storage_init_callback = (PIN_UI_WAIT_CALLBACK)args[0];
- const uint8_t *salt = (const uint8_t *)args[1];
- uint16_t salt_len = args[2];
- storage_init__verified(storage_init_callback_wrapper, salt, salt_len);
+ case SYSCALL_STORAGE_SETUP: {
+ PIN_UI_WAIT_CALLBACK callback = (PIN_UI_WAIT_CALLBACK)args[0];
+ storage_setup__verified(callback);
} break;
case SYSCALL_STORAGE_WIPE: {
@@ -651,11 +636,6 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
args[0] = storage_next_counter__verified(key, count);
} break;
- case SYSCALL_ENTROPY_GET: {
- entropy_data_t *entropy = (entropy_data_t *)args[0];
- entropy_get__verified(entropy);
- } break;
-
case SYSCALL_TRANSLATIONS_WRITE: {
const uint8_t *data = (const uint8_t *)args[0];
uint32_t offset = args[1];
diff --git a/core/embed/sys/syscall/stm32/syscall_probe.c b/core/embed/sys/syscall/stm32/syscall_probe.c
index 6c25e472..593b03e2 100644
--- a/core/embed/sys/syscall/stm32/syscall_probe.c
+++ b/core/embed/sys/syscall/stm32/syscall_probe.c
@@ -119,6 +119,27 @@ bool probe_write_access(void *addr, size_t len) {
return false;
}
+bool probe_execute_access(const void *addr) {
+ applet_t *applet = syscall_get_context();
+
+ if (addr == NULL) {
+ return true;
+ }
+
+ // Check if the first 4 bytes at the address are within
+ // the applet's code areas.
+
+ if (inside_area(addr, 4, &applet->layout.code1)) {
+ return true;
+ }
+
+ if (inside_area(addr, 4, &applet->layout.code2)) {
+ return true;
+ }
+
+ return false;
+}
+
void handle_access_violation(const char *file, int line) {
static const char *msg = "Access violation";
applet_t *applet = syscall_get_context();
diff --git a/core/embed/sys/syscall/stm32/syscall_probe.h b/core/embed/sys/syscall/stm32/syscall_probe.h
index 058e30c6..2c69ecb7 100644
--- a/core/embed/sys/syscall/stm32/syscall_probe.h
+++ b/core/embed/sys/syscall/stm32/syscall_probe.h
@@ -36,6 +36,10 @@ bool probe_read_access(const void *addr, size_t len);
// given memory range.
bool probe_write_access(void *addr, size_t len);
+// Checks if the current application task can execute code at the
+// given address.
+bool probe_execute_access(const void *addr);
+
// Handles access violation by exiting the current application task
// with a fatal error and the message "Access violation".
void handle_access_violation(const char *file, int line);
diff --git a/core/embed/sys/syscall/stm32/syscall_stubs.c b/core/embed/sys/syscall/stm32/syscall_stubs.c
index 58a89d74..3e5af3af 100644
--- a/core/embed/sys/syscall/stm32/syscall_stubs.c
+++ b/core/embed/sys/syscall/stm32/syscall_stubs.c
@@ -504,22 +504,20 @@ void optiga_set_sec_max(void) { syscall_invoke0(SYSCALL_OPTIGA_SET_SEC_MAX); }
// storage.h
// =============================================================================
-#include "storage.h"
+#include <sec/storage.h>
static PIN_UI_WAIT_CALLBACK storage_init_callback = NULL;
-static void storage_init_callback_wrapper(uint32_t wait, uint32_t progress,
- enum storage_ui_message_t message) {
+static void storage_callback_wrapper(uint32_t wait, uint32_t progress,
+ enum storage_ui_message_t message) {
secbool retval = storage_init_callback(wait, progress, message);
return_from_unprivileged_callback(retval);
}
-void storage_init(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt,
- const uint16_t salt_len) {
+void storage_setup(PIN_UI_WAIT_CALLBACK callback) {
storage_init_callback = callback;
- syscall_invoke3((uint32_t)storage_init_callback_wrapper, (uint32_t)salt,
- salt_len, SYSCALL_STORAGE_INIT);
+ syscall_invoke1((uint32_t)storage_callback_wrapper, SYSCALL_STORAGE_SETUP);
}
void storage_wipe(void) { syscall_invoke0(SYSCALL_STORAGE_WIPE); }
@@ -600,16 +598,6 @@ secbool storage_next_counter(const uint16_t key, uint32_t *count) {
SYSCALL_STORAGE_NEXT_COUNTER);
}
-// =============================================================================
-// entropy.h
-// =============================================================================
-
-#include <sec/entropy.h>
-
-void entropy_get(entropy_data_t *entropy) {
- syscall_invoke1((uint32_t)entropy, SYSCALL_ENTROPY_GET);
-}
-
// =============================================================================
// translations.h
// =============================================================================
diff --git a/core/embed/sys/syscall/stm32/syscall_verifiers.c b/core/embed/sys/syscall/stm32/syscall_verifiers.c
index 7113b39b..6153e0ff 100644
--- a/core/embed/sys/syscall/stm32/syscall_verifiers.c
+++ b/core/embed/sys/syscall/stm32/syscall_verifiers.c
@@ -562,13 +562,25 @@ access_violation:
// ---------------------------------------------------------------------
-void storage_init__verified(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt,
- const uint16_t salt_len) {
- if (!probe_read_access(salt, salt_len)) {
+static PIN_UI_WAIT_CALLBACK storage_callback = NULL;
+
+static secbool storage_callback_wrapper(uint32_t wait, uint32_t progress,
+ enum storage_ui_message_t message) {
+ secbool result;
+
+ applet_t *applet = syscall_get_context();
+ result = systask_invoke_callback(&applet->task, wait, progress, message,
+ storage_callback);
+ return result;
+}
+
+void storage_setup__verified(PIN_UI_WAIT_CALLBACK callback) {
+ if (!probe_execute_access(callback)) {
goto access_violation;
}
+ storage_callback = callback;
- storage_init(callback, salt, salt_len);
+ storage_setup(storage_callback_wrapper);
return;
access_violation:
@@ -728,20 +740,6 @@ access_violation:
// ---------------------------------------------------------------------
-void entropy_get__verified(entropy_data_t *entropy) {
- if (!probe_write_access(entropy, sizeof(*entropy))) {
- goto access_violation;
- }
-
- entropy_get(entropy);
- return;
-
-access_violation:
- apptask_access_violation();
-}
-
-// ---------------------------------------------------------------------
-
int firmware_hash_start__verified(const uint8_t *challenge,
size_t challenge_len) {
if (!probe_read_access(challenge, challenge_len)) {
diff --git a/core/embed/sys/syscall/stm32/syscall_verifiers.h b/core/embed/sys/syscall/stm32/syscall_verifiers.h
index 03b83ea8..110dc7b9 100644
--- a/core/embed/sys/syscall/stm32/syscall_verifiers.h
+++ b/core/embed/sys/syscall/stm32/syscall_verifiers.h
@@ -147,10 +147,9 @@ bool __wur optiga_random_buffer__verified(uint8_t *dest, size_t size);
#endif // USE_OPTIGA
// ---------------------------------------------------------------------
-#include "storage.h"
+#include <sec/storage.h>
-void storage_init__verified(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt,
- const uint16_t salt_len);
+void storage_setup__verified(PIN_UI_WAIT_CALLBACK callback);
secbool storage_unlock__verified(const uint8_t *pin, size_t pin_len,
const uint8_t *ext_salt);
@@ -183,11 +182,6 @@ bool translations_write__verified(const uint8_t *data, uint32_t offset,
const uint8_t *translations_read__verified(uint32_t *len, uint32_t offset);
-// ---------------------------------------------------------------------
-#include <sec/entropy.h>
-
-void entropy_get__verified(entropy_data_t *entropy);
-
// ---------------------------------------------------------------------
#include <util/fwutils.h>
diff --git a/core/embed/upymod/modtrezorconfig/modtrezorconfig.c b/core/embed/upymod/modtrezorconfig/modtrezorconfig.c
index 98d0f509..6f6b8ce6 100644
--- a/core/embed/upymod/modtrezorconfig/modtrezorconfig.c
+++ b/core/embed/upymod/modtrezorconfig/modtrezorconfig.c
@@ -25,11 +25,11 @@
#if MICROPY_PY_TREZORCONFIG
+#include <sec/storage.h>
+
#include "embed/upymod/trezorobj.h"
-#include <sec/entropy.h>
#include "memzero.h"
-#include "storage.h"
static secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress,
enum storage_ui_message_t message) {
@@ -51,20 +51,17 @@ static secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress,
/// None
/// ) -> None:
/// """
-/// Initializes the storage. Must be called before any other method is
-/// called from this module!
+/// Performs a soft re-initialization of the storage.
+/// Locks the storage if it is currently unlocked, and allows setting
+/// a new UI callback.
/// """
STATIC mp_obj_t mod_trezorconfig_init(size_t n_args, const mp_obj_t *args) {
- entropy_data_t entropy;
- entropy_get(&entropy);
-
if (n_args > 0) {
MP_STATE_VM(trezorconfig_ui_wait_callback) = args[0];
- storage_init(wrapped_ui_wait_callback, entropy.bytes, entropy.size);
+ storage_setup(wrapped_ui_wait_callback);
} else {
- storage_init(NULL, entropy.bytes, entropy.size);
+ storage_setup(NULL);
}
- memzero(&entropy, sizeof(entropy));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_init_obj, 0, 1,
diff --git a/core/mocks/generated/trezorconfig.pyi b/core/mocks/generated/trezorconfig.pyi
index 48393ae9..44f72b77 100644
--- a/core/mocks/generated/trezorconfig.pyi
+++ b/core/mocks/generated/trezorconfig.pyi
@@ -7,8 +7,9 @@ def init(
None
) -> None:
"""
- Initializes the storage. Must be called before any other method is
- called from this module!
+ Performs a soft re-initialization of the storage.
+ Locks the storage if it is currently unlocked, and allows setting
+ a new UI callback.
"""
Why this scored 11/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.