refactor(core): remove coreapp specific logic from applets

[no changelog]
This commit is contained in:
cepetr
2025-11-13 08:12:20 +01:00
committed by cepetr
parent b8d5b8cc47
commit 3f383a6fd1
8 changed files with 205 additions and 116 deletions

View File

@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <trezor_model.h>
#include <trezor_rtl.h>
#include <gfx/gfx_bitblt.h>
@@ -24,8 +25,8 @@
#include <sec/random_delays.h>
#include <sec/secret.h>
#include <sec/secure_aes.h>
#include <sys/applet.h>
#include <sys/bootutils.h>
#include <sys/coreapp.h>
#include <sys/mpu.h>
#include <sys/syscall_ipc.h>
#include <sys/sysevent.h>
@@ -33,7 +34,6 @@
#include <sys/systick.h>
#include <util/board_capabilities.h>
#include <util/boot_image.h>
#include <util/image.h>
#include <util/option_bytes.h>
#include <util/rsod.h>
#include <util/unit_properties.h>
@@ -54,6 +54,10 @@
#include <io/haptic.h>
#endif
#ifdef USE_HASH_PROCESSOR
#include <sec/hash_processor.h>
#endif
#ifdef USE_OPTIGA
#include <sec/optiga_init.h>
#endif
@@ -212,42 +216,6 @@ static void kernel_loop(applet_t *coreapp) {
} while (applet_is_alive(coreapp));
}
// defined in linker script
extern uint32_t _kernel_flash_end;
#define KERNEL_END COREAPP_CODE_ALIGN((uint32_t) & _kernel_flash_end)
// Initializes coreapp applet
static void coreapp_init(applet_t *applet) {
const uint32_t CODE1_START = KERNEL_END;
#ifdef FIRMWARE_P1_START
const uint32_t CODE1_END = FIRMWARE_P1_START + FIRMWARE_P1_MAXSIZE;
#else
const uint32_t CODE1_END = FIRMWARE_START + FIRMWARE_MAXSIZE;
#endif
const applet_layout_t coreapp_layout = {
.data1.start = (uint32_t)AUX1_RAM_START,
.data1.size = (uint32_t)AUX1_RAM_SIZE,
#ifdef AUX2_RAM_START
.data2.start = (uint32_t)AUX2_RAM_START,
.data2.size = (uint32_t)AUX2_RAM_SIZE,
#endif
.code1.start = CODE1_START,
.code1.size = CODE1_END - CODE1_START,
#ifdef FIRMWARE_P2_START
.code2.start = FIRMWARE_P2_START,
.code2.size = FIRMWARE_P2_MAXSIZE,
#endif
};
applet_privileges_t coreapp_privileges = {
.assets_area_access = true,
};
applet_init(applet, &coreapp_layout, &coreapp_privileges);
}
#ifndef USE_BOOTARGS_RSOD
// Shows RSOD (Red Screen of Death)
@@ -257,7 +225,7 @@ static void show_rsod(const systask_postmortem_t *pminfo) {
coreapp_init(&coreapp);
// Reset and run the coreapp in RSOD mode
if (applet_reset(&coreapp, 1, pminfo, sizeof(systask_postmortem_t))) {
if (coreapp_reset(&coreapp, 1, pminfo, sizeof(systask_postmortem_t))) {
// Run the applet & wait for it to finish
applet_run(&coreapp);
// Loop until the coreapp is terminated
@@ -320,12 +288,13 @@ int main(void) {
coreapp_init(&coreapp);
// Reset and run the coreapp
if (!applet_reset(&coreapp, 0, NULL, 0)) {
if (!coreapp_reset(&coreapp, 0, NULL, 0)) {
error_shutdown("Cannot start coreapp");
}
// Run the applet
applet_run(&coreapp);
// Loop until the coreapp is terminated
kernel_loop(&coreapp);
// Release the coreapp resources

View File

@@ -110,6 +110,7 @@ __attribute((no_stack_protector)) void saes_unpriv_callback(void) {
#ifdef KERNEL
#include <sys/coreapp.h>
#include <sys/mpu.h>
#include <sys/systask.h>
@@ -144,11 +145,12 @@ secbool secure_aes_unpriv_encrypt(const uint8_t *input, size_t size,
applet_t *applet = secure_aes_unpriv_applet;
const applet_header_t *header = (applet_header_t *)applet->layout.code1.start;
const coreapp_header_t *header =
(coreapp_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;
void *unpriv_input = header->saes_input;
void *unpriv_output = header->saes_output;
void *unpriv_callback = header->saes_callback;
memzero(unpriv_input, SAES_DATA_SIZE_WITH_UNPRIV_KEY);
memzero(unpriv_output, SAES_DATA_SIZE_WITH_UNPRIV_KEY);

View File

@@ -25,28 +25,6 @@
#include <sys/systask.h>
// Applet entry point
typedef void (*applet_startup_t)(const char* args, uint32_t random);
// Applet header found at the beginning of the applet binary
typedef struct {
// Applet entry point
applet_startup_t startup;
// Stack area
mpu_area_t stack;
// TLS area
mpu_area_t tls;
// Coreapp specific data
struct {
// Unprivileged SAES input buffer
void* saes_input;
// Unprivileged SAES output buffer
void* saes_output;
// Unprivileged SAES callback
void* saes_callback;
} coreapp;
} applet_header_t;
// Applet privileges
typedef struct {
bool assets_area_access;
@@ -68,15 +46,6 @@ typedef struct {
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.
//
// Applet does not start immediately, it needs to be run by
// `applet_run()` after calling this function.
//
// Returns `true` if the applet was successfully reset.
bool applet_reset(applet_t* applet, uint32_t cmd, const void* arg,
size_t arg_size);
// Runs the applet and waits until it finishes.
void applet_run(applet_t* applet);

View File

@@ -0,0 +1,64 @@
/*
* 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/>.
*/
#pragma once
#ifdef KERNEL_MODE
#include <trezor_types.h>
#include <sys/applet.h>
#include <sys/mpu.h>
// Coreapp entry point
typedef void (*coreapp_startup_t)(const char* args, uint32_t random);
// Applet header found at the beginning of the coreapp binary
typedef struct {
// Applet entry point
coreapp_startup_t startup;
// Stack area
mpu_area_t stack;
// TLS area
mpu_area_t tls;
// Unprivileged SAES input buffer
void* saes_input;
// Unprivileged SAES output buffer
void* saes_output;
// Unprivileged SAES callback
void* saes_callback;
} coreapp_header_t;
// Initializes the coreapp applet structure
void coreapp_init(applet_t* applet);
// Resets the coreapp and prepares it for execution from its entry point.
//
// Coreapp does not start immediately, it needs to be run by
// `applet_run()` after calling this function.
//
// Returns `true` if the applet was successfully reset.
bool coreapp_reset(applet_t* applet, uint32_t cmd, const void* arg,
size_t arg_size);
mpu_area_t coreapp_get_code_area(void);
mpu_area_t coreapp_get_tls_area(void);
#endif // KERNEL_MODE

View File

@@ -40,47 +40,6 @@ void applet_init(applet_t* applet, const applet_layout_t* layout,
applet->privileges = *privileges;
}
static void applet_clear_memory(applet_t* applet) {
mpu_set_active_applet(&applet->layout);
if (applet->layout.data1.size > 0) {
memset((void*)applet->layout.data1.start, 0, applet->layout.data1.size);
}
if (applet->layout.data2.size > 0) {
memset((void*)applet->layout.data2.start, 0, applet->layout.data2.size);
}
}
bool applet_reset(applet_t* applet, uint32_t cmd, const void* arg,
size_t arg_size) {
// 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, header->stack.start, header->stack.size, 0,
applet)) {
return false;
}
// Copy the arguments onto the applet stack
void* arg_copy = NULL;
if (arg != NULL && arg_size > 0) {
arg_copy = systask_push_data(&applet->task, arg, arg_size);
if (arg_copy == NULL) {
return false;
}
}
// Schedule the applet task run
uint32_t arg1 = cmd;
uint32_t arg2 = (uint32_t)arg_copy;
uint32_t arg3 = rng_get();
return systask_push_call(&applet->task, header->startup, arg1, arg2, arg3);
}
#ifdef USE_TRUSTZONE
// Sets unprivileged access to the applet memory regions
// and allows applet to use some specific peripherals.

View File

@@ -0,0 +1,124 @@
/*
* 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 KERNEL
#include <trezor_rtl.h>
#include <sec/rng.h>
#include <sys/applet.h>
#include <sys/coreapp.h>
#include <sys/mpu.h>
#include <sys/systask.h>
#include <util/image.h>
static mpu_area_t coreapp_code_area;
static mpu_area_t coreapp_tls_area;
// defined in linker script
extern uint32_t _kernel_flash_end;
#define KERNEL_END COREAPP_CODE_ALIGN((uint32_t) & _kernel_flash_end)
// Initializes coreapp applet
void coreapp_init(applet_t* applet) {
const uint32_t CODE1_START = KERNEL_END;
#ifdef FIRMWARE_P1_START
const uint32_t CODE1_END = FIRMWARE_P1_START + FIRMWARE_P1_MAXSIZE;
#else
const uint32_t CODE1_END = FIRMWARE_START + FIRMWARE_MAXSIZE;
#endif
const applet_layout_t coreapp_layout = {
.data1.start = (uint32_t)AUX1_RAM_START,
.data1.size = (uint32_t)AUX1_RAM_SIZE,
#ifdef AUX2_RAM_START
.data2.start = (uint32_t)AUX2_RAM_START,
.data2.size = (uint32_t)AUX2_RAM_SIZE,
#endif
.code1.start = CODE1_START,
.code1.size = CODE1_END - CODE1_START,
#ifdef FIRMWARE_P2_START
.code2.start = FIRMWARE_P2_START,
.code2.size = FIRMWARE_P2_MAXSIZE,
#endif
};
applet_privileges_t coreapp_privileges = {
.assets_area_access = true,
};
applet_init(applet, &coreapp_layout, &coreapp_privileges);
}
static void coreapp_clear_memory(applet_t* applet) {
if (applet->layout.data1.size > 0) {
memset((void*)applet->layout.data1.start, 0, applet->layout.data1.size);
}
if (applet->layout.data2.size > 0) {
memset((void*)applet->layout.data2.start, 0, applet->layout.data2.size);
}
}
bool coreapp_reset(applet_t* applet, uint32_t cmd, const void* arg,
size_t arg_size) {
// Enable access to coreapp memory regions
mpu_set_active_applet(&applet->layout);
// Clear all memory the applet is allowed to use
coreapp_clear_memory(applet);
const coreapp_header_t* header =
(coreapp_header_t*)applet->layout.code1.start;
// Remember code and TLS areas
// (we will need then later for extension applets)
coreapp_tls_area = header->tls;
coreapp_code_area = applet->layout.code1;
// Reset the applet task (stack pointer, etc.)
if (!systask_init(&applet->task, header->stack.start, header->stack.size, 0,
applet)) {
return false;
}
systask_enable_tls(&applet->task, header->tls);
// Copy the arguments onto the applet stack
void* arg_copy = NULL;
if (arg != NULL && arg_size > 0) {
arg_copy = systask_push_data(&applet->task, arg, arg_size);
if (arg_copy == NULL) {
return false;
}
}
// Schedule the applet task run
uint32_t arg1 = cmd;
uint32_t arg2 = (uint32_t)arg_copy;
uint32_t arg3 = rng_get();
return systask_push_call(&applet->task, header->startup, arg1, arg2, arg3);
}
mpu_area_t coreapp_get_code_area(void) { return coreapp_code_area; }
mpu_area_t coreapp_get_tls_area(void) { return coreapp_tls_area; }
#endif // KERNEL

View File

@@ -91,6 +91,7 @@ def stm32f4_common_files(env, features_wanted, defines, sources, paths):
"embed/sys/syscall/stm32/syscall_stubs.c",
"embed/sys/syscall/stm32/syscall_verifiers.c",
"embed/sys/task/stm32/applet.c",
"embed/sys/task/stm32/coreapp.c",
"embed/sys/task/stm32/systask.c",
"embed/sys/task/stm32/system.c",
"embed/sys/time/stm32/systick.c",

View File

@@ -152,6 +152,7 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
if "applet" in features_wanted:
sources += ["embed/sys/task/stm32/applet.c"]
sources += ["embed/sys/task/stm32/coreapp.c"]
if "usb" in features_wanted:
sources += [