Merge branch 'refactor/esp_tee_ss_layer_in_flash' into 'master'

refactor(esp_tee): Place the secure services `_ss_` layer in the flash by default

See merge request espressif/esp-idf!38336
This commit is contained in:
Laukik Hase
2025-04-17 19:58:47 +08:00
19 changed files with 554 additions and 657 deletions

View File

@@ -14,18 +14,18 @@ menu "ESP-TEE (Trusted Execution Environment)"
config SECURE_TEE_IRAM_SIZE
hex "IRAM region size"
default 0x8000
range 0x8000 0x10000
range 0x7000 0xA000
help
This configuration sets the IRAM size for the TEE module.
This should be a multiple of 0x1000.
This should be 256-byte (0x100) aligned.
config SECURE_TEE_DRAM_SIZE
hex "DRAM region size"
default 0x8000
range 0x8000 0x10000
default 0x6000
range 0x5000 0x7000
help
This configuration sets the DRAM size for the TEE module.
This should be a multiple of 0x1000.
This should be 256-byte (0x100) aligned.
config SECURE_TEE_STACK_SIZE
hex "Stack size"
@@ -34,7 +34,7 @@ menu "ESP-TEE (Trusted Execution Environment)"
help
This configuration sets the stack size for the TEE module.
The TEE stack will be allocated from the TEE DRAM region.
This should be a multiple of 0x100.
This should be 16-byte (0x10) aligned.
config SECURE_TEE_INTR_STACK_SIZE
hex "Interrupt Stack size"
@@ -43,7 +43,7 @@ menu "ESP-TEE (Trusted Execution Environment)"
help
This configuration sets the interrupt stack size for the TEE module.
The TEE interrupt stack will be allocated from the TEE DRAM region.
This should be a multiple of 0x100.
This should be 16-byte (0x10) aligned.
config SECURE_TEE_IROM_SIZE
hex

View File

@@ -23,6 +23,22 @@ extern "C" {
#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1))
#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1))
#if ((CONFIG_SECURE_TEE_IRAM_SIZE) & (0xFF))
#error "CONFIG_SECURE_TEE_IRAM_SIZE must be 256-byte (0x100) aligned"
#endif
#if ((CONFIG_SECURE_TEE_DRAM_SIZE) & (0xFF))
#error "CONFIG_SECURE_TEE_DRAM_SIZE must be 256-byte (0x100) aligned"
#endif
#if ((CONFIG_SECURE_TEE_STACK_SIZE) & 0xF)
#error "CONFIG_SECURE_TEE_STACK_SIZE must be 16-byte (0x10) aligned"
#endif
#if ((CONFIG_SECURE_TEE_INTR_STACK_SIZE) & 0xF)
#error "CONFIG_SECURE_TEE_INTR_STACK_SIZE must be 16-byte (0x10) aligned"
#endif
/* NOTE: ESP32-C6 - TEE/REE memory regions */
/* TEE I/DRAM */
#define SOC_S_IRAM_START (SOC_IRAM_LOW)

View File

@@ -134,26 +134,10 @@ secure_services:
- family: hal
entries:
- id: 54
type: IDF
function: efuse_hal_chip_revision
args: 0
- id: 55
type: IDF
function: efuse_hal_get_chip_ver_pkg
args: 1
- id: 56
type: IDF
function: efuse_hal_get_disable_wafer_version_major
args: 0
- id: 57
type: IDF
function: efuse_hal_get_mac
args: 1
- id: 58
type: IDF
function: wdt_hal_init
args: 4
- id: 59
- id: 55
type: IDF
function: wdt_hal_deinit
args: 1
@@ -256,22 +240,7 @@ secure_services:
type: IDF
function: esp_ecc_point_verify
args: 1
# ID: 134-149 (16) - eFuse
- family: efuse
entries:
- id: 134
type: IDF
function: esp_efuse_check_secure_version
args: 1
- id: 135
type: IDF
function: esp_efuse_read_field_blob
args: 3
- id: 136
type: IDF
function: esp_flash_encryption_enabled
args: 0
# ID: 150-169 (20) - Reserved for future use
# ID: 134-169 (36) - Reserved for future use
- family: attestation
entries:
- id: 170

View File

@@ -6,7 +6,6 @@
#include <stdarg.h>
#include "esp_err.h"
#include "esp_efuse.h"
#include "esp_random.h"
#include "hal/sha_types.h"
@@ -32,43 +31,6 @@ void IRAM_ATTR __wrap_esp_rom_route_intr_matrix(int cpu_no, uint32_t model_num,
esp_tee_service_call(4, SS_ESP_ROM_ROUTE_INTR_MATRIX, cpu_no, model_num, intr_num);
}
/* ---------------------------------------------- eFuse ------------------------------------------------- */
uint32_t __wrap_efuse_hal_chip_revision(void)
{
return esp_tee_service_call(1, SS_EFUSE_HAL_CHIP_REVISION);
}
uint32_t __wrap_efuse_hal_get_chip_ver_pkg(void)
{
return esp_tee_service_call(1, SS_EFUSE_HAL_GET_CHIP_VER_PKG);
}
bool __wrap_efuse_hal_get_disable_wafer_version_major(void)
{
return esp_tee_service_call(1, SS_EFUSE_HAL_GET_DISABLE_WAFER_VERSION_MAJOR);
}
void __wrap_efuse_hal_get_mac(uint8_t *mac)
{
esp_tee_service_call(2, SS_EFUSE_HAL_GET_MAC, mac);
}
bool __wrap_esp_efuse_check_secure_version(uint32_t secure_version)
{
return esp_tee_service_call(4, SS_ESP_EFUSE_CHECK_SECURE_VERSION, secure_version);
}
esp_err_t __wrap_esp_efuse_read_field_blob(const esp_efuse_desc_t *field[], void *dst, size_t dst_size_bits)
{
return esp_tee_service_call(4, SS_ESP_EFUSE_READ_FIELD_BLOB, (uint32_t)field, (uint32_t)dst, (uint32_t)dst_size_bits);
}
bool __wrap_esp_flash_encryption_enabled(void)
{
return esp_tee_service_call(1, SS_ESP_FLASH_ENCRYPTION_ENABLED);
}
/* ---------------------------------------------- RTC_WDT ------------------------------------------------- */
void __wrap_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr)

View File

@@ -12,6 +12,7 @@ extern "C" {
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#define MIN_SEC_STG_SLOT_ID 0 /*!< Minimum secure storage slot ID */
#define MAX_SEC_STG_SLOT_ID 14 /*!< Maximum secure storage slot ID */

View File

@@ -9,6 +9,7 @@ set(include)
set(srcs "core/esp_tee_init.c"
"core/esp_tee_intr.c"
"core/esp_secure_services.c"
"core/esp_secure_services_iram.c"
"core/esp_secure_dispatcher.c"
"core/esp_secure_service_table.c")

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -20,12 +20,12 @@
#include "esp_tee.h"
#include "esp_tee_apm_intr.h"
#include "esp_tee_rv_utils.h"
#include "panic_helper.h"
#include "sdkconfig.h"
#define RV_FUNC_STK_SZ (32)
#define tee_panic_print(format, ...) esp_rom_printf(DRAM_STR(format), ##__VA_ARGS__)
static void tee_panic_end(void)
{
// Disable interrupts
@@ -67,26 +67,27 @@ void abort(void)
ESP_INFINITE_LOOP();
}
static void panic_handler(void *frame, bool pseudo_exccause)
static void panic_print_info(const void *frame, int core)
{
int fault_core = esp_cpu_get_core_id();
tee_panic_print("\n=================================================\n");
tee_panic_print("Secure exception occurred on Core %d\n", fault_core);
if (pseudo_exccause) {
panic_print_isrcause((const void *)frame, fault_core);
} else {
panic_print_exccause((const void *)frame, fault_core);
}
tee_panic_print("=================================================\n");
panic_print_registers((const void *)frame, fault_core);
panic_print_registers((const void *)frame, core);
tee_panic_print("\n");
panic_print_backtrace((const void *)frame, 100);
tee_panic_print("\n");
tee_panic_print("Rebooting...\r\n\n");
tee_panic_end();
}
static void panic_handler(void *frame, bool pseudo_exccause)
{
int fault_core = esp_cpu_get_core_id();
if (pseudo_exccause) {
panic_print_isrcause((const void *)frame, fault_core);
} else {
panic_print_exccause((const void *)frame, fault_core);
}
panic_print_info((const void *)frame, fault_core);
ESP_INFINITE_LOOP();
}
@@ -105,34 +106,24 @@ void tee_apm_violation_isr(void *arg)
intptr_t exc_sp = RV_READ_CSR(mscratch);
RvExcFrame *frame = (RvExcFrame *)exc_sp;
apm_ctrl_path_t *apm_excp_type = NULL;
apm_ctrl_exception_info_t excp_info;
apm_ctrl_path_t *apm_excp_type = (apm_ctrl_path_t *)arg;
apm_ctrl_exception_info_t excp_info = {
.apm_path = {
.apm_ctrl = apm_excp_type->apm_ctrl,
.apm_m_path = apm_excp_type->apm_m_path,
}
};
apm_excp_type = (apm_ctrl_path_t *)arg;
excp_info.apm_path.apm_ctrl = apm_excp_type->apm_ctrl;
excp_info.apm_path.apm_m_path = apm_excp_type->apm_m_path;
apm_hal_apm_ctrl_get_exception_info(&excp_info);
/* Clear APM M path interrupt. */
apm_hal_apm_ctrl_exception_clear(apm_excp_type);
int fault_core = esp_cpu_get_core_id();
panic_print_rsn((const void *)frame, fault_core, esp_tee_apm_excp_type_to_str(excp_info.excp_type));
tee_panic_print("\n=================================================\n");
tee_panic_print("APM permission violation occurred on Core %d\n", fault_core);
tee_panic_print("Guru Meditation Error: Core %d panic'ed (%s). ", fault_core, esp_tee_apm_excp_type_to_str(excp_info.excp_type));
tee_panic_print("Exception was unhandled.\n");
tee_panic_print("Fault addr: 0x%x | Mode: %s\n", excp_info.excp_addr, esp_tee_apm_excp_mode_to_str(excp_info.excp_mode));
tee_panic_print("Module: %s | Path: 0x%02x\n", esp_tee_apm_excp_ctrl_to_str(excp_info.apm_path.apm_ctrl), excp_info.apm_path.apm_m_path);
tee_panic_print("Master: %s | Region: 0x%02x\n", esp_tee_apm_excp_mid_to_str(excp_info.excp_id), excp_info.excp_regn);
tee_panic_print("=================================================\n");
panic_print_registers((const void *)frame, fault_core);
tee_panic_print("\n");
panic_print_backtrace((const void *)frame, 100);
tee_panic_print("\n");
tee_panic_print("Rebooting...\r\n\n");
tee_panic_print("Access addr: 0x%x | Mode: %s\n", excp_info.excp_addr, esp_tee_apm_excp_mode_to_str(excp_info.excp_mode));
tee_panic_print("Module: %s | Path: %d\n", esp_tee_apm_excp_ctrl_to_str(excp_info.apm_path.apm_ctrl), excp_info.apm_path.apm_m_path);
tee_panic_print("Master: %s | Region: %d\n", esp_tee_apm_excp_mid_to_str(excp_info.excp_id), (excp_info.excp_regn == 0) ? 0 : (__builtin_ffs(excp_info.excp_regn) - 1));
tee_panic_end();
panic_print_info((const void *)frame, fault_core);
ESP_INFINITE_LOOP();
}

View File

@@ -3,11 +3,21 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdarg.h>
#include "esp_rom_sys.h"
#if CONFIG_SECURE_TEE_DEBUG_MODE
#define tee_panic_print(format, ...) esp_rom_printf(DRAM_STR(format), ##__VA_ARGS__)
#else
#define tee_panic_print(format, ...)
#endif
void panic_print_backtrace(const void *f, int depth);
void panic_print_registers(const void *f, int core);
void panic_print_rsn(const void *f, int core, const char *rsn);
void panic_print_exccause(const void *f, int core);
void panic_print_isrcause(const void *f, int core);

View File

@@ -13,8 +13,8 @@
#include "riscv/rvruntime-frames.h"
#include "esp_tee.h"
#define tee_panic_print(format, ...) esp_rom_printf(DRAM_STR(format), ##__VA_ARGS__)
#include "panic_helper.h"
#include "sdkconfig.h"
void panic_print_backtrace(const void *f, int depth)
{
@@ -55,23 +55,47 @@ void panic_print_registers(const void *f, int core)
}
}
tee_panic_print("MIE : 0x%08x ", RV_READ_CSR(mie));
tee_panic_print("MIP : 0x%08x ", RV_READ_CSR(mip));
tee_panic_print("MSCRATCH: 0x%08x\n", RV_READ_CSR(mscratch));
tee_panic_print("UEPC : 0x%08x ", RV_READ_CSR(uepc));
tee_panic_print("USTATUS : 0x%08x ", RV_READ_CSR(ustatus));
tee_panic_print("UTVEC : 0x%08x ", RV_READ_CSR(utvec));
tee_panic_print("UCAUSE : 0x%08x\n", RV_READ_CSR(ucause));
tee_panic_print("UTVAL : 0x%08x ", RV_READ_CSR(utval));
tee_panic_print("UIE : 0x%08x ", RV_READ_CSR(uie));
tee_panic_print("UIP : 0x%08x\n", RV_READ_CSR(uip));
#if CONFIG_SECURE_TEE_TEST_MODE
struct {
const char *name;
uint32_t value;
} csr_regs[] = {
{ "MIE ", RV_READ_CSR(mie) },
{ "MIP ", RV_READ_CSR(mip) },
{ "MSCRATCH", RV_READ_CSR(mscratch) },
{ "UEPC ", RV_READ_CSR(uepc) },
{ "USTATUS ", RV_READ_CSR(ustatus) },
{ "UTVEC ", RV_READ_CSR(utvec) },
{ "UCAUSE ", RV_READ_CSR(ucause) },
{ "UTVAL ", RV_READ_CSR(utval) },
{ "UIE ", RV_READ_CSR(uie) },
{ "UIP ", RV_READ_CSR(uip) },
};
tee_panic_print("\n\n");
for (int i = 0; i < sizeof(csr_regs) / sizeof(csr_regs[0]); i++) {
tee_panic_print("%s: 0x%08x ", csr_regs[i].name, csr_regs[i].value);
if ((i + 1) % 4 == 0 || i == sizeof(csr_regs) / sizeof(csr_regs[0]) - 1) {
tee_panic_print("\n");
}
}
#endif
}
void panic_print_rsn(const void *f, int core, const char *rsn)
{
const RvExcFrame *regs = (const RvExcFrame *)f;
const void *addr = (const void *)regs->mepc;
tee_panic_print("Guru Meditation Error: Core %d panic'ed (%s). Exception was unhandled.\n", core, rsn);
tee_panic_print("Fault addr: %p | Origin: %s\n", addr, (regs->mstatus & MSTATUS_MPP) ? "M-mode" : "U-mode");
}
void panic_print_exccause(const void *f, int core)
{
RvExcFrame *regs = (RvExcFrame *) f;
const RvExcFrame *regs = (const RvExcFrame *)f;
//Please keep in sync with PANIC_RSN_* defines
static const char *reason[] = {
"Instruction address misaligned",
"Instruction access fault",
@@ -98,27 +122,14 @@ void panic_print_exccause(const void *f, int core)
}
}
const char *desc = "Exception was unhandled.";
const void *addr = (void *) regs->mepc;
tee_panic_print("Guru Meditation Error: Core %d panic'ed (%s). %s\n", core, rsn, desc);
const char *exc_origin = "U-mode";
if (regs->mstatus & MSTATUS_MPP) {
exc_origin = "M-mode";
}
tee_panic_print("Fault addr: %p | Exception origin: %s\n", addr, exc_origin);
panic_print_rsn(f, core, rsn);
}
void panic_print_isrcause(const void *f, int core)
{
RvExcFrame *regs = (RvExcFrame *) f;
const void *addr = (void *) regs->mepc;
const RvExcFrame *regs = (const RvExcFrame *)f;
const char *rsn = "Unknown reason";
/* The mcause has been set by the CPU when the panic occurred.
* All SoC-level panic will call this function, thus, this register
* lets us know which error was triggered. */
switch (regs->mcause) {
case ETS_CACHEERR_INUM:
rsn = "Cache error";
@@ -131,16 +142,7 @@ void panic_print_isrcause(const void *f, int core)
rsn = "Interrupt wdt timeout on CPU1";
break;
#endif
default:
break;
}
const char *desc = "Exception was unhandled.";
tee_panic_print("Guru Meditation Error: Core %d panic'ed (%s). %s\n", core, rsn, desc);
const char *exc_origin = "U-mode";
if (regs->mstatus & MSTATUS_MPP) {
exc_origin = "M-mode";
}
tee_panic_print("Fault addr: %p | Exception origin: %s\n", addr, exc_origin);
panic_print_rsn(f, core, rsn);
}

View File

@@ -5,25 +5,10 @@
*/
#include <stdarg.h>
#include "esp_cpu.h"
#include "esp_efuse.h"
#include "esp_fault.h"
#include "esp_flash.h"
#include "esp_flash_encrypt.h"
#include "esp_rom_efuse.h"
#include "hal/efuse_hal.h"
#include "hal/mmu_types.h"
#include "hal/mmu_hal.h"
#include "hal/wdt_hal.h"
#include "hal/sha_hal.h"
#include "hal/spi_flash_hal.h"
#include "hal/spi_flash_types.h"
#include "spi_flash_chip_generic.h"
#include "memspi_host_driver.h"
#include "soc/soc_caps.h"
#include "hal/sha_hal.h"
#include "aes/esp_aes.h"
#include "sha/sha_core.h"
#include "esp_hmac.h"
@@ -33,14 +18,10 @@
#include "esp_tee.h"
#include "esp_tee_memory_utils.h"
#include "esp_tee_intr.h"
#include "esp_tee_aes_intr.h"
#include "esp_tee_rv_utils.h"
#include "esp_tee_flash.h"
#include "esp_tee_sec_storage.h"
#include "esp_tee_ota_ops.h"
#include "esp_attestation.h"
static __attribute__((unused)) const char *TAG = "esp_tee_sec_srv";
@@ -49,123 +30,6 @@ void _ss_invalid_secure_service(void)
assert(0);
}
/* ---------------------------------------------- Interrupts ------------------------------------------------- */
void _ss_esp_rom_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num)
{
return esp_tee_route_intr_matrix(cpu_no, model_num, intr_num);
}
void _ss_rv_utils_intr_enable(uint32_t intr_mask)
{
rv_utils_tee_intr_enable(intr_mask);
}
void _ss_rv_utils_intr_disable(uint32_t intr_mask)
{
rv_utils_tee_intr_disable(intr_mask);
}
void _ss_rv_utils_intr_set_priority(int rv_int_num, int priority)
{
rv_utils_tee_intr_set_priority(rv_int_num, priority);
}
void _ss_rv_utils_intr_set_type(int intr_num, enum intr_type type)
{
rv_utils_tee_intr_set_type(intr_num, type);
}
void _ss_rv_utils_intr_set_threshold(int priority_threshold)
{
rv_utils_tee_intr_set_threshold(priority_threshold);
}
void _ss_rv_utils_intr_edge_ack(uint32_t intr_num)
{
rv_utils_tee_intr_edge_ack(intr_num);
}
void _ss_rv_utils_intr_global_enable(void)
{
rv_utils_tee_intr_global_enable();
}
/* ---------------------------------------------- eFuse ------------------------------------------------- */
uint32_t _ss_efuse_hal_chip_revision(void)
{
return efuse_hal_chip_revision();
}
uint32_t _ss_efuse_hal_get_chip_ver_pkg(void)
{
return efuse_hal_get_chip_ver_pkg();
}
bool _ss_efuse_hal_get_disable_wafer_version_major(void)
{
return efuse_hal_get_disable_wafer_version_major();
}
void _ss_efuse_hal_get_mac(uint8_t *mac)
{
bool valid_addr = ((esp_tee_ptr_in_ree((void *)mac)) &
(esp_tee_ptr_in_ree((void *)(mac + 6))));
if (!valid_addr) {
return;
}
ESP_FAULT_ASSERT(valid_addr);
efuse_hal_get_mac(mac);
}
bool _ss_esp_efuse_check_secure_version(uint32_t secure_version)
{
return esp_efuse_check_secure_version(secure_version);
}
esp_err_t _ss_esp_efuse_read_field_blob(const esp_efuse_desc_t *field[], void *dst, size_t dst_size_bits)
{
if ((field != NULL) && (field[0]->efuse_block >= EFUSE_BLK4)) {
return ESP_ERR_INVALID_ARG;
}
return esp_efuse_read_field_blob(field, dst, dst_size_bits);
}
bool _ss_esp_flash_encryption_enabled(void)
{
uint32_t flash_crypt_cnt = 0;
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
flash_crypt_cnt = efuse_ll_get_flash_crypt_cnt();
#else
esp_efuse_read_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_SPI_BOOT_CRYPT_CNT[0]->bit_count) ;
#endif
/* __builtin_parity is in flash, so we calculate parity inline */
bool enabled = false;
while (flash_crypt_cnt) {
if (flash_crypt_cnt & 1) {
enabled = !enabled;
}
flash_crypt_cnt >>= 1;
}
return enabled;
}
/* ---------------------------------------------- RTC_WDT ------------------------------------------------- */
void _ss_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr)
{
wdt_hal_init(hal, wdt_inst, prescaler, enable_intr);
}
void _ss_wdt_hal_deinit(wdt_hal_context_t *hal)
{
wdt_hal_deinit(hal);
}
/* ---------------------------------------------- AES ------------------------------------------------- */
void _ss_esp_aes_intr_alloc(void)
@@ -502,79 +366,6 @@ esp_err_t _ss_esp_tee_sec_storage_gen_key(uint16_t slot_id, uint8_t key_type)
return esp_tee_sec_storage_gen_key(slot_id, key_type);
}
esp_err_t _ss_esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign)
{
bool valid_addr = ((esp_tee_ptr_in_ree((void *)hash) && esp_tee_ptr_in_ree((void *)out_sign)) &&
(esp_tee_ptr_in_ree((void *)(hash + hlen)) &&
esp_tee_ptr_in_ree((void *)((char *)out_sign + sizeof(esp_tee_sec_storage_sign_t)))));
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
return esp_tee_sec_storage_get_signature(slot_id, key_type, hash, hlen, out_sign);
}
esp_err_t _ss_esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey)
{
bool valid_addr = ((esp_tee_ptr_in_ree((void *)pubkey)) &&
(esp_tee_ptr_in_ree((void *)((char *)pubkey + sizeof(esp_tee_sec_storage_pubkey_t)))));
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
return esp_tee_sec_storage_get_pubkey(slot_id, key_type, pubkey);
}
esp_err_t _ss_esp_tee_sec_storage_encrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
{
bool valid_addr = (esp_tee_ptr_in_ree((void *)input) &&
esp_tee_ptr_in_ree((void *)tag) &&
esp_tee_ptr_in_ree((void *)output));
valid_addr &= (esp_tee_ptr_in_ree((void *)(input + len)) &&
esp_tee_ptr_in_ree((void *)(tag + tag_len)) &&
esp_tee_ptr_in_ree((void *)(output + len)));
if (aad) {
valid_addr &= (esp_tee_ptr_in_ree((void *)aad) && esp_tee_ptr_in_ree((void *)(aad + aad_len)));
}
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
return esp_tee_sec_storage_encrypt(slot_id, input, len, aad, aad_len, tag, tag_len, output);
}
esp_err_t _ss_esp_tee_sec_storage_decrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
{
bool valid_addr = (esp_tee_ptr_in_ree((void *)input) &&
esp_tee_ptr_in_ree((void *)tag) &&
esp_tee_ptr_in_ree((void *)output));
valid_addr &= (esp_tee_ptr_in_ree((void *)(input + len)) &&
esp_tee_ptr_in_ree((void *)(tag + tag_len)) &&
esp_tee_ptr_in_ree((void *)(output + len)));
if (aad) {
valid_addr &= (esp_tee_ptr_in_ree((void *)aad) && esp_tee_ptr_in_ree((void *)(aad + aad_len)));
}
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
return esp_tee_sec_storage_decrypt(slot_id, input, len, aad, aad_len, tag, tag_len, output);
}
bool _ss_esp_tee_sec_storage_is_slot_empty(uint16_t slot_id)
{
return esp_tee_sec_storage_is_slot_empty(slot_id);
@@ -584,197 +375,3 @@ esp_err_t _ss_esp_tee_sec_storage_clear_slot(uint16_t slot_id)
{
return esp_tee_sec_storage_clear_slot(slot_id);
}
/* ---------------------------------------------- MMU HAL ------------------------------------------------- */
void _ss_mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr,
uint32_t paddr, uint32_t len, uint32_t *out_len)
{
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(paddr);
if (vaddr_chk || paddr_chk) {
return;
}
ESP_FAULT_ASSERT(!vaddr_chk && !paddr_chk);
mmu_hal_map_region(mmu_id, mem_type, vaddr, paddr, len, out_len);
}
void _ss_mmu_hal_unmap_region(uint32_t mmu_id, uint32_t vaddr, uint32_t len)
{
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
if (vaddr_chk) {
return;
}
ESP_FAULT_ASSERT(!vaddr_chk);
mmu_hal_unmap_region(mmu_id, vaddr, len);
}
bool _ss_mmu_hal_vaddr_to_paddr(uint32_t mmu_id, uint32_t vaddr, uint32_t *out_paddr, mmu_target_t *out_target)
{
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
if (vaddr_chk) {
return false;
}
ESP_FAULT_ASSERT(!vaddr_chk);
return mmu_hal_vaddr_to_paddr(mmu_id, vaddr, out_paddr, out_target);
}
bool _ss_mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target, mmu_vaddr_t type, uint32_t *out_vaddr)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(paddr);
if (paddr_chk) {
return false;
}
ESP_FAULT_ASSERT(!paddr_chk);
return mmu_hal_paddr_to_vaddr(mmu_id, paddr, target, type, out_vaddr);
}
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
uint32_t _ss_spi_flash_hal_check_status(spi_flash_host_inst_t *host)
{
return spi_flash_hal_check_status(host);
}
esp_err_t _ss_spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans)
{
return spi_flash_hal_common_command(host, trans);
}
esp_err_t _ss_spi_flash_hal_device_config(spi_flash_host_inst_t *host)
{
return spi_flash_hal_device_config(host);
}
void _ss_spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(start_address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, start_address);
return;
}
ESP_FAULT_ASSERT(!paddr_chk);
spi_flash_hal_erase_block(host, start_address);
}
void _ss_spi_flash_hal_erase_chip(spi_flash_host_inst_t *host)
{
spi_flash_hal_erase_chip(host);
}
void _ss_spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(start_address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, start_address);
return;
}
ESP_FAULT_ASSERT(!paddr_chk);
spi_flash_hal_erase_sector(host, start_address);
}
void _ss_spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
return;
}
bool buf_addr_chk = ((esp_tee_ptr_in_ree((void *)buffer) && esp_tee_ptr_in_ree((void *)(buffer + length))));
if (!buf_addr_chk) {
return;
}
ESP_FAULT_ASSERT(!paddr_chk && buf_addr_chk);
spi_flash_hal_program_page(host, buffer, address, length);
}
esp_err_t _ss_spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
return ESP_FAIL;
}
bool buf_addr_chk = ((esp_tee_ptr_in_ree((void *)buffer) && esp_tee_ptr_in_ree((void *)(buffer + read_len))));
if (!buf_addr_chk) {
return ESP_FAIL;
}
ESP_FAULT_ASSERT(!paddr_chk && buf_addr_chk);
return spi_flash_hal_read(host, buffer, address, read_len);
}
void _ss_spi_flash_hal_resume(spi_flash_host_inst_t *host)
{
spi_flash_hal_resume(host);
}
esp_err_t _ss_spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp)
{
return spi_flash_hal_set_write_protect(host, wp);
}
esp_err_t _ss_spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const spi_flash_sus_cmd_conf *sus_conf)
{
return spi_flash_hal_setup_read_suspend(host, sus_conf);
}
bool _ss_spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p)
{
return spi_flash_hal_supports_direct_read(host, p);
}
bool _ss_spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p)
{
return spi_flash_hal_supports_direct_write(host, p);
}
void _ss_spi_flash_hal_suspend(spi_flash_host_inst_t *host)
{
spi_flash_hal_suspend(host);
}
/* ---------------------------------------------- SPI Flash Extras ------------------------------------------------- */
extern uint32_t bootloader_flash_execute_command_common(uint8_t command, uint32_t addr_len, uint32_t address,
uint8_t dummy_len, uint8_t mosi_len, uint32_t mosi_data,
uint8_t miso_len);
uint32_t _ss_bootloader_flash_execute_command_common(
uint8_t command,
uint32_t addr_len, uint32_t address,
uint8_t dummy_len,
uint8_t mosi_len, uint32_t mosi_data,
uint8_t miso_len)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
return ESP_FAIL;
}
ESP_FAULT_ASSERT(!paddr_chk);
return bootloader_flash_execute_command_common(command, addr_len, address, dummy_len,
mosi_len, mosi_data, miso_len);
}
esp_err_t _ss_memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(addr);
if (paddr_chk) {
return ESP_FAIL;
}
ESP_FAULT_ASSERT(!paddr_chk);
return memspi_host_flush_cache(host, addr, size);
}
esp_err_t _ss_spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, uint32_t flags)
{
return spi_flash_chip_generic_config_host_io_mode(chip, flags);
}
#endif

View File

@@ -0,0 +1,353 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdarg.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_fault.h"
#include "hal/mmu_types.h"
#include "hal/mmu_hal.h"
#include "hal/wdt_hal.h"
#include "hal/spi_flash_hal.h"
#include "hal/spi_flash_types.h"
#include "spi_flash_chip_generic.h"
#include "memspi_host_driver.h"
#include "esp_flash.h"
#include "esp_tee.h"
#include "esp_tee_memory_utils.h"
#include "esp_tee_intr.h"
#include "esp_tee_rv_utils.h"
#include "esp_tee_flash.h"
#include "esp_tee_sec_storage.h"
static __attribute__((unused)) const char *TAG = "esp_tee_sec_srv_iram";
/* ---------------------------------------------- Interrupts ------------------------------------------------- */
void _ss_esp_rom_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num)
{
return esp_tee_route_intr_matrix(cpu_no, model_num, intr_num);
}
void _ss_rv_utils_intr_enable(uint32_t intr_mask)
{
rv_utils_tee_intr_enable(intr_mask);
}
void _ss_rv_utils_intr_disable(uint32_t intr_mask)
{
rv_utils_tee_intr_disable(intr_mask);
}
void _ss_rv_utils_intr_set_priority(int rv_int_num, int priority)
{
rv_utils_tee_intr_set_priority(rv_int_num, priority);
}
void _ss_rv_utils_intr_set_type(int intr_num, enum intr_type type)
{
rv_utils_tee_intr_set_type(intr_num, type);
}
void _ss_rv_utils_intr_set_threshold(int priority_threshold)
{
rv_utils_tee_intr_set_threshold(priority_threshold);
}
void _ss_rv_utils_intr_edge_ack(uint32_t intr_num)
{
rv_utils_tee_intr_edge_ack(intr_num);
}
void _ss_rv_utils_intr_global_enable(void)
{
rv_utils_tee_intr_global_enable();
}
/* ---------------------------------------------- RTC_WDT ------------------------------------------------- */
void _ss_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr)
{
wdt_hal_init(hal, wdt_inst, prescaler, enable_intr);
}
void _ss_wdt_hal_deinit(wdt_hal_context_t *hal)
{
wdt_hal_deinit(hal);
}
/* ---------------------------------------------- Secure Storage ------------------------------------------------- */
esp_err_t _ss_esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign)
{
bool valid_addr = ((esp_tee_ptr_in_ree((void *)hash) && esp_tee_ptr_in_ree((void *)out_sign)) &
(esp_tee_ptr_in_ree((void *)(hash + hlen)) &&
esp_tee_ptr_in_ree((void *)((char *)out_sign + sizeof(esp_tee_sec_storage_sign_t)))));
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
return esp_tee_sec_storage_get_signature(slot_id, key_type, hash, hlen, out_sign);
}
esp_err_t _ss_esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey)
{
bool valid_addr = ((esp_tee_ptr_in_ree((void *)pubkey)) &
(esp_tee_ptr_in_ree((void *)((char *)pubkey + sizeof(esp_tee_sec_storage_pubkey_t)))));
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
return esp_tee_sec_storage_get_pubkey(slot_id, key_type, pubkey);
}
esp_err_t _ss_esp_tee_sec_storage_encrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
{
bool valid_addr = (esp_tee_ptr_in_ree((void *)input) &&
esp_tee_ptr_in_ree((void *)tag) &&
esp_tee_ptr_in_ree((void *)output));
valid_addr &= (esp_tee_ptr_in_ree((void *)(input + len)) &&
esp_tee_ptr_in_ree((void *)(tag + tag_len)) &&
esp_tee_ptr_in_ree((void *)(output + len)));
if (aad) {
valid_addr &= (esp_tee_ptr_in_ree((void *)aad) && esp_tee_ptr_in_ree((void *)(aad + aad_len)));
}
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
return esp_tee_sec_storage_encrypt(slot_id, input, len, aad, aad_len, tag, tag_len, output);
}
esp_err_t _ss_esp_tee_sec_storage_decrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
{
bool valid_addr = (esp_tee_ptr_in_ree((void *)input) &&
esp_tee_ptr_in_ree((void *)tag) &&
esp_tee_ptr_in_ree((void *)output));
valid_addr &= (esp_tee_ptr_in_ree((void *)(input + len)) &&
esp_tee_ptr_in_ree((void *)(tag + tag_len)) &&
esp_tee_ptr_in_ree((void *)(output + len)));
if (aad) {
valid_addr &= (esp_tee_ptr_in_ree((void *)aad) && esp_tee_ptr_in_ree((void *)(aad + aad_len)));
}
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
return esp_tee_sec_storage_decrypt(slot_id, input, len, aad, aad_len, tag, tag_len, output);
}
/* ---------------------------------------------- MMU HAL ------------------------------------------------- */
void _ss_mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr,
uint32_t paddr, uint32_t len, uint32_t *out_len)
{
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(paddr);
if (vaddr_chk || paddr_chk) {
return;
}
ESP_FAULT_ASSERT(!vaddr_chk && !paddr_chk);
mmu_hal_map_region(mmu_id, mem_type, vaddr, paddr, len, out_len);
}
void _ss_mmu_hal_unmap_region(uint32_t mmu_id, uint32_t vaddr, uint32_t len)
{
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
if (vaddr_chk) {
return;
}
ESP_FAULT_ASSERT(!vaddr_chk);
mmu_hal_unmap_region(mmu_id, vaddr, len);
}
bool _ss_mmu_hal_vaddr_to_paddr(uint32_t mmu_id, uint32_t vaddr, uint32_t *out_paddr, mmu_target_t *out_target)
{
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
if (vaddr_chk) {
return false;
}
ESP_FAULT_ASSERT(!vaddr_chk);
return mmu_hal_vaddr_to_paddr(mmu_id, vaddr, out_paddr, out_target);
}
bool _ss_mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target, mmu_vaddr_t type, uint32_t *out_vaddr)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(paddr);
if (paddr_chk) {
return false;
}
ESP_FAULT_ASSERT(!paddr_chk);
return mmu_hal_paddr_to_vaddr(mmu_id, paddr, target, type, out_vaddr);
}
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
uint32_t _ss_spi_flash_hal_check_status(spi_flash_host_inst_t *host)
{
return spi_flash_hal_check_status(host);
}
esp_err_t _ss_spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans)
{
return spi_flash_hal_common_command(host, trans);
}
esp_err_t _ss_spi_flash_hal_device_config(spi_flash_host_inst_t *host)
{
return spi_flash_hal_device_config(host);
}
void _ss_spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(start_address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, start_address);
return;
}
ESP_FAULT_ASSERT(!paddr_chk);
spi_flash_hal_erase_block(host, start_address);
}
void _ss_spi_flash_hal_erase_chip(spi_flash_host_inst_t *host)
{
spi_flash_hal_erase_chip(host);
}
void _ss_spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(start_address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, start_address);
return;
}
ESP_FAULT_ASSERT(!paddr_chk);
spi_flash_hal_erase_sector(host, start_address);
}
void _ss_spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
return;
}
bool buf_addr_chk = ((esp_tee_ptr_in_ree((void *)buffer) && esp_tee_ptr_in_ree((void *)(buffer + length))));
if (!buf_addr_chk) {
return;
}
ESP_FAULT_ASSERT(!paddr_chk && buf_addr_chk);
spi_flash_hal_program_page(host, buffer, address, length);
}
esp_err_t _ss_spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
return ESP_FAIL;
}
bool buf_addr_chk = ((esp_tee_ptr_in_ree((void *)buffer) && esp_tee_ptr_in_ree((void *)(buffer + read_len))));
if (!buf_addr_chk) {
return ESP_FAIL;
}
ESP_FAULT_ASSERT(!paddr_chk && buf_addr_chk);
return spi_flash_hal_read(host, buffer, address, read_len);
}
void _ss_spi_flash_hal_resume(spi_flash_host_inst_t *host)
{
spi_flash_hal_resume(host);
}
esp_err_t _ss_spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp)
{
return spi_flash_hal_set_write_protect(host, wp);
}
esp_err_t _ss_spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const spi_flash_sus_cmd_conf *sus_conf)
{
return spi_flash_hal_setup_read_suspend(host, sus_conf);
}
bool _ss_spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p)
{
return spi_flash_hal_supports_direct_read(host, p);
}
bool _ss_spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p)
{
return spi_flash_hal_supports_direct_write(host, p);
}
void _ss_spi_flash_hal_suspend(spi_flash_host_inst_t *host)
{
spi_flash_hal_suspend(host);
}
/* ---------------------------------------------- SPI Flash Extras ------------------------------------------------- */
extern uint32_t bootloader_flash_execute_command_common(uint8_t command, uint32_t addr_len, uint32_t address,
uint8_t dummy_len, uint8_t mosi_len, uint32_t mosi_data,
uint8_t miso_len);
uint32_t _ss_bootloader_flash_execute_command_common(
uint8_t command,
uint32_t addr_len, uint32_t address,
uint8_t dummy_len,
uint8_t mosi_len, uint32_t mosi_data,
uint8_t miso_len)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(address);
if (paddr_chk) {
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
return ESP_FAIL;
}
ESP_FAULT_ASSERT(!paddr_chk);
return bootloader_flash_execute_command_common(command, addr_len, address, dummy_len,
mosi_len, mosi_data, miso_len);
}
esp_err_t _ss_memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size)
{
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(addr);
if (paddr_chk) {
return ESP_FAIL;
}
ESP_FAULT_ASSERT(!paddr_chk);
return memspi_host_flush_cache(host, addr, size);
}
esp_err_t _ss_spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, uint32_t flags)
{
return spi_flash_chip_generic_config_host_io_mode(chip, flags);
}
#endif

View File

@@ -106,7 +106,7 @@ SECTIONS
*libtee_flash_mgr.a:*(.rodata .srodata .rodata.* .srodata.*)
*libbootloader_support.a:bootloader_flash.*(.rodata .srodata .rodata.* .srodata.*)
/* Secure services */
*libmain.a:esp_secure_services.c.*(.rodata .srodata .rodata.* .srodata.*)
*libmain.a:esp_secure_services_iram.c.*(.rodata .srodata .rodata.* .srodata.*)
*libmain.a:esp_secure_dispatcher.c.*(.rodata .srodata .rodata.* .srodata.*)
/* Panic handler */
*libmain.a:panic_helper_riscv.*(.rodata .srodata .rodata.* .srodata.*)
@@ -120,7 +120,7 @@ SECTIONS
.dram.tee.heap :
{
. = ALIGN (8);
. = ALIGN (16);
_tee_heap_start = ABSOLUTE(.);
. = ORIGIN(dram_tee_seg) + LENGTH(dram_tee_seg);
_tee_heap_end = ABSOLUTE(.);
@@ -128,19 +128,17 @@ SECTIONS
.dram.tee.stack :
{
. = ALIGN (8);
. = ALIGN (16);
_tee_stack_bottom = ABSOLUTE(.);
. = ORIGIN(stack_tee_seg) + LENGTH(stack_tee_seg);
. = ALIGN (8);
_tee_stack = ABSOLUTE(.);
} > stack_tee_seg
.dram.tee.intr_stack :
{
. = ALIGN (8);
. = ALIGN (16);
_tee_intr_stack_bottom = ABSOLUTE(.);
. = ORIGIN(intr_stack_tee_seg) + LENGTH(intr_stack_tee_seg);
. = ALIGN (8);
_tee_intr_stack = ABSOLUTE(.);
} > intr_stack_tee_seg
@@ -172,7 +170,7 @@ SECTIONS
* | MMU | text+rodata | SRAM |
* | CACHE | text+rodata | SRAM |
* | WDT | text | SRAM |
* | APM | text | Flash |
* | APM | text | Flash* |
* | AES | text | Flash |
* | SHA | text | Flash |
* | HMAC | text | Flash |
@@ -192,13 +190,19 @@ SECTIONS
.flash.text :
{
_tee_xip_text_start = ABSOLUTE(.);
/* Secure Services */
*libmain.a:esp_secure_services.c*(.literal .text .literal.* .text.*)
/* HAL */
*libhal.a:aes_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:sha_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:hmac_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:ds_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:ecc_hal.c*(.literal .text .literal.* .text.*)
/* NOTE: There is a possibility of APM violations (SPI1 flash protection)
* being triggered with the flash cache disabled */
#if !CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
#endif
*libhal.a:brownout_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:spi_flash_hal.c*(.literal .text .literal.* .text.*)
/* These HAL modules have functions marked with the IRAM_ATTR attribute which get placed in the SRAM */
@@ -220,7 +224,6 @@ SECTIONS
.iram.tee.text :
{
. = ALIGN(4);
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_tee_vec_start = ABSOLUTE(.);

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,69 +12,39 @@
#include "esp_tee.h"
#include "esp_tee_apm_intr.h"
static const char *const excp_mid_strs[] = {
[APM_LL_MASTER_HPCORE] = "HPCORE",
[APM_LL_MASTER_LPCORE] = "LPCORE",
[APM_LL_MASTER_REGDMA] = "REGDMA",
[APM_LL_MASTER_SDIOSLV] = "SDIOSLV",
[APM_LL_MASTER_MODEM] = "MODEM",
[APM_LL_MASTER_MEM_MONITOR] = "MEM_MONITOR",
[APM_LL_MASTER_TRACE] = "TRACE",
[APM_LL_MASTER_GDMA_SPI2] = "GDMA_SPI2",
[APM_LL_MASTER_GDMA_UHCI0] = "GDMA_UHCI0",
[APM_LL_MASTER_GDMA_I2S0] = "GDMA_I2S0",
[APM_LL_MASTER_GDMA_AES] = "GDMA_AES",
[APM_LL_MASTER_GDMA_SHA] = "GDMA_SHA",
[APM_LL_MASTER_GDMA_ADC] = "GDMA_ADC",
[APM_LL_MASTER_GDMA_PARLIO] = "GDMA_PARLIO",
};
const char *esp_tee_apm_excp_mid_to_str(uint8_t mid)
{
char *excp_mid = NULL;
switch (mid) {
case APM_LL_MASTER_HPCORE:
excp_mid = "HPCORE";
break;
case APM_LL_MASTER_LPCORE:
excp_mid = "LPCORE";
break;
case APM_LL_MASTER_REGDMA:
excp_mid = "REGDMA";
break;
case APM_LL_MASTER_SDIOSLV:
excp_mid = "SDIOSLV";
break;
case APM_LL_MASTER_MODEM:
excp_mid = "MODEM";
break;
case APM_LL_MASTER_MEM_MONITOR:
excp_mid = "MEM_MONITOR";
break;
case APM_LL_MASTER_TRACE:
excp_mid = "TRACE";
break;
case APM_LL_MASTER_GDMA_SPI2:
excp_mid = "GDMA_SPI2";
break;
case APM_LL_MASTER_GDMA_UHCI0:
excp_mid = "GDMA_UHCI0";
break;
case APM_LL_MASTER_GDMA_I2S0:
excp_mid = "GDMA_I2S0";
break;
case APM_LL_MASTER_GDMA_AES:
excp_mid = "GDMA_AES";
break;
case APM_LL_MASTER_GDMA_SHA:
excp_mid = "GDMA_SHA";
break;
case APM_LL_MASTER_GDMA_ADC:
excp_mid = "GDMA_ADC";
break;
case APM_LL_MASTER_GDMA_PARLIO:
excp_mid = "GDMA_PARLIO";
break;
default:
excp_mid = "Unknown";
break;
if (mid < sizeof(excp_mid_strs) / sizeof(excp_mid_strs[0]) && excp_mid_strs[mid]) {
return excp_mid_strs[mid];
}
return excp_mid;
return "Unknown";
}
const char *esp_tee_apm_excp_type_to_str(uint8_t type)
{
char *excp_type = "Unknown exception";
char *excp_type = "APM - Unknown exception";
if (type & 0x01) {
excp_type = "Authority exception";
excp_type = "APM - Authority exception";
} else if (type & 0x02) {
excp_type = "Space exception";
excp_type = "APM - Space exception";
}
return excp_type;

View File

@@ -1,6 +1,11 @@
idf_component_register(SRCS "tee_srv_att.c"
"tee_srv_ota.c"
"tee_srv_sec_str.c"
"tee_cmd_wifi.c"
"app_main.c"
set(srcs "tee_srv_ota.c"
"tee_srv_sec_str.c"
"tee_cmd_wifi.c"
"app_main.c")
if(CONFIG_SECURE_TEE_ATTESTATION)
list(APPEND srcs "tee_srv_att.c")
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ".")

View File

@@ -41,7 +41,9 @@ static void setup_console(void)
register_cmd_wifi();
register_srv_tee_ota();
register_srv_user_ota();
#if CONFIG_SECURE_TEE_ATTESTATION
register_srv_attestation();
#endif
register_cmd_msg_sha256();
register_srv_sec_stg_gen_key();
register_srv_sec_stg_sign();

View File

@@ -0,0 +1,18 @@
# Minimal TEE configuration
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y
CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK=9
# Reducing TEE DRAM and STACK sizes
# 21KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x5400
# 2.5KB
CONFIG_SECURE_TEE_STACK_SIZE=0xa00
# Disabling ATTESTATION
CONFIG_SECURE_TEE_ATTESTATION=n
# Disabling flash protection over SPI1
CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1=n
# Disabling support for SECP192R1 signature
CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN=n

View File

@@ -1,6 +1,5 @@
# Enabling TEE
CONFIG_SECURE_ENABLE_TEE=y
CONFIG_SECURE_TEE_IRAM_SIZE=0x9000
# Enabling flash protection over SPI1
CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1=y

View File

@@ -94,7 +94,7 @@ def test_esp_tee_apm_violation(dut: IdfDut) -> None:
dut.expect_exact('Press ENTER to see the list of tests')
dut.write(f'"Test APM violation interrupt: {check}"')
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
if exc != 'Authority exception':
if exc != 'APM - Authority exception':
raise RuntimeError('Incorrect exception received!')
@@ -141,7 +141,7 @@ def test_esp_tee_isolation_checks(dut: IdfDut) -> None:
actual_exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
if actual_exc != expected_exc:
raise RuntimeError('Incorrect exception received!')
dut.expect('Exception origin: U-mode')
dut.expect('Origin: U-mode')
# ---------------- TEE Flash Protection Tests ----------------
@@ -155,47 +155,45 @@ class TeeFlashAccessApi(Enum):
ESP_ROM_SPIFLASH = 5
def check_panic_or_reset(dut: IdfDut) -> None:
try:
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=5).group(2).decode()
if exc not in {'Cache error', 'Authority exception'}:
raise RuntimeError('Flash operation incorrect exception')
except Exception:
rst_rsn = dut.expect(r'rst:(0x[0-9A-Fa-f]+) \(([^)]+)\)', timeout=5).group(2).decode()
# Fault assert check produces this reset reason
if rst_rsn != 'LP_SW_HPSYS':
raise RuntimeError('Flash operation incorrect reset reason')
def expect_panic_rsn(dut: IdfDut, expected_rsn: str) -> None:
actual_rsn = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=10).group(2).decode()
if actual_rsn != expected_rsn:
raise RuntimeError(f'Incorrect exception: {actual_rsn} (expected: {expected_rsn})')
def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFlashAccessApi) -> None:
exp_seq = {
expected_ops = {
TeeFlashAccessApi.ESP_PARTITION: ['read', 'program_page', 'program_page', 'erase_sector'],
TeeFlashAccessApi.ESP_FLASH: ['program_page', 'read', 'erase_sector', 'program_page'],
}
flash_enc_enabled = dut.app.sdkconfig.get('SECURE_FLASH_ENC_ENABLED', True)
for stage in range(1, stages + 1):
dut.write(str(test_case_num))
dut.expect(r'\s+\((\d+)\)\s+"([^"]+)"\r?\n', timeout=30)
dut.write(str(stage))
if 1 < stage <= stages:
if api in exp_seq:
try:
match = dut.expect(
r'\[_ss_spi_flash_hal_(\w+)\] Illegal flash access at \s*(0x[0-9a-fA-F]+)', timeout=5
)
fault_api = match.group(1).decode()
if fault_api != exp_seq[api][stage - 2]:
raise RuntimeError('Flash operation address check failed')
except Exception:
if stage > 1:
if api in {TeeFlashAccessApi.ESP_PARTITION_MMAP, TeeFlashAccessApi.SPI_FLASH_MMAP}:
expect_panic_rsn(dut, 'Cache error')
elif api in {TeeFlashAccessApi.ESP_PARTITION, TeeFlashAccessApi.ESP_FLASH}:
op_index = stage - 2
curr_op = expected_ops[api][op_index]
if api == TeeFlashAccessApi.ESP_PARTITION and curr_op == 'read' and flash_enc_enabled:
# NOTE: The esp_partition_read API handles both decrypted
# and plaintext reads. When flash encryption is enabled,
# it uses the MMU HAL instead of the SPI flash HAL.
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=5).group(2).decode()
if exc != 'Cache error':
raise RuntimeError('Flash operation incorrect exception')
else:
check_panic_or_reset(dut)
expect_panic_rsn(dut, 'Cache error')
else:
match = dut.expect(
r'\[_ss_spi_flash_hal_(\w+)\] Illegal flash access at \s*(0x[0-9a-fA-F]+)', timeout=10
)
actual_op = match.group(1).decode()
if actual_op != curr_op:
raise RuntimeError(f'Unexpected flash operation: {actual_op} (expected: {curr_op})')
elif api == TeeFlashAccessApi.ESP_ROM_SPIFLASH:
expect_panic_rsn(dut, 'APM - Authority exception')
if stage != stages:
dut.expect_exact('Press ENTER to see the list of tests.')

View File

@@ -13,4 +13,4 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
# TEE IRAM size
CONFIG_SECURE_TEE_IRAM_SIZE=0x9000
CONFIG_SECURE_TEE_IRAM_SIZE=0x8400