diff --git a/components/esp_hw_support/include/esp_ds.h b/components/esp_hw_support/include/esp_ds.h index f5c68a16b1..2ed1b7f4c6 100644 --- a/components/esp_hw_support/include/esp_ds.h +++ b/components/esp_hw_support/include/esp_ds.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,8 @@ #ifdef SOC_DIG_SIGN_SUPPORTED +#include "rom/digital_signature.h" + #ifdef __cplusplus extern "C" { #endif @@ -38,7 +40,15 @@ extern "C" { + ESP_DS_SIGNATURE_L_BIT_LEN \ + ESP_DS_SIGNATURE_PADDING_BIT_LEN) / 8)) -typedef struct esp_ds_context esp_ds_context_t; +/** + * @brief Context object used for non-blocking digital signature operations + * + * This object is allocated by \c esp_ds_start_sign() and must be passed to + * \c esp_ds_finish_sign() to complete the digital signature operation. + */ +typedef struct esp_ds_context { + const ets_ds_data_t *data; /*!< Pointer to the encrypted private key data */ +} esp_ds_context_t; typedef enum { ESP_DS_RSA_1024 = (1024 / 32) - 1, diff --git a/components/esp_security/CMakeLists.txt b/components/esp_security/CMakeLists.txt index 39004e9bb8..6b09a6294c 100644 --- a/components/esp_security/CMakeLists.txt +++ b/components/esp_security/CMakeLists.txt @@ -32,7 +32,8 @@ 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_hw_support esp_system esp_timer) elseif(esp_tee_build) - list(APPEND srcs "src/esp_crypto_lock.c" "src/esp_crypto_periph_clk.c") + list(APPEND srcs "src/esp_crypto_lock.c" "src/esp_crypto_periph_clk.c" + "src/esp_hmac.c" "src/esp_ds.c") list(APPEND includes "src/${IDF_TARGET}") list(APPEND priv_requires esp_hw_support) endif() @@ -44,4 +45,6 @@ idf_component_register(SRCS ${srcs} if(NOT non_os_build) target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_security_init_include_impl") +elseif(esp_tee_build) + target_link_libraries(${COMPONENT_LIB} PRIVATE idf::efuse) endif() diff --git a/components/esp_security/src/esp_ds.c b/components/esp_security/src/esp_ds.c index 6f6a461e74..6bdcad3376 100644 --- a/components/esp_security/src/esp_ds.c +++ b/components/esp_security/src/esp_ds.c @@ -8,10 +8,15 @@ #include #include +#if !ESP_TEE_BUILD #include "freertos/FreeRTOS.h" #include "freertos/task.h" - #include "esp_timer.h" +#else +#include "esp_rom_sys.h" +#include "esp_cpu.h" +#endif + #include "esp_ds.h" #include "esp_crypto_lock.h" #include "esp_crypto_periph_clk.h" @@ -32,42 +37,6 @@ #include "hal/sha_ll.h" #endif /* !CONFIG_IDF_TARGET_ESP32S2 */ -#if CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/rom/digital_signature.h" -#endif - -#if CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/rom/digital_signature.h" -#endif - -#if CONFIG_IDF_TARGET_ESP32C3 -#include "esp32c3/rom/digital_signature.h" -#endif - -#if CONFIG_IDF_TARGET_ESP32C6 -#include "esp32c6/rom/digital_signature.h" -#endif - -#if CONFIG_IDF_TARGET_ESP32C5 -#include "esp32c5/rom/digital_signature.h" -#endif - -#if CONFIG_IDF_TARGET_ESP32H2 -#include "esp32h2/rom/digital_signature.h" -#endif - -#if CONFIG_IDF_TARGET_ESP32H21 -#include "esp32h21/rom/digital_signature.h" -#endif - -#if CONFIG_IDF_TARGET_ESP32P4 -#include "esp32p4/rom/digital_signature.h" -#endif - -struct esp_ds_context { - const ets_ds_data_t *data; -}; - /** * The vtask delay \c esp_ds_sign() is using while waiting for completion of the signing operation. */ @@ -263,6 +232,15 @@ esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data, #else /* !CONFIG_IDF_TARGET_ESP32S2 (targets other than esp32s2) */ +static inline int64_t get_time_us(void) +{ +#if !ESP_TEE_BUILD + return esp_timer_get_time(); +#else + return (int64_t)esp_cpu_get_cycle_count() / (int64_t)esp_rom_get_cpu_ticks_per_us(); +#endif +} + static void ds_acquire_enable(void) { esp_crypto_ds_lock_acquire(); @@ -301,14 +279,23 @@ esp_err_t esp_ds_sign(const void *message, return ESP_ERR_INVALID_ARG; } - esp_ds_context_t *context; + esp_ds_context_t *context = NULL; +#if ESP_TEE_BUILD + esp_ds_context_t ctx; + context = &ctx; +#endif + esp_err_t result = esp_ds_start_sign(message, data, key_id, &context); if (result != ESP_OK) { return result; } while (esp_ds_is_busy()) { +#if !ESP_TEE_BUILD vTaskDelay(ESP_DS_SIGN_TASK_DELAY_MS / portTICK_PERIOD_MS); +#else + esp_rom_delay_us(1); +#endif } return esp_ds_finish_sign(signature, context); @@ -349,16 +336,18 @@ esp_err_t esp_ds_start_sign(const void *message, ds_hal_start(); // check encryption key from HMAC - int64_t start_time = esp_timer_get_time(); + int64_t start_time = get_time_us(); while (ds_ll_busy() != 0) { - if ((esp_timer_get_time() - start_time) > SOC_DS_KEY_CHECK_MAX_WAIT_US) { + if ((get_time_us() - start_time) > SOC_DS_KEY_CHECK_MAX_WAIT_US) { ds_disable_release(); return ESP_ERR_HW_CRYPTO_DS_INVALID_KEY; } } - esp_ds_context_t *context = malloc(sizeof(esp_ds_context_t)); - if (!context) { +#if !ESP_TEE_BUILD + *esp_ds_ctx = malloc(sizeof(esp_ds_context_t)); +#endif + if (!*esp_ds_ctx) { ds_disable_release(); return ESP_ERR_NO_MEM; } @@ -371,8 +360,7 @@ esp_err_t esp_ds_start_sign(const void *message, // initiate signing ds_hal_start_sign(); - context->data = (const ets_ds_data_t *)data; - *esp_ds_ctx = context; + (*esp_ds_ctx)->data = (const ets_ds_data_t *)data; return ESP_OK; } @@ -405,7 +393,9 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx) return_value = ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING; } +#if !ESP_TEE_BUILD free(esp_ds_ctx); +#endif hmac_hal_clean(); diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index e21297a2df..06f10b3782 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -295,10 +295,10 @@ __attribute__((weak)) void esp_perip_clk_init(void) // NOTE: [ESP-TEE] The TEE is responsible for the AES and SHA peripherals periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); -#endif - periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE); +#endif + periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE); // TODO: Replace with hal implementation REG_CLR_BIT(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); diff --git a/components/esp_tee/CMakeLists.txt b/components/esp_tee/CMakeLists.txt index f49ac66730..2da9c5904f 100644 --- a/components/esp_tee/CMakeLists.txt +++ b/components/esp_tee/CMakeLists.txt @@ -73,7 +73,7 @@ else() idf_component_register(INCLUDE_DIRS include SRCS ${srcs} - PRIV_REQUIRES efuse esp_system spi_flash) + PRIV_REQUIRES efuse esp_security esp_system spi_flash) if(CONFIG_SECURE_ENABLE_TEE) set(EXTRA_LINK_FLAGS) diff --git a/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml b/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml index e567aca201..90e0c8645a 100644 --- a/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml +++ b/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml @@ -212,6 +212,42 @@ secure_services: type: IDF function: esp_crypto_sha_enable_periph_clk args: 1 + - id: 99 + type: IDF + function: esp_hmac_calculate + args: 4 + - id: 100 + type: IDF + function: esp_hmac_jtag_enable + args: 2 + - id: 101 + type: IDF + function: esp_hmac_jtag_disable + args: 0 + - id: 102 + type: IDF + function: esp_ds_sign + args: 4 + - id: 103 + type: IDF + function: esp_ds_start_sign + args: 4 + - id: 104 + type: IDF + function: esp_ds_is_busy + args: 0 + - id: 105 + type: IDF + function: esp_ds_finish_sign + args: 2 + - id: 106 + type: IDF + function: esp_ds_encrypt_params + args: 4 + - id: 107 + type: IDF + function: esp_crypto_mpi_enable_periph_clk + args: 1 # ID: 134-149 (16) - eFuse - family: efuse entries: diff --git a/components/esp_tee/src/esp_secure_service_wrapper.c b/components/esp_tee/src/esp_secure_service_wrapper.c index 70250d91d0..59dbeca671 100644 --- a/components/esp_tee/src/esp_secure_service_wrapper.c +++ b/components/esp_tee/src/esp_secure_service_wrapper.c @@ -11,9 +11,13 @@ #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_types.h" +#include "esp_hmac.h" +#include "esp_ds.h" +#include "esp_crypto_lock.h" #include "esp_flash.h" #include "soc/soc_caps.h" @@ -97,7 +101,10 @@ int __wrap_esp_aes_crypt_cbc(esp_aes_context *ctx, const unsigned char *input, unsigned char *output) { - return esp_tee_service_call(7, SS_ESP_AES_CRYPT_CBC, ctx, mode, length, iv, input, output); + esp_crypto_sha_aes_lock_acquire(); + esp_err_t err = esp_tee_service_call(7, SS_ESP_AES_CRYPT_CBC, ctx, mode, length, iv, input, output); + esp_crypto_sha_aes_lock_release(); + return err; } int __wrap_esp_aes_crypt_cfb128(esp_aes_context *ctx, @@ -108,8 +115,11 @@ int __wrap_esp_aes_crypt_cfb128(esp_aes_context *ctx, const unsigned char *input, unsigned char *output) { - return esp_tee_service_call(8, SS_ESP_AES_CRYPT_CFB128, (uint32_t)ctx, - mode, length, iv_off, iv, (uint32_t)input, (uint32_t)output); + esp_crypto_sha_aes_lock_acquire(); + esp_err_t err = esp_tee_service_call(8, SS_ESP_AES_CRYPT_CFB128, (uint32_t)ctx, + mode, length, iv_off, iv, (uint32_t)input, (uint32_t)output); + esp_crypto_sha_aes_lock_release(); + return err; } int __wrap_esp_aes_crypt_cfb8(esp_aes_context *ctx, @@ -119,8 +129,11 @@ int __wrap_esp_aes_crypt_cfb8(esp_aes_context *ctx, const unsigned char *input, unsigned char *output) { - return esp_tee_service_call(7, SS_ESP_AES_CRYPT_CFB8, ctx, - mode, length, iv, input, output); + esp_crypto_sha_aes_lock_acquire(); + esp_err_t err = esp_tee_service_call(7, SS_ESP_AES_CRYPT_CFB8, ctx, + mode, length, iv, input, output); + esp_crypto_sha_aes_lock_release(); + return err; } int __wrap_esp_aes_crypt_ctr(esp_aes_context *ctx, @@ -131,7 +144,10 @@ int __wrap_esp_aes_crypt_ctr(esp_aes_context *ctx, const unsigned char *input, unsigned char *output) { - return esp_tee_service_call(8, SS_ESP_AES_CRYPT_CTR, ctx, length, nc_off, nonce_counter, stream_block, input, output); + esp_crypto_sha_aes_lock_acquire(); + esp_err_t err = esp_tee_service_call(8, SS_ESP_AES_CRYPT_CTR, ctx, length, nc_off, nonce_counter, stream_block, input, output); + esp_crypto_sha_aes_lock_release(); + return err; } int __wrap_esp_aes_crypt_ecb(esp_aes_context *ctx, @@ -139,9 +155,12 @@ int __wrap_esp_aes_crypt_ecb(esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16]) { - return esp_tee_service_call(5, SS_ESP_AES_CRYPT_ECB, - (uint32_t)ctx, (uint32_t)mode, - (uint32_t)input, (uint32_t)output); + esp_crypto_sha_aes_lock_acquire(); + esp_err_t err = esp_tee_service_call(5, SS_ESP_AES_CRYPT_ECB, + (uint32_t)ctx, (uint32_t)mode, + (uint32_t)input, (uint32_t)output); + esp_crypto_sha_aes_lock_release(); + return err; } int __wrap_esp_aes_crypt_ofb(esp_aes_context *ctx, @@ -151,8 +170,11 @@ int __wrap_esp_aes_crypt_ofb(esp_aes_context *ctx, const unsigned char *input, unsigned char *output) { - return esp_tee_service_call(7, SS_ESP_AES_CRYPT_OFB, (uint32_t)ctx, length, - iv_off, iv, (uint32_t)input, (uint32_t)output); + esp_crypto_sha_aes_lock_acquire(); + esp_err_t err = esp_tee_service_call(7, SS_ESP_AES_CRYPT_OFB, (uint32_t)ctx, length, + iv_off, iv, (uint32_t)input, (uint32_t)output); + esp_crypto_sha_aes_lock_release(); + return err; } /* ---------------------------------------------- SHA ------------------------------------------------- */ @@ -233,6 +255,93 @@ void __wrap_esp_crypto_sha_enable_periph_clk(bool enable) esp_tee_service_call(2, SS_ESP_CRYPTO_SHA_ENABLE_PERIPH_CLK, enable); } +/* ---------------------------------------------- HMAC ------------------------------------------------- */ + +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(); + esp_err_t err = esp_tee_service_call(5, SS_ESP_HMAC_CALCULATE, key_id, message, message_len, hmac); + esp_crypto_hmac_lock_release(); + return err; +} + +esp_err_t __wrap_esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token) +{ + esp_crypto_hmac_lock_acquire(); + esp_err_t err = esp_tee_service_call(3, SS_ESP_HMAC_JTAG_ENABLE, key_id, token); + esp_crypto_hmac_lock_release(); + return err; +} + +esp_err_t __wrap_esp_hmac_jtag_disable(void) +{ + esp_crypto_hmac_lock_acquire(); + esp_err_t err = esp_tee_service_call(1, SS_ESP_HMAC_JTAG_DISABLE); + esp_crypto_hmac_lock_release(); + return err; +} + +/* ---------------------------------------------- DS ------------------------------------------------- */ + +esp_err_t __wrap_esp_ds_sign(const void *message, + const esp_ds_data_t *data, + hmac_key_id_t key_id, + void *signature) +{ + esp_crypto_ds_lock_acquire(); + esp_err_t err = esp_tee_service_call(5, SS_ESP_DS_SIGN, message, data, key_id, signature); + esp_crypto_ds_lock_release(); + return err; +} + +esp_err_t __wrap_esp_ds_start_sign(const void *message, + const esp_ds_data_t *data, + hmac_key_id_t key_id, + esp_ds_context_t **esp_ds_ctx) +{ + esp_crypto_ds_lock_acquire(); + if (esp_ds_ctx != NULL) { + *esp_ds_ctx = malloc(sizeof(esp_ds_context_t)); + if (!*esp_ds_ctx) { + return ESP_ERR_NO_MEM; + } + } + return esp_tee_service_call(5, SS_ESP_DS_START_SIGN, message, data, key_id, esp_ds_ctx); +} + +bool __wrap_esp_ds_is_busy(void) +{ + return esp_tee_service_call(1, SS_ESP_DS_IS_BUSY); +} + +esp_err_t __wrap_esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx) +{ + esp_err_t err = esp_tee_service_call(3, SS_ESP_DS_FINISH_SIGN, signature, esp_ds_ctx); + if (err != ESP_ERR_INVALID_ARG) { + free(esp_ds_ctx); + } + esp_crypto_ds_lock_release(); + return err; +} + +esp_err_t __wrap_esp_ds_encrypt_params(esp_ds_data_t *data, + const void *iv, + const esp_ds_p_data_t *p_data, + const void *key) +{ + esp_crypto_sha_aes_lock_acquire(); + esp_err_t err = esp_tee_service_call(5, SS_ESP_DS_ENCRYPT_PARAMS, data, iv, p_data, key); + esp_crypto_sha_aes_lock_release(); + return err; +} + +/* ---------------------------------------------- MPI ------------------------------------------------- */ + +void __wrap_esp_crypto_mpi_enable_periph_clk(bool enable) +{ + esp_tee_service_call(2, SS_ESP_CRYPTO_MPI_ENABLE_PERIPH_CLK, enable); +} + /* ---------------------------------------------- MMU HAL ------------------------------------------------- */ void IRAM_ATTR __wrap_mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr, uint32_t paddr, uint32_t len, uint32_t *out_len) diff --git a/components/esp_tee/subproject/CMakeLists.txt b/components/esp_tee/subproject/CMakeLists.txt index e346447c96..b4d77bd32b 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 mbedtls) +list(APPEND COMPONENTS bootloader_support efuse esp_security mbedtls) # TEE-specific components list(APPEND COMPONENTS tee_flash_mgr tee_ota_ops tee_sec_storage tee_attestation) 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 3940f0c822..3bd8f82f49 100644 --- a/components/esp_tee/subproject/main/core/esp_secure_services.c +++ b/components/esp_tee/subproject/main/core/esp_secure_services.c @@ -26,6 +26,8 @@ #include "soc/soc_caps.h" #include "aes/esp_aes.h" #include "sha/sha_core.h" +#include "esp_hmac.h" +#include "esp_ds.h" #include "esp_crypto_periph_clk.h" #include "esp_tee.h" @@ -331,6 +333,117 @@ void _ss_esp_crypto_sha_enable_periph_clk(bool enable) esp_crypto_sha_enable_periph_clk(enable); } +/* ---------------------------------------------- HMAC ------------------------------------------------- */ + +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)) && + esp_tee_ptr_in_ree((void *)((char *)message + message_len))); + + if (!valid_addr) { + return ESP_ERR_INVALID_ARG; + } + ESP_FAULT_ASSERT(valid_addr); + + return esp_hmac_calculate(key_id, message, message_len, hmac); +} + +esp_err_t _ss_esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token) +{ + bool valid_addr = (esp_tee_ptr_in_ree((void *)token)); + + if (!valid_addr) { + return ESP_ERR_INVALID_ARG; + } + ESP_FAULT_ASSERT(valid_addr); + + return esp_hmac_jtag_enable(key_id, token); +} + +esp_err_t _ss_esp_hmac_jtag_disable(void) +{ + return esp_hmac_jtag_disable(); +} + +esp_err_t _ss_esp_ds_sign(const void *message, + const esp_ds_data_t *data, + hmac_key_id_t key_id, + void *signature) +{ + bool valid_addr = (esp_tee_ptr_in_ree((void *)message) && + esp_tee_ptr_in_ree((void *)data) && + esp_tee_ptr_in_ree((void *)signature)); + + if (!valid_addr) { + return ESP_ERR_INVALID_ARG; + } + ESP_FAULT_ASSERT(valid_addr); + + return esp_ds_sign(message, data, key_id, signature); +} + +esp_err_t _ss_esp_ds_start_sign(const void *message, + const esp_ds_data_t *data, + hmac_key_id_t key_id, + esp_ds_context_t **esp_ds_ctx) +{ + bool valid_addr = (esp_tee_ptr_in_ree((void *)message) && + esp_tee_ptr_in_ree((void *)data) && + esp_tee_ptr_in_ree((void *)esp_ds_ctx)); + + if (!valid_addr) { + return ESP_ERR_INVALID_ARG; + } + ESP_FAULT_ASSERT(valid_addr); + + return esp_ds_start_sign(message, data, key_id, esp_ds_ctx); +} + +bool _ss_esp_ds_is_busy(void) +{ + return esp_ds_is_busy(); +} + +esp_err_t _ss_esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx) +{ + bool valid_addr = (esp_tee_ptr_in_ree((void *)signature) && + esp_tee_ptr_in_ree((void *)esp_ds_ctx)); + + valid_addr &= esp_tee_ptr_in_ree((void *)((char *)esp_ds_ctx + sizeof(esp_ds_data_t))); + + if (!valid_addr) { + return ESP_ERR_INVALID_ARG; + } + ESP_FAULT_ASSERT(valid_addr); + + return esp_ds_finish_sign(signature, esp_ds_ctx); +} + +esp_err_t _ss_esp_ds_encrypt_params(esp_ds_data_t *data, + const void *iv, + const esp_ds_p_data_t *p_data, + const void *key) +{ + bool valid_addr = ((esp_tee_ptr_in_ree((void *)data) && esp_tee_ptr_in_ree((void *)p_data)) && + (esp_tee_ptr_in_ree((void *)iv) && esp_tee_ptr_in_ree((void *)key))); + + valid_addr &= esp_tee_ptr_in_ree((void *)((char *)data + sizeof(esp_ds_data_t))); + + if (!valid_addr) { + return ESP_ERR_INVALID_ARG; + } + ESP_FAULT_ASSERT(valid_addr); + + return esp_ds_encrypt_params(data, iv, p_data, key); +} + +/* ---------------------------------------------- MPI ------------------------------------------------- */ + +void _ss_esp_crypto_mpi_enable_periph_clk(bool enable) +{ + esp_crypto_mpi_enable_periph_clk(enable); +} + /* ---------------------------------------------- OTA ------------------------------------------------- */ int _ss_esp_tee_ota_begin(void) 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 b9cfadaa1b..624f1be77b 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 @@ -175,6 +175,8 @@ SECTIONS * | APM | text | Flash | * | AES | text | Flash | * | SHA | text | Flash | + * | HMAC | text | Flash | + * | DS | text | Flash | * | BROWNOUT | text | Flash | * | EFUSE | text | Flash | * | LPTIMER | text | Flash | @@ -192,6 +194,8 @@ SECTIONS /* HAL */ *libhal.a:aes_hal.c*(.literal .text .literal.* .text.*) *libhal.a:sha_hal.c*(.literal .text .literal.* .text.*) + *libhal.a:hmac_hal.c*(.literal .text .literal.* .text.*) + *libhal.a:ds_hal.c*(.literal .text .literal.* .text.*) *libhal.a:apm_hal.c*(.literal .text .literal.* .text.*) *libhal.a:brownout_hal.c*(.literal .text .literal.* .text.*) *libhal.a:spi_flash_hal.c*(.literal .text .literal.* .text.*) @@ -201,6 +205,8 @@ SECTIONS /* Mbedtls for TEE */ *libmbedtls.a:*(.literal .text .literal.* .text.*) *libmbedcrypto.a:*(.literal .text .literal.* .text.*) + /* HMAC-DS layer */ + *libesp_security.a:*(.literal .text .literal.* .text.*) /* TEE attestation module */ *libattestation.a:*(.literal .text .literal.* .text.*) *json_generator.a:*(.literal .text .literal.* .text.*) diff --git a/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_apm_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_apm_prot_cfg.c index da17b38773..f746d82188 100644 --- a/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_apm_prot_cfg.c +++ b/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_apm_prot_cfg.c @@ -46,92 +46,121 @@ static const char *TAG = "esp_tee_apm_prot_cfg"; /*----------------------- HP APM range and filter configuration -----------------------*/ -/* HP_APM: REE0 mode accessible regions */ -apm_ctrl_region_config_data_t hp_apm_pms_data[] = { - /* Region 0: RTC memory (RWX) */ +/* HP_APM: TEE mode accessible regions */ +apm_ctrl_region_config_data_t hp_apm_pms_data_tee[] = { + /* Region 0: Entire memory region (RWX)*/ { .regn_num = 0, + .regn_start_addr = 0x0, + .regn_end_addr = ~0x0, + .regn_pms = 0x7, + .filter_enable = 1, + }, +}; + +/* HP_APM: REE0 mode accessible regions */ +apm_ctrl_region_config_data_t hp_apm_pms_data[] = { + /* NOTE: Without this entry, the REE SRAM region becomes inaccessible to + * the MODEM master, resulting in an APM violation during Wi-Fi initialization. + */ + /* Region 1: REE SRAM region (RW) */ + { + .regn_num = 1, + .regn_start_addr = SOC_NS_IRAM_START, + .regn_end_addr = SOC_IRAM_HIGH, + .regn_pms = 0x6, + .filter_enable = 1, + }, + /* Region 2: RTC memory (RWX) */ + { + .regn_num = 2, .regn_start_addr = SOC_RTC_IRAM_LOW, .regn_end_addr = SOC_RTC_IRAM_HIGH, .regn_pms = 0x7, .filter_enable = 1, }, - /* Region 1: Peripherals [Start - MMU] (RW) */ + /* Region 3: Peripherals [Start - MMU] (RW) */ /* Protected: MMU */ { - .regn_num = 1, + .regn_num = 3, .regn_start_addr = SOC_PERIPHERAL_LOW, .regn_end_addr = (SPI_MEM_MMU_ITEM_CONTENT_REG(0) - 0x4), .regn_pms = 0x6, .filter_enable = 1, }, - /* Region 2: Peripherals [MMU - SPI1] (RW) */ + /* Region 4: Peripherals [MMU - SPI1] (RW) */ /* Protected: SPI1 */ { - .regn_num = 2, + .regn_num = 4, .regn_start_addr = SPI_MEM_MMU_POWER_CTRL_REG(0), .regn_end_addr = (HP_APM_SPI1_REG_START - 0x4), .regn_pms = 0x6, .filter_enable = 1, }, - /* Region 3: Peripherals [SPI1 - Interrupt Matrix] (RW) */ + /* Region 5: Peripherals [SPI1 - Interrupt Matrix] (RW) */ /* Protected: Interrupt Matrix */ { - .regn_num = 3, + .regn_num = 5, .regn_start_addr = HP_APM_SPI1_REG_END, .regn_end_addr = (DR_REG_INTMTX_BASE - 0x4), .regn_pms = 0x6, .filter_enable = 1, }, - /* Region 4: Peripherals [H/W Lock - AES] (RW) */ - /* Protected: AES, SHA */ + /* Region 6/7: Peripherals [H/W Lock - HMAC] (RW) */ + /* Protected: AES, SHA, DS, HMAC */ { - .regn_num = 4, + .regn_num = 6, .regn_start_addr = DR_REG_ATOMIC_BASE, .regn_end_addr = (DR_REG_AES_BASE - 0x4), .regn_pms = 0x6, .filter_enable = 1, }, - /* Region 5/6: Peripherals [RSA - TEE Controller & APM] (RW) */ - /* Protected: AES + SHA PCR, APM, TEE Controller */ { - .regn_num = 5, + .regn_num = 7, .regn_start_addr = DR_REG_RSA_BASE, + .regn_end_addr = (DR_REG_DS_BASE - 0x4), + .regn_pms = 0x6, + .filter_enable = 1, + }, + /* Region 8/9/10: Peripherals [DS - TEE Controller & APM] (RW) */ + /* Protected: AES, SHA, DS, HMAC PCR, APM, TEE Controller */ + { + .regn_num = 8, + .regn_start_addr = DR_REG_IO_MUX_BASE, .regn_end_addr = (PCR_AES_CONF_REG - 0x4), .regn_pms = 0x6, .filter_enable = 1, }, { - .regn_num = 6, + .regn_num = 9, .regn_start_addr = PCR_RSA_CONF_REG, + .regn_end_addr = (PCR_DS_CONF_REG - 0x4), + .regn_pms = 0x6, + .filter_enable = 1, + }, + { + .regn_num = 10, + .regn_start_addr = PCR_IOMUX_CONF_REG, .regn_end_addr = (DR_REG_TEE_BASE - 0x4), .regn_pms = 0x6, .filter_enable = 1, }, - /* Region 7: Peripherals [Miscellaneous - PMU] (RW) */ + /* Region 11: Peripherals [Miscellaneous - PMU] (RW) */ { - .regn_num = 7, + .regn_num = 11, .regn_start_addr = DR_REG_MISC_BASE, .regn_end_addr = (DR_REG_PMU_BASE - 0x04), .regn_pms = 0x6, .filter_enable = 1, }, - /* Region 8: Peripherals [DEBUG - PWDET] (RW) */ + /* Region 12: Peripherals [DEBUG - PWDET] (RW) */ { - .regn_num = 8, + .regn_num = 12, .regn_start_addr = DR_REG_OPT_DEBUG_BASE, .regn_end_addr = 0x600D0000, .regn_pms = 0x6, .filter_enable = 1, }, - /* Region 9: REE SRAM region (RW) */ - { - .regn_num = 9, - .regn_start_addr = SOC_NS_IRAM_START, - .regn_end_addr = SOC_IRAM_HIGH, - .regn_pms = 0x6, - .filter_enable = 1, - }, }; /* NOTE: Following are the master IDs for setting the security mode and access through APM: @@ -160,28 +189,6 @@ apm_ctrl_region_config_data_t hp_apm_pms_data[] = { * +---------+-------------+ */ -/* HP_APM: REE0 mode masters' configuration */ -apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data = { - .apm_ctrl = HP_APM_CTRL, - .apm_m_cnt = HP_APM_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_REE0, - /* All masters except crypto DMA (AES/SHA) and HP CPU */ - .master_ids = 0xFF3FFFFE, - .pms_data = hp_apm_pms_data, -}; - -/* HP_APM: TEE mode accessible regions */ -apm_ctrl_region_config_data_t hp_apm_pms_data_tee[] = { - /* Region 10: Entire memory region (RWX)*/ - { - .regn_num = 10, - .regn_start_addr = 0x0, - .regn_end_addr = ~0x0, - .regn_pms = 0x7, - .filter_enable = 1, - }, -}; - /* HP_APM: TEE mode masters' configuration */ apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data_tee = { .apm_ctrl = HP_APM_CTRL, @@ -192,6 +199,16 @@ apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data_tee = { .pms_data = hp_apm_pms_data_tee, }; +/* HP_APM: REE0 mode masters' configuration */ +apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data = { + .apm_ctrl = HP_APM_CTRL, + .apm_m_cnt = HP_APM_MAX_ACCESS_PATH, + .sec_mode = APM_LL_SECURE_MODE_REE0, + /* All masters except crypto DMA (AES/SHA) and HP CPU */ + .master_ids = 0xFF3FFFFE, + .pms_data = hp_apm_pms_data, +}; + /*----------------------- LP_APM0 range and filter configuration -----------------------*/ /* LP_APM0: REE0 mode accessible regions */ @@ -218,28 +235,40 @@ apm_ctrl_secure_mode_config_t lp_apm0_sec_mode_data = { /*----------------------- LP_APM range and filter configuration -----------------------*/ -/* LP_APM: REE0 mode accessible regions */ -apm_ctrl_region_config_data_t lp_apm_pms_data[] = { - /* Region 0: RTC memory (RWX) */ +/* LP_APM: TEE mode accessible regions */ +apm_ctrl_region_config_data_t lp_apm_pms_data_tee[] = { + /* Region 0: Entire memory region (RWX) */ { .regn_num = 0, + .regn_start_addr = 0x0, + .regn_end_addr = ~0x0, + .regn_pms = 0x7, + .filter_enable = 1, + }, +}; + +/* LP_APM: REE0 mode accessible regions */ +apm_ctrl_region_config_data_t lp_apm_pms_data[] = { + /* Region 1: RTC memory (RWX) */ + { + .regn_num = 1, .regn_start_addr = SOC_RTC_IRAM_LOW, .regn_end_addr = SOC_RTC_IRAM_HIGH, .regn_pms = 0x7, .filter_enable = 1, }, - /* Region 1: LP Peripherals [PMU - eFuse BLK x] (RW) */ + /* Region 2: LP Peripherals [PMU - eFuse BLK x] (RW) */ /* Protected: eFuse BLK x */ { - .regn_num = 1, + .regn_num = 2, .regn_start_addr = DR_REG_PMU_BASE, .regn_end_addr = (LP_APM_EFUSE_REG_START - 0x04), .regn_pms = 0x6, .filter_enable = 1, }, - /* Region 2: LP Peripherals [eFuse - END] (RW) */ + /* Region 3: LP Peripherals [eFuse - END] (RW) */ { - .regn_num = 2, + .regn_num = 3, .regn_start_addr = LP_APM_EFUSE_REG_END, .regn_end_addr = (DR_REG_TRACE_BASE - 0x04), .regn_pms = 0x6, @@ -247,28 +276,6 @@ apm_ctrl_region_config_data_t lp_apm_pms_data[] = { }, }; -/* LP_APM: REE0 mode masters' configuration */ -apm_ctrl_secure_mode_config_t lp_apm_sec_mode_data = { - .apm_ctrl = LP_APM_CTRL, - .apm_m_cnt = LP_APM_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_REE0, - /* HP_CPU and LP_CPU */ - .master_ids = 0x3, - .pms_data = lp_apm_pms_data, -}; - -/* LP_APM: TEE mode accessible regions */ -apm_ctrl_region_config_data_t lp_apm_pms_data_tee[] = { - /* Region 3: Entire memory region (RWX) */ - { - .regn_num = 3, - .regn_start_addr = 0x0, - .regn_end_addr = ~0x0, - .regn_pms = 0x7, - .filter_enable = 1, - }, -}; - /* LP_APM0: TEE mode masters' configuration */ apm_ctrl_secure_mode_config_t lp_apm_sec_mode_data_tee = { .apm_ctrl = LP_APM_CTRL, @@ -279,6 +286,16 @@ apm_ctrl_secure_mode_config_t lp_apm_sec_mode_data_tee = { .pms_data = lp_apm_pms_data_tee, }; +/* LP_APM: REE0 mode masters' configuration */ +apm_ctrl_secure_mode_config_t lp_apm_sec_mode_data = { + .apm_ctrl = LP_APM_CTRL, + .apm_m_cnt = LP_APM_MAX_ACCESS_PATH, + .sec_mode = APM_LL_SECURE_MODE_REE0, + /* HP_CPU and LP_CPU */ + .master_ids = 0x3, + .pms_data = lp_apm_pms_data, +}; + /*---------------- TEE APM API-----------------------*/ void esp_tee_apm_int_enable(apm_ctrl_secure_mode_config_t *sec_mode_data) diff --git a/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_secure_sys_cfg.c b/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_secure_sys_cfg.c index 24f3b3c085..3f54dc6520 100644 --- a/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_secure_sys_cfg.c +++ b/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_secure_sys_cfg.c @@ -12,7 +12,10 @@ #include "esp_cpu.h" #include "esp_log.h" #include "hal/apm_hal.h" -#include "hal/clk_gate_ll.h" +#include "hal/aes_ll.h" +#include "hal/sha_ll.h" +#include "hal/hmac_ll.h" +#include "hal/ds_ll.h" #include "esp_tee.h" #include "esp_tee_intr.h" @@ -93,9 +96,11 @@ void esp_tee_soc_secure_sys_init(void) esp_tee_protect_intr_src(ETS_AES_INTR_SOURCE); // AES esp_tee_protect_intr_src(ETS_SHA_INTR_SOURCE); // SHA - /* Disable AES/SHA peripheral clocks; they will be toggled as needed when the peripheral is in use */ - periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); - periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); + /* Disable protected crypto peripheral clocks; they will be toggled as needed when the peripheral is in use */ + aes_ll_enable_bus_clock(false); + sha_ll_enable_bus_clock(false); + hmac_ll_enable_bus_clock(false); + ds_ll_enable_bus_clock(false); } IRAM_ATTR inline void esp_tee_switch_to_ree(uint32_t ree_entry_addr) 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 2d65585fed..c3366d3b72 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 @@ -1,11 +1,14 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "soc/aes_reg.h" +#include "soc/hmac_reg.h" +#include "soc/ds_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/spi_mem_reg.h" @@ -32,14 +35,6 @@ extern uint32_t _instruction_reserved_start; #define TEST_APM_EFUSE_PROT_REG EFUSE_RD_KEY5_DATA0_REG #endif -TEST_CASE("Test APM violation interrupt: AES", "[apm_violation]") -{ - uint32_t val = UINT32_MAX; - val = REG_READ(AES_DATE_REG); - TEST_ASSERT_EQUAL(0, val); - TEST_FAIL_MESSAGE("APM violation interrupt should have been generated"); -} - TEST_CASE("Test APM violation interrupt: eFuse", "[apm_violation]") { uint32_t val = UINT32_MAX; @@ -57,6 +52,44 @@ TEST_CASE("Test APM violation interrupt: MMU", "[apm_violation]") TEST_FAIL_MESSAGE("APM violation interrupt should have been generated"); } +TEST_CASE("Test APM violation interrupt: AES", "[apm_violation]") +{ + uint32_t val = UINT32_MAX; + val = REG_READ(AES_KEY_2_REG); + TEST_ASSERT_EQUAL(0, val); + TEST_FAIL_MESSAGE("APM violation interrupt should have been generated"); +} + +TEST_CASE("Test APM violation interrupt: HMAC", "[apm_violation]") +{ + uint32_t val = UINT32_MAX; + REG_WRITE(HMAC_SET_PARA_KEY_REG, val); + TEST_FAIL_MESSAGE("APM violation interrupt should have been generated"); +} + +TEST_CASE("Test APM violation interrupt: DS", "[apm_violation]") +{ + uint32_t val = UINT32_MAX; + val = REG_READ(DS_Z_MEM); + TEST_ASSERT_EQUAL(0, val); + TEST_FAIL_MESSAGE("APM violation interrupt should have been generated"); +} + +TEST_CASE("Test APM violation interrupt: SHA PCR", "[apm_violation]") +{ + uint32_t val = UINT32_MAX; + val = REG_READ(PCR_SHA_CONF_REG); + TEST_ASSERT_EQUAL(0, val); + TEST_FAIL_MESSAGE("APM violation interrupt should have been generated"); +} + +TEST_CASE("Test APM violation interrupt: DS PCR", "[apm_violation]") +{ + uint32_t val = UINT32_MAX; + REG_WRITE(PCR_DS_CONF_REG, val); + TEST_FAIL_MESSAGE("APM violation interrupt should have been generated"); +} + /* TEE IRAM: Reserved/Vector-table boundary */ TEST_CASE("Test TEE-TEE violation: IRAM (W1)", "[exception]") { 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 e4f574c69f..f9fd574216 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 @@ -39,9 +39,7 @@ REE_ISOLATION_TEST_EXC_RSN: Dict[str, Any] = { } } -TEE_APM_VIOLATION_EXC_CHK = ['AES', 'eFuse', 'MMU'] - -TEST_PARTITION_LABEL = 'test' +TEE_APM_VIOLATION_EXC_CHK = ['eFuse', 'MMU', 'AES', 'HMAC', 'DS', 'SHA PCR', 'DS PCR'] # ---------------- TEE default tests ---------------- diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index c30987b9bf..5f7678b13e 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -50,7 +50,9 @@ if(esp_tee_build) "brownout_hal.c" "wdt_hal_iram.c" "aes_hal.c" - "sha_hal.c") + "sha_hal.c" + "hmac_hal.c" + "ds_hal.c") if(CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1) list(APPEND srcs "spi_flash_hal.c") diff --git a/docs/en/security/tee/tee-advanced.rst b/docs/en/security/tee/tee-advanced.rst index 96156a72fb..51346b14b6 100644 --- a/docs/en/security/tee/tee-advanced.rst +++ b/docs/en/security/tee/tee-advanced.rst @@ -164,6 +164,8 @@ The following peripherals are protected using the APM module and accessible only - Access Permission Management (APM) peripheral - AES, SHA accelerators + - Hash-Based Message Authentication Code (HMAC) module + - Digital Signature module - eFuse Controller - Interrupt Controller - Brownout Detector @@ -175,8 +177,6 @@ The following peripherals are protected using the APM module and accessible only - MPI accelerator (RSA) - ECC accelerator - - Digital Signature module - - Hash-Based Message Authentication Code (HMAC) module Firmware ^^^^^^^^