diff --git a/components/esp_tee/Kconfig.projbuild b/components/esp_tee/Kconfig.projbuild index 4e6f6604f6f..14b7518734a 100644 --- a/components/esp_tee/Kconfig.projbuild +++ b/components/esp_tee/Kconfig.projbuild @@ -96,11 +96,20 @@ menu "ESP-TEE (Trusted Execution Environment)" help eFuse block key ID storing the HMAC key for deriving PBKDF2-based ECDSA keys - config SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN - bool "Secure Storage: Support signing with the ECDSA SECP192R1 curve" - default n - help - Enable ECDSA signing with the SECP192R1 curve using the TEE secure storage. + menu "Secure Storage: Additional supported curves for ECDSA signing" + + config SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + bool "SECP192R1" + help + Enable ECDSA signing with the SECP192R1 curve using TEE secure storage + + config SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + bool "SECP384R1" + depends on SOC_ECDSA_SUPPORT_CURVE_P384 + help + Enable ECDSA signing with the SECP384R1 curve using TEE secure storage + + endmenu config SECURE_TEE_ATTESTATION bool "Enable Attestation" diff --git a/components/esp_tee/scripts/esp_tee_sec_stg_keygen/README.md b/components/esp_tee/scripts/esp_tee_sec_stg_keygen/README.md index 59ea02d58af..45b4ef1fed8 100644 --- a/components/esp_tee/scripts/esp_tee_sec_stg_keygen/README.md +++ b/components/esp_tee/scripts/esp_tee_sec_stg_keygen/README.md @@ -7,13 +7,13 @@ ``` $ python esp_tee_sec_stg_keygen.py --help -usage: esp_tee_sec_stg_keygen.py [-h] -k {aes256,ecdsa_p256,ecdsa_p192} -o OUTPUT [-i INPUT] [--write-once] +usage: esp_tee_sec_stg_keygen.py [-h] -k {aes256,ecdsa_p256,ecdsa_p192,ecdsa_p384} -o OUTPUT [-i INPUT] [--write-once] Generate or import a cryptographic key structure for secure storage options: -h, --help show this help message and exit - -k, --key-type {aes256,ecdsa_p256,ecdsa_p192} + -k, --key-type {aes256,ecdsa_p256,ecdsa_p192,ecdsa_p384} key type to be processed -o, --output OUTPUT output binary file name -i, --input INPUT input key file (.pem for ecdsa, .bin for aes) @@ -25,6 +25,7 @@ options: ```bash python esp_tee_sec_stg_keygen.py -k ecdsa_p256 -o ecdsa_p256_k0.bin python esp_tee_sec_stg_keygen.py -k ecdsa_p192 -o ecdsa_p192_k0.bin +python esp_tee_sec_stg_keygen.py -k ecdsa_p384 -o ecdsa_p384_k0.bin ``` #### With custom PEM: @@ -65,6 +66,7 @@ tee_sec_stg_ns,namespace,, aes256_key0,file,binary,aes256_gcm_k0.bin p256_key0,file,binary,ecdsa_p256_k0.bin p192_key0,file,binary,ecdsa_p192_k0.bin +p384_key0,file,binary,ecdsa_p384_k0.bin attest_key0,file,binary,ecdsa_p256_k1.bin ``` > [!IMPORTANT] diff --git a/components/esp_tee/scripts/esp_tee_sec_stg_keygen/esp_tee_sec_stg_keygen.py b/components/esp_tee/scripts/esp_tee_sec_stg_keygen/esp_tee_sec_stg_keygen.py index 6a70113d32f..2f2dcc12cae 100644 --- a/components/esp_tee/scripts/esp_tee_sec_stg_keygen/esp_tee_sec_stg_keygen.py +++ b/components/esp_tee/scripts/esp_tee_sec_stg_keygen/esp_tee_sec_stg_keygen.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import argparse @@ -8,7 +8,6 @@ import struct from enum import Enum from enum import IntFlag from typing import Any -from typing import Optional from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization @@ -21,6 +20,7 @@ AES_DEFAULT_IV_LEN = 16 AES_GCM_IV_LEN = 12 ECDSA_P256_LEN = 32 ECDSA_P192_LEN = 24 +ECDSA_P384_LEN = 48 # === Key Type Enum === @@ -28,6 +28,7 @@ class KeyType(Enum): AES256 = 0 ECDSA_P256 = 1 ECDSA_P192 = 2 + ECDSA_P384 = 3 # === Bitwise Flags Enum === @@ -39,7 +40,7 @@ class Flags(IntFlag): # === Key Generators === -def generate_aes256_key(flags: Flags, key_file: Optional[str] = None) -> bytes: +def generate_aes256_key(flags: Flags, key_file: str | None = None) -> bytes: if key_file: with open(key_file, 'rb') as f: key_data = f.read() @@ -68,7 +69,7 @@ def generate_aes256_key(flags: Flags, key_file: Optional[str] = None) -> bytes: def generate_ecdsa_key( - curve: ec.EllipticCurve, key_type_enum: KeyType, key_len: int, flags: Flags, pem_file: Optional[str] = None + curve: ec.EllipticCurve, key_type_enum: KeyType, key_len: int, flags: Flags, pem_file: str | None = None ) -> bytes: if pem_file: with open(pem_file, 'rb') as f: @@ -87,13 +88,15 @@ def generate_ecdsa_key( return packed + b'\x00' * (SEC_STG_KEY_DATA_SZ - len(packed)) -def generate_key_data(key_type: KeyType, flags: Flags, input_file: Optional[str]) -> bytes: +def generate_key_data(key_type: KeyType, flags: Flags, input_file: str | None) -> bytes: if key_type == KeyType.AES256: return generate_aes256_key(flags, input_file) elif key_type == KeyType.ECDSA_P256: return generate_ecdsa_key(ec.SECP256R1(), key_type, ECDSA_P256_LEN, flags, input_file) elif key_type == KeyType.ECDSA_P192: return generate_ecdsa_key(ec.SECP192R1(), key_type, ECDSA_P192_LEN, flags, input_file) + elif key_type == KeyType.ECDSA_P384: + return generate_ecdsa_key(ec.SECP384R1(), key_type, ECDSA_P384_LEN, flags, input_file) else: raise ValueError(f'Unsupported key type: {key_type}') diff --git a/components/esp_tee/subproject/components/tee_sec_storage/include/esp_tee_sec_storage.h b/components/esp_tee/subproject/components/tee_sec_storage/include/esp_tee_sec_storage.h index b9cf001238c..82e94c9c24a 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/include/esp_tee_sec_storage.h +++ b/components/esp_tee/subproject/components/tee_sec_storage/include/esp_tee_sec_storage.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,11 @@ extern "C" { #include "esp_err.h" #include "esp_bit_defs.h" -#define MAX_ECDSA_SUPPORTED_KEY_LEN 32 /*!< Maximum supported size for the ECDSA key */ +#if SOC_ECDSA_SUPPORT_CURVE_P384 +#define MAX_ECDSA_SUPPORTED_KEY_LEN 48 /*!< Maximum supported size for the ECDSA key (SECP384R1) */ +#else +#define MAX_ECDSA_SUPPORTED_KEY_LEN 32 /*!< Maximum supported size for the ECDSA key (SECP256R1) */ +#endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ #define MAX_AES_SUPPORTED_KEY_LEN 32 /*!< Maximum supported size for the AES key */ #define SEC_STORAGE_FLAG_NONE 0 /*!< No flags */ @@ -30,6 +34,9 @@ typedef enum { ESP_SEC_STG_KEY_AES256 = 0, ESP_SEC_STG_KEY_ECDSA_SECP256R1 = 1, ESP_SEC_STG_KEY_ECDSA_SECP192R1 = 2, +#if SOC_ECDSA_SUPPORT_CURVE_P384 + ESP_SEC_STG_KEY_ECDSA_SECP384R1 = 3, +#endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ ESP_SEC_STG_TYPE_MAX, } esp_tee_sec_storage_type_t; 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 2c24ee9bd5b..f45f8d28fa7 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,6 +34,7 @@ #define AES256_KEY_BITS (AES256_KEY_LEN * 8) #define AES256_DEFAULT_IV_LEN 16 #define AES256_GCM_IV_LEN 12 +#define ECDSA_SECP384R1_KEY_LEN 48 #define ECDSA_SECP256R1_KEY_LEN 32 #define ECDSA_SECP192R1_KEY_LEN 24 @@ -44,6 +45,12 @@ #define PBKDF2_HMAC_ITER 2048 +/* Structure to hold ECDSA SECP384R1 key pair */ +typedef struct { + uint8_t priv_key[ECDSA_SECP384R1_KEY_LEN]; /* Private key for ECDSA SECP384R1 */ + uint8_t pub_key[2 * ECDSA_SECP384R1_KEY_LEN]; /* Public key for ECDSA SECP384R1 (X and Y coordinates) */ +} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_ecdsa_secp384r1_t; + /* Structure to hold ECDSA SECP256R1 key pair */ typedef struct { uint8_t priv_key[ECDSA_SECP256R1_KEY_LEN]; /* Private key for ECDSA SECP256R1 */ @@ -67,11 +74,12 @@ typedef struct { const esp_tee_sec_storage_type_t type; /* Type of the key */ uint32_t flags; /* Flags associated with the key */ union { + sec_stg_ecdsa_secp384r1_t ecdsa_secp384r1; /* ECDSA SECP384R1 key pair */ sec_stg_ecdsa_secp256r1_t ecdsa_secp256r1; /* ECDSA SECP256R1 key pair */ sec_stg_ecdsa_secp192r1_t ecdsa_secp192r1; /* ECDSA SECP192R1 key pair */ sec_stg_aes256_t aes256; /* AES-256 key and IV */ }; - uint32_t reserved[38]; /* Reserved space for future use */ + uint32_t reserved[26]; /* Reserved space for future use */ } __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_key_t; _Static_assert(sizeof(sec_stg_key_t) == 256, "Incorrect sec_stg_key_t size"); @@ -296,6 +304,50 @@ esp_err_t esp_tee_sec_storage_clear_key(const char *key_id) return err; } +static esp_err_t get_ecdsa_curve_info(esp_tee_sec_storage_type_t type, sec_stg_key_t *ctx, + uint8_t **priv_key, size_t *priv_key_len, uint8_t **pub_key, size_t *pub_key_len) +{ + if (!ctx || !priv_key || !priv_key_len || !pub_key || !pub_key_len) { + return ESP_ERR_INVALID_ARG; + } + + esp_err_t err = ESP_FAIL; + + switch (type) { + case ESP_SEC_STG_KEY_ECDSA_SECP256R1: + *priv_key_len = ECDSA_SECP256R1_KEY_LEN; + *priv_key = ctx->ecdsa_secp256r1.priv_key; + *pub_key_len = sizeof(ctx->ecdsa_secp256r1.pub_key); + *pub_key = ctx->ecdsa_secp256r1.pub_key; + err = ESP_OK; + break; +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + case ESP_SEC_STG_KEY_ECDSA_SECP192R1: + *priv_key_len = ECDSA_SECP192R1_KEY_LEN; + *priv_key = ctx->ecdsa_secp192r1.priv_key; + *pub_key_len = sizeof(ctx->ecdsa_secp192r1.pub_key); + *pub_key = ctx->ecdsa_secp192r1.pub_key; + err = ESP_OK; + break; +#endif +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + case ESP_SEC_STG_KEY_ECDSA_SECP384R1: + *priv_key_len = ECDSA_SECP384R1_KEY_LEN; + *priv_key = ctx->ecdsa_secp384r1.priv_key; + *pub_key_len = sizeof(ctx->ecdsa_secp384r1.pub_key); + *pub_key = ctx->ecdsa_secp384r1.pub_key; + err = ESP_OK; + break; +#endif + default: + ESP_LOGE(TAG, "Unsupported ECDSA curve type"); + err = ESP_ERR_INVALID_ARG; + break; + } + + return err; +} + static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t key_type) { if (keyctx == NULL) { @@ -304,19 +356,20 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t psa_key_id_t key_id = 0; psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_bits(&key_attributes, ECDSA_SECP256R1_KEY_LEN * 8); + uint8_t *priv_key_buf = NULL; + size_t priv_key_buf_size = 0; + uint8_t *pub_key_buf = NULL; + size_t pub_key_buf_size = 0; + esp_err_t err = get_ecdsa_curve_info(key_type, keyctx, &priv_key_buf, &priv_key_buf_size, &pub_key_buf, &pub_key_buf_size); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to get ECDSA curve info: %d", err); + return -1; + } + psa_set_key_bits(&key_attributes, priv_key_buf_size * 8); psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH); psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); - if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { -#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN - psa_set_key_bits(&key_attributes, ECDSA_SECP192R1_KEY_LEN * 8); -#else - ESP_LOGE(TAG, "Unsupported key-type!"); - return -1; -#endif - } psa_status_t status = psa_generate_key(&key_attributes, &key_id); if (status != PSA_SUCCESS) { ESP_LOGE(TAG, "Failed to generate ECDSA key: %ld", status); @@ -326,26 +379,6 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t size_t priv_key_len = 0; size_t pub_key_len = 0; - /* Use the correct union member based on key type */ - uint8_t *priv_key_buf = NULL; - size_t priv_key_buf_size = 0; - uint8_t *pub_key_buf = NULL; - size_t pub_key_buf_size = 0; - - if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { -#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN - priv_key_buf = keyctx->ecdsa_secp192r1.priv_key; - priv_key_buf_size = sizeof(keyctx->ecdsa_secp192r1.priv_key); - pub_key_buf = keyctx->ecdsa_secp192r1.pub_key; - pub_key_buf_size = sizeof(keyctx->ecdsa_secp192r1.pub_key); -#endif - } else { - priv_key_buf = keyctx->ecdsa_secp256r1.priv_key; - priv_key_buf_size = sizeof(keyctx->ecdsa_secp256r1.priv_key); - pub_key_buf = keyctx->ecdsa_secp256r1.pub_key; - pub_key_buf_size = sizeof(keyctx->ecdsa_secp256r1.pub_key); - } - status = psa_export_key(key_id, priv_key_buf, priv_key_buf_size, &priv_key_len); if (status != PSA_SUCCESS) { ESP_LOGE(TAG, "Failed to export ECDSA private key: %ld", status); @@ -356,7 +389,7 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t * We need to strip the prefix and store only X and Y coordinates (64 bytes for secp256r1, 48 bytes for secp192r1) * Use fixed-size array to avoid VLA issues with goto statements */ - uint8_t pub_key_with_prefix[(2 * ECDSA_SECP256R1_KEY_LEN) + 1]; /* Max size: 65 bytes for secp256r1 */ + uint8_t pub_key_with_prefix[(2 * ECDSA_SECP384R1_KEY_LEN) + 1]; /* Max size: 65 bytes for secp256r1 */ size_t pub_key_len_with_prefix = 0; size_t expected_pub_key_len_with_prefix = pub_key_buf_size + 1; @@ -421,6 +454,9 @@ esp_err_t esp_tee_sec_storage_gen_key(const esp_tee_sec_storage_key_cfg_t *cfg) case ESP_SEC_STG_KEY_ECDSA_SECP256R1: #if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN case ESP_SEC_STG_KEY_ECDSA_SECP192R1: +#endif +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + case ESP_SEC_STG_KEY_ECDSA_SECP384R1: #endif if (generate_ecdsa_key(&keyctx, cfg->type) != 0) { ESP_LOGE(TAG, "Failed to generate ECDSA keypair"); @@ -449,7 +485,12 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cf #if !CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { - ESP_LOGE(TAG, "Unsupported key-type!"); + return ESP_ERR_NOT_SUPPORTED; + } +#endif + +#if SOC_ECC_SUPPORT_CURVE_P384 && !CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP384R1) { return ESP_ERR_NOT_SUPPORTED; } #endif @@ -490,12 +531,18 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cf psa_set_key_bits(&key_attributes, ECDSA_SECP192R1_KEY_LEN * 8); priv_key = keyctx.ecdsa_secp192r1.priv_key; priv_key_len = sizeof(keyctx.ecdsa_secp192r1.priv_key); +#endif +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + } else if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP384R1) { + psa_set_key_bits(&key_attributes, ECDSA_SECP384R1_KEY_LEN * 8); + priv_key = keyctx.ecdsa_secp384r1.priv_key; + priv_key_len = sizeof(keyctx.ecdsa_secp384r1.priv_key); #endif } psa_status_t status = psa_import_key(&key_attributes, priv_key, priv_key_len, &key_id); if (status != PSA_SUCCESS) { - err = ESP_FAIL; + err = ESP_ERR_INVALID_ARG; ESP_LOGE(TAG, "Failed to import ECDSA private key: %ld", status); goto exit; } @@ -559,6 +606,12 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg pub_key_src = keyctx.ecdsa_secp192r1.pub_key; pub_key_len = ECDSA_SECP192R1_KEY_LEN; break; +#endif +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + case ESP_SEC_STG_KEY_ECDSA_SECP384R1: + pub_key_src = keyctx.ecdsa_secp384r1.pub_key; + pub_key_len = ECDSA_SECP384R1_KEY_LEN; + break; #endif default: ESP_LOGE(TAG, "Unsupported key-type"); @@ -683,7 +736,11 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2 } int cfg_key_id = (int)CONFIG_SECURE_TEE_PBKDF2_EFUSE_HMAC_KEY_ID; - if (cfg_key_id < 0 || cfg_key_id >= HMAC_KEY_MAX) { + /* Split the checks to keep Coverity happy */ + if (cfg_key_id < 0) { + return ESP_ERR_INVALID_ARG; + } + if (cfg_key_id >= HMAC_KEY_MAX) { return ESP_ERR_INVALID_ARG; } diff --git a/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_sec_str.c b/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_sec_str.c index 25fb6ef49f9..f2ee33060ac 100644 --- a/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_sec_str.c +++ b/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_sec_str.c @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include "soc/soc_caps.h" #include "esp_event.h" #include "esp_log.h" @@ -20,11 +21,17 @@ #include "example_tee_srv.h" #define SHA256_DIGEST_SZ (32) -#define ECDSA_SECP256R1_KEY_LEN (32) +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN +#define MAX_ECDSA_KEY_LEN (48) +#else +#define MAX_ECDSA_KEY_LEN (32) +#endif /* CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN */ #define AES256_GCM_TAG_LEN (16) #define MAX_AES_PLAINTEXT_LEN (256) +#define ECDSA_SECP256R1_KEY_LEN (32) + static const char *TAG = "tee_sec_stg"; static esp_err_t hexstr_to_hexbuf(const char *hexstr, size_t hexstr_len, void *hexbuf, size_t hexbuf_sz) @@ -266,7 +273,7 @@ static int tee_sec_stg_sign(int argc, char **argv) goto exit; } - size_t sign_hexstr_len = (ECDSA_SECP256R1_KEY_LEN * 2) * 2 + 1; + size_t sign_hexstr_len = (MAX_ECDSA_KEY_LEN * 2) * 2 + 1; char *sign_hexstr = calloc(sign_hexstr_len, sizeof(char)); if (sign_hexstr == NULL) { err = ESP_ERR_NO_MEM; @@ -284,7 +291,7 @@ static int tee_sec_stg_sign(int argc, char **argv) goto exit; } - size_t pubkey_hexstr_len = (ECDSA_SECP256R1_KEY_LEN * 2) * 2 + 1; + size_t pubkey_hexstr_len = (MAX_ECDSA_KEY_LEN * 2) * 2 + 1; char *pubkey_hexstr = calloc(pubkey_hexstr_len, sizeof(char)); if (pubkey_hexstr == NULL) { err = ESP_ERR_NO_MEM; 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 a7d8d713b55..6469233172b 100644 --- a/components/esp_tee/test_apps/tee_test_fw/conftest.py +++ b/components/esp_tee/test_apps/tee_test_fw/conftest.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 # pylint: disable=W0621 # redefined-outer-name import base64 @@ -339,6 +339,20 @@ class TEESerial(IdfSerial): 'LS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=' ), }, + {'key': 'p192_key0', 'type': 'ecdsa_p192', 'input': None, 'write_once': False}, + { + 'key': 'p384_key0', + 'type': 'ecdsa_p384', + 'input': 'ecdsa_p384_key.pem', + 'write_once': True, + 'b64': ( + 'LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1JR2tBZ0VCQkRDQUIreENyckkrOWJObWlzVlVsSG1R' + 'T3dZMHIyNWVIL09DalVMUVY4NHZtZU0wWDVLMnYrRE4KZkdSUkRZd0NheGlnQndZRks0RUVBQ0toWkFOaUFB' + 'UVFWcHFObVY0Qm1aemw5VWZBcm0veVpiak9QZTJoUEtDRQp0RERZLy9FS0lOZExvY1dvMUgwWWhzYTBuU2xj' + 'cGk2SDM3eXlSVHNxUnFueFBOeXFYZDdqbXo1WkIySWZHWHhBCmptZnZLVmJIcVNJV0JDRUx0WUxwS2t3UHNCO' + 'XV4WW89Ci0tLS0tRU5EIEVDIFBSSVZBVEUgS0VZLS0tLS0=' + ), + }, ] NVS_KEYS_B64 = 'MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzA==' diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_att.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_att.c index 5b551f8efbd..f6008aac423 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_att.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_att.c @@ -35,7 +35,7 @@ static const char *TAG = "test_esp_tee_att"; -extern int verify_ecdsa_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_ecdsa_pubkey_t *pubkey, const esp_tee_sec_storage_ecdsa_sign_t *sign, bool is_crv_p192); +extern int verify_ecdsa_sign(const esp_tee_sec_storage_type_t key_type, const uint8_t *digest, size_t len, const esp_tee_sec_storage_ecdsa_pubkey_t *pubkey, const esp_tee_sec_storage_ecdsa_sign_t *sign); static uint8_t hexchar_to_byte(char hex) { @@ -268,7 +268,7 @@ TEST_CASE("Test TEE Attestation - Generate and verify the EAT", "[attestation]") fetch_signature((const char *)token_buf, &sign_ctx); // Verifying the generated token - TEST_ASSERT_EQUAL(0, verify_ecdsa_sign(digest, sizeof(digest), &pubkey_ctx, &sign_ctx, false)); + TEST_ASSERT_EQUAL(0, verify_ecdsa_sign(ESP_SEC_STG_KEY_ECDSA_SECP256R1, digest, sizeof(digest), &pubkey_ctx, &sign_ctx)); free(token_buf); } diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c index 284e4c69501..da72c34c27a 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,7 +27,9 @@ error hex value (mbedTLS uses -N for error codes) */ #define TEST_ASSERT_MBEDTLS_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X)) +#define SHA384_DIGEST_SZ (48) #define SHA256_DIGEST_SZ (32) +#define ECDSA_SECP384R1_KEY_LEN (48) #define ECDSA_SECP256R1_KEY_LEN (32) #define ECDSA_SECP192R1_KEY_LEN (24) @@ -38,10 +40,13 @@ static const char *TAG = "test_esp_tee_sec_storage"; -int verify_ecdsa_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_ecdsa_pubkey_t *pubkey, const esp_tee_sec_storage_ecdsa_sign_t *sign, bool is_crv_p192) +int verify_ecdsa_sign(const esp_tee_sec_storage_type_t key_type, const uint8_t *digest, size_t len, const esp_tee_sec_storage_ecdsa_pubkey_t *pubkey, const esp_tee_sec_storage_ecdsa_sign_t *sign) { #if !CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN - TEST_ASSERT_FALSE(is_crv_p192); + TEST_ASSERT_FALSE(key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1); +#endif +#if SOC_ECDSA_SUPPORT_CURVE_P384 && !CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + TEST_ASSERT_FALSE(key_type == ESP_SEC_STG_KEY_ECDSA_SECP384R1); #endif TEST_ASSERT_NOT_NULL(pubkey); @@ -59,22 +64,40 @@ int verify_ecdsa_sign(const uint8_t *digest, size_t len, const esp_tee_sec_stora size_t pub_key_len; size_t signature_size; - if (is_crv_p192) { + + /* Use fixed-size array large enough for all supported curves (max: SECP384R1 = 2*48+1 = 97) */ + uint8_t pub_key[2 * ECDSA_SECP384R1_KEY_LEN + 1]; + + switch (key_type) { +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + case ESP_SEC_STG_KEY_ECDSA_SECP192R1: psa_set_key_bits(&key_attributes, ECDSA_SECP192R1_KEY_LEN * 8); pub_key_len = ECDSA_SECP192R1_KEY_LEN; signature_size = ECDSA_SECP192R1_KEY_LEN * 2; - } else { + break; +#endif // CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + case ESP_SEC_STG_KEY_ECDSA_SECP256R1: psa_set_key_bits(&key_attributes, ECDSA_SECP256R1_KEY_LEN * 8); pub_key_len = ECDSA_SECP256R1_KEY_LEN; signature_size = ECDSA_SECP256R1_KEY_LEN * 2; + break; +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + case ESP_SEC_STG_KEY_ECDSA_SECP384R1: + psa_set_key_bits(&key_attributes, ECDSA_SECP384R1_KEY_LEN * 8); + pub_key_len = ECDSA_SECP384R1_KEY_LEN; + signature_size = ECDSA_SECP384R1_KEY_LEN * 2; + break; +#endif // CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + default: + ESP_LOGE(TAG, "Unsupported ECDSA curve type"); + err = ESP_ERR_INVALID_ARG; + goto exit; } - - uint8_t pub_key[2 * pub_key_len + 1]; pub_key[0] = 0x04; memcpy(pub_key + 1, pubkey->pub_x, pub_key_len); memcpy(pub_key + 1 + pub_key_len, pubkey->pub_y, pub_key_len); - psa_status_t status = psa_import_key(&key_attributes, pub_key, sizeof(pub_key), &key_id); + psa_status_t status = psa_import_key(&key_attributes, pub_key, 2 * pub_key_len + 1, &key_id); if (status != PSA_SUCCESS) { ESP_LOGE(TAG, "Failed to import ECDSA public key: %ld", status); err = ESP_ERR_INVALID_ARG; @@ -131,7 +154,7 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_stora esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {}; TEST_ESP_OK(esp_tee_sec_storage_ecdsa_get_pubkey(&key_cfg, &pubkey)); - TEST_ESP_OK(verify_ecdsa_sign(msg_digest, msg_digest_len, &pubkey, &sign, false)); + TEST_ESP_OK(verify_ecdsa_sign(key_cfg.type, msg_digest, msg_digest_len, &pubkey, &sign)); TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id)); } @@ -173,7 +196,51 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp192r1)", "[sec_stora esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {}; TEST_ESP_OK(esp_tee_sec_storage_ecdsa_get_pubkey(&key_cfg, &pubkey)); - TEST_ESP_OK(verify_ecdsa_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign, true)); + TEST_ESP_OK(verify_ecdsa_sign(key_cfg.type, msg_digest, sizeof(msg_digest), &pubkey, &sign)); + + TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id)); + } +} +#endif + +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN +TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp384r1)", "[sec_storage]") +{ + const size_t buf_sz = 16 * 1024 + 6; // NOTE: Not an exact multiple of SHA block size + unsigned char *message = heap_caps_malloc(buf_sz, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(message); + + esp_fill_random(message, buf_sz); + + uint8_t msg_digest[SHA384_DIGEST_SZ]; + // TEST_ASSERT_MBEDTLS_OK(mbedtls_sha512(message, buf_sz, msg_digest, false)); + size_t msg_digest_len = 0; + psa_status_t status = psa_hash_compute(PSA_ALG_SHA_384, message, buf_sz, msg_digest, sizeof(msg_digest), &msg_digest_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + (void)msg_digest_len; + free(message); + + esp_tee_sec_storage_key_cfg_t key_cfg = { + .type = ESP_SEC_STG_KEY_ECDSA_SECP384R1 + }; + + for (unsigned int i = 0; i < MAX_SEC_STG_ITER; i++) { + char key_id[32]; + int ret = snprintf(key_id, sizeof(key_id), "ecdsa_key_%u", i); + TEST_ASSERT_TRUE(ret > 0 && ret < sizeof(key_id)); + + key_cfg.id = key_id; + esp_err_t err = esp_tee_sec_storage_clear_key(key_cfg.id); + TEST_ASSERT_TRUE(err == ESP_OK || err == ESP_ERR_NOT_FOUND); + TEST_ESP_OK(esp_tee_sec_storage_gen_key(&key_cfg)); + + esp_tee_sec_storage_ecdsa_sign_t sign = {}; + TEST_ESP_OK(esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, sizeof(msg_digest), &sign)); + + esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {}; + TEST_ESP_OK(esp_tee_sec_storage_ecdsa_get_pubkey(&key_cfg, &pubkey)); + + TEST_ESP_OK(verify_ecdsa_sign(key_cfg.type, msg_digest, sizeof(msg_digest), &pubkey, &sign)); TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id)); } @@ -288,7 +355,7 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys", TEST_ESP_OK(esp_tee_sec_storage_gen_key(&key_cfg)); esp_tee_sec_storage_ecdsa_sign_t sign = {}; - TEST_ESP_ERR(ESP_FAIL, esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, sizeof(msg_digest), &sign)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, sizeof(msg_digest), &sign)); TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id)); // Test with non-existent data @@ -400,46 +467,64 @@ static void test_aead_encrypt_decrypt(const char *key_id, const uint8_t *input, free(decrypted); } +static void do_ecdsa_sign_and_verify(const esp_tee_sec_storage_key_cfg_t *cfg, const uint8_t *digest, size_t digest_len) +{ + esp_tee_sec_storage_ecdsa_sign_t sign = {0}; + esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {0}; + + TEST_ESP_OK(esp_tee_sec_storage_ecdsa_sign(cfg, digest, digest_len, &sign)); + TEST_ESP_OK(esp_tee_sec_storage_ecdsa_get_pubkey(cfg, &pubkey)); + TEST_ESP_OK(verify_ecdsa_sign(cfg->type, digest, digest_len, &pubkey, &sign)); +} + TEST_CASE("Test TEE Secure Storage - Host-generated keys", "[sec_storage_host_keygen]") { - const char *aes_key_id0 = "aes256_key0"; - const char *aes_key_id1 = "aes256_key1"; + const char *aes_key_ids[] = { "aes256_key0", "aes256_key1" }; const char *ecdsa_key_id0 = "p256_key0"; - const char *attest_key_id = "attest_key"; - TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_tee_sec_storage_clear_key(aes_key_id0)); + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_tee_sec_storage_clear_key(aes_key_ids[0])); const size_t SZ = 100; uint8_t *plaintext = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); TEST_ASSERT_NOT_NULL(plaintext); esp_fill_random(plaintext, SZ); - test_aead_encrypt_decrypt(aes_key_id0, plaintext, SZ); - test_aead_encrypt_decrypt(aes_key_id1, plaintext, SZ); + for (size_t i = 0; i < sizeof(aes_key_ids) / sizeof(aes_key_ids[0]); ++i) { + test_aead_encrypt_decrypt(aes_key_ids[i], plaintext, SZ); + } - free(plaintext); + heap_caps_free(plaintext); - TEST_ESP_OK(esp_tee_sec_storage_clear_key(aes_key_id1)); + TEST_ESP_OK(esp_tee_sec_storage_clear_key(aes_key_ids[1])); - uint8_t msg_digest[SHA256_DIGEST_SZ]; - esp_fill_random(msg_digest, sizeof(msg_digest)); + uint8_t digest_buf[SHA384_DIGEST_SZ]; + esp_fill_random(digest_buf, sizeof(digest_buf)); esp_tee_sec_storage_key_cfg_t key_cfg = { - .id = ecdsa_key_id0, + .id = ecdsa_key_id0, .type = ESP_SEC_STG_KEY_ECDSA_SECP256R1, }; - esp_tee_sec_storage_ecdsa_sign_t sign = {}; - TEST_ESP_OK(esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, sizeof(msg_digest), &sign)); - - esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {}; - TEST_ESP_OK(esp_tee_sec_storage_ecdsa_get_pubkey(&key_cfg, &pubkey)); - - TEST_ESP_OK(verify_ecdsa_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign, false)); - + do_ecdsa_sign_and_verify(&key_cfg, digest_buf, SHA256_DIGEST_SZ); TEST_ESP_OK(esp_tee_sec_storage_clear_key(ecdsa_key_id0)); - TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_tee_sec_storage_clear_key(attest_key_id)); +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + const char *ecdsa_key_id1 = "p192_key0"; + key_cfg.id = ecdsa_key_id1; + key_cfg.type = ESP_SEC_STG_KEY_ECDSA_SECP192R1; + + do_ecdsa_sign_and_verify(&key_cfg, digest_buf, SHA256_DIGEST_SZ); + TEST_ESP_OK(esp_tee_sec_storage_clear_key(ecdsa_key_id1)); +#endif /* CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN */ + +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + const char *ecdsa_key_id2 = "p384_key0"; + key_cfg.id = ecdsa_key_id2; + key_cfg.type = ESP_SEC_STG_KEY_ECDSA_SECP384R1; + + do_ecdsa_sign_and_verify(&key_cfg, digest_buf, SHA384_DIGEST_SZ); + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_tee_sec_storage_clear_key(ecdsa_key_id2)); +#endif /* CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN */ #if CONFIG_SECURE_TEE_ATTESTATION uint8_t *token_buf = heap_caps_calloc(ESP_ATT_TK_BUF_SIZE, sizeof(uint8_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); @@ -450,29 +535,52 @@ TEST_CASE("Test TEE Secure Storage - Host-generated keys", "[sec_storage_host_ke token_buf, ESP_ATT_TK_BUF_SIZE, &token_len)); free(token_buf); -#endif + + const char *attest_key_id = "attest_key"; + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_tee_sec_storage_clear_key(attest_key_id)); +#endif /* CONFIG_SECURE_TEE_ATTESTATION */ } #if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN static const uint8_t sha[] = { - 0x0c, 0xaa, 0x08, 0xb4, 0xf0, 0x89, 0xd3, 0x45, - 0xbb, 0x55, 0x98, 0xd9, 0xc2, 0xe9, 0x65, 0x5d, - 0x7e, 0xa3, 0xa9, 0xc3, 0xcd, 0x69, 0xb1, 0xcf, - 0x91, 0xbe, 0x58, 0x10, 0xfe, 0x80, 0x65, 0x6e + 0xda, 0x99, 0x5d, 0x66, 0xcb, 0xa5, 0xcb, 0xc7, + 0xc5, 0x3d, 0x8d, 0x08, 0x4d, 0x6a, 0x5e, 0x8e, + 0xf0, 0x84, 0x4b, 0x7b, 0xdd, 0xd0, 0x20, 0x47, + 0xa3, 0x6c, 0x61, 0xf3, 0xbc, 0xcf, 0xf4, 0xe2, + 0xf7, 0x70, 0xcd, 0x19, 0xf7, 0x31, 0x52, 0x48, + 0x1f, 0x29, 0x0e, 0x13, 0x24, 0x55, 0x9d, 0xb9, + 0x1a, 0x48, 0xa4, 0x0e, 0x75, 0xc2, 0xa8, 0x35, + 0xa9, 0x53, 0x97, 0xec, 0xcc, 0x66, 0x5b, 0xa6 }; static void test_ecdsa_sign(mbedtls_ecp_group_id gid) { - bool is_crv_p192 = false; - esp_tee_sec_storage_type_t key_type = ESP_SEC_STG_KEY_ECDSA_SECP256R1; - size_t key_len = ECDSA_SECP256R1_KEY_LEN; + esp_tee_sec_storage_type_t key_type = ESP_SEC_STG_TYPE_MAX; + size_t key_len = 0; + size_t sha_len = SHA256_DIGEST_SZ; - if (gid == MBEDTLS_ECP_DP_SECP192R1) { - is_crv_p192 = true; + switch (gid) { + case MBEDTLS_ECP_DP_SECP256R1: + key_type = ESP_SEC_STG_KEY_ECDSA_SECP256R1; + key_len = ECDSA_SECP256R1_KEY_LEN; + break; +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + case MBEDTLS_ECP_DP_SECP192R1: key_type = ESP_SEC_STG_KEY_ECDSA_SECP192R1; - key_len = ECDSA_SECP192R1_KEY_LEN; + key_len = ECDSA_SECP192R1_KEY_LEN; + break; +#endif +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + case MBEDTLS_ECP_DP_SECP384R1: + key_type = ESP_SEC_STG_KEY_ECDSA_SECP384R1; + key_len = ECDSA_SECP384R1_KEY_LEN; + sha_len = SHA384_DIGEST_SZ; + break; +#endif + default: + ESP_LOGE(TAG, "Unsupported curve ID: %d", gid); + return; } - const char *key_id = "ecdsa_k0"; esp_tee_sec_storage_key_cfg_t key_cfg = { @@ -509,13 +617,13 @@ static void test_ecdsa_sign(mbedtls_ecp_group_id gid) mbedtls_ecp_keypair *keypair = key_ctx.MBEDTLS_PRIVATE(pk_ctx); //mbedtls_pk_ec(key_ctx); mbedtls_mpi key_mpi = keypair->MBEDTLS_PRIVATE(d); - TEST_ASSERT_MBEDTLS_OK(mbedtls_ecdsa_sign(&ecdsa_context.MBEDTLS_PRIVATE(grp), &r, &s, &key_mpi, sha, SHA256_DIGEST_SZ, NULL, NULL)); + TEST_ASSERT_MBEDTLS_OK(mbedtls_ecdsa_sign(&ecdsa_context.MBEDTLS_PRIVATE(grp), &r, &s, &key_mpi, sha, sha_len, NULL, NULL)); esp_tee_sec_storage_ecdsa_sign_t sign = {}; TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&r, sign.signature, key_len)); TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&s, sign.signature + key_len, key_len)); - TEST_ESP_OK(verify_ecdsa_sign(sha, sizeof(sha), &pubkey, &sign, is_crv_p192)); + TEST_ESP_OK(verify_ecdsa_sign(key_type, sha, sha_len, &pubkey, &sign)); esp_ecdsa_free_pk_context(&key_ctx); mbedtls_ecdsa_free(&ecdsa_context); @@ -531,5 +639,8 @@ TEST_CASE("Test TEE Secure Storage - mbedtls ECDSA signing", "[mbedtls]") #if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN && !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2) test_ecdsa_sign(MBEDTLS_ECP_DP_SECP192R1); #endif +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN + test_ecdsa_sign(MBEDTLS_ECP_DP_SECP384R1); +#endif } #endif diff --git a/components/esp_tee/test_apps/tee_test_fw/sdkconfig.ci.tee_ota b/components/esp_tee/test_apps/tee_test_fw/sdkconfig.ci.tee_ota index 7cbca448490..13a1bc558d4 100644 --- a/components/esp_tee/test_apps/tee_test_fw/sdkconfig.ci.tee_ota +++ b/components/esp_tee/test_apps/tee_test_fw/sdkconfig.ci.tee_ota @@ -9,6 +9,8 @@ CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y CONFIG_SECURE_TEE_LOG_LEVEL_DEBUG=y CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN=y +# Takes effect only for supported targets +CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN=y # secure storage key slot for attestation CONFIG_SECURE_TEE_ATT_KEY_STR_ID="tee_att_keyN" diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h index 9b8df61efe4..29f56df700a 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -47,6 +47,9 @@ #define MBEDTLS_ASN1_WRITE_C #define MBEDTLS_ASN1_PARSE_C #define MBEDTLS_BIGNUM_C +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#endif #define MBEDTLS_ECP_DP_SECP256R1_ENABLED #if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN #define MBEDTLS_ECP_DP_SECP192R1_ENABLED diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index aedebbbc3ad..be79e7ee26a 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -829,7 +829,14 @@ int esp_ecdsa_tee_load_pubkey(mbedtls_ecp_keypair *keypair, const char *tee_key_ } else if (keypair->MBEDTLS_PRIVATE(grp).id == MBEDTLS_ECP_DP_SECP192R1) { len = ECDSA_KEY_LEN_P192; key_type = ESP_SEC_STG_KEY_ECDSA_SECP192R1; - } else { + } +#if SOC_ECDSA_SUPPORT_CURVE_P384 + else if (keypair->MBEDTLS_PRIVATE(grp).id == MBEDTLS_ECP_DP_SECP384R1) { + len = ECDSA_KEY_LEN_P384; + key_type = ESP_SEC_STG_KEY_ECDSA_SECP384R1; + } +#endif + else { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -947,7 +954,14 @@ static int esp_ecdsa_tee_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mp } else if (grp->id == MBEDTLS_ECP_DP_SECP192R1) { len = ECDSA_KEY_LEN_P192; key_type = ESP_SEC_STG_KEY_ECDSA_SECP192R1; - } else { + } +#if SOC_ECDSA_SUPPORT_CURVE_P384 + else if (grp->id == MBEDTLS_ECP_DP_SECP384R1) { + len = ECDSA_KEY_LEN_P384; + key_type = ESP_SEC_STG_KEY_ECDSA_SECP384R1; + } +#endif + else { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -966,7 +980,7 @@ static int esp_ecdsa_tee_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mp esp_tee_sec_storage_ecdsa_sign_t sign = {}; esp_err_t err = esp_tee_sec_storage_ecdsa_sign(&cfg, (uint8_t *)msg, msg_len, &sign); if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to get signature"); + ESP_LOGE(TAG, "Failed to get signature: 0x%08lx", err); return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } diff --git a/docs/en/security/tee/tee-sec-storage.rst b/docs/en/security/tee/tee-sec-storage.rst index c3c0e880554..de770eaeec5 100644 --- a/docs/en/security/tee/tee-sec-storage.rst +++ b/docs/en/security/tee/tee-sec-storage.rst @@ -20,8 +20,14 @@ The TEE Secure Storage service provides persistent storage for securely storing Additionally, the secure storage provides interfaces for performing the following cryptographic services from the TEE using securely stored key material: - #. Message signing and public key retrieval using the ``ecdsa_secp256r1`` and ``ecdsa_secp192r1`` algorithms - #. Authenticated encryption and decryption using the ``aes256_gcm`` algorithm +#. Authenticated encryption and decryption using the ``aes256_gcm`` algorithm +#. Message signing and public key retrieval using ECDSA with the following curves + + .. list:: + - ``ecdsa_secp256r1`` + - ``ecdsa_secp192r1`` + :SOC_ECDSA_SUPPORT_CURVE_P384: - ``ecdsa_secp384r1`` + .. note:: @@ -47,8 +53,14 @@ Each data object consisting of the type, associated metadata flags (e.g., ``WRIT Currently, TEE secure storage supports storing the following cryptographic keys: - #. ``ecdsa_secp256r1`` and ``ecdsa_secp192r1`` curve key-pairs, including private and public key components - #. ``aes256`` keys, including the key and initialization vector (IV) +#. ``aes256`` keys, including the key and initialization vector (IV) +#. ECDSA key-pairs for the following curves, including both public and private components + + .. list:: + - ``ecdsa_secp256r1`` + - ``ecdsa_secp192r1`` + :SOC_ECDSA_SUPPORT_CURVE_P384: - ``ecdsa_secp384r1`` + All assets related to TEE secure storage are protected by the APM peripheral and are inaccessible to the REE application. Any direct access attempts will result in a system fault. Future updates are planned to add support for additional key types and general-purpose data storage.