From b6a51f0ff65fa5addda55245bb9fde1c94ff1ea4 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Fri, 7 Nov 2025 17:25:02 +0530 Subject: [PATCH] ci(esp_tee): Enable the TEE examples for ESP32-C61 --- .../esp_tee/test_apps/tee_cli_app/README.md | 37 +++++--- examples/security/.build-test-rules.yml | 8 +- .../security/tee/tee_attestation/README.md | 4 +- examples/security/tee/tee_basic/README.md | 28 +++--- .../example_secure_service/CMakeLists.txt | 11 ++- .../example_secure_service/example_service.c | 94 +++++++++++++++---- .../include/example_service.h | 24 +++-- .../sec_srv_tbl_example.yml | 8 +- .../tee/tee_basic/main/CMakeLists.txt | 4 +- .../security/tee/tee_basic/main/tee_main.c | 89 +++++++++++------- .../tee/tee_basic/pytest_tee_basic.py | 11 ++- .../security/tee/tee_basic/sdkconfig.defaults | 1 + .../security/tee/tee_secure_ota/README.md | 4 +- .../security/tee/tee_secure_storage/README.md | 31 ++++-- 14 files changed, 232 insertions(+), 122 deletions(-) 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 cc2ad5bfb2..67ae90d8f1 100644 --- a/components/esp_tee/test_apps/tee_cli_app/README.md +++ b/components/esp_tee/test_apps/tee_cli_app/README.md @@ -17,20 +17,35 @@ This example can be executed on any development board with a Espressif SOC chip - Configure the secure storage key ID for generating/fetching the ECDSA keypair for attestation token signing at `ESP-TEE (Trusted Execution Environment) → Secure Services → Attestation: Secure Storage key ID for EAT signing`. -Configure the Secure Storage mode for determining how the NVS XTS encryption keys are derived at `ESP-TEE (Trusted Execution Environment) → Secure Services → Secure Storage: Mode` +Configure the Secure Storage mode for determining how the NVS XTS-AES encryption keys are derived at `ESP-TEE (Trusted Execution Environment) → Secure Services → Secure Storage: Mode` - **Development** Mode: Encryption keys are embedded in the ESP-TEE firmware (identical across all instances). - - **Release** Mode: Encryption keys are derived via the HMAC peripheral using a key stored in eFuse. - - Set the eFuse key ID storing the HMAC key at `ESP-TEE (Trusted Execution Environment) → Secure Services → Secure Storage: eFuse HMAC key ID for storage encryption keys`. - - Snippet for burning the secure storage key in eFuse is given below. + - **Release** Mode: Encryption keys are derived using a key stored in eFuse, specified by `CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID`. + - Set the eFuse key ID at `ESP-TEE (Trusted Execution Environment) → Secure Services → Secure Storage: eFuse HMAC key ID for storage encryption keys`. + - Before running the application, users must program the required key into the configured eFuse block - refer to the instructions below. - ```shell - # Generate a random 32-byte HMAC key - openssl rand -out hmac_key_file.bin 32 - # Programming the HMAC key (256-bit) in eFuse - # Here, BLOCK_KEYx is a free eFuse key-block between BLOCK_KEY0 and BLOCK_KEY5 - espefuse -p PORT burn-key BLOCK_KEYx hmac_key_file.bin HMAC_UP - ``` +**For targets without HMAC peripheral (ESP32-C61):** + +```shell +# Generate a random 32-byte key +openssl rand -out hmac_key_file.bin 32 +# Program the USER purpose key (256-bit) in eFuse +# Here, BLOCK_KEYx is a free eFuse key-block between BLOCK_KEY0 and BLOCK_KEY5 +espefuse -p PORT burn-key --no-read-protect BLOCK_KEYx hmac_key_file.bin USER +``` + +> [!IMPORTANT] +> When programming the key into eFuse for targets without HMAC peripheral, ensure that it is **NOT** marked as read-protected (use the `--no-read-protect` flag). If the key is read-protected, the TEE will be unable to access it. However, this does not weaken security: the APM peripheral already blocks software access to the key, and any illegal read or write attempt from the REE triggers a fault. + +**For targets with HMAC peripheral:** + +```shell +# Generate a random 32-byte HMAC key +openssl rand -out hmac_key_file.bin 32 +# Program the HMAC key (256-bit) in eFuse +# Here, BLOCK_KEYx is a free eFuse key-block between BLOCK_KEY0 and BLOCK_KEY5 +espefuse -p PORT burn-key BLOCK_KEYx hmac_key_file.bin HMAC_UP +``` ### Build and Flash diff --git a/examples/security/.build-test-rules.yml b/examples/security/.build-test-rules.yml index 1190e81772..1849b89f52 100644 --- a/examples/security/.build-test-rules.yml +++ b/examples/security/.build-test-rules.yml @@ -38,7 +38,7 @@ examples/security/security_features_app: examples/security/tee/tee_attestation: disable: - - if: IDF_TARGET not in ["esp32c6", "esp32c5"] + - if: IDF_TARGET not in ["esp32c6", "esp32c5", "esp32c61"] depends_components: - esp_tee depends_filepatterns: @@ -46,7 +46,7 @@ examples/security/tee/tee_attestation: examples/security/tee/tee_basic: disable: - - if: IDF_TARGET not in ["esp32c6", "esp32c5"] + - if: IDF_TARGET not in ["esp32c6", "esp32c5", "esp32c61"] depends_components: - esp_tee depends_filepatterns: @@ -54,7 +54,7 @@ examples/security/tee/tee_basic: examples/security/tee/tee_secure_ota: disable: - - if: IDF_TARGET not in ["esp32c6", "esp32c5"] + - if: IDF_TARGET not in ["esp32c6", "esp32c5", "esp32c61"] depends_components: - esp_tee depends_filepatterns: @@ -62,7 +62,7 @@ examples/security/tee/tee_secure_ota: examples/security/tee/tee_secure_storage: disable: - - if: IDF_TARGET not in ["esp32c6", "esp32c5"] + - if: IDF_TARGET not in ["esp32c6", "esp32c5", "esp32c61"] depends_components: - esp_tee depends_filepatterns: diff --git a/examples/security/tee/tee_attestation/README.md b/examples/security/tee/tee_attestation/README.md index d9be06c58c..fd2e9914c6 100644 --- a/examples/security/tee/tee_attestation/README.md +++ b/examples/security/tee/tee_attestation/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | +| ----------------- | -------- | -------- | --------- | # TEE: Attestation example diff --git a/examples/security/tee/tee_basic/README.md b/examples/security/tee/tee_basic/README.md index 9abee63673..10d87a71ca 100644 --- a/examples/security/tee/tee_basic/README.md +++ b/examples/security/tee/tee_basic/README.md @@ -1,12 +1,12 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | +| ----------------- | -------- | -------- | --------- | # Basic TEE example ## Overview - This example illustrates the ESP-TEE (Trusted Execution Environment) framework to encrypt/decrypt data using AES within a secure environment. -- The non-secure world i.e. the Rich Execution Environment (REE) raises a request for AES operation in TEE through the secure service call interface. The TEE performs encrypts/decrypts the given buffer with the AES-256-CBC mode using the key protected by TEE. If the operation is successful, the result of the AES operation is returned in the output buffer provided in the secure service call by the REE. +- The non-secure world i.e. the Rich Execution Environment (REE) raises a request for AES operation in TEE through the secure service call interface. The TEE performs encrypts/decrypts the given buffer with the AES-256-GCM mode using the key protected by TEE. If the operation is successful, the result of the AES operation is returned in the output buffer provided in the secure service call by the REE. - This example also demonstrates how to add custom service calls to TEE. You can refer to `components/example_service` for more information - see the structure below. ``` @@ -43,15 +43,15 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ### Example Output ```log -I (315) main_task: Calling app_main() -I (315) example_tee_basic: AES-256-CBC operations in TEE -TEE: Secure service call for AES-256-CBC operation -TEE: In PROTECTED M-mode -I (325) example_tee_basic: AES encryption successful! -I (325) example_tee_basic: Cipher text - -I (325) example_tee_basic: ee 04 9b ee 95 6f 25 04 1e 8c e4 4e 8e 4e 7a d3 -TEE: Secure service call for AES-256-CBC operation -TEE: In PROTECTED M-mode -I (345) example_tee_basic: AES decryption successful! -I (345) main_task: Returned from app_main() +I (353) main_task: Calling app_main() +I (353) example_tee_basic: AES-256-GCM operations in TEE +I (364) example_tee_service: Secure service call: PROTECTED M-mode +I (370) example_tee_service: AES-256-GCM encryption +I (373) ciphertext: 23 32 a6 1f ff 27 15 d7 35 70 db f5 e3 0c 13 41 +I (373) ciphertext: eb 80 d7 2c 9c f5 68 5a b4 2c 43 b0 64 68 13 36 +I (383) tag: f8 85 ab 3b 47 a6 65 0d 0a 42 bd 3d +I (391) example_tee_service: Secure service call: PROTECTED M-mode +I (397) example_tee_service: AES-256-GCM decryption +I (393) example_tee_basic: AES-GCM decryption successful! +I (403) main_task: Returned from app_main() ``` diff --git a/examples/security/tee/tee_basic/components/example_secure_service/CMakeLists.txt b/examples/security/tee/tee_basic/components/example_secure_service/CMakeLists.txt index 4007e34517..58deeca4de 100644 --- a/examples/security/tee/tee_basic/components/example_secure_service/CMakeLists.txt +++ b/examples/security/tee/tee_basic/components/example_secure_service/CMakeLists.txt @@ -2,10 +2,13 @@ cmake_minimum_required(VERSION 3.22) idf_build_get_property(esp_tee_build ESP_TEE_BUILD) -if(NOT esp_tee_build) - return() +set(srcs) +set(include_dirs include) + +if(esp_tee_build) + list(APPEND srcs "example_service.c") endif() -idf_component_register(SRCS "example_service.c" - INCLUDE_DIRS include +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${include_dirs} PRIV_REQUIRES main) diff --git a/examples/security/tee/tee_basic/components/example_secure_service/example_service.c b/examples/security/tee/tee_basic/components/example_secure_service/example_service.c index 0be518e82a..ba8b738da6 100644 --- a/examples/security/tee/tee_basic/components/example_secure_service/example_service.c +++ b/examples/security/tee/tee_basic/components/example_secure_service/example_service.c @@ -1,39 +1,95 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ +#include #include "esp_cpu.h" #include "esp_err.h" -#include "esp_rom_sys.h" +#include "esp_log.h" -#include "hal/aes_hal.h" -#include "aes/esp_aes.h" +#include "mbedtls/gcm.h" #include "esp_tee.h" #include "secure_service_num.h" +#include "example_service.h" -/* Fixed key */ -static const uint8_t key[AES_256_KEY_BYTES] = {[0 ... 31] = 0xA5}; +#define AES256_KEY_LEN 32 +#define AES256_KEY_BITS (AES256_KEY_LEN * 8) +#define AES256_NONCE_LEN 12 -esp_err_t _ss_example_sec_serv_aes_op(int mode, size_t length, unsigned char iv[16], const unsigned char *input, unsigned char *output) +static const char *TAG = "tee_secure_service"; + +/* Fixed key (only for example purposes) */ +static const uint8_t key[AES256_KEY_LEN] = {[0 ... AES256_KEY_LEN - 1] = 0xA5}; + +/* Fixed nonce (only for example purposes) */ +static const uint8_t nonce[AES256_NONCE_LEN] = {[0 ... AES256_NONCE_LEN - 1] = 0x5A}; + +static esp_err_t aes_gcm_crypt_common(example_aes_gcm_ctx_t *ctx, uint8_t *tag, size_t tag_len, + uint8_t *output, bool is_encrypt) { - if (length == 0 || iv == NULL || input == NULL || output == NULL) { - return ESP_ERR_INVALID_ARG; - } - if (esp_cpu_get_curr_privilege_level() != ESP_CPU_S_MODE) { - esp_rom_printf("Operation executing from illegal privilege level!\n"); + ESP_LOGE(TAG, "Operation executing from illegal privilege level!"); return ESP_ERR_INVALID_STATE; } - esp_rom_printf("TEE: Secure service call for AES-256-CBC operation\n"); - esp_rom_printf("TEE: In PROTECTED M-mode\n"); + if (ctx == NULL || ctx->input == NULL || output == NULL || tag == NULL) { + return ESP_ERR_INVALID_ARG; + } - esp_aes_context ctx = {}; - ctx.key_bytes = AES_256_KEY_BYTES; - ctx.key_in_hardware = 0; - memcpy(ctx.key, key, ctx.key_bytes); + if (ctx->input_len == 0 || tag_len == 0) { + return ESP_ERR_INVALID_ARG; + } - return (esp_err_t)esp_aes_crypt_cbc(&ctx, mode, length, iv, input, output); + ESP_LOGI(TAG, "Secure service call: PROTECTED M-mode"); + ESP_LOGI(TAG, "AES-256-GCM %s", is_encrypt ? "encryption" : "decryption"); + + mbedtls_gcm_context gcm; + mbedtls_gcm_init(&gcm); + + esp_err_t err = ESP_FAIL; + + int ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, key, AES256_KEY_BITS); + if (ret != 0) { + ESP_LOGE(TAG, "Error in setting key: %d", ret); + goto cleanup; + } + + if (is_encrypt) { + ret = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, ctx->input_len, + nonce, AES256_NONCE_LEN, + ctx->aad, ctx->aad_len, + ctx->input, output, + tag_len, tag); + if (ret != 0) { + ESP_LOGE(TAG, "Error in encrypting data: %d", ret); + goto cleanup; + } + } else { + ret = mbedtls_gcm_auth_decrypt(&gcm, ctx->input_len, + nonce, AES256_NONCE_LEN, + ctx->aad, ctx->aad_len, + tag, tag_len, + ctx->input, output); + if (ret != 0) { + ESP_LOGE(TAG, "Error in decrypting data: %d", ret); + goto cleanup; + } + } + err = ESP_OK; + +cleanup: + mbedtls_gcm_free(&gcm); + return err; +} + +esp_err_t _ss_example_sec_serv_aes_gcm_encrypt(example_aes_gcm_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output) +{ + return aes_gcm_crypt_common(ctx, tag, tag_len, output, true); +} + +esp_err_t _ss_example_sec_serv_aes_gcm_decrypt(example_aes_gcm_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output) +{ + return aes_gcm_crypt_common(ctx, (uint8_t *)tag, tag_len, output, false); } diff --git a/examples/security/tee/tee_basic/components/example_secure_service/include/example_service.h b/examples/security/tee/tee_basic/components/example_secure_service/include/example_service.h index 6ea9efa37f..f13267e0fa 100644 --- a/examples/security/tee/tee_basic/components/example_secure_service/include/example_service.h +++ b/examples/security/tee/tee_basic/components/example_secure_service/include/example_service.h @@ -1,20 +1,18 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #include "esp_err.h" -/** - * @brief Perform AES-256-CBC encryption/decryption operation in TEE - * - * @param mode ESP_AES_ENCRYPT (1) for encryption, ESP_AES_DECRYPT (0) for decryption - * @param length Length of input data in bytes - * @param iv Initialization vector (16 bytes) - * @param input Input buffer containing plaintext (for encryption) or ciphertext (for decryption) - * @param output Output buffer for ciphertext (for encryption) or plaintext (for decryption) - * - * @return esp_err_t ESP_OK on success, appropriate error code on failure - */ -esp_err_t example_sec_serv_aes_op(int mode, size_t length, unsigned char iv[16], const unsigned char *input, unsigned char *output); +typedef struct { + const uint8_t *aad; /*!< Additional authenticated data */ + size_t aad_len; /*!< Length of additional authenticated data */ + const uint8_t *input; /*!< Input data buffer */ + size_t input_len; /*!< Length of input data */ +} example_aes_gcm_ctx_t; + +esp_err_t example_sec_serv_aes_gcm_encrypt(example_aes_gcm_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output); + +esp_err_t example_sec_serv_aes_gcm_decrypt(example_aes_gcm_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output); diff --git a/examples/security/tee/tee_basic/components/example_secure_service/sec_srv_tbl_example.yml b/examples/security/tee/tee_basic/components/example_secure_service/sec_srv_tbl_example.yml index 8b55150673..3ecc846124 100644 --- a/examples/security/tee/tee_basic/components/example_secure_service/sec_srv_tbl_example.yml +++ b/examples/security/tee/tee_basic/components/example_secure_service/sec_srv_tbl_example.yml @@ -3,5 +3,9 @@ secure_services: entries: - id: 200 type: custom - function: example_sec_serv_aes_op - args: 5 + function: example_sec_serv_aes_gcm_encrypt + args: 4 + - id: 201 + type: custom + function: example_sec_serv_aes_gcm_decrypt + args: 4 diff --git a/examples/security/tee/tee_basic/main/CMakeLists.txt b/examples/security/tee/tee_basic/main/CMakeLists.txt index c9e36bfd72..962b2a0326 100644 --- a/examples/security/tee/tee_basic/main/CMakeLists.txt +++ b/examples/security/tee/tee_basic/main/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "tee_main.c" - INCLUDE_DIRS "" - PRIV_REQUIRES esp_tee mbedtls) + INCLUDE_DIRS "" + PRIV_REQUIRES esp_tee mbedtls example_secure_service) diff --git a/examples/security/tee/tee_basic/main/tee_main.c b/examples/security/tee/tee_basic/main/tee_main.c index 6d30288a84..e050320b9e 100644 --- a/examples/security/tee/tee_basic/main/tee_main.c +++ b/examples/security/tee/tee_basic/main/tee_main.c @@ -1,6 +1,6 @@ /* ESP-TEE (Trusted Execution Environment) Example * - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -10,55 +10,72 @@ #include "esp_log.h" #include "esp_err.h" -#include "aes/esp_aes.h" +#include "esp_random.h" #include "esp_tee.h" #include "secure_service_num.h" +#include "example_service.h" -#define BUF_SZ (16) +#define EXAMPLE_BUF_SZ (32) +#define AES256_GCM_TAG_LEN (12) +#define AES256_GCM_AAD_LEN (16) static const char *TAG = "example_tee_basic"; -static const uint8_t expected_cipher[] = { - 0xee, 0x04, 0x9b, 0xee, 0x95, 0x6f, 0x25, 0x04, - 0x1e, 0x8c, 0xe4, 0x4e, 0x8e, 0x4e, 0x7a, 0xd3 -}; - -static const uint8_t nonce[IV_BYTES] = {[0 ... IV_BYTES - 1] = 0xFF}; - /* * Example workflow: - * 1. The REE initiates an AES operation request via the secure service call interface - * 2. The TEE receives the request and performs encryption/decryption using AES-256-CBC mode - * 3. The TEE uses a protected key that is only accessible within the secure environment - * 4. The encrypted/decrypted result is returned to the non-secure world through an output buffer - * provided in the secure service call + * 1. The REE generates random plaintext and AAD (Additional Authenticated Data) + * 2. The REE initiates an AES-256-GCM encryption request and provides output buffers + * for ciphertext and authentication tag + * 3. The TEE receives the request and performs encryption using a protected key and + * nonce that are only accessible within the secure environment + * 4. The encrypted ciphertext and authentication tag are returned to the REE + * 5. The REE initiates a decryption request with the ciphertext and authentication tag + * 6. The TEE performs authenticated decryption, verifying the tag and returning the plaintext + * 7. The REE verifies that the decrypted data matches the original plaintext */ void app_main(void) { - ESP_LOGI(TAG, "AES-256-CBC operations in TEE"); + ESP_LOGI(TAG, "AES-256-GCM operations in TEE"); - uint8_t plain_text[BUF_SZ] = {[0 ... BUF_SZ - 1] = 0x3A}; - uint8_t cipher_text[BUF_SZ] = {0}; - uint8_t decrypted_text[BUF_SZ] = {0}; - uint8_t iv[IV_BYTES] = {0}; + uint8_t plain_text[EXAMPLE_BUF_SZ]; + uint8_t cipher_text[EXAMPLE_BUF_SZ] = {0}; + uint8_t decrypted_text[EXAMPLE_BUF_SZ] = {0}; + uint8_t tag[AES256_GCM_TAG_LEN] = {0}; + uint8_t aad_buf[AES256_GCM_AAD_LEN]; - memcpy(iv, nonce, sizeof(iv)); - uint32_t ret = esp_tee_service_call(6, SS_EXAMPLE_SEC_SERV_AES_OP, ESP_AES_ENCRYPT, sizeof(plain_text), iv, plain_text, cipher_text); - if (ret != ESP_OK || memcmp(cipher_text, expected_cipher, sizeof(expected_cipher))) { - ESP_LOGE(TAG, "Failed to encrypt data!"); + /* Generate random plaintext and AAD */ + esp_fill_random(plain_text, sizeof(EXAMPLE_BUF_SZ)); + esp_fill_random(aad_buf, AES256_GCM_AAD_LEN); + + /* Encryption operation */ + example_aes_gcm_ctx_t enc_ctx = { + .aad = aad_buf, + .aad_len = sizeof(aad_buf), + .input = plain_text, + .input_len = sizeof(plain_text), + }; + + uint32_t ret = esp_tee_service_call(5, SS_EXAMPLE_SEC_SERV_AES_GCM_ENCRYPT, &enc_ctx, tag, AES256_GCM_TAG_LEN, cipher_text); + ESP_ERROR_CHECK((esp_err_t)ret); + + ESP_LOG_BUFFER_HEX_LEVEL("ciphertext", cipher_text, sizeof(cipher_text), ESP_LOG_INFO); + ESP_LOG_BUFFER_HEX_LEVEL("tag", tag, AES256_GCM_TAG_LEN, ESP_LOG_INFO); + + /* Decryption operation */ + example_aes_gcm_ctx_t dec_ctx = { + .aad = aad_buf, + .aad_len = sizeof(aad_buf), + .input = cipher_text, + .input_len = sizeof(cipher_text), + }; + + ret = esp_tee_service_call(5, SS_EXAMPLE_SEC_SERV_AES_GCM_DECRYPT, &dec_ctx, tag, AES256_GCM_TAG_LEN, decrypted_text); + ESP_ERROR_CHECK((esp_err_t)ret); + + if (memcmp(decrypted_text, plain_text, sizeof(plain_text)) != 0) { + ESP_LOGE(TAG, "Decrypted data mismatch!"); } else { - ESP_LOGI(TAG, "AES encryption successful!"); - } - - ESP_LOGI(TAG, "Cipher text -"); - ESP_LOG_BUFFER_HEX_LEVEL(TAG, cipher_text, sizeof(cipher_text), ESP_LOG_INFO); - - memcpy(iv, nonce, sizeof(iv)); - ret = esp_tee_service_call(6, SS_EXAMPLE_SEC_SERV_AES_OP, ESP_AES_DECRYPT, sizeof(cipher_text), iv, cipher_text, decrypted_text); - if (ret != ESP_OK || memcmp(decrypted_text, plain_text, sizeof(plain_text))) { - ESP_LOGE(TAG, "Failed to decrypt data!"); - } else { - ESP_LOGI(TAG, "AES decryption successful!"); + ESP_LOGI(TAG, "AES-GCM decryption successful!"); } } diff --git a/examples/security/tee/tee_basic/pytest_tee_basic.py b/examples/security/tee/tee_basic/pytest_tee_basic.py index 77524eb231..fdc466118e 100644 --- a/examples/security/tee/tee_basic/pytest_tee_basic.py +++ b/examples/security/tee/tee_basic/pytest_tee_basic.py @@ -22,8 +22,9 @@ def test_example_tee_basic(dut: Dut) -> None: logging.info(f'{log_label}: {bin_size // 1024}KB') # Start test - dut.expect('AES-256-CBC operations in TEE', timeout=30) - dut.expect('TEE: In PROTECTED M-mode', timeout=30) - dut.expect('AES encryption successful!', timeout=30) - dut.expect('ee 04 9b ee 95 6f 25 04 1e 8c e4 4e 8e 4e 7a d3', timeout=30) - dut.expect('AES decryption successful!', timeout=30) + dut.expect('AES-256-GCM operations in TEE', timeout=10) + dut.expect('Secure service call: PROTECTED M-mode', timeout=10) + dut.expect('AES-256-GCM encryption', timeout=10) + dut.expect('Secure service call: PROTECTED M-mode', timeout=10) + dut.expect('AES-256-GCM decryption', timeout=10) + dut.expect('Returned from app_main()', timeout=10) diff --git a/examples/security/tee/tee_basic/sdkconfig.defaults b/examples/security/tee/tee_basic/sdkconfig.defaults index 4c3a898568..214076f76e 100644 --- a/examples/security/tee/tee_basic/sdkconfig.defaults +++ b/examples/security/tee/tee_basic/sdkconfig.defaults @@ -1,5 +1,6 @@ # Enabling TEE CONFIG_SECURE_ENABLE_TEE=y +CONFIG_SECURE_TEE_LOG_LEVEL_INFO=y CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y CONFIG_SECURE_TEE_ATTESTATION=n CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN=n diff --git a/examples/security/tee/tee_secure_ota/README.md b/examples/security/tee/tee_secure_ota/README.md index 257bae962f..f52d25b0c8 100644 --- a/examples/security/tee/tee_secure_ota/README.md +++ b/examples/security/tee/tee_secure_ota/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | +| ----------------- | -------- | -------- | --------- | # TEE: Secure OTA example diff --git a/examples/security/tee/tee_secure_storage/README.md b/examples/security/tee/tee_secure_storage/README.md index 85bd3be512..e9f735ee00 100644 --- a/examples/security/tee/tee_secure_storage/README.md +++ b/examples/security/tee/tee_secure_storage/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | +| ----------------- | -------- | -------- | --------- | # TEE: Secure Storage example @@ -31,22 +31,37 @@ Open the project configuration menu (`idf.py menuconfig`). - Configure the secure storage example key ID at `Example Configuration → TEE: Secure Storage Key ID`. -TEE Secure Storage follows the NVS partition format and uses an AES-XTS encryption scheme derived via the HMAC peripheral. It supports two key derivation modes, configurable via `CONFIG_SECURE_TEE_SEC_STG_MODE`: +TEE Secure Storage follows the NVS partition format and uses an XTS-AES encryption scheme derived via the HMAC peripheral or software-based HMAC implementation. It supports two key derivation modes, configurable via `CONFIG_SECURE_TEE_SEC_STG_MODE`: - **Development** Mode: Encryption keys are embedded in the ESP-TEE firmware (identical across all instances). - - **Release** Mode: Encryption keys are derived via the HMAC peripheral using a key stored in eFuse, specified by `CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID`. + - **Release** Mode: Encryption keys are derived using a key stored in eFuse, specified by `CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID`. -#### Configure the eFuse key ID storing the HMAC key +#### Configure the eFuse key ID for storage encryption - Navigate to `ESP-TEE (Trusted Execution Environment) → Secure Services → Secure Storage: Mode` and enable the `Release` mode configuration. -- Set the eFuse key ID storing the HMAC key at `ESP-TEE (Trusted Execution Environment) → Secure Services → Secure Storage: eFuse HMAC key ID for storage encryption keys`. +- Set the eFuse key ID storing the HMAC/USER key at `ESP-TEE (Trusted Execution Environment) → Secure Services → Secure Storage: eFuse HMAC key ID for storage encryption keys`. -**Note:** Before running the example, users must program the HMAC key into the configured eFuse block - refer to the snippet below. The TEE checks whether the specified eFuse block is empty or already programmed with a key. If the block is empty, an error will be returned; otherwise, the pre-programmed key will be used. +**Note:** Before running the example, users must program the required key into the configured eFuse block - refer to the snippet below. The TEE checks whether the specified eFuse block is empty or already programmed with a key. If the block is empty, an error will be returned; otherwise, the pre-programmed key will be used. + +**For targets without HMAC peripheral (ESP32-C61):** + +```shell +# Generate a random 32-byte key +openssl rand -out hmac_key_file.bin 32 +# Program the USER purpose key (256-bit) in eFuse +# Here, BLOCK_KEYx is a free eFuse key-block between BLOCK_KEY0 and BLOCK_KEY5 +espefuse -p PORT burn-key --no-read-protect BLOCK_KEYx hmac_key_file.bin USER +``` + +> [!IMPORTANT] +> When programming the key into eFuse for targets without HMAC peripheral, ensure that it is **NOT** marked as read-protected (use the `--no-read-protect` flag). If the key is read-protected, the TEE will be unable to access it. However, this does not weaken security: the APM peripheral already blocks software access to the key, and any illegal read or write attempt from the REE triggers a fault. + +**For targets with HMAC peripheral:** ```shell # Generate a random 32-byte HMAC key openssl rand -out hmac_key_file.bin 32 -# Programming the HMAC key (256-bit) in eFuse +# Program the HMAC key (256-bit) in eFuse # Here, BLOCK_KEYx is a free eFuse key-block between BLOCK_KEY0 and BLOCK_KEY5 espefuse -p PORT burn-key BLOCK_KEYx hmac_key_file.bin HMAC_UP ```