From 2394e9451dfe4f8a03965597d7eecd892e613c02 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Fri, 19 Sep 2025 15:43:52 +0530 Subject: [PATCH 1/4] feat(esp_tee): Support for ESP32-C61 - the `esp_tee` component --- components/esp_tee/CMakeLists.txt | 4 +- components/esp_tee/Kconfig.projbuild | 3 +- .../scripts/esp32c61/sec_srv_tbl_default.yml | 258 ++++++++++++++++++ .../esp_tee/src/esp_secure_service_wrapper.c | 36 ++- components/esp_tee/subproject/CMakeLists.txt | 2 +- .../tee_sec_storage/tee_sec_storage.c | 14 +- .../tee_sec_storage/tee_sec_storage_wrapper.c | 9 +- .../esp_tee/subproject/main/CMakeLists.txt | 17 +- .../subproject/main/common/syscall_stubs.c | 2 +- .../main/core/esp_secure_services.c | 28 +- .../esp_tee/subproject/main/idf_component.yml | 2 +- .../clic}/esp_tee_rv_utils.h | 0 .../main/include/esp_tee_memory_utils.h | 12 +- .../plic}/esp_tee_rv_utils.h | 0 .../subproject/main/ld/esp32c5/esp_tee.ld.in | 7 +- .../subproject/main/ld/esp32c6/esp_tee.ld.in | 2 +- .../subproject/main/ld/esp32c61/esp_tee.ld.in | 216 +++++++++++++++ .../subproject/main/ld/esp32h2/esp_tee.ld.in | 2 +- .../main/soc/esp32c61/esp_tee_apm_prot_cfg.c | 226 +++++++++++++++ .../soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c | 159 +++++++++++ .../soc/esp32c61/esp_tee_secure_sys_cfg.c | 124 +++++++++ .../soc/esp32c61/include/esp_tee_intr_defs.h | 41 +++ .../soc/esp32h2/include/esp_tee_rv_utils.h | 116 -------- .../test_sec_srv/src/test_interrupt.c | 10 +- .../test_apps/tee_test_fw/main/CMakeLists.txt | 27 +- .../tee_test_fw/main/test_esp_tee_panic.c | 14 + 26 files changed, 1162 insertions(+), 169 deletions(-) create mode 100644 components/esp_tee/scripts/esp32c61/sec_srv_tbl_default.yml rename components/esp_tee/subproject/main/{soc/esp32c5/include => include/clic}/esp_tee_rv_utils.h (100%) rename components/esp_tee/subproject/main/{soc/esp32c6/include => include/plic}/esp_tee_rv_utils.h (100%) create mode 100644 components/esp_tee/subproject/main/ld/esp32c61/esp_tee.ld.in create mode 100644 components/esp_tee/subproject/main/soc/esp32c61/esp_tee_apm_prot_cfg.c create mode 100644 components/esp_tee/subproject/main/soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c create mode 100644 components/esp_tee/subproject/main/soc/esp32c61/esp_tee_secure_sys_cfg.c create mode 100644 components/esp_tee/subproject/main/soc/esp32c61/include/esp_tee_intr_defs.h delete mode 100644 components/esp_tee/subproject/main/soc/esp32h2/include/esp_tee_rv_utils.h diff --git a/components/esp_tee/CMakeLists.txt b/components/esp_tee/CMakeLists.txt index 4de84941879..3bd4ba4bfe0 100644 --- a/components/esp_tee/CMakeLists.txt +++ b/components/esp_tee/CMakeLists.txt @@ -6,8 +6,8 @@ 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, H2 and C5 SoCs -set(SUPPORTED_TARGETS "esp32c6" "esp32h2" "esp32c5") +# ESP-TEE is currently supported only on the ESP32-C6, H2, C5 and C61 SoCs +set(SUPPORTED_TARGETS "esp32c6" "esp32h2" "esp32c5" "esp32c61") if(NOT target IN_LIST SUPPORTED_TARGETS) message(STATUS "ESP-TEE is currently supported only on the ${SUPPORTED_TARGETS} SoCs") return() diff --git a/components/esp_tee/Kconfig.projbuild b/components/esp_tee/Kconfig.projbuild index 39552c1de6a..9f6682a1b88 100644 --- a/components/esp_tee/Kconfig.projbuild +++ b/components/esp_tee/Kconfig.projbuild @@ -1,5 +1,5 @@ menu "ESP-TEE (Trusted Execution Environment)" - depends on IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32C5 + depends on IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C61 config SECURE_ENABLE_TEE bool "Enable the ESP-TEE framework" @@ -90,6 +90,7 @@ menu "ESP-TEE (Trusted Execution Environment)" config SECURE_TEE_PBKDF2_EFUSE_HMAC_KEY_ID int "Secure Storage: eFuse HMAC key ID for PBKDF2 key derivation" + depends on SOC_HMAC_SUPPORTED range -1 5 default -1 help diff --git a/components/esp_tee/scripts/esp32c61/sec_srv_tbl_default.yml b/components/esp_tee/scripts/esp32c61/sec_srv_tbl_default.yml new file mode 100644 index 00000000000..ded5928aacd --- /dev/null +++ b/components/esp_tee/scripts/esp32c61/sec_srv_tbl_default.yml @@ -0,0 +1,258 @@ +secure_services: + - family: misc + entries: + - id: 0 + type: custom + function: invalid_secure_service + args: 0 + # ID: 1-4 (4) - External memory (Flash) protection [SPI0] + - family: flash_protection_spi0 + entries: + - id: 1 + type: IDF + function: mmu_hal_map_region + args: 6 + - id: 2 + type: IDF + function: mmu_hal_unmap_region + args: 3 + - id: 3 + type: IDF + function: mmu_hal_vaddr_to_paddr + args: 4 + - id: 4 + type: IDF + function: mmu_hal_paddr_to_vaddr + args: 5 + # ID 5 empty + # ID: 6-22 (17) - External memory (Flash) protection [SPI1] + - family: flash_protection_spi1 + entries: + - id: 6 + type: IDF + function: spi_flash_hal_check_status + args: 1 + - id: 7 + type: IDF + function: spi_flash_hal_common_command + args: 2 + - id: 8 + type: IDF + function: spi_flash_hal_device_config + args: 1 + - id: 9 + type: IDF + function: spi_flash_hal_erase_block + args: 2 + # ID: 10 empty + - id: 11 + type: IDF + function: spi_flash_hal_erase_sector + args: 2 + - id: 12 + type: IDF + function: spi_flash_hal_program_page + args: 4 + - id: 13 + type: IDF + function: spi_flash_hal_read + args: 4 + - id: 14 + type: IDF + function: spi_flash_hal_resume + args: 1 + - id: 15 + type: IDF + function: spi_flash_hal_set_write_protect + args: 2 + - id: 16 + type: IDF + function: spi_flash_hal_setup_read_suspend + args: 2 + - id: 17 + type: IDF + function: spi_flash_hal_supports_direct_read + args: 2 + - id: 18 + type: IDF + function: spi_flash_hal_supports_direct_write + args: 2 + - id: 19 + type: IDF + function: spi_flash_hal_suspend + args: 1 + - id: 20 + type: IDF + function: bootloader_flash_execute_command_common + args: 7 + - id: 21 + type: IDF + function: memspi_host_flush_cache + args: 3 + - id: 22 + type: IDF + function: spi_flash_chip_generic_config_host_io_mode + args: 2 + # ID: 30-53 (24) - Interrupt Handling + - family: interrupt_handling + entries: + - id: 30 + type: IDF + function: esp_rom_route_intr_matrix + args: 3 + - id: 31 + type: IDF + function: rv_utils_intr_enable + args: 1 + - id: 32 + type: IDF + function: rv_utils_intr_disable + args: 1 + - id: 33 + type: IDF + function: rv_utils_intr_set_priority + args: 2 + - id: 34 + type: IDF + function: rv_utils_intr_set_type + args: 2 + - id: 35 + type: IDF + function: rv_utils_intr_set_threshold + args: 1 + - id: 36 + type: IDF + function: rv_utils_intr_edge_ack + args: 1 + - id: 37 + type: IDF + function: rv_utils_intr_global_enable + args: 0 + - id: 38 + type: IDF + function: rv_utils_intr_get_enabled_mask + args: 0 + - id: 39 + type: IDF + function: rv_utils_set_cycle_count + args: 1 + - id: 40 + type: IDF + function: rv_utils_en_branch_predictor + args: 0 + - id: 41 + type: IDF + function: rv_utils_dis_branch_predictor + args: 0 + - id: 42 + type: IDF + function: rv_utils_wfe_mode_enable + args: 1 + - id: 43 + type: IDF + function: esprv_int_set_vectored + args: 2 + # ID: 54-85 (32) - HAL + - family: hal + entries: + - id: 54 + type: IDF + function: wdt_hal_init + args: 4 + - id: 55 + type: IDF + function: wdt_hal_deinit + args: 1 + # ID: 86-133 (48) - Crypto + - family: crypto + entries: + - id: 86 + type: IDF + function: esp_sha + args: 4 + - id: 87 + type: IDF + function: esp_sha_block + args: 3 + - id: 88 + type: IDF + function: esp_sha_dma + args: 6 + - id: 89 + type: IDF + function: esp_sha_read_digest_state + args: 2 + - id: 90 + type: IDF + function: esp_sha_write_digest_state + args: 2 + - id: 91 + type: IDF + function: esp_sha_set_mode + args: 1 + - id: 92 + type: IDF + function: esp_crypto_sha_enable_periph_clk + args: 1 + - id: 93 + type: IDF + function: esp_ecc_point_multiply + args: 4 + - id: 94 + type: IDF + function: esp_ecc_point_verify + args: 1 + - id: 95 + type: IDF + function: esp_crypto_ecc_enable_periph_clk + args: 1 + # ID: 134-169 (36) - Reserved for future use + - family: attestation + entries: + - id: 170 + type: custom + function: esp_tee_att_generate_token + args: 6 + # ID: 175-194 (20) - Secure Storage + - family: secure_storage + entries: + - id: 175 + type: custom + function: esp_tee_sec_storage_clear_key + args: 1 + - id: 176 + type: custom + function: esp_tee_sec_storage_gen_key + args: 1 + - id: 177 + type: custom + function: esp_tee_sec_storage_ecdsa_sign + args: 4 + - id: 178 + type: custom + function: esp_tee_sec_storage_ecdsa_get_pubkey + args: 2 + - id: 179 + type: custom + function: esp_tee_sec_storage_aead_encrypt + args: 4 + - id: 180 + type: custom + function: esp_tee_sec_storage_aead_decrypt + args: 4 + # ID: 195-199 (5) - OTA + - family: ota + entries: + - id: 195 + type: custom + function: esp_tee_ota_begin + args: 0 + - id: 196 + type: custom + function: esp_tee_ota_write + args: 3 + - id: 197 + type: custom + function: esp_tee_ota_end + args: 0 + # ID: 200+ - User-defined diff --git a/components/esp_tee/src/esp_secure_service_wrapper.c b/components/esp_tee/src/esp_secure_service_wrapper.c index a6c8e39ea3a..4be9c3ffc8b 100644 --- a/components/esp_tee/src/esp_secure_service_wrapper.c +++ b/components/esp_tee/src/esp_secure_service_wrapper.c @@ -5,27 +5,32 @@ */ #include +#include "soc/soc_caps.h" #include "esp_err.h" #include "esp_random.h" -#include "hal/sha_types.h" -#include "hal/sha_hal.h" -#include "rom/digital_signature.h" #include "hal/mmu_types.h" #include "hal/wdt_hal.h" #include "hal/spi_flash_hal.h" #include "hal/spi_flash_types.h" #include "esp_private/mspi_timing_tuning.h" +#if SOC_SHA_SUPPORTED +#include "hal/sha_types.h" +#include "hal/sha_hal.h" +#endif +#if SOC_HMAC_SUPPORTED #include "esp_hmac.h" +#endif +#if SOC_DIG_SIGN_SUPPORTED #include "esp_ds.h" +#include "rom/digital_signature.h" +#endif #include "esp_crypto_lock.h" #include "esp_flash.h" -#include "soc/soc_caps.h" -#include "sdkconfig.h" - #include "esp_tee.h" #include "secure_service_num.h" +#include "sdkconfig.h" /* ---------------------------------------------- Interrupts ------------------------------------------------- */ @@ -43,18 +48,19 @@ void IRAM_ATTR __wrap_esprv_int_set_vectored(int rv_int_num, bool vectored) /* ---------------------------------------------- RTC_WDT ------------------------------------------------- */ -void __wrap_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr) +void IRAM_ATTR __wrap_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr) { esp_tee_service_call(5, SS_WDT_HAL_INIT, hal, wdt_inst, prescaler, enable_intr); } -void __wrap_wdt_hal_deinit(wdt_hal_context_t *hal) +void IRAM_ATTR __wrap_wdt_hal_deinit(wdt_hal_context_t *hal) { esp_tee_service_call(2, SS_WDT_HAL_DEINIT, hal); } /* ---------------------------------------------- AES ------------------------------------------------- */ +#if SOC_AES_SUPPORTED typedef struct { uint8_t key_bytes; volatile uint8_t key_in_hardware; /* This variable is used for fault injection checks, so marked volatile to avoid optimisation */ @@ -148,9 +154,10 @@ int __wrap_esp_aes_crypt_ofb(esp_aes_context *ctx, esp_crypto_sha_aes_lock_release(); return err; } - +#endif /* ---------------------------------------------- SHA ------------------------------------------------- */ +#if SOC_SHA_SUPPORTED typedef enum { ESP_SHA1_STATE_INIT, ESP_SHA1_STATE_IN_PROCESS @@ -238,9 +245,11 @@ int __wrap_esp_sha_512_t_init_hash(uint16_t t) return esp_tee_service_call(2, SS_ESP_SHA_512_T_INIT_HASH, t); } #endif +#endif /* ---------------------------------------------- HMAC ------------------------------------------------- */ +#if SOC_HMAC_SUPPORTED esp_err_t __wrap_esp_hmac_calculate(hmac_key_id_t key_id, const void *message, size_t message_len, uint8_t *hmac) { esp_crypto_hmac_lock_acquire(); @@ -264,9 +273,11 @@ esp_err_t __wrap_esp_hmac_jtag_disable(void) esp_crypto_hmac_lock_release(); return err; } +#endif /* ---------------------------------------------- DS ------------------------------------------------- */ +#if SOC_DIG_SIGN_SUPPORTED esp_err_t __wrap_esp_ds_sign(const void *message, const esp_ds_data_t *data, hmac_key_id_t key_id, @@ -318,16 +329,20 @@ esp_err_t __wrap_esp_ds_encrypt_params(esp_ds_data_t *data, esp_crypto_sha_aes_lock_release(); return err; } +#endif /* ---------------------------------------------- MPI ------------------------------------------------- */ +#if SOC_MPI_SUPPORTED void __wrap_esp_crypto_mpi_enable_periph_clk(bool enable) { esp_tee_service_call(2, SS_ESP_CRYPTO_MPI_ENABLE_PERIPH_CLK, enable); } +#endif /* ---------------------------------------------- ECC ------------------------------------------------- */ +#if SOC_ECC_SUPPORTED #define P256_LEN (256/8) #define P192_LEN (192/8) @@ -352,8 +367,9 @@ int __wrap_esp_ecc_point_verify(const ecc_point_t *point) esp_crypto_ecc_lock_release(); return err; } +#endif -#if SOC_ECDSA_SUPPORTED +#if SOC_ECC_SUPPORTED && SOC_ECDSA_SUPPORTED void __wrap_esp_crypto_ecc_enable_periph_clk(bool enable) { esp_tee_service_call(2, SS_ESP_CRYPTO_ECC_ENABLE_PERIPH_CLK, enable); diff --git a/components/esp_tee/subproject/CMakeLists.txt b/components/esp_tee/subproject/CMakeLists.txt index 91370fa0779..ceccfe2bc1d 100644 --- a/components/esp_tee/subproject/CMakeLists.txt +++ b/components/esp_tee/subproject/CMakeLists.txt @@ -25,7 +25,7 @@ set(ESP_TEE_BUILD 1) set(NON_OS_BUILD 1) # Additional components -list(APPEND COMPONENTS bootloader_support efuse esp_hal_mspi esp_security mbedtls esp_stdio) +list(APPEND COMPONENTS bootloader_support efuse esp_hal_mspi esp_hal_wdt esp_security mbedtls esp_stdio) # TEE-specific components list(APPEND COMPONENTS tee_flash_mgr tee_ota_ops tee_sec_storage tee_attestation) diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c index 0868e386066..d42c20c0cf0 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c @@ -6,22 +6,22 @@ #include +#include "soc/soc_caps.h" #include "esp_log.h" -#include "esp_cpu.h" #include "esp_fault.h" -#include "esp_flash.h" #include "esp_efuse.h" #include "esp_efuse_chip.h" -#include "esp_hmac.h" #include "esp_random.h" #include "spi_flash_mmap.h" +#if SOC_HMAC_SUPPORTED +#include "esp_hmac.h" +#include "esp_hmac_pbkdf2.h" +#endif #include "mbedtls/aes.h" #include "mbedtls/gcm.h" #include "mbedtls/sha256.h" #include "mbedtls/ecdsa.h" -#include "mbedtls/error.h" -#include "esp_hmac_pbkdf2.h" #include "esp_rom_sys.h" #include "nvs.h" @@ -87,9 +87,11 @@ static const char *TAG = "secure_storage"; #error "TEE Secure Storage: Configured eFuse block (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID) out of range!" #endif +#if SOC_HMAC_SUPPORTED #if CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID == CONFIG_SECURE_TEE_PBKDF2_EFUSE_HMAC_KEY_ID #error "TEE Secure Storage: Configured eFuse block for storage encryption keys (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID) and PBKDF2 key derivation (CONFIG_SECURE_TEE_PBKDF2_EFUSE_HMAC_KEY_ID) cannot be the same!" #endif +#endif static int buffer_hexdump(const char *label, const void *buffer, size_t length) { @@ -610,6 +612,7 @@ esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t return tee_sec_storage_crypt_common(ctx->key_id, ctx->input, ctx->input_len, ctx->aad, ctx->aad_len, (uint8_t *)tag, tag_len, output, false); } +#if SOC_HMAC_SUPPORTED esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2_ctx_t *ctx, const uint8_t *hash, size_t hlen, esp_tee_sec_storage_ecdsa_sign_t *out_sign, @@ -743,3 +746,4 @@ exit: mbedtls_mpi_free(&s); return err; } +#endif diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c index 828b6bd550e..ae1fa9564c0 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c @@ -3,10 +3,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "secure_service_num.h" -#include "esp_tee.h" + +#include "soc/soc_caps.h" #include "esp_err.h" + +#include "esp_tee.h" #include "esp_tee_sec_storage.h" +#include "secure_service_num.h" esp_err_t esp_tee_sec_storage_clear_key(const char *key_id) { @@ -38,7 +41,9 @@ esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t return esp_tee_service_call_with_noniram_intr_disabled(5, SS_ESP_TEE_SEC_STORAGE_AEAD_DECRYPT, ctx, tag, tag_len, output); } +#if SOC_HMAC_SUPPORTED esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2_ctx_t *ctx, const uint8_t *hash, size_t hlen, esp_tee_sec_storage_ecdsa_sign_t *out_sign, esp_tee_sec_storage_ecdsa_pubkey_t *out_pubkey) { return esp_tee_service_call(6, SS_ESP_TEE_SEC_STORAGE_ECDSA_SIGN_PBKDF2, ctx, hash, hlen, out_sign, out_pubkey); } +#endif diff --git a/components/esp_tee/subproject/main/CMakeLists.txt b/components/esp_tee/subproject/main/CMakeLists.txt index 83a77c34cea..9de09704c71 100644 --- a/components/esp_tee/subproject/main/CMakeLists.txt +++ b/components/esp_tee/subproject/main/CMakeLists.txt @@ -27,8 +27,11 @@ list(APPEND srcs "soc/${target}/esp_tee_secure_sys_cfg.c" "soc/${target}/esp_tee_pmp_pma_prot_cfg.c" "soc/${target}/esp_tee_apm_prot_cfg.c") -list(APPEND srcs "soc/common/esp_tee_apm_intr.c" - "soc/common/esp_tee_aes_intr.c") +list(APPEND srcs "soc/common/esp_tee_apm_intr.c") + +if(CONFIG_SOC_AES_SUPPORTED) + list(APPEND srcs "soc/common/esp_tee_aes_intr.c") +endif() # Common module implementation for TEE @@ -44,6 +47,12 @@ list(APPEND include "include" "soc/common/include" "soc/${target}/include") +if(CONFIG_SOC_INT_PLIC_SUPPORTED) + list(APPEND include "include/plic") +elseif(CONFIG_SOC_INT_CLIC_SUPPORTED) + list(APPEND include "include/clic") +endif() + # Heap list(APPEND srcs "common/multi_heap.c") @@ -59,9 +68,9 @@ list(APPEND srcs "common/syscall_stubs.c") idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${include}) -# NOTE: The ESP32-H2 ROM does not have sprintf/snprintf implementation, +# NOTE: The ESP32-H2 and C61 ROM does not have sprintf/snprintf implementation, # thus newlib-nano implementation from the toolchain has been used. -if(CONFIG_IDF_TARGET_ESP32H2) +if(CONFIG_IDF_TARGET_ESP32H2 OR CONFIG_IDF_TARGET_ESP32C61) target_link_libraries(${COMPONENT_LIB} INTERFACE "--specs=nano.specs") endif() diff --git a/components/esp_tee/subproject/main/common/syscall_stubs.c b/components/esp_tee/subproject/main/common/syscall_stubs.c index ee810a1aac2..4062764ada2 100644 --- a/components/esp_tee/subproject/main/common/syscall_stubs.c +++ b/components/esp_tee/subproject/main/common/syscall_stubs.c @@ -130,7 +130,7 @@ int __cxa_thread_atexit(void (*func)(void *), void *arg, void *dso) return 0; } -#if CONFIG_IDF_TARGET_ESP32H2 +#if CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C61 void *_sbrk(ptrdiff_t incr) { return (void *) -1; diff --git a/components/esp_tee/subproject/main/core/esp_secure_services.c b/components/esp_tee/subproject/main/core/esp_secure_services.c index 1a8553eaa70..1a3bcf64cce 100644 --- a/components/esp_tee/subproject/main/core/esp_secure_services.c +++ b/components/esp_tee/subproject/main/core/esp_secure_services.c @@ -8,13 +8,23 @@ #include "esp_fault.h" #include "soc/soc_caps.h" -#include "hal/sha_hal.h" +#if SOC_AES_SUPPORTED #include "aes/esp_aes.h" +#endif +#if SOC_SHA_SUPPORTED +#include "hal/sha_hal.h" #include "sha/sha_core.h" +#endif +#if SOC_HMAC_SUPPORTED #include "esp_hmac.h" +#endif +#if SOC_DIG_SIGN_SUPPORTED #include "esp_ds.h" -#include "esp_crypto_periph_clk.h" +#endif +#if SOC_ECC_SUPPORTED #include "ecc_impl.h" +#endif +#include "esp_crypto_periph_clk.h" #include "esp_tee.h" #include "esp_tee_memory_utils.h" @@ -32,6 +42,7 @@ void _ss_invalid_secure_service(void) /* ---------------------------------------------- AES ------------------------------------------------- */ +#if SOC_AES_SUPPORTED void _ss_esp_aes_intr_alloc(void) { esp_tee_aes_intr_alloc(); @@ -144,9 +155,11 @@ int _ss_esp_aes_crypt_ofb(esp_aes_context *ctx, return esp_aes_crypt_ofb(ctx, length, iv_off, iv, input, output); } +#endif /* ---------------------------------------------- SHA ------------------------------------------------- */ +#if SOC_SHA_SUPPORTED void _ss_esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output) { bool valid_addr = ((esp_tee_ptr_in_ree((void *)input) && esp_tee_ptr_in_ree((void *)output)) && @@ -209,9 +222,11 @@ int _ss_esp_sha_512_t_init_hash(uint16_t t) return esp_sha_512_t_init_hash(t); } #endif +#endif /* ---------------------------------------------- HMAC ------------------------------------------------- */ +#if SOC_HMAC_SUPPORTED esp_err_t _ss_esp_hmac_calculate(hmac_key_id_t key_id, const void *message, size_t message_len, uint8_t *hmac) { bool valid_addr = ((esp_tee_ptr_in_ree((void *)message) && esp_tee_ptr_in_ree((void *)hmac)) && @@ -251,7 +266,9 @@ esp_err_t _ss_esp_hmac_jtag_disable(void) { return esp_hmac_jtag_disable(); } +#endif +#if SOC_DIG_SIGN_SUPPORTED esp_err_t _ss_esp_ds_sign(const void *message, const esp_ds_data_t *data, hmac_key_id_t key_id, @@ -333,16 +350,20 @@ esp_err_t _ss_esp_ds_encrypt_params(esp_ds_data_t *data, return esp_ds_encrypt_params(data, iv, p_data, key); } +#endif /* ---------------------------------------------- MPI ------------------------------------------------- */ +#if SOC_MPI_SUPPORTED void _ss_esp_crypto_mpi_enable_periph_clk(bool enable) { esp_crypto_mpi_enable_periph_clk(enable); } +#endif /* ---------------------------------------------- ECC ------------------------------------------------- */ +#if SOC_ECC_SUPPORTED int _ss_esp_ecc_point_multiply(const ecc_point_t *point, const uint8_t *scalar, ecc_point_t *result, bool verify_first) { bool valid_addr = (esp_tee_ptr_in_ree((void *)result)) && @@ -360,11 +381,14 @@ int _ss_esp_ecc_point_verify(const ecc_point_t *point) { return esp_ecc_point_verify(point); } +#endif +#if SOC_ECC_SUPPORTED && SOC_ECDSA_SUPPORTED void _ss_esp_crypto_ecc_enable_periph_clk(bool enable) { esp_crypto_ecc_enable_periph_clk(enable); } +#endif /* ---------------------------------------------- OTA ------------------------------------------------- */ diff --git a/components/esp_tee/subproject/main/idf_component.yml b/components/esp_tee/subproject/main/idf_component.yml index 76f3ab99880..304eaae2e81 100644 --- a/components/esp_tee/subproject/main/idf_component.yml +++ b/components/esp_tee/subproject/main/idf_component.yml @@ -3,4 +3,4 @@ dependencies: espressif/json_generator: version: "^1.1.2" rules: - - if: "target in [esp32c6, esp32h2, esp32c5]" + - if: "target in [esp32c6, esp32h2, esp32c5, esp32c61]" diff --git a/components/esp_tee/subproject/main/soc/esp32c5/include/esp_tee_rv_utils.h b/components/esp_tee/subproject/main/include/clic/esp_tee_rv_utils.h similarity index 100% rename from components/esp_tee/subproject/main/soc/esp32c5/include/esp_tee_rv_utils.h rename to components/esp_tee/subproject/main/include/clic/esp_tee_rv_utils.h diff --git a/components/esp_tee/subproject/main/include/esp_tee_memory_utils.h b/components/esp_tee/subproject/main/include/esp_tee_memory_utils.h index 437a619c1ac..772b963a389 100644 --- a/components/esp_tee/subproject/main/include/esp_tee_memory_utils.h +++ b/components/esp_tee/subproject/main/include/esp_tee_memory_utils.h @@ -16,9 +16,15 @@ extern "C" { FORCE_INLINE_ATTR bool esp_tee_ptr_in_ree(const void *p) { - return (((intptr_t)p >= SOC_NS_IDRAM_START && (intptr_t)p < SOC_NS_IDRAM_END) || - ((intptr_t)p >= (size_t)esp_tee_app_config.ns_drom_start && (intptr_t)p < SOC_S_MMU_MMAP_RESV_START_VADDR) || - ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH)); + intptr_t addr = (intptr_t)p; + return ( + (addr >= SOC_NS_IDRAM_START && addr < SOC_NS_IDRAM_END) || + (addr >= (intptr_t)esp_tee_app_config.ns_drom_start && + addr < SOC_S_MMU_MMAP_RESV_START_VADDR) +#if SOC_RTC_MEM_SUPPORTED + || (addr >= SOC_RTC_DATA_LOW && addr < SOC_RTC_DATA_HIGH) +#endif + ); } #ifdef __cplusplus diff --git a/components/esp_tee/subproject/main/soc/esp32c6/include/esp_tee_rv_utils.h b/components/esp_tee/subproject/main/include/plic/esp_tee_rv_utils.h similarity index 100% rename from components/esp_tee/subproject/main/soc/esp32c6/include/esp_tee_rv_utils.h rename to components/esp_tee/subproject/main/include/plic/esp_tee_rv_utils.h diff --git a/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in index 3fa95a92f9d..314c55388af 100644 --- a/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in @@ -32,12 +32,7 @@ * should be stored via esp_app_tee_config structure */ -#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS -PROVIDE ( esp_tee_app_config = SRAM_REE_SEG_START + 0x22b0 ); -#else PROVIDE ( esp_tee_app_config = SRAM_REE_SEG_START + 0x2b0 ); -#endif - PROVIDE ( GDMA = 0x60080000 ); /* SPI Flash functions required from the ROM (refer esp32c5.rom.spiflash.ld) */ @@ -101,9 +96,9 @@ SECTIONS /* HAL */ *libhal.a:mmu_hal.c*(.literal .text .literal.* .text.*) *libhal.a:cache_hal.c*(.literal .text .literal.* .text.*) - *libhal.a:wdt_hal_iram.c*(.literal .text .literal.* .text.*) *libhal.a:apm_hal.c*(.literal .text .literal.* .text.*) *libesp_hal_mspi.a:*(.literal .text .literal.* .text.*) + *libesp_hal_wdt.a:*(.literal .text .literal.* .text.*) /* IDF components */ *libbootloader_support.a:*(.literal .text .literal.* .text.*) *libesp_hw_support.a:*(.literal .text .literal.* .text.*) diff --git a/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in index 98e4d6a5610..f36768407cb 100644 --- a/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in @@ -101,9 +101,9 @@ SECTIONS /* HAL */ *libhal.a:mmu_hal.c*(.literal .text .literal.* .text.*) *libhal.a:cache_hal.c*(.literal .text .literal.* .text.*) - *libhal.a:wdt_hal_iram.c*(.literal .text .literal.* .text.*) *libhal.a:apm_hal.c*(.literal .text .literal.* .text.*) *libesp_hal_mspi.a:*(.literal .text .literal.* .text.*) + *libesp_hal_wdt.a:*(.literal .text .literal.* .text.*) /* IDF components */ *libbootloader_support.a:*(.literal .text .literal.* .text.*) *libesp_hw_support.a:*(.literal .text .literal.* .text.*) diff --git a/components/esp_tee/subproject/main/ld/esp32c61/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32c61/esp_tee.ld.in new file mode 100644 index 00000000000..ac4feedefd8 --- /dev/null +++ b/components/esp_tee/subproject/main/ld/esp32c61/esp_tee.ld.in @@ -0,0 +1,216 @@ +/* + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "ld.common" + +#define SRAM_TEE_SEG_START (0x40800000) +#define SRAM_REE_SEG_START (SRAM_TEE_SEG_START + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE) + +#define SRAM_TEE_DRAM_SIZE (CONFIG_SECURE_TEE_DRAM_SIZE - CONFIG_SECURE_TEE_STACK_SIZE - CONFIG_SECURE_TEE_INTR_STACK_SIZE) +#define SRAM_TEE_DRAM_END (SRAM_TEE_SEG_START + CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_TEE_DRAM_SIZE) + +#define SRAM_TEE_SEG_SIZE (CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_TEE_DRAM_SIZE) + +/* TEE interrupt stack is placed at the end of the TEE DRAM segment. + * The top of the TEE stack is before the end of interrupt stack + * and the bottom of the stack is at _heap_end. + */ +#define SRAM_TEE_STACK_SEG_START (SRAM_TEE_DRAM_END) +#define SRAM_TEE_INTR_STACK_SEG_START (SRAM_TEE_DRAM_END + CONFIG_SECURE_TEE_STACK_SIZE) + +#define FLASH_TEE_SEG_START (0x42000000) +#define FLASH_TEE_SEG_SIZE (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE) + +/** + * These values are the same in every app binary for the same chip target. + * + * Values that may change when the app is rebuilt, or in a new ESP-IDF version, + * should be stored via esp_app_tee_config structure + */ + +PROVIDE ( esp_tee_app_config = SRAM_REE_SEG_START + 0x2b0 ); +PROVIDE ( GDMA = 0x60080000 ); + +/* SPI Flash functions required from the ROM (refer esp32c61.rom.spiflash.ld) */ +PROVIDE ( spi_flash_check_and_flush_cache = 0x40000230 ); +PROVIDE ( spi_flash_chip_generic_config_host_io_mode = 0x400002d4 ); +PROVIDE ( memspi_host_flush_cache = 0x40000318 ); + +/* Default entry point: */ +ENTRY(esp_tee_init); + +MEMORY +{ +/* Flash text section */ + irom_tee_seg (RX): org = FLASH_TEE_SEG_START + 0x20, len = FLASH_TEE_SEG_SIZE - 0x20 + +/* Flash data section */ + drom_tee_seg (R) : org = FLASH_TEE_SEG_START + 0x20, len = FLASH_TEE_SEG_SIZE - 0x20 + +/* I/DRAM section */ + sram_tee_seg (RWX) : org = SRAM_TEE_SEG_START, len = SRAM_TEE_SEG_SIZE + +/* Stack section */ + stack_tee_seg (RW) : org = SRAM_TEE_STACK_SEG_START, len = CONFIG_SECURE_TEE_STACK_SIZE + +/* Interrupt stack section */ + intr_stack_tee_seg (RW) : org = SRAM_TEE_INTR_STACK_SEG_START, len = CONFIG_SECURE_TEE_INTR_STACK_SIZE +} + +SECTIONS +{ + .iram.tee.text : + { + /* Vectors go to start of IRAM */ + ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); + _tee_vec_start = ABSOLUTE(.); + KEEP(*(.exception_vectors_table.text)); + KEEP(*(.exception_vectors.text)); + ALIGNED_SYMBOL(4, _invalid_pc_placeholder) + _tee_vec_end = ABSOLUTE(.); + + /* Code marked as running out of IRAM */ + _tee_iram_start = ABSOLUTE(.); + *(.iram1 .iram1.*) + /* TEE initialization */ + *libmain.a:esp_tee_init.c*(.literal .text .literal.* .text.*) + *libmain.a:esp_tee_secure_sys_cfg.c*(.literal .text .literal.* .text.*) + *libmain.a:esp_tee_pmp_pma_prot_cfg.c*(.literal .text .literal.* .text.*) + *libmain.a:esp_tee_apm_prot_cfg.c*(.literal .text .literal.* .text.*) + *libmain.a:brownout.c*(.literal .text .literal.* .text.*) + *libmain.a:multi_heap.c*(.literal .text .literal.* .text.*) + /* Panic handler */ + *libmain.a:esp_tee_panic.c*(.literal .text .literal.* .text.*) + *libmain.a:panic_helper_riscv.c*(.literal .text .literal.* .text.*) + /* Service call execution */ + *libmain.a:esp_tee_vectors_clic.S*(.literal .text .literal.* .text.*) + *libmain.a:esp_secure_dispatcher.c*(.literal .text .literal.* .text.*) + *libmain.a:esp_secure_services_iram.c*(.literal .text .literal.* .text.*) + /* Interrupt configuration */ + *libmain.a:esp_tee_intr.c*(.literal .text .literal.* .text.*) + *libmain.a:esp_tee_apm_intr.c*(.literal .text .literal.* .text.*) + /* HAL */ + *libhal.a:mmu_hal.c*(.literal .text .literal.* .text.*) + *libhal.a:cache_hal.c*(.literal .text .literal.* .text.*) + *libhal.a:apm_hal.c*(.literal .text .literal.* .text.*) + *libesp_hal_mspi.a:*(.literal .text .literal.* .text.*) + *libesp_hal_wdt.a:*(.literal .text .literal.* .text.*) + /* IDF components */ + *libbootloader_support.a:*(.literal .text .literal.* .text.*) + *libesp_hw_support.a:*(.literal .text .literal.* .text.*) + *liblog.a:*(.literal .text .literal.* .text.*) + *libriscv.a:*(.literal .text .literal.* .text.*) + /* TEE services: Secure storage, OTA, attestation */ + *libtee_flash_mgr.a:*(.literal .text .literal.* .text.*) + *libtee_sec_storage.a:*(.literal .text .literal.* .text.*) + *libtee_ota_ops.a:*(.literal .text .literal.* .text.*) + *libtee_attestation.a:*(.literal .text .literal.* .text.*) + + /* Align the end of code region as per PMP region granularity */ + ALIGNED_SYMBOL(_esp_pmp_align_size, _tee_iram_end) + } > sram_tee_seg + + .dram.tee.data : + { + _tee_dram_start = ABSOLUTE(.); + _tee_data_start = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.*) + *(.dram1 .dram1.*) + _tee_data_end = ABSOLUTE(.); + } > sram_tee_seg + + .dram.tee.bss (NOLOAD) : + { + ALIGNED_SYMBOL(8, _tee_bss_start) + *(.bss .bss.*) + *(.sbss .sbss.*) + ALIGNED_SYMBOL(8, _tee_bss_end) + } > sram_tee_seg + + .dram.tee.rodata : + { + _tee_rodata_start = ABSOLUTE(.); + /* TEE flash manager */ + *libtee_flash_mgr.a:*(.rodata .srodata .rodata.* .srodata.*) + *libbootloader_support.a:bootloader_flash.*(.rodata .srodata .rodata.* .srodata.*) + /* Secure services */ + *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.*) + *libmain.a:esp_tee_apm_intr.c.*(.rodata .srodata .rodata.* .srodata.*) + /* HAL (noflash) */ + *libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*) + *libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*) + *libesp_hal_mspi.a:*(.rodata .srodata .rodata.* .srodata.*) + _tee_rodata_end = ABSOLUTE(.); + _tee_dram_end = ABSOLUTE(.); + } > sram_tee_seg + + .dram.tee.heap (NOLOAD): ALIGN(0x10) + { + _tee_heap_start = ABSOLUTE(.); + . = ORIGIN(sram_tee_seg) + LENGTH(sram_tee_seg); + _tee_heap_end = ABSOLUTE(.); + } > sram_tee_seg + + .dram.tee.stack (NOLOAD): ALIGN(0x10) + { + _tee_stack_bottom = ABSOLUTE(.); + . = ORIGIN(stack_tee_seg) + LENGTH(stack_tee_seg); + _tee_stack = ABSOLUTE(.); + } > stack_tee_seg + + .dram.tee.intr_stack (NOLOAD): ALIGN(0x10) + { + _tee_intr_stack_bottom = ABSOLUTE(.); + . = ORIGIN(intr_stack_tee_seg) + LENGTH(intr_stack_tee_seg); + _tee_intr_stack = ABSOLUTE(.); + } > intr_stack_tee_seg + + + .flash.tee.rodata : ALIGN(0x10) + { + _tee_flash_data_start = ABSOLUTE(.); + *(.rodata_desc .rodata_desc.*) /* Should be the first. TEE App version info. DO NOT PUT ANYTHING BEFORE IT! */ + *(.rodata .rodata.*) + *(.srodata .srodata.*) + *(.gcc_except_table .gcc_except_table.*) + _tee_flash_data_end = ABSOLUTE(.); + } > drom_tee_seg + + .flash.tee.text_dummy (NOLOAD): + { + /* Create an empty gap as big as .flash.tee.rodata section */ + . = ALIGN(ALIGNOF(.flash.tee.rodata)) + SIZEOF(.flash.tee.rodata); + /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ + . = ALIGN(_esp_mmu_page_size) + 0x20; + } > irom_tee_seg + + .flash.tee.text : + { + _tee_flash_text_start = ABSOLUTE(.); + *(.literal .text .literal.* .text.*) + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + /** + * CPU will try to prefetch up to 16 bytes of of instructions. + * This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += _esp_flash_mmap_prefetch_pad_size; + _tee_flash_text_end = ABSOLUTE(.); + } > irom_tee_seg + +#include "elf_misc.ld.in" +} + +ASSERT ((_tee_iram_end <= _tee_dram_start), + "Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required."); +ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000), + "Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required."); diff --git a/components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in index 0f38b3c64d0..9c42a51038d 100644 --- a/components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in @@ -101,9 +101,9 @@ SECTIONS /* HAL */ *libhal.a:mmu_hal.c*(.literal .text .literal.* .text.*) *libhal.a:cache_hal.c*(.literal .text .literal.* .text.*) - *libhal.a:wdt_hal_iram.c*(.literal .text .literal.* .text.*) *libhal.a:apm_hal.c*(.literal .text .literal.* .text.*) *libesp_hal_mspi.a:*(.literal .text .literal.* .text.*) + *libesp_hal_wdt.a:*(.literal .text .literal.* .text.*) /* IDF components */ *libbootloader_support.a:*(.literal .text .literal.* .text.*) *libesp_hw_support.a:*(.literal .text .literal.* .text.*) diff --git a/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_apm_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_apm_prot_cfg.c new file mode 100644 index 00000000000..b3e963aca59 --- /dev/null +++ b/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_apm_prot_cfg.c @@ -0,0 +1,226 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/spi_mem_c_reg.h" +#include "soc/efuse_reg.h" +#include "soc/pcr_reg.h" +#include "soc/lp_analog_peri_reg.h" +#include "soc/lp_wdt_reg.h" + +#include "soc/apm_defs.h" +#include "hal/apm_types.h" +#include "hal/apm_hal.h" + +#include "esp_log.h" +#include "esp_bit_defs.h" +#include "esp_tee.h" +#include "esp_tee_intr.h" + +extern void tee_apm_violation_isr(void *arg); + +static const char *TAG = "esp_tee_apm_prot_cfg"; + +/* NOTE: Figuring out the eFuse protection range based on where the TEE secure storage key is stored */ +#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE +#if CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID < 0 +#error "TEE: eFuse protection region for APM out of range! (see CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID)" +#endif +#define LP_APM_EFUSE_REG_START \ + (EFUSE_RD_KEY0_DATA0_REG + (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID * 0x20)) + +#define LP_APM_EFUSE_REG_END \ + (EFUSE_RD_KEY1_DATA0_REG + (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID * 0x20)) +#elif CONFIG_SECURE_TEE_SEC_STG_MODE_DEVELOPMENT +#define LP_APM_EFUSE_REG_START EFUSE_RD_KEY5_DATA0_REG +#if CONFIG_SECURE_TEE_TEST_MODE +#define LP_APM_EFUSE_REG_END EFUSE_RD_SYS_PART2_DATA0_REG +#else +#define LP_APM_EFUSE_REG_END LP_APM_EFUSE_REG_START +#endif +#endif + +/* NOTE: Flash protection over the SPI1 controller */ +#define HP_APM_SPI1_REG_START DR_REG_MSPI1_BASE +#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1 +#define HP_APM_SPI1_REG_END DR_REG_I2C_BASE +#else +#define HP_APM_SPI1_REG_END HP_APM_SPI1_REG_START +#endif + +/* NOTE: Super-Watchdog and Brownout Detector protection */ +#define LP_APM_SWD_REG_START (LP_WDT_SWD_CONFIG_REG) +#define LP_APM_SWD_REG_END (LP_WDT_INT_CLR_REG) +#define LP_APM_BOD_REG_START (LP_ANA_BOD_MODE0_CNTL_REG) +#define LP_APM_BOD_REG_END (LP_ANA_LP_INT_CLR_REG) + +/* NOTE: Following are the master IDs for setting the security mode and access through APM: + * +---------+-------------+ + * | Bit | Source | + * +---------+-------------+ + * | 0 | HP CPU | + * | 1 | reserved | + * | 2 | reserved | + * | 3 | SDIO_SLV | + * | 4 | reserved | + * | 5 | MEM_MONITOR | + * | 6 | TRACE | + * | 7~15 | reserved | + * | 16 | SPI2 | + * | 17 | Dummy-1 | + * | 18 | UHCI | + * | 19 | I2S | + * | 20 | Dummy-4 | + * | 21 | Dummy-5 | + * | 22 | reserved | + * | 23 | SHA | + * | 24 | ADC | + * | 25 | PARLIO | + * | 26~31 | Dummy-10~15 | + * +---------+-------------+ + */ + +#define APM_MASTERS_ALL (UINT32_MAX) +#define APM_MASTERS_HP_CPU (BIT(APM_MASTER_HPCORE)) +#define APM_MASTERS_GDMA_CRYPTO (BIT(APM_MASTER_GDMA_SHA)) +#define APM_MASTERS_TEE (APM_MASTERS_HP_CPU | APM_MASTERS_GDMA_CRYPTO) +#define APM_MASTERS_REE (APM_MASTERS_ALL & ~(APM_MASTERS_TEE)) + +/*----------------------- REE0 mode configuration -----------------------*/ + +/*----------------------- HP_APM configuration -----------------------*/ + +/* HP_APM: REE0 mode accessible regions */ +static apm_hal_ctrl_region_cfg_t hp_apm_regn_cfg_ree0[] = { + /* Region 0: CPU peripherals (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 0, DR_REG_TRACE_BASE, 0x600D0000, APM_PERM_R | APM_PERM_W, true), + + /* NOTE: Without this entry, the REE D/IRAM region becomes inaccessible to + * the MODEM master, resulting in an APM violation during Wi-Fi initialization. + */ + /* Region 1: REE SRAM region (RW) - for all other masters */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 1, SOC_NS_IRAM_START, SOC_IRAM_HIGH, APM_PERM_R | APM_PERM_W, true), + + /* Region 2: Peripherals [Start - MMU] (RW) */ + /* Protected: MMU */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 2, SOC_PERIPHERAL_LOW, SPI_MEM_MMU_ITEM_CONTENT_REG(0), APM_PERM_R | APM_PERM_W, true), + + /* Region 3: Peripherals [MMU - SPI1] (RW) */ + /* Protected: SPI1 */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 3, SPI_MEM_MMU_POWER_CTRL_REG(0), HP_APM_SPI1_REG_START, APM_PERM_R | APM_PERM_W, true), + + /* Region 4: Peripherals [SPI1 - Interrupt Matrix] (RW) */ + /* Protected: Interrupt Matrix */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 4, HP_APM_SPI1_REG_END, DR_REG_INTMTX_BASE, APM_PERM_R | APM_PERM_W, true), + + /* Region 5/6/7/8: Peripherals [ETM - PMU] (RW) */ + /* Protected: SHA, ECC, PCR (SHA, ECC), TEE, HP_APM, CPU_APM */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 5, DR_REG_SOC_ETM_BASE, DR_REG_SHA_BASE, APM_PERM_R | APM_PERM_W, true), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 6, DR_REG_ECDSA_BASE, PCR_SHA_CONF_REG, APM_PERM_R | APM_PERM_W, true), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 7, PCR_ECDSA_CONF_REG, DR_REG_TEE_BASE, APM_PERM_R | APM_PERM_W, true), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 8, 0x6009B000, DR_REG_PMU_BASE, APM_PERM_R | APM_PERM_W, true), + + /* Region 9: EXT_MEM region (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 9, SOC_S_DROM_HIGH, SOC_EXTRAM_DATA_HIGH, APM_PERM_R | APM_PERM_W, true), +}; + +/* HP_APM: REE0 mode masters' configuration */ +static apm_hal_ctrl_sec_mode_cfg_t hp_apm_ctrl_sec_mode_cfg_ree0 = + APM_HAL_SEC_MODE_CFG(APM_CTRL_HP_APM, APM_SEC_MODE_REE0, hp_apm_regn_cfg_ree0); + +/*----------------------- LP_APM configuration -----------------------*/ + +static apm_hal_ctrl_region_cfg_t lp_apm_regn_cfg_ree0[] = { + /* Region 0: LP Peripherals [PMU - SWDT] (RW) */ + /* Protected: SWDT */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 0, DR_REG_PMU_BASE, LP_APM_SWD_REG_START, APM_PERM_R | APM_PERM_W, true), + + /* Region 2: LP Peripherals [SWDT - BOD] (RW) */ + /* Protected: BOD */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 1, LP_APM_SWD_REG_END, LP_APM_BOD_REG_START, APM_PERM_R | APM_PERM_W, true), + + /* Region 3: LP Peripherals [BOD - eFuse BLK x] (RW) */ + /* Protected: eFuse BLK x */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 2, LP_APM_BOD_REG_END, LP_APM_EFUSE_REG_START, APM_PERM_R | APM_PERM_W, true), + + /* Region 4: LP Peripherals [eFuse - END] (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 3, LP_APM_EFUSE_REG_END, DR_REG_TRACE_BASE, APM_PERM_R | APM_PERM_W, true), +}; + +/* LP_APM: REE0 mode masters' configuration */ +static apm_hal_ctrl_sec_mode_cfg_t lp_apm_ctrl_sec_mode_cfg_ree0 = + APM_HAL_SEC_MODE_CFG(APM_CTRL_LP_APM, APM_SEC_MODE_REE0, lp_apm_regn_cfg_ree0); + +/*----------------------- CPU_APM configuration -----------------------*/ + +/* CPU_APM: REE0 mode accessible regions */ +static apm_hal_ctrl_region_cfg_t cpu_apm_regn_cfg_ree0[] = { + /* Region 0: All SRAM access (RWX) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 0, SOC_IRAM_LOW, SOC_DRAM_HIGH, APM_PERM_ALL, true), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 0, SOC_IRAM_LOW, SOC_DRAM_HIGH, APM_PERM_ALL, true), +}; + +/* CPU_APM: REE0 mode masters' configuration */ +static apm_hal_ctrl_sec_mode_cfg_t cpu_apm_ctrl_sec_mode_cfg_ree0 = + APM_HAL_SEC_MODE_CFG(APM_CTRL_CPU_APM, APM_SEC_MODE_REE0, cpu_apm_regn_cfg_ree0); + +/*---------------- TEE APM Setup -----------------------*/ + +static void enable_apm_intr(apm_ctrl_module_t ctrl_mod, uint32_t path_count) +{ + for (uint32_t i = 0; i < path_count; i++) { + apm_hal_ctrl_info_t *ctrl_info = calloc(1, sizeof(apm_hal_ctrl_info_t)); + assert(ctrl_info != NULL); + + ctrl_info->ctrl_mod = ctrl_mod; + ctrl_info->path = i; + + int intr_src_num = apm_hal_get_intr_src_num(ctrl_info); + + struct vector_desc_t apm_vd = {0}; + apm_vd.source = intr_src_num; + apm_vd.isr = tee_apm_violation_isr; + apm_vd.arg = (void *)ctrl_info; + + /* Register interrupt handler with TEE. */ + esp_tee_intr_register((void *)&apm_vd); + + /* Enable APM Ctrl interrupt for access path(M[0:n]) */ + apm_hal_clear_exception_status(ctrl_info); + apm_hal_enable_intr(ctrl_info, true); + } +} + +void esp_tee_configure_apm_protection(void) +{ + /* Disable all control filter first to have full access of address rage. */ + apm_hal_enable_ctrl_filter_all(false); + + /* HP_APM REE0 configuration. */ + apm_hal_set_ctrl_sec_mode_cfg(&hp_apm_ctrl_sec_mode_cfg_ree0); + /* HP_APM interrupt configuration. */ + enable_apm_intr(APM_CTRL_HP_APM, APM_CTRL_HP_APM_PATH_NUM); + ESP_LOGD(TAG, "[HP_APM] Configured for REE0"); + + /* LP_APM REE0 configuration. */ + apm_hal_set_ctrl_sec_mode_cfg(&lp_apm_ctrl_sec_mode_cfg_ree0); + /* LP_APM interrupt configuration. */ + enable_apm_intr(APM_CTRL_LP_APM, APM_CTRL_LP_APM_PATH_NUM); + ESP_LOGD(TAG, "[LP_APM] Configured for REE0"); + + /* CPU_APM REE0 configuration. */ + apm_hal_set_ctrl_sec_mode_cfg(&cpu_apm_ctrl_sec_mode_cfg_ree0); + /* CPU_APM interrupt configuration. */ + enable_apm_intr(APM_CTRL_CPU_APM, APM_CTRL_CPU_APM_PATH_NUM); + ESP_LOGD(TAG, "[CPU_APM] Configured for REE0"); + + /* Switch HP_CPU to TEE mode and rest of the masters to REE0 mode */ + apm_hal_set_master_sec_mode(APM_MASTERS_TEE, APM_SEC_MODE_TEE); + apm_hal_set_master_sec_mode(APM_MASTERS_REE, APM_SEC_MODE_REE0); + apm_hal_lock_master_sec_mode(APM_MASTERS_ALL); +} diff --git a/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c new file mode 100644 index 00000000000..26c8116cf94 --- /dev/null +++ b/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c @@ -0,0 +1,159 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "sdkconfig.h" +#include "soc/soc.h" +#include "soc/ext_mem_defs.h" +#include "esp_cpu.h" +#include "esp_fault.h" +#include "esp32c61/rom/rom_layout.h" +#include "esp_tee.h" + +#define IS_PMA_ENTRY_UNLOCKED(ENTRY) \ + ((RV_READ_CSR((CSR_PMACFG0) + (ENTRY)) & PMA_L) == 0) + +static void esp_cpu_configure_invalid_regions(void) +{ + const unsigned PMA_NONE = PMA_L | PMA_EN; + __attribute__((unused)) const unsigned PMA_RW = PMA_L | PMA_EN | PMA_R | PMA_W; + __attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X; + __attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X; + + // ROM uses some PMA entries, so we need to clear them before using them in ESP-IDF + + // 0. Gap at bottom of address space + PMA_RESET_AND_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE); + + // 1. Gap between debug region & IROM + PMA_RESET_AND_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE); + + // 3. Gap between ROM & RAM + PMA_RESET_AND_ENTRY_SET_TOR(3, SOC_DROM_MASK_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(4, SOC_IRAM_LOW, PMA_TOR | PMA_NONE); + + // 4. Gap between DRAM and I_Cache + PMA_RESET_AND_ENTRY_SET_TOR(5, SOC_IRAM_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE); + + // 5. ROM has configured the MSPI region with RX permission, we should add W attribute for psram and lock the configuration + // This function sets invalid regions but this is a valid memory region configuration that could have + // been configured using PMP as well, but due to insufficient PMP entries we are configuring this using PMA. + // This entry is also required to be set using PMA because the region needs to be configured as cacheable. + PMA_RESET_AND_ENTRY_SET_NAPOT(7, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_RWX); + + // 6. Gap between D_Cache & peripheral addresses + PMA_RESET_AND_ENTRY_SET_TOR(8, SOC_DROM_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(9, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE); + + // 7. End of address space + PMA_RESET_AND_ENTRY_SET_TOR(10, SOC_PERIPHERAL_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(11, UINT32_MAX, PMA_TOR | PMA_NONE); + + // 8. Using PMA to configure the TEE text and data section access attribute. */ + PMA_ENTRY_CFG_RESET(12); + assert(IS_PMA_ENTRY_UNLOCKED(13)); + assert(IS_PMA_ENTRY_UNLOCKED(14)); + assert(IS_PMA_ENTRY_UNLOCKED(15)); + + extern int _tee_iram_end; + PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(14, (int)&_tee_iram_end, PMA_TOR | PMA_RX); + PMA_RESET_AND_ENTRY_SET_TOR(15, SOC_S_DRAM_END, PMA_TOR | PMA_RW); + +} + +void esp_tee_configure_region_protection(void) +{ + /* Notes on implementation: + * + * 1) Note: ESP32-C61 CPU support overlapping PMP regions + * + * 2) ESP32-C61 supports 16 PMA regions so we use this feature to block all the invalid address ranges + * + * 3) We use combination of NAPOT (Naturally Aligned Power Of Two) and TOR (top of range) + * entries to map all the valid address space, bottom to top. This leaves us with some extra PMP entries + * which can be used to provide more granular access + * + * 4) Entries are grouped in order with some static asserts to try and verify everything is + * correct. + */ + const unsigned NONE = PMP_L; + const unsigned R = PMP_L | PMP_R; + const unsigned RW = PMP_L | PMP_R | PMP_W; + const unsigned RX = PMP_L | PMP_R | PMP_X; + const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X; + + // + // Configure all the invalid address regions using PMA + // + esp_cpu_configure_invalid_regions(); + + // + // Configure all the valid address regions using PMP + // + + // 1. CPU Subsystem region - contains interrupt config registers + PMP_ENTRY_CFG_RESET(0); + const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_CPU_SUBSYSTEM_LOW, SOC_CPU_SUBSYSTEM_HIGH); + PMP_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RWX); + _Static_assert(SOC_CPU_SUBSYSTEM_LOW < SOC_CPU_SUBSYSTEM_HIGH, "Invalid CPU subsystem region"); + + // 2. I/D-ROM + PMP_ENTRY_CFG_RESET(1); + PMP_ENTRY_CFG_RESET(2); + PMP_ENTRY_CFG_RESET(3); + const uint32_t drom_start = (uint32_t)(ets_rom_layout_p->drom_start); + if ((drom_start & (SOC_CPU_PMP_REGION_GRANULARITY - 1)) == 0) { + PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE); + PMP_ENTRY_SET(2, drom_start, PMP_TOR | RX); + PMP_ENTRY_SET(3, SOC_DROM_MASK_HIGH, PMP_TOR | R); + } else { + PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE); + PMP_ENTRY_SET(2, SOC_IROM_MASK_HIGH, PMP_TOR | RX); + _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region"); + } + + // 3. IRAM and DRAM + PMP_ENTRY_CFG_RESET(4); + PMP_ENTRY_CFG_RESET(5); + PMP_ENTRY_CFG_RESET(6); + if (esp_cpu_dbgr_is_attached()) { + // Anti-FI check that cpu is really in ocd mode + ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached()); + PMP_ENTRY_SET(4, SOC_IRAM_LOW, NONE); + PMP_ENTRY_SET(5, SOC_IRAM_HIGH, PMP_TOR | RWX); + _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region"); + } else { + // REE SRAM (D/IRAM) + PMP_ENTRY_SET(4, (int)SOC_NS_IRAM_START, NONE); + PMP_ENTRY_SET(5, (int)esp_tee_app_config.ns_iram_end, PMP_TOR | RX); + PMP_ENTRY_SET(6, SOC_DRAM_HIGH, PMP_TOR | RW); + } + + const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE; + const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end); + const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end); + const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR); + + // 4. I_Cache / D_Cache (flash) - REE + PMP_ENTRY_CFG_RESET(7); + PMP_ENTRY_CFG_RESET(8); + PMP_ENTRY_CFG_RESET(9); + PMP_ENTRY_CFG_RESET(10); + PMP_ENTRY_SET(7, s_irom_resv_end, NONE); + PMP_ENTRY_SET(8, ns_irom_resv_end, PMP_TOR | RX); + PMP_ENTRY_SET(9, ns_drom_resv_end, PMP_TOR | R); + PMP_ENTRY_SET(10, ns_drom_mmap_end, PMP_TOR | RX); + + // 5. Peripheral addresses + PMP_ENTRY_CFG_RESET(11); + const uint32_t pmpaddr11 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH); + PMP_ENTRY_SET(11, pmpaddr11, PMP_NAPOT | RW); + _Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region"); + + //TODO: Add protection for SPIRAM +} diff --git a/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_secure_sys_cfg.c b/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_secure_sys_cfg.c new file mode 100644 index 00000000000..8946c35f0ed --- /dev/null +++ b/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_secure_sys_cfg.c @@ -0,0 +1,124 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include "riscv/rv_utils.h" +#include "riscv/encoding.h" + +#include "hal/apm_hal.h" +#include "hal/sha_ll.h" +#include "hal/ecc_ll.h" +#include "hal/ecdsa_ll.h" + +#include "soc/clic_reg.h" +#include "soc/interrupts.h" + +#include "esp_tee.h" +#include "esp_tee_intr.h" +#include "esp_tee_rv_utils.h" + +#include "esp_cpu.h" +#include "esp_log.h" + +#define CSR_MCOUNTEREN 0x306 + +#define _m2u_switch(arg0, arg1) \ + ({ \ + register uintptr_t ra asm("ra") = (uintptr_t)(arg0); \ + register uintptr_t a1 asm("a1") = (uintptr_t)(arg1); \ + asm volatile("ecall" : :"r"(ra), "r"(a1) : ); \ + }) + +#define SET_BIT(t, n) (t |= (1UL << (n))) +#define CLR_BIT(t, n) (t &= ~(1UL << (n))) + +static const char *TAG = "esp_tee_secure_sys_cfg"; + +extern uint32_t _vector_table; +extern uint32_t _mtvt_table; + +void esp_tee_soc_secure_sys_init(void) +{ + ESP_LOGI(TAG, "Current privilege level - 0x%x", esp_cpu_get_curr_privilege_level()); + + /* Setting the M-mode vector table */ + rv_utils_set_mtvec((uint32_t)&_vector_table); + rv_utils_set_mtvt((uint32_t)&_mtvt_table); + + /* Disable global interrupts */ + RV_CLEAR_CSR(mstatus, MSTATUS_UIE); + RV_CLEAR_CSR(mstatus, MSTATUS_MIE); + + /* Enabled support for U-mode interrupts */ + REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_NMBITS, 0x01); + REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_UNLBITS, NLBITS); + REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_MNLBITS, NLBITS); + + /* Allow reading the cycle counter CSRs from U-mode */ + RV_WRITE_CSR(CSR_MCOUNTEREN, 0x07); + + /* Clearing all interrupt configurations */ + uint32_t core_id = esp_cpu_get_core_id(); + for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) { + interrupt_clic_ll_route(core_id, i, ETS_INVALID_INUM); + REG_CLR_BIT(DR_REG_INTMTX_BASE + 4 * i, BIT(8)); + } + + /* TODO: IDF-8958 + * The values for the secure interrupt number and priority and + * the interrupt priority threshold (for both M and U mode) need + * to be investigated further + */ + esprv_int_set_threshold(0); + + esprv_int_set_priority(TEE_SECURE_INUM, 7); + esprv_int_set_type(TEE_SECURE_INUM, ESP_CPU_INTR_TYPE_LEVEL); + esprv_int_enable(BIT(TEE_SECURE_INUM)); + esprv_int_set_vectored(TEE_SECURE_INUM, true); + rv_utils_tee_intr_set_mode(TEE_SECURE_INUM, PRV_M); + + esprv_int_set_priority(TEE_PASS_INUM, 1); + esprv_int_set_type(TEE_PASS_INUM, ESP_CPU_INTR_TYPE_LEVEL); + esprv_int_enable(BIT(TEE_PASS_INUM)); + esprv_int_set_vectored(TEE_PASS_INUM, true); + rv_utils_tee_intr_set_mode(TEE_PASS_INUM, PRV_M); + + ESP_LOGD(TAG, "Initial interrupt config -"); + ESP_LOGD(TAG, "mtvec: 0x%08x", RV_READ_CSR(mtvec)); + ESP_LOGD(TAG, "mtvt: 0x%08x", RV_READ_CSR(MTVT_CSR)); + ESP_LOGD(TAG, "mstatus: 0x%08x", RV_READ_CSR(mstatus)); + ESP_LOGD(TAG, "mcounteren: 0x%08x", RV_READ_CSR(CSR_MCOUNTEREN)); + + /* PMP, PMA and APM configuration to isolate the resources between TEE and REE. */ + esp_tee_configure_region_protection(); + esp_tee_configure_apm_protection(); + + /* Protect secure interrupt sources */ + esp_tee_protect_intr_src(ETS_LP_APM_M0_INTR_SOURCE); // LP_APM_M0 + esp_tee_protect_intr_src(ETS_HP_APM_M0_INTR_SOURCE); // HP_APM_M0 + esp_tee_protect_intr_src(ETS_HP_APM_M1_INTR_SOURCE); // HP_APM_M1 + esp_tee_protect_intr_src(ETS_HP_APM_M2_INTR_SOURCE); // HP_APM_M2 + esp_tee_protect_intr_src(ETS_HP_APM_M3_INTR_SOURCE); // HP_APM_M3 + esp_tee_protect_intr_src(ETS_CPU_APM_M0_INTR_SOURCE); // CPU_APM_M0 + esp_tee_protect_intr_src(ETS_CPU_APM_M1_INTR_SOURCE); // CPU_APM_M1 + esp_tee_protect_intr_src(ETS_SHA_INTR_SOURCE); // SHA + esp_tee_protect_intr_src(ETS_ECC_INTR_SOURCE); // ECC + esp_tee_protect_intr_src(ETS_ECDSA_INTR_SOURCE); // ECDSA + + /* Disable protected crypto peripheral clocks; they will be toggled as needed when the peripheral is in use */ + sha_ll_enable_bus_clock(false); + ecc_ll_enable_bus_clock(false); + ecdsa_ll_enable_bus_clock(false); +} + +IRAM_ATTR inline void esp_tee_switch_to_ree(uint32_t ns_entry_addr) +{ + /* 2nd argument is used as magic value to detect very first M2U switch */ + /* TBD: clean this up and use proper temporary register instead of a1 */ + /* Switch to non-secure world and launch App. */ + _m2u_switch(ns_entry_addr, ESP_TEE_M2U_SWITCH_MAGIC << 12); +} diff --git a/components/esp_tee/subproject/main/soc/esp32c61/include/esp_tee_intr_defs.h b/components/esp_tee/subproject/main/soc/esp32c61/include/esp_tee_intr_defs.h new file mode 100644 index 00000000000..b05508713bf --- /dev/null +++ b/components/esp_tee/subproject/main/soc/esp32c61/include/esp_tee_intr_defs.h @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "soc/interrupt_matrix_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// LP_APM_M0_INTR +#define TEE_SECURE_INT_APM_MASK_0 (0x00040000) +// HP_APM_M0_INTR, HP_APM_M1_INTR, HP_APM_M2_INTR +// HP_APM_M3_INTR, CPU_APM_M0_INTR, CPU_APM_M1_INTR +#define TEE_SECURE_INT_APM_MASK_1 (0x0000003F) + +// LP_RTC_TIMER_INTR +#define TEE_SECURE_INT_MASK_0 (TEE_SECURE_INT_APM_MASK_0 | 0x00008000) +#if !CONFIG_SECURE_TEE_TEST_MODE +// SHA_INTR +#define TEE_SECURE_INT_MASK_1 (TEE_SECURE_INT_APM_MASK_1 | 0x10000000) +#else +// + TG0_T0_INTR (only for test mode) +#define TEE_SECURE_INT_MASK_1 (TEE_SECURE_INT_APM_MASK_1 | 0x10004000) +#endif +// ECC_INTR, ECDSA_INTR +#define TEE_SECURE_INT_MASK_2 (0x00000003) + +#define INTMTX_STATUS_REG_0 (INTERRUPT_CORE0_INT_STATUS_REG_0_REG) +#define INTMTX_STATUS_REG_1 (INTERRUPT_CORE0_INT_STATUS_REG_1_REG) +#define INTMTX_STATUS_REG_2 (INTERRUPT_CORE0_INT_STATUS_REG_2_REG) + +#define INTMTX_SEC_STATUS_REG (INTERRUPT_CORE0_SECURE_STATUS_REG) +#define INTMTX_SIG_IDX_ASSERT_IN_SEC_REG (INTERRUPT_CORE0_SIG_IDX_ASSERT_IN_SEC_REG) + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_tee/subproject/main/soc/esp32h2/include/esp_tee_rv_utils.h b/components/esp_tee/subproject/main/soc/esp32h2/include/esp_tee_rv_utils.h deleted file mode 100644 index 3d10f53c46a..00000000000 --- a/components/esp_tee/subproject/main/soc/esp32h2/include/esp_tee_rv_utils.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once - -#include -#include - -#include "riscv/csr.h" -#include "riscv/interrupt.h" - -#include "soc/interrupt_reg.h" -#include "soc/plic_reg.h" - -#include "esp_attr.h" -#include "esp_tee.h" - -#ifdef __cplusplus -extern "C" { -#endif - -FORCE_INLINE_ATTR void rv_utils_tee_intr_global_enable(void) -{ - /* - * Set the the U-mode previous enable global interrupts state - * - * NOTE: The TICK interrupt is setup before this service call and thus, - * it occurs in the return path of this call. - * - * Before entering the U-mode interrupt handler routine, USTATUS:UIE is - * cleared to disable U-mode interrupts temporarily. - * - * While exiting the above routine, URET is executed, setting USTATUS:UIE - * to the value of USTATUS:UPIE. However, since no interrupts were enabled - * previously, USTATUS:UPIE and thus, USTATUS:UIE is cleared. - * - * The service call completes and returns to U-mode with USTATUS:UIE disabled, - * preventing any further interrupts in U-mode. - * - */ - RV_SET_CSR(ustatus, USTATUS_UPIE); - /* Enabling the global M-mode and U-mode interrupts */ - RV_SET_CSR(ustatus, USTATUS_UIE); - RV_SET_CSR(mstatus, MSTATUS_UIE); - RV_SET_CSR(mstatus, MSTATUS_MIE); -} - -FORCE_INLINE_ATTR void rv_utils_tee_intr_global_disable(void) -{ - RV_CLEAR_CSR(ustatus, USTATUS_UIE); - RV_CLEAR_CSR(mstatus, MSTATUS_UIE); - RV_CLEAR_CSR(mstatus, MSTATUS_MIE); -} - -FORCE_INLINE_ATTR void rv_utils_tee_intr_enable(uint32_t intr_mask) -{ - // Disable all interrupts to make updating of the interrupt mask atomic. - unsigned old_xstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE); - REG_SET_BIT(PLIC_MXINT_ENABLE_REG, intr_mask); - REG_SET_BIT(PLIC_UXINT_ENABLE_REG, intr_mask); - RV_SET_CSR(mie, intr_mask); - RV_SET_CSR(uie, intr_mask); - RV_SET_CSR(mstatus, old_xstatus & MSTATUS_MIE); -} - -FORCE_INLINE_ATTR void rv_utils_tee_intr_disable(uint32_t intr_mask) -{ - // Disable all interrupts to make updating of the interrupt mask atomic. - unsigned old_xstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE); - REG_CLR_BIT(PLIC_MXINT_ENABLE_REG, intr_mask); - REG_CLR_BIT(PLIC_UXINT_ENABLE_REG, intr_mask); - RV_CLEAR_CSR(mie, intr_mask); - RV_CLEAR_CSR(uie, intr_mask); - RV_SET_CSR(mstatus, old_xstatus & MSTATUS_MIE); -} - -FORCE_INLINE_ATTR void rv_utils_tee_intr_set_type(int intr_num, enum intr_type type) -{ - assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); - - if (type == INTR_TYPE_LEVEL) { - REG_CLR_BIT(PLIC_MXINT_TYPE_REG, BIT(intr_num)); - REG_CLR_BIT(PLIC_UXINT_TYPE_REG, BIT(intr_num)); - } else { - REG_SET_BIT(PLIC_MXINT_TYPE_REG, BIT(intr_num)); - REG_SET_BIT(PLIC_UXINT_TYPE_REG, BIT(intr_num)); - } -} - -FORCE_INLINE_ATTR void rv_utils_tee_intr_set_priority(int rv_int_num, int priority) -{ - assert(rv_int_num >= 0 && rv_int_num < SOC_CPU_INTR_NUM); - - REG_WRITE(PLIC_MXINT_PRI_REG(rv_int_num), priority); - REG_WRITE(PLIC_UXINT_PRI_REG(rv_int_num), priority); -} - -FORCE_INLINE_ATTR void rv_utils_tee_intr_set_threshold(int priority_threshold) -{ - REG_WRITE(PLIC_MXINT_THRESH_REG, priority_threshold); - REG_WRITE(PLIC_UXINT_THRESH_REG, priority_threshold); -} - -FORCE_INLINE_ATTR void rv_utils_tee_intr_edge_ack(int intr_num) -{ - assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); - - REG_SET_BIT(PLIC_MXINT_CLEAR_REG, BIT(intr_num)); - REG_SET_BIT(PLIC_UXINT_CLEAR_REG, BIT(intr_num)); -} - -#ifdef __cplusplus -} -#endif diff --git a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_interrupt.c b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_interrupt.c index f7f2c59d7ec..046289b5ad1 100644 --- a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_interrupt.c +++ b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_interrupt.c @@ -21,6 +21,12 @@ static const char *TAG __attribute__((unused)) = "esp_tee_intr_test"; +#if CONFIG_IDF_TARGET_ESP32C61 +#define TIMER_INTR_SRC ETS_TG0_T0_INTR_SOURCE +#else +#define TIMER_INTR_SRC ETS_TG0_T0_LEVEL_INTR_SOURCE +#endif + /* ---------------------------------------------------- Utility functions ---------------------------------------------------- */ #define TEST_TIMER_GROUP (0) @@ -63,7 +69,7 @@ static void test_timer_deinit(void) // Deregister ISR struct vector_desc_t timer_vd = { - .source = ETS_TG0_T0_LEVEL_INTR_SOURCE, + .source = TIMER_INTR_SRC, }; esp_tee_intr_deregister((void *)&timer_vd); timer_ll_enable_clock(TEST_TIMER_GROUP, timer_id, false); @@ -90,7 +96,7 @@ static void test_timer_init(volatile uint32_t *arg) // Register ISR struct vector_desc_t timer_vd = { - .source = ETS_TG0_T0_LEVEL_INTR_SOURCE, + .source = TIMER_INTR_SRC, .isr = test_timer_isr, .arg = (void *)arg, }; diff --git a/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt b/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt index ed0dcc3d268..f38d3ffc802 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt +++ b/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt @@ -22,20 +22,25 @@ endif() set(mbedtls_test_srcs_dir "${idf_path}/components/mbedtls/test_apps/main") # AES -list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes.c" - "${mbedtls_test_srcs_dir}/test_aes_gcm.c" - "${mbedtls_test_srcs_dir}/test_aes_perf.c") +if(CONFIG_SOC_AES_SUPPORTED) + list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes.c" + "${mbedtls_test_srcs_dir}/test_aes_gcm.c" + "${mbedtls_test_srcs_dir}/test_aes_perf.c") +endif() # SHA -list(APPEND srcs "${mbedtls_test_srcs_dir}/test_mbedtls_sha.c" - "${mbedtls_test_srcs_dir}/test_sha.c" - "${mbedtls_test_srcs_dir}/test_sha_perf.c") - +if(CONFIG_SOC_SHA_SUPPORTED) + list(APPEND srcs "${mbedtls_test_srcs_dir}/test_mbedtls_sha.c" + "${mbedtls_test_srcs_dir}/test_sha.c" + "${mbedtls_test_srcs_dir}/test_sha_perf.c") +endif() # Mixed -list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes_sha_parallel.c") - +if(CONFIG_SOC_AES_SUPPORTED AND CONFIG_SOC_SHA_SUPPORTED) + list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes_sha_parallel.c") +endif() # ECC -list(APPEND srcs "${mbedtls_test_srcs_dir}/test_ecp.c") - +if(CONFIG_SOC_ECC_SUPPORTED) + list(APPEND srcs "${mbedtls_test_srcs_dir}/test_ecp.c") +endif() # Utility list(APPEND srcs "${mbedtls_test_srcs_dir}/test_apb_dport_access.c" "${mbedtls_test_srcs_dir}/test_mbedtls_utils.c") diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c index 612c0d475bd..cb058018bce 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c @@ -4,9 +4,17 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "soc/soc_caps.h" + +#if SOC_AES_SUPPORTED #include "soc/aes_reg.h" +#endif +#if SOC_HMAC_SUPPORTED #include "soc/hmac_reg.h" +#endif +#if SOC_DIG_SIGN_SUPPORTED #include "soc/ds_reg.h" +#endif #include "soc/efuse_reg.h" #include "soc/pcr_reg.h" #include "soc/lp_analog_peri_reg.h" @@ -52,6 +60,7 @@ TEST_CASE("Test APM violation: MMU", "[apm_violation]") TEST_FAIL_MESSAGE("APM violation should have been generated"); } +#if SOC_AES_SUPPORTED TEST_CASE("Test APM violation: AES", "[apm_violation]") { uint32_t val = UINT32_MAX; @@ -59,7 +68,9 @@ TEST_CASE("Test APM violation: AES", "[apm_violation]") TEST_ASSERT_EQUAL(0, val); TEST_FAIL_MESSAGE("APM violation should have been generated"); } +#endif +#if SOC_AES_SUPPORTED TEST_CASE("Test APM violation: HMAC", "[apm_violation]") { uint32_t val = UINT32_MAX; @@ -67,7 +78,9 @@ TEST_CASE("Test APM violation: HMAC", "[apm_violation]") TEST_ASSERT_EQUAL(0, val); TEST_FAIL_MESSAGE("APM violation should have been generated"); } +#endif +#if SOC_DIG_SIGN_SUPPORTED TEST_CASE("Test APM violation: DS", "[apm_violation]") { uint32_t val = UINT32_MAX; @@ -75,6 +88,7 @@ TEST_CASE("Test APM violation: DS", "[apm_violation]") TEST_ASSERT_EQUAL(0, val); TEST_FAIL_MESSAGE("APM violation should have been generated"); } +#endif TEST_CASE("Test APM violation: SHA PCR", "[apm_violation]") { From 2cb0fa5c3458504fc7adf03c2511ed5180a5ac23 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Fri, 19 Sep 2025 15:44:13 +0530 Subject: [PATCH 2/4] feat(esp_tee): Support for ESP32-C61 - the rest of the components --- components/esp_hw_support/esp_clk.c | 4 ++ components/esp_hw_support/include/esp_cpu.h | 2 +- .../esp32c61/mspi_timing_tuning_configs.h | 2 +- .../port/esp32c61/CMakeLists.txt | 4 +- .../port/esp32c61/cpu_region_protect.c | 9 +++++ .../port/esp32c61/esp_cpu_intr.c | 17 ++++++++- .../esp_mm/port/esp32c61/ext_mem_layout.c | 33 +++++++++++++++-- components/esp_security/CMakeLists.txt | 11 +++++- .../esp_system/ld/esp32c61/memory.ld.in | 20 +++++++++- .../esp_system/ld/esp32c61/sections.ld.in | 13 +++++++ components/hal/CMakeLists.txt | 27 +++++++++++--- components/heap/port/esp32c61/memory_layout.c | 15 +++++++- .../esp_tee/esp_tee_crypto_shared_gdma.c | 19 +++++++--- .../mbedtls/esp_tee/esp_tee_mbedtls.cmake | 37 +++++++++++-------- .../mbedtls/esp_tee/esp_tee_mbedtls_config.h | 8 +++- .../soc/esp32c61/register/soc/tee_reg.h | 1 - 16 files changed, 180 insertions(+), 42 deletions(-) diff --git a/components/esp_hw_support/esp_clk.c b/components/esp_hw_support/esp_clk.c index 3eaefc4cf87..da2bab1d2d5 100644 --- a/components/esp_hw_support/esp_clk.c +++ b/components/esp_hw_support/esp_clk.c @@ -163,7 +163,9 @@ void esp_clk_slowclk_cal_set(uint32_t new_cal) #if SOC_RTC_MEM_SUPPORTED esp_rtc_get_time_us(); #else +#if !NON_OS_BUILD esp_os_enter_critical_safe(&s_esp_rtc_time_lock); +#endif uint32_t old_cal = clk_ll_rtc_slow_load_cal(); if (old_cal != 0) { /** @@ -186,7 +188,9 @@ void esp_clk_slowclk_cal_set(uint32_t new_cal) new_fix_us = old_fix_us - new_fix_us; clk_ll_rtc_slow_store_rtc_fix_us(new_fix_us); } +#if !NON_OS_BUILD esp_os_exit_critical_safe(&s_esp_rtc_time_lock); +#endif #endif // SOC_RTC_MEM_SUPPORTED #endif // CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER clk_ll_rtc_slow_store_cal(new_cal); diff --git a/components/esp_hw_support/include/esp_cpu.h b/components/esp_hw_support/include/esp_cpu.h index cbecbafff64..87678f2f6c2 100644 --- a/components/esp_hw_support/include/esp_cpu.h +++ b/components/esp_hw_support/include/esp_cpu.h @@ -469,7 +469,7 @@ FORCE_INLINE_ATTR uint32_t esp_cpu_intr_get_enabled_mask(void) #ifdef __XTENSA__ return xt_utils_intr_get_enabled_mask(); #else -#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD && CONFIG_IDF_TARGET_ESP32C5 +#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD && SOC_INT_CLIC_SUPPORTED extern esprv_int_mgmt_t esp_tee_intr_sec_srv_cb; return esp_tee_intr_sec_srv_cb(1, SS_RV_UTILS_INTR_GET_ENABLED_MASK); #else diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h b/components/esp_hw_support/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h index 42755b434f1..600754208db 100644 --- a/components/esp_hw_support/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h +++ b/components/esp_hw_support/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h @@ -42,7 +42,7 @@ #define MSPI_TIMING_PSRAM_MODULE_CLOCK 10 //Define this to 10MHz #endif //------------------------------------PSRAM Needs Tuning or not-------------------------------------// -#if MSPI_TIMING_PSRAM_STR_MODE +#if MSPI_TIMING_PSRAM_STR_MODE && !CONFIG_SECURE_ENABLE_TEE #define MSPI_TIMING_PSRAM_NEEDS_TUNING (MSPI_TIMING_PSRAM_MODULE_CLOCK > 40) #endif diff --git a/components/esp_hw_support/port/esp32c61/CMakeLists.txt b/components/esp_hw_support/port/esp32c61/CMakeLists.txt index ad67c18301c..34af45cde61 100644 --- a/components/esp_hw_support/port/esp32c61/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c61/CMakeLists.txt @@ -1,3 +1,5 @@ +idf_build_get_property(non_os_build NON_OS_BUILD) + set(srcs "rtc_clk_init.c" "rtc_clk.c" "pmu_param.c" @@ -8,7 +10,7 @@ set(srcs "rtc_clk_init.c" "ocode_init.c" ) -if(NOT BOOTLOADER_BUILD) +if(NOT non_os_build) list(APPEND srcs "sar_periph_ctrl.c") endif() diff --git a/components/esp_hw_support/port/esp32c61/cpu_region_protect.c b/components/esp_hw_support/port/esp32c61/cpu_region_protect.c index 5c4a4cdca2f..73b9078c8c6 100644 --- a/components/esp_hw_support/port/esp32c61/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32c61/cpu_region_protect.c @@ -123,6 +123,15 @@ void esp_cpu_configure_region_protection(void) // Configure all the invalid address regions using PMA // esp_cpu_configure_invalid_regions(); + + /* NOTE: When ESP-TEE is active, only configure invalid memory regions in bootloader + * to prevent errors before TEE initialization. TEE will handle all other + * memory protection. + */ +#if CONFIG_SECURE_ENABLE_TEE && BOOTLOADER_BUILD + return; +#endif + // // Configure all the valid address regions using PMP // diff --git a/components/esp_hw_support/port/esp32c61/esp_cpu_intr.c b/components/esp_hw_support/port/esp32c61/esp_cpu_intr.c index ded3030aebc..4a3f315010a 100644 --- a/components/esp_hw_support/port/esp32c61/esp_cpu_intr.c +++ b/components/esp_hw_support/port/esp32c61/esp_cpu_intr.c @@ -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 */ @@ -15,7 +15,20 @@ void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_ * Reserve interrupt line 1 for the Wifi controller. * Reserve interrupt line 6 since it is used for disabling interrupts in the interrupt allocator (INT_MUX_DISABLED_INTNO) */ - const uint32_t rsvd_mask = BIT(1) | BIT(6); + const uint32_t base_rsvd_mask = BIT(1) | BIT(6); + + /* On the ESP32-C61, interrupt 31 is reserved for ESP-TEE + * for operations related to secure peripherals under its control + * (e.g. SHA, ECC, APM) + * + * Interrupt 30 is reserved for handling REE interrupts occurring in TEE. + */ +#if CONFIG_SECURE_ENABLE_TEE + const uint32_t rsvd_mask = base_rsvd_mask | BIT(30) | BIT(31); +#else + const uint32_t rsvd_mask = base_rsvd_mask; +#endif + intr_desc_ret->priority = 1; intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask); diff --git a/components/esp_mm/port/esp32c61/ext_mem_layout.c b/components/esp_mm/port/esp32c61/ext_mem_layout.c index b7c44be4ff4..722779f4c5a 100644 --- a/components/esp_mm/port/esp32c61/ext_mem_layout.c +++ b/components/esp_mm/port/esp32c61/ext_mem_layout.c @@ -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 */ @@ -10,15 +10,40 @@ #include "../ext_mem_layout.h" #include "hal/mmu_types.h" +/* NOTE: With ESP-TEE enabled: + * - The start address is moved by the size of TEE IDROM segments since these + * segments are placed at the start of the linear address space + * - TEE IROM and DROM segments are both 64KB (CONFIG_SECURE_TEE_IROM_SIZE, + * CONFIG_SECURE_TEE_DROM_SIZE) for now. Thus, the number of reserved entries + * from the start would be (64KB + 64KB)/MMU_PAGE_SIZE + * - The last few MMU entries are reserved for TEE flash operations. The number + * of reserved entries matches the size of TEE IDROM segments (IROM + DROM) + * plus one additional entry, i.e. (64KB + 64KB)/MMU_PAGE_SIZE + 1 + */ +#if CONFIG_SECURE_ENABLE_TEE +#define TEE_MMU_MEM_REG_START_OFFS (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE) +#define TEE_MMU_RESV_PAGES ((CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE) / CONFIG_MMU_PAGE_SIZE) +#define TEE_MMU_MEM_REG_END_OFFS ((TEE_MMU_RESV_PAGES + 1) * CONFIG_MMU_PAGE_SIZE) + +#define MMU_MEM_REG_START_ADDR_W_TEE (SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW + TEE_MMU_MEM_REG_START_OFFS) +#define MMU_MEM_REG_END_ADDR_W_TEE (SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH - TEE_MMU_MEM_REG_END_OFFS) + +#define MMU_IRAM0_LINEAR_ADDRESS_LOW MMU_MEM_REG_START_ADDR_W_TEE +#define MMU_IRAM0_LINEAR_ADDRESS_HIGH MMU_MEM_REG_END_ADDR_W_TEE +#else +#define MMU_IRAM0_LINEAR_ADDRESS_LOW SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW +#define MMU_IRAM0_LINEAR_ADDRESS_HIGH SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH +#endif + /** * The start addresses in this list should always be sorted from low to high, as MMU driver will need to * coalesce adjacent regions */ const mmu_mem_region_t g_mmu_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = { [0] = { - .start = SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW, - .end = SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH, - .size = SOC_BUS_SIZE(SOC_MMU_IRAM0_LINEAR), + .start = MMU_IRAM0_LINEAR_ADDRESS_LOW, + .end = MMU_IRAM0_LINEAR_ADDRESS_HIGH, + .size = MMU_IRAM0_LINEAR_ADDRESS_HIGH - MMU_IRAM0_LINEAR_ADDRESS_LOW, .bus_id = CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0, .targets = MMU_TARGET_FLASH0 | MMU_TARGET_PSRAM0, .caps = MMU_MEM_CAP_EXEC | MMU_MEM_CAP_READ | MMU_MEM_CAP_WRITE | MMU_MEM_CAP_32BIT | MMU_MEM_CAP_8BIT, diff --git a/components/esp_security/CMakeLists.txt b/components/esp_security/CMakeLists.txt index cc7a1fcb19e..35dc2361d9a 100644 --- a/components/esp_security/CMakeLists.txt +++ b/components/esp_security/CMakeLists.txt @@ -32,9 +32,16 @@ if(NOT non_os_build) list(APPEND srcs "src/esp_crypto_lock.c" "src/esp_crypto_periph_clk.c") list(APPEND priv_requires efuse esp_system esp_timer) elseif(esp_tee_build) - list(APPEND srcs "src/esp_crypto_lock.c" "src/esp_crypto_periph_clk.c" - "src/esp_hmac.c" "src/esp_ds.c") + list(APPEND srcs "src/esp_crypto_lock.c" "src/esp_crypto_periph_clk.c") list(APPEND includes "src/${IDF_TARGET}") + + if(CONFIG_SOC_HMAC_SUPPORTED) + list(APPEND srcs "src/esp_hmac.c") + endif() + + if(CONFIG_SOC_DIG_SIGN_SUPPORTED) + list(APPEND srcs "src/esp_ds.c") + endif() endif() idf_component_register(SRCS ${srcs} diff --git a/components/esp_system/ld/esp32c61/memory.ld.in b/components/esp_system/ld/esp32c61/memory.ld.in index 1d2137e8991..a1af258aeb6 100644 --- a/components/esp_system/ld/esp32c61/memory.ld.in +++ b/components/esp_system/ld/esp32c61/memory.ld.in @@ -15,7 +15,13 @@ #include "sdkconfig.h" #include "ld.common" -#define SRAM_SEG_START 0x40800000 +#if !CONFIG_SECURE_ENABLE_TEE +#define SRAM_SEG_START (0x40800000) +#else +#define SRAM_SEG_START (0x40800000 + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE) +#define FLASH_SEG_OFFSET (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE) +#endif // CONFIG_SECURE_ENABLE_TEE + #define SRAM_SEG_END 0x4083ea70 /* 2nd stage bootloader iram_loader_seg start address */ #define SRAM_SEG_SIZE SRAM_SEG_END - SRAM_SEG_START @@ -33,8 +39,14 @@ MEMORY */ #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS +#if CONFIG_SECURE_ENABLE_TEE + /* Flash mapped instruction data */ + irom_seg (RX) : org = 0x42000020 + FLASH_SEG_OFFSET, + len = IDRAM0_2_SEG_SIZE - FLASH_SEG_OFFSET - 0x20 +#else /* Flash mapped instruction data */ irom_seg (RX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 +#endif /** * (0x20 offset above is a convenience for the app binary image generation. @@ -52,8 +64,14 @@ MEMORY sram_seg (RWX) : org = SRAM_SEG_START, len = SRAM_SEG_SIZE #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS +#if CONFIG_SECURE_ENABLE_TEE /* Flash mapped constant data */ + drom_seg (R) : org = 0x42000020 + FLASH_SEG_OFFSET, + len = IDRAM0_2_SEG_SIZE - FLASH_SEG_OFFSET - 0x20 +#else + /* Flash mapped instruction data */ drom_seg (R) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 +#endif /* (See irom_seg for meaning of 0x20 offset in the above.) */ #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS diff --git a/components/esp_system/ld/esp32c61/sections.ld.in b/components/esp_system/ld/esp32c61/sections.ld.in index daac666f97f..db2675780b5 100644 --- a/components/esp_system/ld/esp32c61/sections.ld.in +++ b/components/esp_system/ld/esp32c61/sections.ld.in @@ -16,9 +16,22 @@ SECTIONS _iram_start = ABSOLUTE(.); /* Vectors go to start of IRAM */ ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); + _vector_table_start = ABSOLUTE(.); KEEP(*(.exception_vectors_table.text)); KEEP(*(.exception_vectors.text)); + ALIGNED_SYMBOL(4, _invalid_pc_placeholder) + + /* esp_tee_config_t structure: used to share information between the TEE and REE + * (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.) + * This symbol is expected by the TEE at an offset of 0x2b0 from the vector table start. + */ +#if CONFIG_SECURE_ENABLE_TEE + ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg) + ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2b0, "esp_tee_app_cfg must be at an offset 0x2b0 from the vector table start"); + *libesp_tee.a:(.esp_tee_app_cfg); +#endif + /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 16ba0b61bbc..1d42d9f4a74 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -47,12 +47,27 @@ endif() if(esp_tee_build) list(APPEND srcs "apm_hal.c" - "brownout_hal.c" - "aes_hal.c" - "sha_hal.c" - "hmac_hal.c" - "ds_hal.c" - "ecc_hal.c") + "brownout_hal.c") + + if(CONFIG_SOC_AES_SUPPORTED) + list(APPEND srcs "aes_hal.c") + endif() + + if(CONFIG_SOC_SHA_SUPPORTED) + list(APPEND srcs "sha_hal.c") + endif() + + if(CONFIG_SOC_HMAC_SUPPORTED) + list(APPEND srcs "hmac_hal.c") + endif() + + if(CONFIG_SOC_DIG_SIGN_SUPPORTED) + list(APPEND srcs "ds_hal.c") + endif() + + if(CONFIG_SOC_ECC_SUPPORTED) + list(APPEND srcs "ecc_hal.c") + endif() elseif(NOT BOOTLOADER_BUILD) list(APPEND srcs "color_hal.c") diff --git a/components/heap/port/esp32c61/memory_layout.c b/components/heap/port/esp32c61/memory_layout.c index c137b781556..c1ca8ee53ef 100644 --- a/components/heap/port/esp32c61/memory_layout.c +++ b/components/heap/port/esp32c61/memory_layout.c @@ -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,6 +12,11 @@ #include "heap_memory_layout.h" #include "esp_heap_caps.h" +#if CONFIG_SECURE_ENABLE_TEE +#define SRAM_DIRAM_TEE_ORG (SOC_DIRAM_IRAM_LOW) +#define SRAM_DIRAM_TEE_END (SRAM_DIRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE) +#endif + /* Memory layout for ESP32C61 SoC * Note that the external memory is not represented in this file since * it is handled by the esp_psram component @@ -89,3 +94,11 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d // Target has a shared D/IRAM virtual address, no need to calculate I_D_OFFSET like previous chips SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code); + +/* NOTE: When ESP-TEE is enabled, the start of the internal SRAM +* is used by the TEE and is protected from any REE access using +* memory protection mechanisms employed by ESP-TEE. +*/ +#if CONFIG_SECURE_ENABLE_TEE +SOC_RESERVE_MEMORY_REGION((intptr_t)SRAM_DIRAM_TEE_ORG, (intptr_t)(SRAM_DIRAM_TEE_END), tee_diram); +#endif diff --git a/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c index 29b55762e58..7b89a83c039 100644 --- a/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c +++ b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c @@ -11,8 +11,6 @@ #include "esp_crypto_dma.h" #include "hal/gdma_types.h" -#include "hal/aes_hal.h" - #include "soc/gdma_channel.h" #include "soc/soc_caps.h" @@ -86,11 +84,18 @@ static void crypto_shared_gdma_init(void) esp_err_t esp_tee_crypto_shared_gdma_start(const crypto_dma_desc_t *input, const crypto_dma_desc_t *output, gdma_trigger_peripheral_t periph) { int periph_inst_id = SOC_GDMA_TRIG_PERIPH_M2M0; - if (periph == GDMA_TRIG_PERIPH_SHA) { + switch (periph) { +#if SOC_SHA_SUPPORTED + case GDMA_TRIG_PERIPH_SHA: periph_inst_id = SOC_GDMA_TRIG_PERIPH_SHA0; - } else if (periph == GDMA_TRIG_PERIPH_AES) { + break; +#endif +#if SOC_AES_SUPPORTED + case GDMA_TRIG_PERIPH_AES: periph_inst_id = SOC_GDMA_TRIG_PERIPH_AES0; - } else { + break; +#endif + default: return ESP_ERR_INVALID_ARG; } @@ -133,6 +138,7 @@ void esp_tee_crypto_shared_gdma_free(void) /* ---------------------------------------------- DMA Implementations: AES ------------------------------------------------- */ +#if SOC_AES_SUPPORTED esp_err_t esp_aes_dma_start(const crypto_dma_desc_t *input, const crypto_dma_desc_t *output) { return esp_tee_crypto_shared_gdma_start(input, output, GDMA_TRIG_PERIPH_AES); @@ -142,10 +148,13 @@ bool esp_aes_dma_done(const crypto_dma_desc_t *output) { return (output->dw0.owner == 0); } +#endif /* ---------------------------------------------- DMA Implementations: SHA ------------------------------------------------- */ +#if SOC_SHA_SUPPORTED esp_err_t esp_sha_dma_start(const crypto_dma_desc_t *input) { return esp_tee_crypto_shared_gdma_start(input, NULL, GDMA_TRIG_PERIPH_SHA); } +#endif diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake index 2beb36233af..4f62a1f9b02 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake @@ -48,23 +48,30 @@ target_include_directories(mbedcrypto PRIVATE ${crypto_port_inc_dirs}) target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/esp_tee/esp_tee_crypto_shared_gdma.c") # AES implementation -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes.c" - "${COMPONENT_DIR}/port/aes/dma/esp_aes_dma_core.c") - -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_common.c" - "${COMPONENT_DIR}/port/aes/esp_aes_xts.c" - "${COMPONENT_DIR}/port/aes/esp_aes_gcm.c") +if(CONFIG_SOC_AES_SUPPORTED) + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes.c" + "${COMPONENT_DIR}/port/aes/dma/esp_aes_dma_core.c" + "${COMPONENT_DIR}/port/aes/esp_aes_common.c" + "${COMPONENT_DIR}/port/aes/esp_aes_xts.c" + "${COMPONENT_DIR}/port/aes/esp_aes_gcm.c") +endif() # SHA implementation -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/core/esp_sha1.c" - "${COMPONENT_DIR}/port/sha/core/esp_sha256.c" - "${COMPONENT_DIR}/port/sha/core/esp_sha512.c") +if(CONFIG_SOC_SHA_SUPPORTED) + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/core/esp_sha1.c" + "${COMPONENT_DIR}/port/sha/core/esp_sha256.c" + "${COMPONENT_DIR}/port/sha/core/esp_sha512.c" + "${COMPONENT_DIR}/port/sha/core/sha.c" + "${COMPONENT_DIR}/port/sha/esp_sha.c") +endif() -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/core/sha.c" - "${COMPONENT_DIR}/port/sha/esp_sha.c") - -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/ecc/esp_ecc.c" - "${COMPONENT_DIR}/port/ecc/ecc_alt.c") +# ECC implementation +if(CONFIG_SOC_ECC_SUPPORTED) + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/ecc/esp_ecc.c" + "${COMPONENT_DIR}/port/ecc/ecc_alt.c") +endif() # HMAC-based PBKDF2 implementation -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c") +if(CONFIG_SOC_HMAC_SUPPORTED) + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c") +endif() diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h index 5021e43c921..b30a8493e12 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -37,8 +37,12 @@ #define MBEDTLS_CIPHER_C #define MBEDTLS_AES_C #define MBEDTLS_GCM_C +#if SOC_AES_SUPPORTED #define MBEDTLS_AES_ALT #define MBEDTLS_GCM_ALT +#else +#define MBEDTLS_AES_ROM_TABLES +#endif #define MBEDTLS_CIPHER_MODE_XTS #define MBEDTLS_ASN1_WRITE_C @@ -61,7 +65,7 @@ #define MBEDTLS_SHA512_C #endif -#if CONFIG_MBEDTLS_HARDWARE_SHA +#if SOC_SHA_SUPPORTED #if CONFIG_MBEDTLS_SHA1_C #define MBEDTLS_SHA1_ALT #endif @@ -71,7 +75,7 @@ #endif #endif -#ifdef CONFIG_MBEDTLS_HARDWARE_ECC +#if SOC_ECC_SUPPORTED #define MBEDTLS_ECP_MUL_ALT #define MBEDTLS_ECP_VERIFY_ALT #endif diff --git a/components/soc/esp32c61/register/soc/tee_reg.h b/components/soc/esp32c61/register/soc/tee_reg.h index 52d683f8a65..95d414f77a0 100644 --- a/components/soc/esp32c61/register/soc/tee_reg.h +++ b/components/soc/esp32c61/register/soc/tee_reg.h @@ -5,7 +5,6 @@ */ #pragma once -#include #include "soc/soc.h" #ifdef __cplusplus extern "C" { From 65436262d5d2becb09f094ef8b54e926a5d9f5b4 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Fri, 26 Sep 2025 19:24:04 +0530 Subject: [PATCH 3/4] feat(esp_tee): Add support for TEE secure storage encryption for ESP32-C61 --- .../tee_sec_storage/tee_sec_storage.c | 61 ++++++++++++++++--- .../mbedtls/esp_tee/esp_tee_mbedtls_config.h | 4 ++ 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c index d42c20c0cf0..0ad68fd8699 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c @@ -16,6 +16,8 @@ #if SOC_HMAC_SUPPORTED #include "esp_hmac.h" #include "esp_hmac_pbkdf2.h" +#else +#include "mbedtls/md.h" #endif #include "mbedtls/aes.h" @@ -139,25 +141,60 @@ static int rand_func(void *rng_state, unsigned char *output, size_t len) } #if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE -static esp_err_t compute_nvs_keys_with_hmac(hmac_key_id_t hmac_key_id, nvs_sec_cfg_t *cfg) +static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_cfg_t *cfg) { - uint32_t ekey_seed[8] = {[0 ... 7] = EKEY_SEED}; - uint32_t tkey_seed[8] = {[0 ... 7] = TKEY_SEED}; + const uint32_t ekey_seed[8] = {[0 ... 7] = EKEY_SEED}; + const uint32_t tkey_seed[8] = {[0 ... 7] = TKEY_SEED}; + esp_err_t err = ESP_FAIL; memset(cfg, 0x00, sizeof(nvs_sec_cfg_t)); - esp_err_t err = ESP_FAIL; +#if SOC_HMAC_SUPPORTED + hmac_key_id_t hmac_key_id = (hmac_key_id_t)(key_blk - EFUSE_BLK_KEY0); + if (hmac_key_id < 0 || hmac_key_id >= HMAC_KEY_MAX) { + return ESP_ERR_INVALID_ARG; + } + err = esp_hmac_calculate(hmac_key_id, ekey_seed, sizeof(ekey_seed), (uint8_t *)cfg->eky); err |= esp_hmac_calculate(hmac_key_id, tkey_seed, sizeof(tkey_seed), (uint8_t *)cfg->tky); if (err != ESP_OK) { + memset(cfg, 0x00, sizeof(nvs_sec_cfg_t)); + ESP_LOGE(TAG, "Failed to calculate seed HMAC"); + return err; + } + ESP_FAULT_ASSERT(err == ESP_OK); +#else + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + if (md_info == NULL) { + return ESP_FAIL; + } + + uint8_t key_buf[SHA256_DIGEST_SZ] = {0}; + /* NOTE: The eFuse key for SoCs without HMAC support should NOT be + * read-protected when burning in the eFuse + */ + err = esp_efuse_read_block(key_blk, key_buf, 0, sizeof(key_buf) * 8); + if (err != ESP_OK) { + return err; + } + + int ret = mbedtls_md_hmac(md_info, key_buf, sizeof(key_buf), + (const uint8_t *)ekey_seed, sizeof(ekey_seed), + cfg->eky); + ret |= mbedtls_md_hmac(md_info, key_buf, sizeof(key_buf), + (const uint8_t *)tkey_seed, sizeof(tkey_seed), + cfg->tky); + if (ret != 0) { + memset(cfg, 0x00, sizeof(nvs_sec_cfg_t)); ESP_LOGE(TAG, "Failed to calculate seed HMAC"); return ESP_FAIL; } - ESP_FAULT_ASSERT(err == ESP_OK); + ESP_FAULT_ASSERT(ret == 0); + memset(key_buf, 0x00, sizeof(key_buf)); +#endif /* NOTE: If the XTS E-key and T-key are the same, we have a hash collision */ ESP_FAULT_ASSERT(memcmp(cfg->eky, cfg->tky, NVS_KEY_SIZE) != 0); - return ESP_OK; } #endif @@ -170,13 +207,17 @@ static esp_err_t read_security_cfg_hmac(nvs_sec_cfg_t *cfg) #if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE esp_efuse_block_t hmac_key_blk = (esp_efuse_block_t)(EFUSE_BLK_KEY0 + (esp_efuse_block_t)CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID); - esp_efuse_purpose_t hmac_efuse_blk_purpose = esp_efuse_get_key_purpose(hmac_key_blk); - if (hmac_efuse_blk_purpose != ESP_EFUSE_KEY_PURPOSE_HMAC_UP) { - ESP_LOGE(TAG, "HMAC key is not burnt in eFuse block"); + esp_efuse_purpose_t purpose = esp_efuse_get_key_purpose(hmac_key_blk); +#if SOC_HMAC_SUPPORTED + if (purpose != ESP_EFUSE_KEY_PURPOSE_HMAC_UP) { +#else + if (purpose != ESP_EFUSE_KEY_PURPOSE_USER) { +#endif + ESP_LOGE(TAG, "Key is not burnt in eFuse block with expected purpose"); return ESP_ERR_NOT_FOUND; } - esp_err_t err = compute_nvs_keys_with_hmac((hmac_key_id_t)CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID, cfg); + esp_err_t err = compute_nvs_keys_with_hmac(hmac_key_blk, cfg); if (err != ESP_OK) { return err; } diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h index b30a8493e12..d8ea8ff8460 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -80,6 +80,10 @@ #define MBEDTLS_ECP_VERIFY_ALT #endif +#if !SOC_HMAC_SUPPORTED +#define MBEDTLS_MD_C +#endif + #define MBEDTLS_ENTROPY_C #endif /* ESP_TEE_MBEDTLS_CONFIG_H */ From 46de215007828bc11837942d1c2578bcc00c312d Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Fri, 26 Sep 2025 17:24:01 +0530 Subject: [PATCH 4/4] ci(esp_tee): Enable the TEE test-apps for ESP32-C61 --- .../esp_tee/test_apps/.build-test-rules.yml | 8 +- .../esp_tee/test_apps/tee_cli_app/README.md | 4 +- .../test_apps/tee_cli_app/pytest_tee_cli.py | 2 +- .../esp_tee/test_apps/tee_test_fw/README.md | 4 +- .../esp_tee/test_apps/tee_test_fw/conftest.py | 81 ++++++++++++++----- .../main/test_esp_tee_flash_prot.c | 2 + .../tee_test_fw/pytest_esp_tee_ut.py | 25 ++++-- 7 files changed, 92 insertions(+), 34 deletions(-) diff --git a/components/esp_tee/test_apps/.build-test-rules.yml b/components/esp_tee/test_apps/.build-test-rules.yml index 906c6b73c3b..081d926e83a 100644 --- a/components/esp_tee/test_apps/.build-test-rules.yml +++ b/components/esp_tee/test_apps/.build-test-rules.yml @@ -2,10 +2,10 @@ components/esp_tee/test_apps/tee_cli_app: disable: - - if: IDF_TARGET not in ["esp32c6", "esp32c5"] - reason: only supported with c6 and c5 + - if: IDF_TARGET not in ["esp32c6", "esp32c5", "esp32c61"] + reason: only supported with c6, c5 and c61 components/esp_tee/test_apps/tee_test_fw: disable: - - if: IDF_TARGET not in ["esp32c6", "esp32h2", "esp32c5"] - reason: only supported with c6, h2 and c5 + - if: IDF_TARGET not in ["esp32c6", "esp32h2", "esp32c5", "esp32c61"] + reason: only supported with c6, h2, c5 and c61 diff --git a/components/esp_tee/test_apps/tee_cli_app/README.md b/components/esp_tee/test_apps/tee_cli_app/README.md index 13b75c25d50..cc2ad5bfb21 100644 --- a/components/esp_tee/test_apps/tee_cli_app/README.md +++ b/components/esp_tee/test_apps/tee_cli_app/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | +| ----------------- | -------- | -------- | --------- | # TEE CLI Application: Secure Services Demonstration diff --git a/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py b/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py index a117c19e0d4..2bf36003862 100644 --- a/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py +++ b/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py @@ -22,7 +22,7 @@ from pytest_embedded import Dut from pytest_embedded_idf.utils import idf_parametrize # TODO: Enable for ESP32-C5 once support is stable -SUPPORTED_TARGETS = ['esp32c6', 'esp32h2'] +SUPPORTED_TARGETS = ['esp32c6', 'esp32c61'] TEST_MSG = 'hello world' diff --git a/components/esp_tee/test_apps/tee_test_fw/README.md b/components/esp_tee/test_apps/tee_test_fw/README.md index 1488da3165a..cb7b6f84890 100644 --- a/components/esp_tee/test_apps/tee_test_fw/README.md +++ b/components/esp_tee/test_apps/tee_test_fw/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-H2 | -| ----------------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | +| ----------------- | -------- | -------- | --------- | -------- | ## ESP-TEE: Test Suite diff --git a/components/esp_tee/test_apps/tee_test_fw/conftest.py b/components/esp_tee/test_apps/tee_test_fw/conftest.py index 8b365947b50..a7d8d713b55 100644 --- a/components/esp_tee/test_apps/tee_test_fw/conftest.py +++ b/components/esp_tee/test_apps/tee_test_fw/conftest.py @@ -28,11 +28,12 @@ esp_tee_empty_bin = { 0x20, 0x00, 0x00, 0x42, 0x00, 0x02, 0x00, 0x00, # esp_app_desc structure 0x32, 0x54, 0xCD, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x73, 0x70, 0x5F, 0x74, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x76, 0x20, 0x31, 0x31, 0x20, 0x32, 0x30, 0x32, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35, @@ -41,7 +42,7 @@ esp_tee_empty_bin = { 0x00, 0x00, 0x00, 0x00, 0x2D, 0x63, 0x66, 0x8B, 0x75, 0xFA, 0x59, 0x05, 0x53, 0x34, 0x91, 0x71, 0x51, 0x33, 0x91, 0xDD, 0xF8, 0xB1, 0xFE, 0x83, 0x06, 0xEB, 0x03, 0x80, 0x45, 0xC9, 0x18, 0x20, 0x83, 0x7E, 0x2E, 0x43, - *([0x00] * 0x58), + *([0x00] * 0x50), # Padding *([0x00] * 0x100), # IRAM segment @@ -56,11 +57,11 @@ esp_tee_empty_bin = { # Padding *([0x00] * 0x0F), # CRC8 checksum - 0x56, + 0x3F, # Image SHA256 - 0xF4, 0xA4, 0xCF, 0x06, 0xAE, 0x94, 0x75, 0x47, 0xBC, 0x88, 0xA2, 0xCA, - 0x52, 0x97, 0x7A, 0x5C, 0x55, 0x43, 0xD9, 0xF5, 0xD3, 0x45, 0xD1, 0x34, - 0xFC, 0x74, 0xB2, 0xB9, 0x34, 0x72, 0xC3, 0x00 + 0x2B, 0xF4, 0x49, 0x65, 0x93, 0xDD, 0xA6, 0x65, 0xE4, 0x31, 0xEA, 0xC5, + 0x42, 0x40, 0xA0, 0x96, 0x8B, 0x70, 0x48, 0xFE, 0xD9, 0x7E, 0x6F, 0x21, + 0x0B, 0xC1, 0xA5, 0xD4, 0x43, 0x87, 0x52, 0x2A ], 'esp32h2': [ 0xE9, 0x04, 0x02, 0x1F, 0x00, 0x00, 0x80, 0x40, 0xEE, 0x00, 0x00, 0x00, @@ -69,11 +70,12 @@ esp_tee_empty_bin = { 0x20, 0x00, 0x00, 0x42, 0x00, 0x02, 0x00, 0x00, # esp_app_desc structure 0x32, 0x54, 0xCD, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x73, 0x70, 0x5F, 0x74, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x76, 0x20, 0x31, 0x31, 0x20, 0x32, 0x30, 0x32, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35, @@ -82,7 +84,7 @@ esp_tee_empty_bin = { 0x00, 0x00, 0x00, 0x00, 0x2D, 0x63, 0x66, 0x8B, 0x75, 0xFA, 0x59, 0x05, 0x53, 0x34, 0x91, 0x71, 0x51, 0x33, 0x91, 0xDD, 0xF8, 0xB1, 0xFE, 0x83, 0x06, 0xEB, 0x03, 0x80, 0x45, 0xC9, 0x18, 0x20, 0x83, 0x7E, 0x2E, 0x43, - *([0x00] * 0x58), + *([0x00] * 0x50), # Padding *([0x00] * 0x100), # IRAM segment @@ -97,11 +99,11 @@ esp_tee_empty_bin = { # Padding *([0x00] * 0x0F), # CRC8 checksum - 0x56, + 0x3F, # Image SHA256 - 0xDC, 0x60, 0x86, 0x6C, 0x37, 0x76, 0xAA, 0x30, 0x1F, 0x61, 0x48, 0x23, - 0xEA, 0x34, 0xAA, 0x19, 0xE8, 0xDE, 0x04, 0x7D, 0x2A, 0x30, 0xC1, 0xDD, - 0x61, 0x38, 0x9D, 0xB5, 0xCA, 0x13, 0x5A, 0x79 + 0x9B, 0x83, 0x45, 0x5A, 0xCD, 0x07, 0xC2, 0x4D, 0x54, 0x29, 0xA9, 0x2B, + 0xA3, 0xB0, 0xFA, 0x97, 0x62, 0x95, 0xDA, 0x5C, 0xAD, 0xEF, 0xAC, 0x9D, + 0xB6, 0xF7, 0x09, 0x95, 0xC2, 0x33, 0x8E, 0x36 ], 'esp32c5': [ 0xE9, 0x04, 0x02, 0x1F, 0x00, 0x00, 0x80, 0x40, 0xEE, 0x00, 0x00, 0x00, @@ -110,11 +112,12 @@ esp_tee_empty_bin = { 0x20, 0x00, 0x00, 0x42, 0x00, 0x02, 0x00, 0x00, # esp_app_desc structure 0x32, 0x54, 0xCD, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x73, 0x70, 0x5F, 0x74, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x76, 0x20, 0x31, 0x31, 0x20, 0x32, 0x30, 0x32, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35, @@ -123,7 +126,7 @@ esp_tee_empty_bin = { 0x00, 0x00, 0x00, 0x00, 0x2D, 0x63, 0x66, 0x8B, 0x75, 0xFA, 0x59, 0x05, 0x53, 0x34, 0x91, 0x71, 0x51, 0x33, 0x91, 0xDD, 0xF8, 0xB1, 0xFE, 0x83, 0x06, 0xEB, 0x03, 0x80, 0x45, 0xC9, 0x18, 0x20, 0x83, 0x7E, 0x2E, 0x43, - *([0x00] * 0x58), + *([0x00] * 0x50), # Padding *([0x00] * 0x100), # IRAM segment @@ -138,11 +141,53 @@ esp_tee_empty_bin = { # Padding *([0x00] * 0x0F), # CRC8 checksum - 0x56, + 0x3F, # Image SHA256 - 0xCD, 0xCC, 0xF2, 0xE3, 0x52, 0x76, 0xE5, 0x6D, 0xF6, 0x32, 0x95, 0x27, - 0x5F, 0xF3, 0xD8, 0x90, 0xD7, 0x95, 0xA0, 0x95, 0xD5, 0xDA, 0xE7, 0xA4, - 0x58, 0x08, 0x84, 0xBB, 0x8F, 0x29, 0xAB, 0xE4 + 0x1C, 0x25, 0x32, 0xD0, 0x99, 0xBD, 0xA4, 0xE8, 0x20, 0x8E, 0x43, 0x61, + 0xDA, 0xCD, 0x47, 0x3B, 0x2A, 0x1C, 0xCE, 0x38, 0x0F, 0x74, 0xA5, 0x7E, + 0xAA, 0x05, 0xA3, 0x8F, 0x6A, 0x22, 0xAE, 0x0B + ], + 'esp32c61': [ + 0xE9, 0x04, 0x02, 0x1F, 0x00, 0x00, 0x80, 0x40, 0xEE, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x64, 0x00, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + # DROM segment + 0x20, 0x00, 0x00, 0x42, 0x00, 0x02, 0x00, 0x00, + # esp_app_desc structure + 0x32, 0x54, 0xCD, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x73, 0x70, 0x5F, 0x74, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x3A, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x76, 0x20, 0x31, 0x31, 0x20, 0x32, + 0x30, 0x32, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2D, 0x63, 0x66, 0x8B, 0x75, 0xFA, 0x59, 0x05, + 0x53, 0x34, 0x91, 0x71, 0x51, 0x33, 0x91, 0xDD, 0xF8, 0xB1, 0xFE, 0x83, + 0x06, 0xEB, 0x03, 0x80, 0x45, 0xC9, 0x18, 0x20, 0x83, 0x7E, 0x2E, 0x43, + *([0x00] * 0x50), + # Padding + *([0x00] * 0x100), + # IRAM segment + 0x00, 0x00, 0x80, 0x40, 0x20, 0x00, 0x00, 0x00, + *([0x00] * 0x20), + # PADDING segment + 0x00, 0x00, 0x00, 0x00, 0xC8, 0x7D, 0x00, 0x00, + *([0x00] * 0x7DC8), + # IROM segment + 0x20, 0x80, 0x00, 0x42, 0x00, 0x01, 0x00, 0x00, + *([0x00] * 0x100), + # Padding + *([0x00] * 0x0F), + # CRC8 checksum + 0x3F, + # Image SHA256 + 0x3F, 0xD4, 0x9C, 0xF4, 0xBC, 0x38, 0xA3, 0x6A, 0xB9, 0xCA, 0x09, 0x3A, + 0x79, 0xFD, 0x9C, 0x20, 0xE2, 0x74, 0x89, 0xA5, 0x04, 0xAD, 0x7C, 0x45, + 0xB7, 0xB7, 0x56, 0xCD, 0x55, 0x8F, 0xD5, 0x6D ], } # fmt: on diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_flash_prot.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_flash_prot.c index 030e6ff1c8c..90cc353c4f8 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_flash_prot.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_flash_prot.c @@ -44,6 +44,7 @@ __attribute__((unused)) static const uint32_t mmu_op_fail_seq[8] = {[0 ... 7] = #define CHECK_MMU_OP_FAIL(ptr_) \ do { \ TEST_ASSERT_EQUAL_HEX8_ARRAY(mmu_op_fail_seq, (ptr_), 0x20); \ + printf("Failed MMU operation, rebooting!\n"); \ esp_restart(); \ } while (0) #endif @@ -247,6 +248,7 @@ TEST_CASE("Test REE-TEE isolation: MMU-spillover", "[exception]") spi_flash_mmap_handle_t handle; const size_t len = 0x100000; // 1MB TEST_ESP_OK(spi_flash_mmap(0x00, len, SPI_FLASH_MMAP_DATA, &ptr, &handle)); + CHECK_MMU_OP_FAIL(ptr); ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 32, ESP_LOG_INFO); TEST_FAIL_MESSAGE("Exception should have been generated!"); } diff --git a/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py b/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py index ea3b222e61b..faa6ec5ee85 100644 --- a/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py +++ b/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py @@ -10,7 +10,7 @@ from pytest_embedded_idf.utils import idf_parametrize # ---------------- Pytest build parameters ---------------- # TODO: Enable for ESP32-C5 once support is stable -SUPPORTED_TARGETS = ['esp32c6', 'esp32h2'] +SUPPORTED_TARGETS = ['esp32c6', 'esp32h2', 'esp32c61'] CONFIG_DEFAULT = [ # 'config, target, markers', @@ -54,7 +54,7 @@ REE_ISOLATION_TEST_EXC_RSN: dict[str, str] = { ('MMU-spillover'): 'Cache error', } -TEE_APM_VIOLATION_EXC_CHK = ['eFuse', 'MMU', 'AES', 'HMAC', 'DS', 'SHA PCR', 'ECC PCR', 'SWDT/BOD'] +TEE_APM_VIOLATION_EXC_CHK = ['eFuse', 'MMU', 'SWDT/BOD', 'AES', 'HMAC', 'DS', 'SHA PCR', 'ECC PCR'] # ---------------- TEE default tests ---------------- @@ -75,6 +75,8 @@ def test_esp_tee(dut: IdfDut) -> None: indirect=['config', 'target'], ) def test_esp_tee_crypto_aes(dut: IdfDut) -> None: + if dut.target == 'esp32c61': + pytest.skip(f'AES not supported on {dut.target}') dut.run_all_single_board_cases(group='aes') dut.run_all_single_board_cases(group='aes-gcm') @@ -96,7 +98,8 @@ def test_esp_tee_crypto_sha(dut: IdfDut) -> None: indirect=['config', 'target'], ) def test_esp_tee_aes_perf(dut: IdfDut) -> None: - # start test + if dut.target == 'esp32c61': + pytest.skip(f'AES not supported on {dut.target}') for i in range(24): dut.run_all_single_board_cases(name=['mbedtls AES performance']) @@ -111,10 +114,12 @@ def test_esp_tee_aes_perf(dut: IdfDut) -> None: ) def test_esp_tee_apm_violation(dut: IdfDut) -> None: for check in TEE_APM_VIOLATION_EXC_CHK: + if dut.target == 'esp32c61' and check in ('AES', 'HMAC', 'DS'): + continue dut.expect_exact('Press ENTER to see the list of tests') dut.write(f'"Test APM violation: {check}"') exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode() - if dut.target == 'esp32c5' or (dut.target == 'esp32h2' and check == 'eFuse'): + if dut.target in ('esp32c5', 'esp32c61') or (dut.target == 'esp32h2' and check == 'eFuse'): exp_str = 'APM - Space exception' elif check == 'SWDT/BOD': exp_str = 'Store access fault' @@ -145,8 +150,9 @@ def test_esp_tee_illegal_instruction(dut: IdfDut) -> None: def test_esp_tee_violation_checks(dut: IdfDut) -> None: checks_list = TEE_VIOLATION_TEST_EXC_RSN for test, expected_exc in checks_list.items(): - if expected_exc is None or dut.target == 'esp32c5': - # TODO: Enable when TEE SRAM is partitioned as IRAM (RX) and DRAM (RW) + # NOTE: For ESP32-C5, access to the region before the SRAM does + # not generate exceptions due to TEE PMA configuration + if expected_exc is None or (dut.target == 'esp32c5' and test == 'IRAM-W1'): continue dut.expect_exact('Press ENTER to see the list of tests') dut.write(f'"Test TEE-TEE violation: {test}"') @@ -167,7 +173,12 @@ def test_esp_tee_isolation_checks(dut: IdfDut) -> None: continue dut.expect_exact('Press ENTER to see the list of tests') dut.write(f'"Test REE-TEE isolation: {test}"') - actual_exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode() + # NOTE: For ESP32-C5 and C61, the MMU-spillover test fails gracefully without raising panic + if dut.target in {'esp32c5', 'esp32c61'} and test == 'MMU-spillover': + dut.expect_exact('Failed MMU operation, rebooting!') + continue + else: + 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('Origin: U-mode')