-
Notifications
You must be signed in to change notification settings - Fork 7.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(esp_tee): Support for ESP-TEE - the
main
component
- Loading branch information
1 parent
420810e
commit 3739306
Showing
111 changed files
with
12,291 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
idf_build_get_property(esp_tee_build ESP_TEE_BUILD) | ||
idf_build_get_property(custom_secure_service_tbl CUSTOM_SECURE_SERVICE_TBL) | ||
idf_build_get_property(custom_secure_service_dir CUSTOM_SECURE_SERVICE_COMPONENT_DIR) | ||
idf_build_get_property(custom_secure_service_component CUSTOM_SECURE_SERVICE_COMPONENT) | ||
idf_build_get_property(target IDF_TARGET) | ||
# headers & sources here are compiled into the app, not the esp_tee binary | ||
# (see subproject/ for the esp_tee binary build files) | ||
|
||
# ESP-TEE is currently supported only on the ESP32-C6 SoC | ||
if(NOT ${target} STREQUAL "esp32c6") | ||
return() | ||
endif() | ||
|
||
if(BOOTLOADER_BUILD) | ||
idf_component_register() | ||
return() | ||
elseif(esp_tee_build) | ||
# TEE build currently only uses the shared headers. | ||
idf_component_register(INCLUDE_DIRS include) | ||
else() | ||
if(CONFIG_SECURE_ENABLE_TEE) | ||
if(NOT CMAKE_BUILD_EARLY_EXPANSION) | ||
# Add custom flash target for TEE binary | ||
partition_table_get_partition_info(partition "--partition-type app --partition-subtype tee_0" "name") | ||
if(NOT partition) | ||
message(FATAL_ERROR "Partition table missing TEE partition entry!") | ||
endif() | ||
add_dependencies(esp_tee partition_table_bin) | ||
add_dependencies(flash esp_tee) | ||
set(image_file ${TEE_BUILD_DIR}/esp_tee.bin) | ||
partition_table_get_partition_info(offset "--partition-name ${partition}" "offset") | ||
esptool_py_flash_target_image(flash "${partition}" "${offset}" "${image_file}") | ||
endif() | ||
|
||
partition_table_get_partition_info(tee_otadata_offset | ||
"--partition-type data --partition-subtype tee_ota" "offset") | ||
partition_table_get_partition_info(tee_otadata_size | ||
"--partition-type data --partition-subtype tee_ota" "size") | ||
|
||
# Add custom target for generating empty otadata partition for flashing | ||
if(tee_otadata_offset AND tee_otadata_size) | ||
idf_build_get_property(build_dir BUILD_DIR) | ||
set(blank_tee_otadata_file ${build_dir}/tee_ota_data_initial.bin) | ||
|
||
idf_build_get_property(python PYTHON) | ||
idf_component_get_property(partition_table_dir partition_table COMPONENT_DIR) | ||
add_custom_command(OUTPUT ${blank_tee_otadata_file} | ||
COMMAND ${python} ${partition_table_dir}/gen_empty_partition.py | ||
${tee_otadata_size} ${blank_tee_otadata_file}) | ||
add_custom_target(blank_tee_ota_data ALL DEPENDS ${blank_tee_otadata_file}) | ||
|
||
add_dependencies(flash blank_tee_ota_data) | ||
add_dependencies(encrypted-flash blank_tee_ota_data) | ||
|
||
partition_table_get_partition_info(tee_otadata_part | ||
"--partition-type data --partition-subtype tee_ota" "name") | ||
|
||
idf_component_get_property(main_args esptool_py FLASH_ARGS) | ||
idf_component_get_property(sub_args esptool_py FLASH_SUB_ARGS) | ||
esptool_py_flash_target(tee_otadata-flash "${main_args}" "${sub_args}") | ||
|
||
esptool_py_flash_target_image(tee_otadata-flash | ||
"${tee_otadata_part}" "${tee_otadata_offset}" "${blank_tee_otadata_file}") | ||
esptool_py_flash_target_image(flash | ||
"${tee_otadata_part}" "${tee_otadata_offset}" "${blank_tee_otadata_file}") | ||
endif() | ||
|
||
set(srcs "src/esp_tee.c" | ||
"src/esp_tee_config.c" | ||
"src/esp_secure_service_wrapper.c" | ||
"src/esp_tee_u2m_switch.S") | ||
endif() | ||
|
||
idf_component_register(INCLUDE_DIRS include | ||
SRCS ${srcs} | ||
PRIV_REQUIRES efuse esp_system spi_flash) | ||
|
||
if(CONFIG_SECURE_ENABLE_TEE) | ||
set(EXTRA_LINK_FLAGS) | ||
list(APPEND EXTRA_LINK_FLAGS "-u esp_tee_app_config") | ||
target_link_libraries(${COMPONENT_LIB} INTERFACE "${EXTRA_LINK_FLAGS}") | ||
endif() | ||
endif() | ||
|
||
set(secure_service_hdr_py | ||
${COMPONENT_DIR}/scripts/secure_service_hdr.py ${CMAKE_CURRENT_BINARY_DIR}/secure_service.tbl | ||
) | ||
|
||
set(secure_service_tbl_py | ||
${COMPONENT_DIR}/scripts/secure_service_tbl.py ${CMAKE_CURRENT_BINARY_DIR}/secure_service.tbl | ||
) | ||
|
||
set(secure_service_wrap_py | ||
${COMPONENT_DIR}/scripts/secure_service_wrap.py ${CMAKE_CURRENT_BINARY_DIR}/secure_service.tbl | ||
) | ||
|
||
set(secure_service_num_h | ||
${CONFIG_DIR}/secure_service_num.h | ||
) | ||
set(secure_service_dec_h | ||
${CONFIG_DIR}/secure_service_dec.h) | ||
|
||
set(secure_service_h | ||
${CONFIG_DIR}/secure_service.h | ||
) | ||
|
||
if(CONFIG_SECURE_ENABLE_TEE) | ||
execute_process(COMMAND cat ${COMPONENT_DIR}/scripts/${target}/secure_service.tbl ${custom_secure_service_tbl} | ||
OUTPUT_FILE secure_service.tbl | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
) | ||
|
||
execute_process(COMMAND python ${secure_service_hdr_py} ${secure_service_num_h} ${secure_service_dec_h} | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
) | ||
|
||
execute_process(COMMAND python ${secure_service_tbl_py} ${secure_service_h} | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
) | ||
|
||
set_property(DIRECTORY "${COMPONENT_DIR}" APPEND PROPERTY | ||
ADDITIONAL_MAKE_CLEAN_FILES ${secure_service_num_h} ${secure_service_dec_h} ${secure_service_h}) | ||
|
||
# For TEE implementation, we don't wrap the APIs since the TEE would also internally use the same API and | ||
# it shouldn't route to secure service API. | ||
# Instead of wrapping, we append _ss_* to the API name and then it must be defined in esp_secure_services.c | ||
if(NOT esp_tee_build) | ||
execute_process(COMMAND python ${secure_service_wrap_py} | ||
OUTPUT_VARIABLE wrap_list | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
OUTPUT_STRIP_TRAILING_WHITESPACE | ||
) | ||
|
||
string(STRIP ${wrap_list} wrap_list) | ||
|
||
target_link_libraries(${COMPONENT_LIB} INTERFACE "${wrap_list}") | ||
endif() | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
menu "ESP-TEE (Trusted Execution Environment)" | ||
depends on IDF_TARGET_ESP32C6 | ||
|
||
config SECURE_ENABLE_TEE | ||
bool "Enable the ESP-TEE framework" | ||
depends on IDF_TARGET_ESP32C6 | ||
select ESP_SYSTEM_MEMPROT_FEATURE_VIA_TEE | ||
help | ||
This configuration enables the Trusted Execution Environment (TEE) feature. | ||
|
||
menu "Memory Configuration" | ||
depends on SECURE_ENABLE_TEE | ||
|
||
config SECURE_TEE_IRAM_SIZE | ||
hex "IRAM region size" | ||
default 0x8000 | ||
range 0x8000 0x10000 | ||
help | ||
This configuration sets the IRAM size for the TEE module. | ||
This should be a multiple of 0x1000. | ||
|
||
config SECURE_TEE_DRAM_SIZE | ||
hex "DRAM region size" | ||
default 0x8000 | ||
range 0x8000 0x10000 | ||
help | ||
This configuration sets the DRAM size for the TEE module. | ||
This should be a multiple of 0x1000. | ||
|
||
config SECURE_TEE_STACK_SIZE | ||
hex "Stack size" | ||
default 0xc00 | ||
range 0x800 0x1000 | ||
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. | ||
|
||
config SECURE_TEE_INTR_STACK_SIZE | ||
hex "Interrupt Stack size" | ||
default 0x400 | ||
range 0x400 0x800 | ||
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. | ||
|
||
config SECURE_TEE_IROM_SIZE | ||
hex | ||
default 0x10000 | ||
help | ||
This should be a multiple of MMU_PAGE_SIZE. | ||
|
||
config SECURE_TEE_DROM_SIZE | ||
hex | ||
default 0x10000 | ||
help | ||
This should be a multiple of MMU_PAGE_SIZE. | ||
|
||
endmenu | ||
|
||
choice SECURE_TEE_SEC_STG_MODE | ||
prompt "Secure Storage: Mode" | ||
depends on SECURE_ENABLE_TEE | ||
default SECURE_TEE_SEC_STG_MODE_DEVELOPMENT | ||
help | ||
Select the TEE secure storage mode | ||
|
||
config SECURE_TEE_SEC_STG_MODE_DEVELOPMENT | ||
bool "Development" | ||
help | ||
Secure storage will be encrypted by the data stored in eFuse BLK2 | ||
|
||
config SECURE_TEE_SEC_STG_MODE_RELEASE | ||
depends on IDF_TARGET_ESP32C6 | ||
bool "Release" | ||
help | ||
Secure storage will be encrypted by the data stored in eFuse block | ||
configured through the SECURE_TEE_SEC_STG_KEY_EFUSE_BLK option | ||
|
||
endchoice | ||
|
||
config SECURE_TEE_SEC_STG_KEY_EFUSE_BLK | ||
int "Secure Storage: Encryption key eFuse block" | ||
depends on SECURE_TEE_SEC_STG_MODE_RELEASE | ||
range 4 10 | ||
default 10 | ||
help | ||
eFuse block ID storing the TEE secure storage encryption key | ||
|
||
config SECURE_TEE_ATT_KEY_SLOT_ID | ||
depends on SECURE_ENABLE_TEE | ||
int "Attestation: Secure Storage slot ID for EAT signing" | ||
default 0 | ||
range 0 14 | ||
help | ||
This configuration sets the slot ID from the TEE secure storage | ||
storing the ECDSA keypair for executing sign/verify operations | ||
from the TEE side (E.g. Attestation) | ||
|
||
config SECURE_TEE_DEBUG_MODE | ||
bool "Enable Debug Mode" | ||
default y | ||
depends on SECURE_ENABLE_TEE | ||
help | ||
This configuration enables the logging from the TEE module. | ||
|
||
choice SECURE_TEE_LOG_LEVEL | ||
bool "Log verbosity" | ||
default SECURE_TEE_LOG_LEVEL_WARN | ||
depends on SECURE_TEE_DEBUG_MODE | ||
help | ||
Specify how much output to see in TEE logs. | ||
|
||
config SECURE_TEE_LOG_LEVEL_NONE | ||
bool "No output" | ||
config SECURE_TEE_LOG_LEVEL_ERROR | ||
bool "Error" | ||
config SECURE_TEE_LOG_LEVEL_WARN | ||
bool "Warning" | ||
config SECURE_TEE_LOG_LEVEL_INFO | ||
bool "Info" | ||
config SECURE_TEE_LOG_LEVEL_DEBUG | ||
bool "Debug" | ||
config SECURE_TEE_LOG_LEVEL_VERBOSE | ||
bool "Verbose" | ||
endchoice | ||
|
||
config SECURE_TEE_LOG_LEVEL | ||
int | ||
default 0 if SECURE_TEE_LOG_LEVEL_NONE || !SECURE_TEE_DEBUG_MODE | ||
default 1 if SECURE_TEE_LOG_LEVEL_ERROR | ||
default 2 if SECURE_TEE_LOG_LEVEL_WARN | ||
default 3 if SECURE_TEE_LOG_LEVEL_INFO | ||
default 4 if SECURE_TEE_LOG_LEVEL_DEBUG | ||
default 5 if SECURE_TEE_LOG_LEVEL_VERBOSE | ||
|
||
config SECURE_TEE_TEST_MODE | ||
bool "Enable Test Mode" | ||
depends on SECURE_ENABLE_TEE | ||
help | ||
This configuration sets up the TEE framework as required for executing the test suite. | ||
|
||
endmenu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#ifndef __ASSEMBLER__ | ||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <stddef.h> | ||
#include "soc/soc.h" | ||
#include "sdkconfig.h" | ||
#include "esp_cpu.h" | ||
#include "esp_attr.h" | ||
|
||
#include "riscv/rv_utils.h" | ||
|
||
#define ESP_TEE_APP_CFG_MAGIC 0x3348AAED | ||
|
||
#define ESP_TEE_API_MAJOR_VER 1 | ||
#define ESP_TEE_API_MINOR_VER 0 | ||
#define ESP_TEE_API_PATCH_VER 0 | ||
|
||
/** | ||
* @brief CPU privilege mode | ||
*/ | ||
typedef enum { | ||
ESP_CPU_NS_MODE = 0, /* Corresponds to the RISC-V User (U) mode */ | ||
ESP_CPU_S_MODE = 3, /* Corresponds to the RISC-V Machine (M) mode */ | ||
} esp_cpu_priv_mode_t; | ||
|
||
/** | ||
* @brief Configuration structure defining the interface between TEE and REE (user) app | ||
* | ||
* This configuration structure is embedded in the REE (user) app's IRAM section. | ||
* The TEE reads and updates this structure before switching to the REE, and then | ||
* write-protects it. | ||
* | ||
* @note All accesses to this structure must be 32-bit aligned since it resides in | ||
* the (user app) IRAM section. | ||
*/ | ||
typedef struct { | ||
uint32_t magic_word; | ||
uint32_t api_major_version; | ||
uint32_t api_minor_version; | ||
uint32_t reserved[2]; | ||
/* TEE-related fields */ | ||
void *s_entry_addr; | ||
void *s_int_handler; | ||
/* REE-related fields */ | ||
void *ns_entry_addr; | ||
void *ns_int_handler; | ||
void *ns_iram_end; | ||
void *ns_irom_end; | ||
void *ns_drom_end; | ||
} __attribute__((aligned(4))) __attribute__((__packed__)) esp_tee_config_t; | ||
|
||
extern esp_tee_config_t esp_tee_app_config; | ||
|
||
#endif // ifndef __ASSEMBLER__ | ||
|
||
#if !ESP_TEE_BUILD | ||
#include "private/esp_tee_app.h" | ||
#else | ||
#include "private/esp_tee_binary.h" | ||
#endif | ||
|
||
/* Offsets of some values in esp_tee_config_t that are used by assembly code */ | ||
#define ESP_TEE_CFG_OFFS_S_ENTRY_ADDR 0x14 | ||
#define ESP_TEE_CFG_OFFS_S_INTR_HANDLER 0x18 | ||
#define ESP_TEE_CFG_OFFS_NS_ENTRY_ADDR 0x1C | ||
#define ESP_TEE_CFG_OFFS_NS_INTR_HANDLER 0x20 | ||
|
||
#ifndef __ASSEMBLER__ | ||
/* Check the offsets are correct using the C compiler */ | ||
ESP_STATIC_ASSERT(offsetof(esp_tee_config_t, s_entry_addr) == ESP_TEE_CFG_OFFS_S_ENTRY_ADDR, "offset macro is wrong"); | ||
ESP_STATIC_ASSERT(offsetof(esp_tee_config_t, s_int_handler) == ESP_TEE_CFG_OFFS_S_INTR_HANDLER, "offset macro is wrong"); | ||
ESP_STATIC_ASSERT(offsetof(esp_tee_config_t, ns_entry_addr) == ESP_TEE_CFG_OFFS_NS_ENTRY_ADDR, "offset macro is wrong"); | ||
ESP_STATIC_ASSERT(offsetof(esp_tee_config_t, ns_int_handler) == ESP_TEE_CFG_OFFS_NS_INTR_HANDLER, "offset macro is wrong"); | ||
#endif // ifndef __ASSEMBLER__ | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
Oops, something went wrong.