Merge branch 'feat/esp_tee_misc_optim' into 'master'

feat(esp_tee): Restrict REE access to TEE-owned secure storage keys

Closes IDF-15938 and IDFGH-17659

See merge request espressif/esp-idf!50307
This commit is contained in:
Laukik Hase
2026-07-16 14:00:51 +05:30
18 changed files with 183 additions and 50 deletions
@@ -6,6 +6,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "rom_patch_tlsf.h"
#include "esp_rom_sys.h"
#include "tlsf_block_functions.h"
@@ -63,6 +64,9 @@ esp_err_t esp_tee_heap_init(void *start_ptr, size_t size)
return ESP_ERR_INVALID_SIZE;
}
/* Zeroize the entire region before registering it as the TEE heap*/
memset(start_ptr, 0, size);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
void *heap = tlsf_create_with_pool(start_ptr + sizeof(heap_t), usable_size);
size_t overhead = tlsf_size();
@@ -227,7 +231,7 @@ void esp_tee_heap_dump_info(void)
/* Definitions for functions from the heap component, used in files shared with ESP-IDF */
void *heap_caps_malloc(size_t alignment, size_t size, uint32_t caps)
void *heap_caps_malloc(size_t size, uint32_t caps)
{
(void) caps;
return esp_tee_heap_malloc(size);
@@ -592,17 +592,24 @@ int _ss_esp_tee_ota_end(void)
*/
esp_err_t _ss_esp_tee_sec_storage_clear_key(const char *key_id)
{
bool valid_arg = !esp_tee_sec_storage_is_key_tee_owned(key_id);
if (!valid_arg) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_arg);
return esp_tee_sec_storage_clear_key(key_id);
}
esp_err_t _ss_esp_tee_sec_storage_gen_key(const esp_tee_sec_storage_key_cfg_t *cfg)
{
bool valid_addr = esp_tee_buf_in_ree(cfg, sizeof(esp_tee_sec_storage_key_cfg_t));
if (!valid_addr) {
bool valid_arg = esp_tee_buf_in_ree(cfg, sizeof(esp_tee_sec_storage_key_cfg_t)) &&
!(cfg->flags & SEC_STORAGE_FLAG_TEE_ONLY) &&
!esp_tee_sec_storage_is_key_tee_owned(cfg->id);
if (!valid_arg) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
ESP_FAULT_ASSERT(valid_arg);
return esp_tee_sec_storage_gen_key(cfg);
}
@@ -192,67 +192,69 @@ void _ss_wdt_hal_deinit(wdt_hal_context_t *hal)
*/
esp_err_t _ss_esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cfg, const uint8_t *hash, size_t hlen, esp_tee_sec_storage_ecdsa_sign_t *out_sign)
{
bool valid_addr = (esp_tee_buf_in_ree(cfg, sizeof(esp_tee_sec_storage_key_cfg_t)) &&
esp_tee_buf_in_ree(hash, hlen) &&
esp_tee_buf_in_ree(out_sign, sizeof(esp_tee_sec_storage_ecdsa_sign_t)));
if (!valid_addr) {
bool valid_arg = (esp_tee_buf_in_ree(cfg, sizeof(esp_tee_sec_storage_key_cfg_t)) &&
esp_tee_buf_in_ree(hash, hlen) &&
esp_tee_buf_in_ree(out_sign, sizeof(esp_tee_sec_storage_ecdsa_sign_t)) &&
!esp_tee_sec_storage_is_key_tee_owned(cfg->id));
if (!valid_arg) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
ESP_FAULT_ASSERT(valid_arg);
return esp_tee_sec_storage_ecdsa_sign(cfg, hash, hlen, out_sign);
}
esp_err_t _ss_esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg_t *cfg, esp_tee_sec_storage_ecdsa_pubkey_t *out_pubkey)
{
bool valid_addr = (esp_tee_buf_in_ree(cfg, sizeof(esp_tee_sec_storage_key_cfg_t)) &&
esp_tee_buf_in_ree(out_pubkey, sizeof(esp_tee_sec_storage_ecdsa_pubkey_t)));
if (!valid_addr) {
bool valid_arg = (esp_tee_buf_in_ree(cfg, sizeof(esp_tee_sec_storage_key_cfg_t)) &&
esp_tee_buf_in_ree(out_pubkey, sizeof(esp_tee_sec_storage_ecdsa_pubkey_t)) &&
!esp_tee_sec_storage_is_key_tee_owned(cfg->id));
if (!valid_arg) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
ESP_FAULT_ASSERT(valid_arg);
return esp_tee_sec_storage_ecdsa_get_pubkey(cfg, out_pubkey);
}
esp_err_t _ss_esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *iv, size_t iv_len, uint8_t *tag, size_t tag_len, uint8_t *output)
{
bool valid_addr = (esp_tee_buf_in_ree(ctx, sizeof(esp_tee_sec_storage_aead_ctx_t)) &&
esp_tee_buf_in_ree(ctx->input, ctx->input_len) &&
esp_tee_buf_in_ree(iv, iv_len) &&
esp_tee_buf_in_ree(tag, tag_len) &&
esp_tee_buf_in_ree(output, ctx->input_len));
bool valid_arg = (esp_tee_buf_in_ree(ctx, sizeof(esp_tee_sec_storage_aead_ctx_t)) &&
esp_tee_buf_in_ree(ctx->input, ctx->input_len) &&
esp_tee_buf_in_ree(iv, iv_len) &&
esp_tee_buf_in_ree(tag, tag_len) &&
esp_tee_buf_in_ree(output, ctx->input_len) &&
!esp_tee_sec_storage_is_key_tee_owned(ctx->key_id));
if (ctx->aad_len != 0) {
valid_addr &= esp_tee_buf_in_ree(ctx->aad, ctx->aad_len);
valid_arg &= esp_tee_buf_in_ree(ctx->aad, ctx->aad_len);
}
if (!valid_addr) {
if (!valid_arg) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
ESP_FAULT_ASSERT(valid_arg);
return esp_tee_sec_storage_aead_encrypt(ctx, iv, iv_len, tag, tag_len, output);
}
esp_err_t _ss_esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *iv, size_t iv_len, const uint8_t *tag, size_t tag_len, uint8_t *output)
{
bool valid_addr = (esp_tee_buf_in_ree(ctx, sizeof(esp_tee_sec_storage_aead_ctx_t)) &&
esp_tee_buf_in_ree(ctx->input, ctx->input_len) &&
esp_tee_buf_in_ree(iv, iv_len) &&
esp_tee_buf_in_ree(tag, tag_len) &&
esp_tee_buf_in_ree(output, ctx->input_len));
bool valid_arg = (esp_tee_buf_in_ree(ctx, sizeof(esp_tee_sec_storage_aead_ctx_t)) &&
esp_tee_buf_in_ree(ctx->input, ctx->input_len) &&
esp_tee_buf_in_ree(iv, iv_len) &&
esp_tee_buf_in_ree(tag, tag_len) &&
esp_tee_buf_in_ree(output, ctx->input_len) &&
!esp_tee_sec_storage_is_key_tee_owned(ctx->key_id));
if (ctx->aad_len != 0) {
valid_addr &= esp_tee_buf_in_ree(ctx->aad, ctx->aad_len);
valid_arg &= esp_tee_buf_in_ree(ctx->aad, ctx->aad_len);
}
if (!valid_addr) {
if (!valid_arg) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
ESP_FAULT_ASSERT(valid_arg);
return esp_tee_sec_storage_aead_decrypt(ctx, iv, iv_len, tag, tag_len, output);
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -26,6 +26,9 @@
/* TEE symbols */
extern uint32_t _tee_stack;
extern uint32_t _tee_stack_bottom;
extern uint32_t _tee_intr_stack;
extern uint32_t _tee_intr_stack_bottom;
extern uint32_t _tee_bss_start;
extern uint32_t _tee_bss_end;
extern uint32_t _tee_s_intr_handler;
@@ -119,6 +122,9 @@ void __attribute__((noreturn)) esp_tee_init(uint32_t ree_entry_addr, uint32_t re
{
/* Clear BSS */
memset(&_tee_bss_start, 0, (&_tee_bss_end - &_tee_bss_start) * sizeof(_tee_bss_start));
/* Clear the TEE stack and interrupt stack */
memset(&_tee_stack_bottom, 0, (&_tee_stack - &_tee_stack_bottom) * sizeof(_tee_stack_bottom));
memset(&_tee_intr_stack_bottom, 0, (&_tee_intr_stack - &_tee_intr_stack_bottom) * sizeof(_tee_intr_stack_bottom));
static uint32_t btld_sp;