From 1e8933d2962ef18f1443d63a74d694d005c3d479 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Wed, 12 Feb 2025 17:16:53 +0530 Subject: [PATCH] feat(esp_tee): Add support for `SECP192R1` curve in TEE secure storage --- components/esp_tee/Kconfig.projbuild | 6 + .../scripts/esp32c6/sec_srv_tbl_default.yml | 4 +- .../attestation/esp_att_utils_crypto.c | 4 +- .../include/esp_tee_sec_storage.h | 9 +- .../tee_sec_storage/tee_sec_storage.c | 125 +++++++++++++++--- .../tee_sec_storage/tee_sec_storage_wrapper.c | 8 +- .../main/core/esp_secure_services.c | 8 +- .../tee_cli_app/main/tee_srv_sec_str.c | 4 +- .../tee_test_fw/main/test_esp_tee_att.c | 4 +- .../tee_test_fw/main/test_esp_tee_sec_stg.c | 76 +++++++++-- .../test_apps/tee_test_fw/sdkconfig.ci.ota | 2 + .../mbedtls/esp_tee/esp_tee_mbedtls_config.h | 1 + .../tee/tee_secure_storage/main/tee_main.c | 4 +- 13 files changed, 200 insertions(+), 55 deletions(-) diff --git a/components/esp_tee/Kconfig.projbuild b/components/esp_tee/Kconfig.projbuild index e01d157db5..6776e8df0b 100644 --- a/components/esp_tee/Kconfig.projbuild +++ b/components/esp_tee/Kconfig.projbuild @@ -91,6 +91,12 @@ menu "ESP-TEE (Trusted Execution Environment)" help eFuse block ID storing the TEE secure storage encryption key + 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. + config SECURE_TEE_ATTESTATION bool "Enable Attestation" default y 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 53349f4d0e..a9bd42c37f 100644 --- a/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml +++ b/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml @@ -248,11 +248,11 @@ secure_services: - id: 177 type: custom function: esp_tee_sec_storage_get_signature - args: 4 + args: 5 - id: 178 type: custom function: esp_tee_sec_storage_get_pubkey - args: 2 + args: 3 - id: 179 type: custom function: esp_tee_sec_storage_encrypt diff --git a/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c b/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c index 2bbffce7b3..de4f699061 100644 --- a/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c +++ b/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c @@ -60,7 +60,7 @@ static esp_err_t gen_ecdsa_keypair_secp256r1(esp_att_ecdsa_keypair_t *keypair) } } - err = esp_tee_sec_storage_get_pubkey(slot_id, &pubkey); + err = esp_tee_sec_storage_get_pubkey(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, &pubkey); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to fetch ECDSA pubkey (%d)", err); return err; @@ -84,7 +84,7 @@ static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair } esp_tee_sec_storage_sign_t sign = {}; - esp_err_t err = esp_tee_sec_storage_get_signature(ESP_ATT_TK_KEY_ID, (uint8_t *)digest, len, &sign); + esp_err_t err = esp_tee_sec_storage_get_signature(ESP_ATT_TK_KEY_ID, ESP_SEC_STG_KEY_ECDSA_SECP256R1, (uint8_t *)digest, len, &sign); if (err != ESP_OK) { return err; } 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 d1a48fd11b..8852e7032a 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 @@ -25,7 +25,8 @@ extern "C" { */ typedef enum { ESP_SEC_STG_KEY_ECDSA_SECP256R1 = 0, - ESP_SEC_STG_KEY_AES256, + ESP_SEC_STG_KEY_AES256 = 1, + ESP_SEC_STG_KEY_ECDSA_SECP192R1 = 2, ESP_SEC_STG_MAX, } esp_tee_sec_storage_type_t; @@ -71,23 +72,25 @@ esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type * the key pair located in the given secure storage slot. * * @param[in] slot_id secure storage slot ID + * @param[in] key_type secure storage key type * @param[in] hash Message digest * @param[in] hlen Digest length * @param[out] out_sign Output context holding the signature * * @return esp_err_t ESP_OK on success, appropriate error code otherwise. */ -esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign); +esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign); /** * @brief Return the public key for the given secure storage slot * * @param[in] slot_id secure storage slot ID + * @param[in] key_type secure storage key type * @param[out] pubkey Output context holding the public key * * @return esp_err_t ESP_OK on success, appropriate error code otherwise. */ -esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_pubkey_t *pubkey); +esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey); /** * @brief Check whether the given slot in the secure storage is empty or not 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 6a34c23a1f..ead8eff497 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 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,6 +40,7 @@ #define AES256_GCM_AAD_LEN 16 #define ECDSA_SECP256R1_KEY_LEN 32 +#define ECDSA_SECP192R1_KEY_LEN 24 /* Structure to hold metadata for secure storage slots */ typedef struct { @@ -58,6 +59,12 @@ typedef struct { uint8_t pub_key[2 * ECDSA_SECP256R1_KEY_LEN]; /* Public key for ECDSA SECP256R1 (X and Y coordinates) */ } __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_ecdsa_secp256r1_t; +/* Structure to hold ECDSA SECP192R1 key pair */ +typedef struct { + uint8_t priv_key[ECDSA_SECP192R1_KEY_LEN]; /* Private key for ECDSA SECP192R1 */ + uint8_t pub_key[2 * ECDSA_SECP192R1_KEY_LEN]; /* Public key for ECDSA SECP192R1 (X and Y coordinates) */ +} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_ecdsa_secp192r1_t; + /* Structure to hold AES-256 GCM key and IV */ typedef struct { uint8_t key[AES256_GCM_KEY_LEN]; /* Key for AES-256 GCM */ @@ -67,6 +74,7 @@ typedef struct { /* Union to hold different types of cryptographic keys */ typedef union { 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_gcm_t aes256_gcm; /* AES-256 GCM key and IV */ } __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_key_t; @@ -348,39 +356,69 @@ esp_err_t esp_tee_sec_storage_init(void) return ESP_OK; } -static int generate_ecdsa_secp256r1_key(sec_stg_key_t *keyctx) +static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t key_type) { if (keyctx == NULL) { return -1; } - ESP_LOGI(TAG, "Generating ECDSA-SECP256R1 private key..."); + mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_SECP256R1; + size_t key_len = ECDSA_SECP256R1_KEY_LEN; + + if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + curve_id = MBEDTLS_ECP_DP_SECP192R1; + key_len = ECDSA_SECP192R1_KEY_LEN; +#else + ESP_LOGE(TAG, "Unsupported key type!"); + return -1; +#endif + } + + ESP_LOGI(TAG, "Generating ECDSA key for curve %d...", curve_id); mbedtls_ecdsa_context ctxECDSA; mbedtls_ecdsa_init(&ctxECDSA); - int ret = mbedtls_ecdsa_genkey(&ctxECDSA, MBEDTLS_ECP_DP_SECP256R1, rand_func, NULL); + int ret = mbedtls_ecdsa_genkey(&ctxECDSA, curve_id, rand_func, NULL); if (ret != 0) { ESP_LOGE(TAG, "Failed to generate ECDSA key"); goto exit; } - ret = mbedtls_mpi_write_binary(&ctxECDSA.MBEDTLS_PRIVATE(d), keyctx->ecdsa_secp256r1.priv_key, ECDSA_SECP256R1_KEY_LEN); + uint8_t *priv_key = (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) ? + keyctx->ecdsa_secp256r1.priv_key : +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + keyctx->ecdsa_secp192r1.priv_key; +#else + NULL; +#endif + + uint8_t *pub_key = (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) ? + keyctx->ecdsa_secp256r1.pub_key : +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + keyctx->ecdsa_secp192r1.pub_key; +#else + NULL; +#endif + + ret = mbedtls_mpi_write_binary(&ctxECDSA.MBEDTLS_PRIVATE(d), priv_key, key_len); if (ret != 0) { goto exit; } - ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), &keyctx->ecdsa_secp256r1.pub_key[0], ECDSA_SECP256R1_KEY_LEN); + ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), pub_key, key_len); if (ret != 0) { goto exit; } - ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), &keyctx->ecdsa_secp256r1.pub_key[ECDSA_SECP256R1_KEY_LEN], ECDSA_SECP256R1_KEY_LEN); + ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), pub_key + key_len, key_len); if (ret != 0) { goto exit; } - buffer_hexdump("Private key", keyctx->ecdsa_secp256r1.priv_key, sizeof(keyctx->ecdsa_secp256r1.priv_key)); + buffer_hexdump("Private key", priv_key, key_len); + buffer_hexdump("Public key", pub_key, key_len * 2); exit: mbedtls_ecdsa_free(&ctxECDSA); @@ -418,7 +456,10 @@ esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type switch (key_type) { case ESP_SEC_STG_KEY_ECDSA_SECP256R1: - if (generate_ecdsa_secp256r1_key(&keyctx) != 0) { +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + case ESP_SEC_STG_KEY_ECDSA_SECP192R1: +#endif + if (generate_ecdsa_key(&keyctx, key_type) != 0) { ESP_LOGE(TAG, "Failed to generate ECDSA keypair (%d)", ret); return ESP_FAIL; } @@ -437,7 +478,7 @@ esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type return secure_storage_write(slot_id, (uint8_t *)&keyctx, sizeof(keyctx), key_type); } -esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign) +esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign) { if (slot_id > MAX_SEC_STG_SLOT_ID || hash == NULL || out_sign == NULL) { return ESP_ERR_INVALID_ARG; @@ -447,9 +488,15 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, siz return ESP_ERR_INVALID_SIZE; } - sec_stg_key_t keyctx; +#if !CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { + ESP_LOGE(TAG, "Unsupported key type!"); + return ESP_ERR_NOT_SUPPORTED; + } +#endif - esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), ESP_SEC_STG_KEY_ECDSA_SECP256R1); + sec_stg_key_t keyctx; + esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), key_type); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to fetch key from slot"); return err; @@ -464,7 +511,19 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, siz mbedtls_ecp_keypair_init(&priv_key); mbedtls_ecdsa_init(&sign_ctx); - int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &priv_key, keyctx.ecdsa_secp256r1.priv_key, sizeof(keyctx.ecdsa_secp256r1.priv_key)); + int ret = -1; + if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) { + ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &priv_key, keyctx.ecdsa_secp256r1.priv_key, sizeof(keyctx.ecdsa_secp256r1.priv_key)); +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + } else if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { + ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP192R1, &priv_key, keyctx.ecdsa_secp192r1.priv_key, sizeof(keyctx.ecdsa_secp192r1.priv_key)); +#endif + } else { + ESP_LOGE(TAG, "Unsupported key type for signature generation"); + err = ESP_ERR_NOT_SUPPORTED; + goto exit; + } + if (ret != 0) { err = ESP_FAIL; goto exit; @@ -476,7 +535,7 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, siz goto exit; } - ESP_LOGI(TAG, "Generating ECDSA-SECP256R1 signature..."); + ESP_LOGI(TAG, "Generating ECDSA signature..."); ret = mbedtls_ecdsa_sign(&sign_ctx.MBEDTLS_PRIVATE(grp), &r, &s, &sign_ctx.MBEDTLS_PRIVATE(d), hash, hlen, rand_func, NULL); @@ -486,13 +545,21 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, siz goto exit; } - ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, ECDSA_SECP256R1_KEY_LEN); + memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_sign_t)); + + size_t key_len = (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) ? ECDSA_SECP256R1_KEY_LEN : +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + ECDSA_SECP192R1_KEY_LEN; +#else + 0; +#endif + ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, key_len); if (ret != 0) { err = ESP_FAIL; goto exit; } - ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, ECDSA_SECP256R1_KEY_LEN); + ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, key_len); if (ret != 0) { err = ESP_FAIL; goto exit; @@ -508,22 +575,38 @@ exit: return err; } -esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_pubkey_t *pubkey) +esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey) { if (slot_id > MAX_SEC_STG_SLOT_ID || pubkey == NULL) { return ESP_ERR_INVALID_ARG; } sec_stg_key_t keyctx; + size_t key_len; + uint8_t *pub_key_src; - esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), ESP_SEC_STG_KEY_ECDSA_SECP256R1); + if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) { + key_len = ECDSA_SECP256R1_KEY_LEN; + pub_key_src = keyctx.ecdsa_secp256r1.pub_key; +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + } else if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { + key_len = ECDSA_SECP192R1_KEY_LEN; + pub_key_src = keyctx.ecdsa_secp192r1.pub_key; +#endif + } else { + ESP_LOGE(TAG, "Unsupported key type"); + return ESP_ERR_INVALID_ARG; + } + + esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), key_type); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to fetch key from slot"); return err; } - memcpy(pubkey->pub_x, &keyctx.ecdsa_secp256r1.pub_key[0], ECDSA_SECP256R1_KEY_LEN); - memcpy(pubkey->pub_y, &keyctx.ecdsa_secp256r1.pub_key[ECDSA_SECP256R1_KEY_LEN], ECDSA_SECP256R1_KEY_LEN); + // Copy public key components in one shot + memcpy(pubkey->pub_x, pub_key_src, key_len); + memcpy(pubkey->pub_y, pub_key_src + key_len, key_len); return ESP_OK; } @@ -618,7 +701,7 @@ static esp_err_t tee_sec_storage_crypt_common(uint16_t slot_id, uint8_t *input, } sec_stg_key_t keyctx; - esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(keyctx), 1); + esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(keyctx), ESP_SEC_STG_KEY_AES256); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to fetch key from slot"); return err; diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c index 94b69a99e7..ea69a0b916 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c @@ -18,14 +18,14 @@ esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type return esp_tee_service_call_with_noniram_intr_disabled(3, SS_ESP_TEE_SEC_STORAGE_GEN_KEY, slot_id, key_type); } -esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *sign) +esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *sign) { - return esp_tee_service_call_with_noniram_intr_disabled(5, SS_ESP_TEE_SEC_STORAGE_GET_SIGNATURE, slot_id, hash, hlen, sign); + return esp_tee_service_call_with_noniram_intr_disabled(6, SS_ESP_TEE_SEC_STORAGE_GET_SIGNATURE, slot_id, key_type, hash, hlen, sign); } -esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_pubkey_t *pubkey) +esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey) { - return esp_tee_service_call_with_noniram_intr_disabled(3, SS_ESP_TEE_SEC_STORAGE_GET_PUBKEY, slot_id, pubkey); + return esp_tee_service_call_with_noniram_intr_disabled(4, SS_ESP_TEE_SEC_STORAGE_GET_PUBKEY, slot_id, key_type, pubkey); } bool esp_tee_sec_storage_is_slot_empty(uint16_t slot_id) 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 0961a304a3..989fc6afcf 100644 --- a/components/esp_tee/subproject/main/core/esp_secure_services.c +++ b/components/esp_tee/subproject/main/core/esp_secure_services.c @@ -368,7 +368,7 @@ esp_err_t _ss_esp_tee_sec_storage_gen_key(uint16_t slot_id, uint8_t key_type) return esp_tee_sec_storage_gen_key(slot_id, key_type); } -esp_err_t _ss_esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign) +esp_err_t _ss_esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign) { bool valid_addr = ((esp_tee_ptr_in_ree((void *)hash) && esp_tee_ptr_in_ree((void *)out_sign)) & (esp_tee_ptr_in_ree((void *)(hash + hlen)) && @@ -379,10 +379,10 @@ esp_err_t _ss_esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, } ESP_FAULT_ASSERT(valid_addr); - return esp_tee_sec_storage_get_signature(slot_id, hash, hlen, out_sign); + return esp_tee_sec_storage_get_signature(slot_id, key_type, hash, hlen, out_sign); } -esp_err_t _ss_esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_pubkey_t *pubkey) +esp_err_t _ss_esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey) { bool valid_addr = ((esp_tee_ptr_in_ree((void *)pubkey)) & (esp_tee_ptr_in_ree((void *)((char *)pubkey + sizeof(esp_tee_sec_storage_pubkey_t))))); @@ -392,7 +392,7 @@ esp_err_t _ss_esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_stora } ESP_FAULT_ASSERT(valid_addr); - return esp_tee_sec_storage_get_pubkey(slot_id, pubkey); + return esp_tee_sec_storage_get_pubkey(slot_id, key_type, pubkey); } esp_err_t _ss_esp_tee_sec_storage_encrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad, 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 fad89de36f..82f60f9ea6 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 @@ -289,7 +289,7 @@ static int tee_sec_stg_sign(int argc, char **argv) } esp_tee_sec_storage_sign_t sign = {}; - err = esp_tee_sec_storage_get_signature(slot_id, digest, sizeof(digest), &sign); + err = esp_tee_sec_storage_get_signature(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, digest, sizeof(digest), &sign); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to generate signature!"); goto exit; @@ -307,7 +307,7 @@ static int tee_sec_stg_sign(int argc, char **argv) free(sign_hexstr); esp_tee_sec_storage_pubkey_t pubkey = {}; - err = esp_tee_sec_storage_get_pubkey(slot_id, &pubkey); + err = esp_tee_sec_storage_get_pubkey(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, &pubkey); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to fetch public-key!"); goto exit; 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 6dd98f1024..864d199712 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 @@ -36,7 +36,7 @@ static const char *TAG = "test_esp_tee_att"; -extern int verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_pubkey_t *pubkey, const esp_tee_sec_storage_sign_t *sign); +extern int verify_ecdsa_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_pubkey_t *pubkey, const esp_tee_sec_storage_sign_t *sign, bool is_crv_p192); static uint8_t hexchar_to_byte(char hex) { @@ -277,7 +277,7 @@ TEST_CASE("Test TEE Attestation - Generate and verify the EAT", "[attestation]") ESP_LOGI(TAG, "Verifying the generated EAT..."); // Verifying the generated token - TEST_ASSERT_EQUAL(0, verify_ecdsa_secp256r1_sign(digest, sizeof(digest), &pubkey_ctx, &sign_ctx)); + TEST_ASSERT_EQUAL(0, verify_ecdsa_sign(digest, sizeof(digest), &pubkey_ctx, &sign_ctx, false)); 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 fa5e381b6e..1422dc27df 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 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ #include "esp_random.h" #include "unity.h" +#include "sdkconfig.h" /* Note: negative value here so that assert message prints a grep-able error hex value (mbedTLS uses -N for error codes) */ @@ -27,11 +28,16 @@ #define SHA256_DIGEST_SZ (32) #define ECDSA_SECP256R1_KEY_LEN (32) +#define ECDSA_SECP192R1_KEY_LEN (24) static const char *TAG = "test_esp_tee_sec_storage"; -int verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_pubkey_t *pubkey, const esp_tee_sec_storage_sign_t *sign) +int verify_ecdsa_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_pubkey_t *pubkey, const esp_tee_sec_storage_sign_t *sign, bool is_crv_p192) { +#if !CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN + TEST_ASSERT_FALSE(is_crv_p192); +#endif + TEST_ASSERT_NOT_NULL(pubkey); TEST_ASSERT_NOT_NULL(digest); TEST_ASSERT_NOT_NULL(sign); @@ -44,7 +50,12 @@ int verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len, const esp_tee mbedtls_ecdsa_context ecdsa_context; mbedtls_ecdsa_init(&ecdsa_context); - TEST_ASSERT_MBEDTLS_OK(mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1)); + mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_SECP256R1; + if (is_crv_p192) { + curve_id = MBEDTLS_ECP_DP_SECP192R1; + } + + TEST_ASSERT_MBEDTLS_OK(mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), curve_id)); size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P); TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&r, sign->sign_r, plen)); @@ -81,19 +92,54 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1) with all key- TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1)); esp_tee_sec_storage_sign_t sign = {}; - TEST_ESP_OK(esp_tee_sec_storage_get_signature(slot_id, msg_digest, sizeof(msg_digest), &sign)); + TEST_ESP_OK(esp_tee_sec_storage_get_signature(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, msg_digest, sizeof(msg_digest), &sign)); esp_tee_sec_storage_pubkey_t pubkey = {}; - TEST_ESP_OK(esp_tee_sec_storage_get_pubkey(slot_id, &pubkey)); + TEST_ESP_OK(esp_tee_sec_storage_get_pubkey(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, &pubkey)); ESP_LOGI(TAG, "Verifying generated signature..."); - TEST_ESP_OK(verify_ecdsa_secp256r1_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign)); + TEST_ESP_OK(verify_ecdsa_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign, false)); TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id)); TEST_ASSERT_TRUE(esp_tee_sec_storage_is_slot_empty(slot_id)); } } +#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN +TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp192r1) with all key-slot IDs", "[secure_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[SHA256_DIGEST_SZ]; + TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256(message, buf_sz, msg_digest, false)); + free(message); + + TEST_ESP_OK(esp_tee_sec_storage_init()); + + for (uint16_t slot_id = 0; slot_id <= MAX_SEC_STG_SLOT_ID; slot_id++) { + ESP_LOGI(TAG, "Slot ID: %u", slot_id); + TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id)); + TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP192R1)); + + esp_tee_sec_storage_sign_t sign = {}; + TEST_ESP_OK(esp_tee_sec_storage_get_signature(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP192R1, msg_digest, sizeof(msg_digest), &sign)); + + esp_tee_sec_storage_pubkey_t pubkey = {}; + TEST_ESP_OK(esp_tee_sec_storage_get_pubkey(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP192R1, &pubkey)); + + ESP_LOGI(TAG, "Verifying generated signature..."); + TEST_ESP_OK(verify_ecdsa_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign, true)); + + TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id)); + TEST_ASSERT_TRUE(esp_tee_sec_storage_is_slot_empty(slot_id)); + } +} +#endif + TEST_CASE("Test TEE Secure Storage - Encrypt-decrypt (aes256_gcm) with all key-slot IDs", "[secure_storage]") { const uint8_t SZ = 100; @@ -161,7 +207,9 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys", const uint16_t slot_id = 7; ESP_LOGI(TAG, "Slot ID: %u - Trying AES operation with ECDSA key...", slot_id); TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id)); - TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1)); + + esp_tee_sec_storage_type_t key_type = ESP_SEC_STG_KEY_ECDSA_SECP256R1; + TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, key_type)); TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_tee_sec_storage_encrypt(slot_id, plaintext, SZ, aad, sizeof(aad), tag, sizeof(tag), ciphertext)); @@ -172,7 +220,7 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys", TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_AES256)); esp_tee_sec_storage_sign_t sign = {}; - TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_tee_sec_storage_get_signature(slot_id, msg_digest, sizeof(msg_digest), &sign)); + TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_tee_sec_storage_get_signature(slot_id, key_type, msg_digest, sizeof(msg_digest), &sign)); TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id)); TEST_ASSERT_TRUE(esp_tee_sec_storage_is_slot_empty(slot_id)); @@ -242,14 +290,16 @@ TEST_CASE("Test TEE Secure Storage - Null Pointer and Zero Length", "[secure_sto TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_decrypt(slot_id, data, sizeof(data), NULL, 0, tag, 0, data)); TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id)); - TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1)); + + esp_tee_sec_storage_type_t key_type = ESP_SEC_STG_KEY_ECDSA_SECP256R1; + TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, key_type)); esp_tee_sec_storage_sign_t sign = {}; - TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_signature(slot_id, NULL, sizeof(data), &sign)); - TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_get_signature(slot_id, data, 0, &sign)); - TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_signature(slot_id, data, sizeof(data), NULL)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_signature(slot_id, key_type, NULL, sizeof(data), &sign)); + TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_get_signature(slot_id, key_type, data, 0, &sign)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_signature(slot_id, key_type, data, sizeof(data), NULL)); - TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_pubkey(slot_id, NULL)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_pubkey(slot_id, key_type, NULL)); TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id)); } diff --git a/components/esp_tee/test_apps/tee_test_fw/sdkconfig.ci.ota b/components/esp_tee/test_apps/tee_test_fw/sdkconfig.ci.ota index ba0a656949..ac1f00d7d0 100644 --- a/components/esp_tee/test_apps/tee_test_fw/sdkconfig.ci.ota +++ b/components/esp_tee/test_apps/tee_test_fw/sdkconfig.ci.ota @@ -7,6 +7,8 @@ CONFIG_PARTITION_TABLE_FILENAME="partitions_tee_ota.csv" # Increasing Bootloader log verbosity CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y +CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN=y + # secure storage key slot for attestation CONFIG_SECURE_TEE_ATT_KEY_SLOT_ID=14 diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h index 72ea061315..3914ab29be 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -42,6 +42,7 @@ #define MBEDTLS_ASN1_PARSE_C #define MBEDTLS_BIGNUM_C #define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED #define MBEDTLS_ECP_C #define MBEDTLS_ECDSA_C diff --git a/examples/security/tee/tee_secure_storage/main/tee_main.c b/examples/security/tee/tee_secure_storage/main/tee_main.c index 21c96efdb6..14742ef03d 100644 --- a/examples/security/tee/tee_secure_storage/main/tee_main.c +++ b/examples/security/tee/tee_secure_storage/main/tee_main.c @@ -125,7 +125,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter) } esp_tee_sec_storage_sign_t sign = {}; - err = esp_tee_sec_storage_get_signature(KEY_SLOT_ID, msg_digest, sizeof(msg_digest), &sign); + err = esp_tee_sec_storage_get_signature(KEY_SLOT_ID, ESP_SEC_STG_KEY_ECDSA_SECP256R1, msg_digest, sizeof(msg_digest), &sign); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to generate signature!"); goto exit; @@ -134,7 +134,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter) ESP_LOG_BUFFER_HEX("Signature", &sign, sizeof(sign)); esp_tee_sec_storage_pubkey_t pubkey = {}; - err = esp_tee_sec_storage_get_pubkey(KEY_SLOT_ID, &pubkey); + err = esp_tee_sec_storage_get_pubkey(KEY_SLOT_ID, ESP_SEC_STG_KEY_ECDSA_SECP256R1, &pubkey); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to fetch public-key!"); goto exit;