refactor(core): improve applet interface
What changed, and why it matters
This commit is a small internal cleanup of how the Trezor firmware's kernel talks to applets (isolated mini-programs). It removes a direct pointer to the applet's header from the applet structure and instead reads that header from the start of the applet's code area when needed. The change is described as a refactor with no changelog. There is no direct evidence in the commit that this fixes a security vulnerability, but it does reduce the chance that a stale or manipulated header pointer could be used.
Treat as routine refactoring. No immediate security action required. Reviewers may want to confirm that `layout.code1.start` always points to a valid applet header and that all `applet_header_t` accesses are now consistently derived from it.
Security signals we found
Removal of redundant applet_header_t pointer from applet_t
Header now derived from applet->layout.code1.start at use sites
Const-correctness improvements in applet_init signature
No changelog, described as refactor
Evidence from the diff
The patch refactors the applet_t interface: applet_init() no longer takes an applet_header_t* argument, and the header field is removed from applet_t. Callers now pass only the memory layout and privileges. Code that previously accessed applet->header (in applet_reset() and secure_aes_unpriv_encrypt()) now derives the header pointer from applet->layout.code1.start. This centralizes header parsing to the code region start and removes a redundant pointer that could theoretically become inconsistent. The change is minor and does not alter memory permissions or trust boundaries.
Changed components
core/embed/sys/task/stm32/applet.ccore/embed/sys/task/inc/sys/applet.hcore/embed/projects/kernel/main.ccore/embed/sec/secure_aes/stm32u5/secure_aes_unpriv.cInspect captured patch +16 / −18
diff --git a/core/embed/projects/kernel/main.c b/core/embed/projects/kernel/main.c
index 6fa2b408..966b8189 100644
--- a/core/embed/projects/kernel/main.c
+++ b/core/embed/projects/kernel/main.c
@@ -226,9 +226,7 @@ static void coreapp_init(applet_t *applet) {
const uint32_t CODE1_END = FIRMWARE_START + FIRMWARE_MAXSIZE;
#endif
- applet_header_t *coreapp_header = (applet_header_t *)CODE1_START;
-
- applet_layout_t coreapp_layout = {
+ const applet_layout_t coreapp_layout = {
.data1.start = (uint32_t)AUX1_RAM_START,
.data1.size = (uint32_t)AUX1_RAM_SIZE,
#ifdef AUX2_RAM_START
@@ -247,7 +245,7 @@ static void coreapp_init(applet_t *applet) {
.assets_area_access = true,
};
- applet_init(applet, coreapp_header, &coreapp_layout, &coreapp_privileges);
+ applet_init(applet, &coreapp_layout, &coreapp_privileges);
}
#ifndef USE_BOOTARGS_RSOD
diff --git a/core/embed/sec/secure_aes/stm32u5/secure_aes_unpriv.c b/core/embed/sec/secure_aes/stm32u5/secure_aes_unpriv.c
index cb4630a3..7049acf8 100644
--- a/core/embed/sec/secure_aes/stm32u5/secure_aes_unpriv.c
+++ b/core/embed/sec/secure_aes/stm32u5/secure_aes_unpriv.c
@@ -144,9 +144,11 @@ secbool secure_aes_unpriv_encrypt(const uint8_t *input, size_t size,
applet_t *applet = secure_aes_unpriv_applet;
- void *unpriv_input = applet->header->coreapp.saes_input;
- void *unpriv_output = applet->header->coreapp.saes_output;
- void *unpriv_callback = applet->header->coreapp.saes_callback;
+ const applet_header_t *header = (applet_header_t *)applet->layout.code1.start;
+
+ void *unpriv_input = header->coreapp.saes_input;
+ void *unpriv_output = header->coreapp.saes_output;
+ void *unpriv_callback = header->coreapp.saes_callback;
memzero(unpriv_input, SAES_DATA_SIZE_WITH_UNPRIV_KEY);
memzero(unpriv_output, SAES_DATA_SIZE_WITH_UNPRIV_KEY);
diff --git a/core/embed/sys/task/inc/sys/applet.h b/core/embed/sys/task/inc/sys/applet.h
index 33ee2f60..a4e8a21c 100644
--- a/core/embed/sys/task/inc/sys/applet.h
+++ b/core/embed/sys/task/inc/sys/applet.h
@@ -51,8 +51,6 @@ typedef struct {
} applet_privileges_t;
typedef struct {
- // Points to the applet header found at the beginning of the applet binary
- applet_header_t* header;
// Applet memory layout describing the memory areas
// the applet is allowed to use
applet_layout_t layout;
@@ -65,8 +63,8 @@ typedef struct {
} applet_t;
// Initializes the applet structure
-void applet_init(applet_t* applet, applet_header_t* header,
- applet_layout_t* layout, applet_privileges_t* privileges);
+void applet_init(applet_t* applet, const applet_layout_t* layout,
+ const applet_privileges_t* privileges);
// Resets the applet and prepares it for execution from its entry point.
//
diff --git a/core/embed/sys/task/stm32/applet.c b/core/embed/sys/task/stm32/applet.c
index a9e6c6a0..273a4fd5 100644
--- a/core/embed/sys/task/stm32/applet.c
+++ b/core/embed/sys/task/stm32/applet.c
@@ -32,11 +32,10 @@
#ifdef KERNEL
-void applet_init(applet_t* applet, applet_header_t* header,
- applet_layout_t* layout, applet_privileges_t* privileges) {
+void applet_init(applet_t* applet, const applet_layout_t* layout,
+ const applet_privileges_t* privileges) {
memset(applet, 0, sizeof(applet_t));
- applet->header = header;
applet->layout = *layout;
applet->privileges = *privileges;
}
@@ -57,9 +56,11 @@ bool applet_reset(applet_t* applet, uint32_t cmd, const void* arg,
// Clear all memory the applet is allowed to use
applet_clear_memory(applet);
+ const applet_header_t* header = (applet_header_t*)applet->layout.code1.start;
+
// Reset the applet task (stack pointer, etc.)
- if (!systask_init(&applet->task, applet->header->stack.start,
- applet->header->stack.size, applet)) {
+ if (!systask_init(&applet->task, header->stack.start, header->stack.size,
+ applet)) {
return false;
}
@@ -77,8 +78,7 @@ bool applet_reset(applet_t* applet, uint32_t cmd, const void* arg,
uint32_t arg2 = (uint32_t)arg_copy;
uint32_t arg3 = rng_get();
- return systask_push_call(&applet->task, applet->header->startup, arg1, arg2,
- arg3);
+ return systask_push_call(&applet->task, header->startup, arg1, arg2, arg3);
}
#ifdef USE_TRUSTZONE
Why this scored 28/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.