feat: migrates esp_tee to PSA APIs

This commit is contained in:
Ashish Sharma
2025-12-23 10:35:30 +08:00
committed by Mahavir Jain
parent fdd5ef561d
commit e7e31d5d39
29 changed files with 588 additions and 505 deletions

View File

@@ -12,14 +12,14 @@ menu "ESP-TEE (Trusted Execution Environment)"
config SECURE_TEE_IRAM_SIZE
hex "IRAM region size"
default 0x8000
range 0x5000 0xA000
range 0x5000 0xF000
help
This configuration sets the IRAM size for the TEE module.
This should be 256-byte (0x100) aligned.
config SECURE_TEE_DRAM_SIZE
hex "DRAM region size"
default 0x4000
default 0x5000
range 0x3000 0x7000
help
This configuration sets the DRAM size for the TEE module.
@@ -45,7 +45,7 @@ menu "ESP-TEE (Trusted Execution Environment)"
config SECURE_TEE_IROM_SIZE
hex
default 0x10000
default 0x20000
help
This should be a multiple of MMU_PAGE_SIZE.

View File

@@ -14,12 +14,8 @@
#include "bootloader_sha.h"
#include "esp_tee_sec_storage.h"
#endif
#include "esp_random.h"
#include "mbedtls/ecdh.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
#include "psa/crypto.h"
#include "esp_attestation_utils.h"
#define ECDSA_PUBKEY_PREFIX_SZ (0x02)
@@ -91,8 +87,8 @@ static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair
return err;
}
memcpy(sign_r, sign.sign_r, sign_r_len);
memcpy(sign_s, sign.sign_s, sign_s_len);
memcpy(sign_r, sign.signature, sign_r_len);
memcpy(sign_s, sign.signature + sign_r_len, sign_s_len);
return ESP_OK;
}
@@ -113,44 +109,34 @@ static esp_err_t gen_ecdsa_keypair_secp256r1(esp_att_ecdsa_keypair_t *keypair)
memset(keypair, 0x00, sizeof(esp_att_ecdsa_keypair_t));
int ret = -1;
esp_err_t err = ESP_FAIL;
mbedtls_ecdsa_context ecdsa_ctx;
mbedtls_ecdsa_init(&ecdsa_ctx);
ret = mbedtls_ecdsa_genkey(&ecdsa_ctx, MBEDTLS_ECP_DP_SECP256R1, rng_func, NULL);
if (ret != 0) {
goto exit;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&key_attributes, 256);
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY);
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA);
psa_status_t status = psa_generate_key(&key_attributes, &keypair->key_id);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
size_t pvt_len = mbedtls_mpi_size(&ecdsa_ctx.MBEDTLS_PRIVATE(d));
ret = mbedtls_mpi_write_binary(&ecdsa_ctx.MBEDTLS_PRIVATE(d), (unsigned char *)keypair->pvt_key, pvt_len);
if (ret != 0) {
goto exit;
size_t pub_key_len = 0;
uint8_t pub_key[2 * SECP256R1_ECDSA_KEY_LEN + 1] = {0};
status = psa_export_public_key(keypair->key_id, pub_key, sizeof(pub_key), &pub_key_len);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
size_t pubx_len = mbedtls_mpi_size(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)));
ret = mbedtls_mpi_write_binary(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), (unsigned char *)(keypair->pub_key_x), pubx_len);
if (ret != 0) {
goto exit;
if (pub_key_len != sizeof(pub_key)) {
return ESP_ERR_INVALID_SIZE;
}
size_t puby_len = mbedtls_mpi_size(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)));
ret = mbedtls_mpi_write_binary(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), (unsigned char *)(keypair->pub_key_y), puby_len);
if (ret != 0) {
goto exit;
}
memcpy(keypair->pub_key_x, pub_key + 1, SECP256R1_ECDSA_KEY_LEN);
memcpy(keypair->pub_key_y, pub_key + 1 + SECP256R1_ECDSA_KEY_LEN, SECP256R1_ECDSA_KEY_LEN);
psa_reset_key_attributes(&key_attributes);
keypair->curve = 0;
err = ESP_OK;
exit:
if (ret != 0) {
ESP_LOGE(TAG, "Failed to generate ECDSA keypair (-0x%X)", -ret);
}
mbedtls_ecdsa_free(&ecdsa_ctx);
return err;
return ESP_OK;
}
static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair, const uint8_t *digest, const size_t len,
@@ -164,67 +150,21 @@ static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair
return ESP_ERR_INVALID_SIZE;
}
esp_err_t err = ESP_FAIL;
mbedtls_ecp_keypair pvt_key;
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
mbedtls_ecp_keypair_init(&pvt_key);
int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &pvt_key, keypair->pvt_key, sizeof(keypair->pvt_key));
if (ret != 0) {
goto exit;
size_t signature_len = 0;
uint8_t signature[sign_r_len + sign_s_len];
psa_status_t status = psa_sign_hash(keypair->key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, signature, sign_r_len + sign_s_len, &signature_len);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
mbedtls_ecdsa_context ecdsa_ctx;
mbedtls_ecdsa_init(&ecdsa_ctx);
ret = mbedtls_ecdsa_from_keypair(&ecdsa_ctx, &pvt_key);
if (ret != 0) {
goto exit;
if (signature_len != sign_r_len + sign_s_len) {
return ESP_ERR_INVALID_SIZE;
}
ret = mbedtls_ecdsa_sign(&ecdsa_ctx.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa_ctx.MBEDTLS_PRIVATE(d),
digest, len, rng_func, NULL);
if (ret != 0) {
return ret;
}
memcpy(sign_r, signature, sign_r_len);
memcpy(sign_s, signature + sign_r_len, sign_s_len);
size_t r_len = mbedtls_mpi_size(&r);
if (r_len > sign_s_len) {
goto exit;
}
ret = mbedtls_mpi_write_binary(&r, (unsigned char *)(sign_r), r_len);
if (ret != 0) {
goto exit;
}
size_t s_len = mbedtls_mpi_size(&s);
if (s_len > sign_s_len) {
goto exit;
}
ret = mbedtls_mpi_write_binary(&s, (unsigned char *)(sign_s), s_len);
if (ret != 0) {
goto exit;
}
err = ESP_OK;
exit:
if (ret != 0) {
ESP_LOGE(TAG, "Failed to generate ECDSA signature (-0x%X)", -ret);
}
mbedtls_ecdsa_free(&ecdsa_ctx);
mbedtls_ecp_keypair_free(&pvt_key);
mbedtls_mpi_free(&s);
mbedtls_mpi_free(&r);
return err;
return ESP_OK;
}
#endif
@@ -241,33 +181,23 @@ esp_err_t esp_att_utils_ecdsa_get_pubkey(const esp_att_ecdsa_keypair_t *keypair,
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = ESP_FAIL;
size_t hexstr_len = sizeof(keypair->pub_key_x) * 2 + ECDSA_PUBKEY_PREFIX_SZ + 1;
char *hexstr = calloc(hexstr_len, sizeof(uint8_t));
if (hexstr == NULL) {
err = ESP_ERR_NO_MEM;
goto exit;
size_t pubkey_hexstr_size = sizeof(keypair->pub_key_x) * 2 + ECDSA_PUBKEY_PREFIX_SZ + 1;
*pubkey_hexstr = calloc(pubkey_hexstr_size, sizeof(char));
if (*pubkey_hexstr == NULL) {
return ESP_ERR_NO_MEM;
}
/* Checking the parity of the y-component of the public key */
char *pubkey_prefix = (keypair->pub_key_y[SECP256R1_ECDSA_KEY_LEN - 1] & 1)
? ECDSA_COMPRESSED_KEY_ODD_PREFIX
: ECDSA_COMPRESSED_KEY_EVEN_PREFIX;
memcpy(hexstr, pubkey_prefix, ECDSA_PUBKEY_PREFIX_SZ);
char *pubkey_prefix = (keypair->pub_key_y[SECP256R1_ECDSA_KEY_LEN - 1] & 1) ? ECDSA_COMPRESSED_KEY_ODD_PREFIX : ECDSA_COMPRESSED_KEY_EVEN_PREFIX;
memcpy(*pubkey_hexstr, pubkey_prefix, ECDSA_PUBKEY_PREFIX_SZ);
err = esp_att_utils_hexbuf_to_hexstr(keypair->pub_key_x, sizeof(keypair->pub_key_x),
&hexstr[ECDSA_PUBKEY_PREFIX_SZ], hexstr_len - ECDSA_PUBKEY_PREFIX_SZ);
int err = esp_att_utils_hexbuf_to_hexstr(keypair->pub_key_x, sizeof(keypair->pub_key_x), *pubkey_hexstr + ECDSA_PUBKEY_PREFIX_SZ, pubkey_hexstr_size - ECDSA_PUBKEY_PREFIX_SZ);
if (err != ESP_OK) {
goto exit;
free(*pubkey_hexstr);
*pubkey_hexstr = NULL;
return err;
}
*pubkey_hexstr = hexstr;
return ESP_OK;
exit:
free(hexstr);
return err;
}
esp_err_t esp_att_utils_ecdsa_get_pubkey_digest(const esp_att_ecdsa_keypair_t *keypair, uint8_t *digest, const size_t len)
@@ -277,16 +207,30 @@ esp_err_t esp_att_utils_ecdsa_get_pubkey_digest(const esp_att_ecdsa_keypair_t *k
}
uint8_t pubkey_c[SECP256R1_ECDSA_KEY_LEN * 2] = {0};
memcpy(pubkey_c, keypair->pub_key_x, SECP256R1_ECDSA_KEY_LEN);
memcpy(pubkey_c + SECP256R1_ECDSA_KEY_LEN, keypair->pub_key_y, SECP256R1_ECDSA_KEY_LEN);
memcpy(pubkey_c, keypair->pub_key_x, sizeof(keypair->pub_key_x));
memcpy(pubkey_c + SECP256R1_ECDSA_KEY_LEN, keypair->pub_key_y, sizeof(keypair->pub_key_y));
uint8_t pubkey_digest[SHA256_DIGEST_SZ];
int ret = mbedtls_sha256((const unsigned char *)pubkey_c, sizeof(pubkey_c), pubkey_digest, false);
if (ret != 0) {
ESP_LOGE(TAG, "Failed to calculate pubkey digest (-%X)", -ret);
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
status = psa_hash_update(&hash_op, pubkey_c, sizeof(pubkey_c));
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
size_t pubkey_digest_len = 0;
status = psa_hash_finish(&hash_op, pubkey_digest, len, &pubkey_digest_len);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
if (pubkey_digest_len != len) {
return ESP_ERR_INVALID_SIZE;
}
memcpy(digest, pubkey_digest, len);
return ESP_OK;
}

View File

@@ -14,11 +14,7 @@
#include "bootloader_sha.h"
#include "esp_tee_sec_storage.h"
#endif
#include "esp_random.h"
#include "mbedtls/ecdh.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
#include "json_generator.h"
#include "esp_attestation_utils.h"

View File

@@ -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
*/
@@ -37,9 +37,8 @@
#include "esp32c6/rom/secure_boot.h"
#endif
#endif
#include "mbedtls/sha256.h"
#define DECLARE_PRIVATE_IDENTIFIERS
#include "psa/crypto.h"
#include "bootloader_flash_priv.h"
#include "esp_attestation_utils.h"
@@ -50,7 +49,7 @@ static const char *TAG = "esp_att_utils";
/* Forward declaration */
static esp_err_t read_partition(uint32_t offset, void *buf, size_t size);
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest);
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest, size_t digest_len);
static esp_err_t get_active_app_part_pos(esp_partition_pos_t *pos);
static esp_err_t get_active_tee_part_pos(esp_partition_pos_t *pos);
@@ -78,7 +77,7 @@ static esp_err_t read_partition(uint32_t offset, void *buf, size_t size)
return (esp_err_t)esp_tee_flash_read(offset, buf, size, true);
}
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest)
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest, size_t digest_len)
{
if (digest == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -87,12 +86,9 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
uint32_t mmu_free_pages_count = esp_tee_flash_mmap_get_free_pages();
uint32_t partial_image_len = mmu_free_pages_count * CONFIG_MMU_PAGE_SIZE;
mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx);
int ret = mbedtls_sha256_starts(&ctx, false);
if (ret != 0) {
mbedtls_sha256_free(&ctx);
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
@@ -100,18 +96,27 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
uint32_t mmap_len = MIN(len, partial_image_len);
const void *image = esp_tee_flash_mmap(flash_offset, mmap_len);
if (image == NULL) {
mbedtls_sha256_free(&ctx);
psa_hash_abort(&hash_op);
return ESP_FAIL;
}
status = psa_hash_update(&hash_op, image, mmap_len);
if (status != PSA_SUCCESS) {
psa_hash_abort(&hash_op);
return ESP_FAIL;
}
mbedtls_sha256_update(&ctx, image, mmap_len);
esp_tee_flash_munmap(image);
flash_offset += mmap_len;
len -= mmap_len;
}
mbedtls_sha256_finish(&ctx, digest);
mbedtls_sha256_free(&ctx);
size_t digest_size = 0;
status = psa_hash_finish(&hash_op, digest, digest_len, &digest_size);
if (status != PSA_SUCCESS) {
psa_hash_abort(&hash_op);
return ESP_FAIL;
}
return ESP_OK;
}
@@ -154,7 +159,7 @@ static esp_err_t read_partition(uint32_t offset, void *buf, size_t size)
return esp_flash_read(NULL, buf, offset, size);
}
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest)
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest, size_t digest_len)
{
if (digest == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -165,11 +170,10 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
uint32_t mmu_free_pages_count = bootloader_mmap_get_free_pages();
uint32_t partial_image_len = mmu_free_pages_count * CONFIG_MMU_PAGE_SIZE;
mbedtls_sha256_context sha256_ctx;
mbedtls_sha256_init(&sha256_ctx);
if (mbedtls_sha256_starts(&sha256_ctx, false) != 0) {
goto exit;
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
while (len > 0) {
@@ -178,7 +182,9 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
if (image == NULL) {
goto exit;
}
if (mbedtls_sha256_update(&sha256_ctx, image, mmap_len) != 0) {
status = psa_hash_update(&hash_op, image, mmap_len);
if (status != PSA_SUCCESS) {
psa_hash_abort(&hash_op);
goto exit;
}
bootloader_munmap(image);
@@ -187,13 +193,16 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
len -= mmap_len;
}
if (mbedtls_sha256_finish(&sha256_ctx, digest) != 0) {
size_t digest_size = 0;
status = psa_hash_finish(&hash_op, digest, digest_len, &digest_size);
if (status != PSA_SUCCESS) {
psa_hash_abort(&hash_op);
goto exit;
}
err = ESP_OK;
exit:
mbedtls_sha256_free(&sha256_ctx);
psa_hash_abort(&hash_op);
return err;
}
@@ -283,7 +292,7 @@ static esp_err_t get_part_digest(const esp_partition_pos_t *pos, esp_att_part_di
return ESP_ERR_NO_MEM;
}
err = get_flash_contents_sha256(pos->offset, image_len, digest);
err = get_flash_contents_sha256(pos->offset, image_len, digest, digest_len);
if (err != ESP_OK) {
goto exit;
}

View File

@@ -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
*/
@@ -14,9 +14,7 @@
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "hal/efuse_hal.h"
#include "mbedtls/sha256.h"
#include "psa/crypto.h"
#include "esp_attestation.h"
#include "esp_attestation_utils.h"
@@ -63,33 +61,28 @@ static esp_err_t fetch_device_id(uint8_t *devid_buf)
goto exit;
}
mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx);
int ret = mbedtls_sha256_starts(&ctx, false);
if (ret != 0) {
mbedtls_sha256_free(&ctx);
err = ESP_FAIL;
goto exit;
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
ret = mbedtls_sha256_update(&ctx, (const unsigned char *)mac_addr, sizeof(mac_addr));
if (ret != 0) {
mbedtls_sha256_free(&ctx);
err = ESP_FAIL;
goto exit;
status = psa_hash_update(&hash_op, mac_addr, sizeof(mac_addr));
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
uint8_t digest[SHA256_DIGEST_SZ] = {0};
ret = mbedtls_sha256_finish(&ctx, digest);
if (ret != 0) {
mbedtls_sha256_free(&ctx);
err = ESP_FAIL;
goto exit;
size_t digest_len = 0;
status = psa_hash_finish(&hash_op, devid_buf, SHA256_DIGEST_SZ, &digest_len);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
memcpy(devid_buf, digest, SHA256_DIGEST_SZ);
mbedtls_sha256_free(&ctx);
if (digest_len != SHA256_DIGEST_SZ) {
return ESP_ERR_INVALID_SIZE;
}
return ESP_OK;
exit:
return err;
@@ -211,12 +204,9 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
memset(token_buf, 0x00, token_buf_size);
mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx);
int ret = mbedtls_sha256_starts(&ctx, false);
if (ret != 0) {
mbedtls_sha256_free(&ctx);
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
@@ -236,9 +226,9 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
}
json_gen_push_object_str(&jstr, "header", hdr_json);
ret = mbedtls_sha256_update(&ctx, (const unsigned char *)hdr_json, hdr_len - 1);
if (ret != 0) {
mbedtls_sha256_free(&ctx);
status = psa_hash_update(&hash_op, (const unsigned char *)hdr_json, hdr_len - 1);
if (status != PSA_SUCCESS) {
psa_hash_abort(&hash_op);
return ESP_FAIL;
}
free(hdr_json);
@@ -253,9 +243,9 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
}
json_gen_push_object_str(&jstr, "eat", eat_json);
ret = mbedtls_sha256_update(&ctx, (const unsigned char *)eat_json, eat_len - 1);
if (ret != 0) {
mbedtls_sha256_free(&ctx);
status = psa_hash_update(&hash_op, (const unsigned char *)eat_json, eat_len - 1);
if (status != PSA_SUCCESS) {
psa_hash_abort(&hash_op);
return ESP_FAIL;
}
free(eat_json);
@@ -269,20 +259,20 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
}
json_gen_push_object_str(&jstr, "public_key", pubkey_json);
ret = mbedtls_sha256_update(&ctx, (const unsigned char *)pubkey_json, pubkey_len - 1);
if (ret != 0) {
mbedtls_sha256_free(&ctx);
status = psa_hash_update(&hash_op, (const unsigned char *)pubkey_json, pubkey_len - 1);
if (status != PSA_SUCCESS) {
psa_hash_abort(&hash_op);
return ESP_FAIL;
}
free(pubkey_json);
uint8_t digest[SHA256_DIGEST_SZ] = {0};
ret = mbedtls_sha256_finish(&ctx, digest);
if (ret != 0) {
mbedtls_sha256_free(&ctx);
size_t digest_len = 0;
status = psa_hash_finish(&hash_op, digest, sizeof(digest), &digest_len);
if (status != PSA_SUCCESS) {
psa_hash_abort(&hash_op);
return ESP_FAIL;
}
mbedtls_sha256_free(&ctx);
char *sign_json = NULL;
int sign_len = -1;

View File

@@ -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
*/
@@ -13,6 +13,8 @@
#include "esp_attestation.h"
#include "psa/crypto.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@@ -86,8 +86,7 @@ typedef struct {
*
*/
typedef struct {
uint8_t sign_r[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< R component */
uint8_t sign_s[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< S component */
uint8_t signature[MAX_ECDSA_SUPPORTED_KEY_LEN * 2]; /*!< Signature */
} __attribute__((__packed__)) esp_tee_sec_storage_ecdsa_sign_t;
#if ESP_TEE_BUILD && !(__DOXYGEN__)

View File

@@ -15,15 +15,11 @@
#include "spi_flash_mmap.h"
#if SOC_HMAC_SUPPORTED
#include "esp_hmac.h"
#include "esp_hmac_pbkdf2.h"
#else
#include "mbedtls/md.h"
#endif
#include "mbedtls/aes.h"
#include "mbedtls/gcm.h"
#include "mbedtls/sha256.h"
#include "mbedtls/ecdsa.h"
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
#include "esp_hmac_pbkdf2.h"
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#include "esp_rom_sys.h"
#include "nvs.h"
@@ -142,12 +138,6 @@ static int buffer_hexdump(const char *label, const void *buffer, size_t length)
return 0;
}
static int rand_func(void *rng_state, unsigned char *output, size_t len)
{
esp_fill_random(output, len);
return 0;
}
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_cfg_t *cfg)
{
@@ -314,10 +304,10 @@ 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, mbedtls_ecp_group_id *curve,
size_t *key_len, uint8_t **priv_key, uint8_t **pub_key)
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 || !curve || !key_len || !priv_key || !pub_key) {
if (!ctx || !priv_key || !priv_key_len || !pub_key || !pub_key_len) {
return ESP_ERR_INVALID_ARG;
}
@@ -325,26 +315,26 @@ static esp_err_t get_ecdsa_curve_info(esp_tee_sec_storage_type_t type, sec_stg_k
switch (type) {
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
*curve = MBEDTLS_ECP_DP_SECP256R1;
*key_len = ECDSA_SECP256R1_KEY_LEN;
*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:
*curve = MBEDTLS_ECP_DP_SECP192R1;
*key_len = ECDSA_SECP192R1_KEY_LEN;
*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:
*curve = MBEDTLS_ECP_DP_SECP384R1;
*key_len = ECDSA_SECP384R1_KEY_LEN;
*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;
@@ -364,46 +354,70 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t
return -1;
}
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_NONE;
size_t key_len = 0;
uint8_t *priv_key = NULL;
uint8_t *pub_key = NULL;
if (get_ecdsa_curve_info(key_type, keyctx, &curve_id, &key_len, &priv_key, &pub_key) != ESP_OK) {
psa_key_id_t key_id = 0;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
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));
ESP_LOGD(TAG, "Generating ECDSA key for curve %d...", curve_id);
mbedtls_ecdsa_context ctxECDSA;
mbedtls_ecdsa_init(&ctxECDSA);
int ret = mbedtls_ecdsa_genkey(&ctxECDSA, curve_id, rand_func, NULL);
if (ret != 0) {
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);
goto exit;
}
ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), pub_key, key_len);
if (ret != 0) {
size_t priv_key_len = 0;
size_t pub_key_len = 0;
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);
goto exit;
}
ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), pub_key + key_len, key_len);
if (ret != 0) {
/* PSA exports public key with 0x04 prefix (65 bytes for secp256r1, 49 bytes for secp192r1)
* 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_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;
status = psa_export_public_key(key_id, pub_key_with_prefix, sizeof(pub_key_with_prefix), &pub_key_len_with_prefix);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to export ECDSA public key: %ld", status);
goto exit;
}
ret = mbedtls_mpi_write_binary(&ctxECDSA.MBEDTLS_PRIVATE(d), priv_key, key_len);
if (ret != 0) {
goto exit;
/* Strip the 0x04 prefix if present */
if (pub_key_len_with_prefix == expected_pub_key_len_with_prefix && pub_key_with_prefix[0] == 0x04) {
memcpy(pub_key_buf, pub_key_with_prefix + 1, pub_key_buf_size);
pub_key_len = pub_key_buf_size;
} else {
/* Fallback: copy directly if format is unexpected (should not happen with PSA) */
ESP_LOGW(TAG, "Unexpected public key format, copying directly");
size_t copy_len = (pub_key_len_with_prefix < pub_key_buf_size) ? pub_key_len_with_prefix : pub_key_buf_size;
memcpy(pub_key_buf, pub_key_with_prefix, copy_len);
pub_key_len = copy_len;
}
buffer_hexdump("Private key", priv_key, key_len);
buffer_hexdump("Public key", pub_key, key_len * 2);
buffer_hexdump("Private key", priv_key_buf, priv_key_len);
buffer_hexdump("Public key", pub_key_buf, pub_key_len);
exit:
mbedtls_ecdsa_free(&ctxECDSA);
return ret;
psa_destroy_key(key_id);
psa_reset_key_attributes(&key_attributes);
return status == PSA_SUCCESS ? 0 : -1;
}
static int generate_aes256_key(sec_stg_key_t *keyctx)
@@ -500,66 +514,53 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cf
return ESP_ERR_INVALID_STATE;
}
mbedtls_mpi r, s;
mbedtls_ecp_keypair keypair_ctx;
mbedtls_ecdsa_context sign_ctx;
psa_key_id_t key_id = 0;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
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));
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
mbedtls_ecp_keypair_init(&keypair_ctx);
mbedtls_ecdsa_init(&sign_ctx);
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_NONE;
size_t key_len = 0;
uint8_t *priv_key = NULL;
uint8_t *pub_key = NULL;
err = get_ecdsa_curve_info(keyctx.type, &keyctx, &curve_id, &key_len, &priv_key, &pub_key);
if (err != ESP_OK) {
return ESP_ERR_INVALID_ARG;
size_t priv_key_len = 0;
if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) {
psa_set_key_bits(&key_attributes, ECDSA_SECP256R1_KEY_LEN * 8);
priv_key = keyctx.ecdsa_secp256r1.priv_key;
priv_key_len = sizeof(keyctx.ecdsa_secp256r1.priv_key);
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
} else if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
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
}
int ret = mbedtls_ecp_read_key(curve_id, &keypair_ctx, priv_key, key_len);
if (ret != 0) {
err = ESP_FAIL;
goto exit;
}
ret = mbedtls_ecdsa_from_keypair(&sign_ctx, &keypair_ctx);
if (ret != 0) {
psa_status_t status = psa_import_key(&key_attributes, priv_key, priv_key_len, &key_id);
if (status != PSA_SUCCESS) {
err = ESP_FAIL;
ESP_LOGE(TAG, "Failed to import ECDSA private key: %ld", status);
goto exit;
}
ESP_LOGD(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);
if (ret != 0) {
ESP_LOGE(TAG, "Error generating signature: %d", ret);
err = ESP_FAIL;
goto exit;
}
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, key_len);
if (ret == 0) {
ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, key_len);
}
if (ret != 0) {
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
size_t signature_len = 0;
status = psa_sign_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, hlen, out_sign->signature, sizeof(out_sign->signature), &signature_len);
if (status != PSA_SUCCESS) {
err = ESP_FAIL;
ESP_LOGE(TAG, "Failed to generate ECDSA signature: %ld", status);
goto exit;
}
err = ESP_OK;
exit:
mbedtls_ecdsa_free(&sign_ctx);
mbedtls_ecp_keypair_free(&keypair_ctx);
mbedtls_mpi_free(&s);
mbedtls_mpi_free(&r);
psa_destroy_key(key_id);
psa_reset_key_attributes(&key_attributes);
return err;
}
@@ -579,6 +580,7 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg
sec_stg_key_t keyctx;
size_t keyctx_len = sizeof(keyctx);
/* Read key from storage first before accessing its fields */
err = secure_storage_read(cfg->id, (void *)&keyctx, &keyctx_len);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to read key from secure storage");
@@ -590,18 +592,34 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg
return ESP_ERR_INVALID_STATE;
}
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_NONE;
size_t key_len = 0;
uint8_t *priv_key = NULL;
uint8_t *pub_key = NULL;
/* Now determine the public key source and length based on key type */
uint8_t *pub_key_src = NULL;
size_t pub_key_len = 0;
err = get_ecdsa_curve_info(keyctx.type, &keyctx, &curve_id, &key_len, &priv_key, &pub_key);
if (err != ESP_OK) {
return err;
switch (cfg->type) {
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
pub_key_src = keyctx.ecdsa_secp256r1.pub_key;
pub_key_len = ECDSA_SECP256R1_KEY_LEN;
break;
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
case ESP_SEC_STG_KEY_ECDSA_SECP192R1:
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");
return ESP_ERR_INVALID_ARG;
}
memcpy(out_pubkey->pub_x, pub_key, key_len);
memcpy(out_pubkey->pub_y, pub_key + key_len, key_len);
memcpy(out_pubkey->pub_x, pub_key_src, pub_key_len);
memcpy(out_pubkey->pub_y, pub_key_src + pub_key_len, pub_key_len);
return ESP_OK;
}
@@ -771,7 +789,7 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2
goto exit;
}
ret = mbedtls_ecp_keypair_calc_public(&keypair, rand_func, NULL);
ret = mbedtls_ecp_keypair_calc_public(&keypair, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE);
if (ret != 0) {
err = ESP_FAIL;
goto exit;
@@ -779,16 +797,16 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2
ret = mbedtls_ecdsa_sign(&keypair.MBEDTLS_PRIVATE(grp), &r, &s,
&keypair.MBEDTLS_PRIVATE(d), hash, hlen,
rand_func, NULL);
mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE);
if (ret != 0) {
err = ESP_FAIL;
goto exit;
}
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, key_len);
ret = mbedtls_mpi_write_binary(&r, out_sign->signature, key_len);
if (ret == 0) {
ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, key_len);
ret = mbedtls_mpi_write_binary(&s, out_sign->signature + key_len, key_len);
}
if (ret != 0) {

View File

@@ -54,6 +54,12 @@ ssize_t _write_r(struct _reent *r, int fd, const void *ptr, size_t len)
return -1;
}
ssize_t _open_r(struct _reent *r, const char *path, int flags, int mode)
{
errno = ENOSYS;
return -1;
}
int _getpid_r(struct _reent *r)
{
return 1;
@@ -180,14 +186,24 @@ int __cxa_thread_atexit(void (*func)(void *), void *arg, void *dso)
return 0;
}
#if CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C61
void *_sbrk(ptrdiff_t incr)
{
return (void *) -1;
}
#endif
void esp_tee_include_syscalls_impl(void)
{
}
int _unlink_r(struct _reent *r, const char *path)
{
errno = ENOSYS;
return -1;
}
int _rename_r(struct _reent *r, const char *src, const char *dst)
{
errno = ENOSYS;
return -1;
}

View File

@@ -22,6 +22,8 @@
#include "esp_app_desc.h"
#endif
#include "psa/crypto.h"
/* TEE symbols */
extern uint32_t _tee_stack;
extern uint32_t _tee_bss_start;
@@ -154,6 +156,13 @@ void __attribute__((noreturn)) esp_tee_init(uint32_t ree_entry_addr, uint32_t re
}
ESP_FAULT_ASSERT(err == ESP_OK);
psa_status_t status = psa_crypto_init();
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to initialize PSA Crypto! (0x%08x)", status);
abort();
}
ESP_FAULT_ASSERT(status == PSA_SUCCESS);
/* Initializing the secure storage */
err = esp_tee_sec_storage_init();
if (err != ESP_OK) {

View File

@@ -214,3 +214,8 @@ ASSERT ((_tee_iram_end <= _tee_dram_start),
"Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required.");
ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000),
"Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required.");
/* MMU Page Alignment Checks */
ASSERT ((CONFIG_SECURE_TEE_IROM_SIZE % 0x10000) == 0,
"Error: SECURE_TEE_IROM_SIZE must be a multiple of MMU_PAGE_SIZE (0x10000/64KB)!");
ASSERT ((CONFIG_SECURE_TEE_DROM_SIZE % 0x10000) == 0,
"Error: SECURE_TEE_DROM_SIZE must be a multiple of MMU_PAGE_SIZE (0x10000/64KB)!");

View File

@@ -219,3 +219,8 @@ ASSERT ((_tee_iram_end <= _tee_dram_start),
"Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required.");
ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000),
"Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required.");
/* MMU Page Alignment Checks */
ASSERT ((CONFIG_SECURE_TEE_IROM_SIZE % CONFIG_MMU_PAGE_SIZE) == 0,
"Error: SECURE_TEE_IROM_SIZE must be a multiple of MMU_PAGE_SIZE (CONFIG_MMU_PAGE_SIZE)!");
ASSERT ((CONFIG_SECURE_TEE_DROM_SIZE % CONFIG_MMU_PAGE_SIZE) == 0,
"Error: SECURE_TEE_DROM_SIZE must be a multiple of MMU_PAGE_SIZE (CONFIG_MMU_PAGE_SIZE)!");

View File

@@ -230,7 +230,7 @@ static void init_ota_sem(void)
static int create_ota_task(const char *url, const char *task_name, void (*ota_task)(void *))
{
init_ota_sem();
if (xTaskCreate(ota_task, task_name, configMINIMAL_STACK_SIZE * 3, (void *)url, 5, NULL) != pdPASS) {
if (xTaskCreate(ota_task, task_name, configMINIMAL_STACK_SIZE * 4, (void *)url, 5, NULL) != pdPASS) {
ESP_LOGE(TAG, "Task creation failed for %s", task_name);
return ESP_FAIL;
}

View File

@@ -15,9 +15,7 @@
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "mbedtls/ecp.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
#include "psa/crypto.h"
#include "esp_tee_sec_storage.h"
#include "example_tee_srv.h"
@@ -32,6 +30,8 @@
#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)
@@ -96,57 +96,33 @@ static esp_err_t verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len,
esp_err_t err = ESP_FAIL;
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
psa_key_id_t key_id = 0;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(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));
mbedtls_ecdsa_context ecdsa_context;
mbedtls_ecdsa_init(&ecdsa_context);
uint8_t pub_key[2 * ECDSA_SECP256R1_KEY_LEN + 1];
pub_key[0] = 0x04;
memcpy(pub_key + 1, pubkey->pub_x, ECDSA_SECP256R1_KEY_LEN);
memcpy(pub_key + 1 + ECDSA_SECP256R1_KEY_LEN, pubkey->pub_y, ECDSA_SECP256R1_KEY_LEN);
int ret = mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
if (ret != 0) {
psa_status_t status = psa_import_key(&key_attributes, pub_key, sizeof(pub_key), &key_id);
if (status != PSA_SUCCESS) {
goto exit;
}
size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P);
ret = mbedtls_mpi_read_binary(&r, sign->sign_r, plen);
if (ret != 0) {
status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, sign->signature, sizeof(sign->signature));
if (status != PSA_SUCCESS) {
goto exit;
}
ret = mbedtls_mpi_read_binary(&s, sign->sign_s, plen);
if (ret != 0) {
goto exit;
}
ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), pubkey->pub_x, plen);
if (ret != 0) {
goto exit;
}
ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pubkey->pub_y, plen);
if (ret != 0) {
goto exit;
}
ret = mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1);
if (ret != 0) {
goto exit;
}
ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), digest, len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s);
if (ret != 0) {
goto exit;
}
err = ESP_OK;
exit:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa_context);
if (key_id) {
psa_destroy_key(key_id);
}
psa_reset_key_attributes(&key_attributes);
return err;
}
@@ -166,8 +142,10 @@ static int get_msg_sha256(int argc, char **argv)
const char *msg = (const char *)cmd_get_msg_sha256_args.msg->sval[0];
uint8_t msg_digest[SHA256_DIGEST_SZ];
int ret = mbedtls_sha256((const unsigned char *)msg, strlen(msg), msg_digest, false);
if (ret != 0) {
size_t msg_len = strlen(msg);
size_t digest_len = 0;
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, (const uint8_t *)msg, msg_len, msg_digest, sizeof(msg_digest), &digest_len);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to calculate message hash!");
return ESP_FAIL;
}

View File

@@ -5,8 +5,8 @@ CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5
# Reducing TEE I/DRAM sizes
# 24KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x6000
# 12KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x3000
# 16KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x4000
# Disable TEE logs (also disable all panic logs)
CONFIG_SECURE_TEE_DEBUG_MODE=n

View File

@@ -1,6 +1,8 @@
# Reducing TEE I/DRAM sizes
# 29KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x7400
# 20KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x5000
# TEE Secure Storage: Release mode
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y

View File

@@ -18,4 +18,4 @@ CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5
# Increasing TEE DRAM size
# 18KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x4800
CONFIG_SECURE_TEE_DRAM_SIZE=0x5000

View File

@@ -21,26 +21,30 @@ endif()
set(mbedtls_test_srcs_dir "${idf_path}/components/mbedtls/test_apps/main")
# AES
#AES
if(CONFIG_SOC_AES_SUPPORTED)
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes.c"
"${mbedtls_test_srcs_dir}/test_aes_gcm.c"
"${mbedtls_test_srcs_dir}/test_aes_perf.c")
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_psa_aes.c"
"${mbedtls_test_srcs_dir}/test_psa_aes_gcm.c"
"${mbedtls_test_srcs_dir}/test_aes_perf.c"
)
endif()
# SHA
if(CONFIG_SOC_SHA_SUPPORTED)
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_mbedtls_sha.c"
"${mbedtls_test_srcs_dir}/test_sha.c"
"${mbedtls_test_srcs_dir}/test_sha_perf.c")
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_sha.c"
"${mbedtls_test_srcs_dir}/test_sha_perf.c")
endif()
# Mixed
if(CONFIG_SOC_AES_SUPPORTED AND CONFIG_SOC_SHA_SUPPORTED)
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes_sha_parallel.c")
endif()
# ECC
#ECC
if(CONFIG_SOC_ECC_SUPPORTED)
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_ecp.c")
endif()
# Utility
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_apb_dport_access.c"
"${mbedtls_test_srcs_dir}/test_mbedtls_utils.c")

View File

@@ -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
*/
@@ -9,10 +9,64 @@
#include "nvs_flash.h"
#include "unity.h"
#include "memory_checks.h"
#include "psa/crypto.h"
#if SOC_SHA_SUPPORT_PARALLEL_ENG
#include "sha/sha_parallel_engine.h"
#else
#include "sha/sha_core.h"
#endif
#include "bignum_impl.h"
/* setUp runs before every test */
void setUp(void)
{
#if SOC_SHA_SUPPORTED
// Execute esp_sha operation to allocate internal SHA semaphore (in case of ESP32)
// and initial DMA setup memory which is considered as leaked otherwise
const uint8_t input_buffer[64] = {0};
uint8_t output_buffer[64];
#if SOC_SHA_SUPPORT_SHA1
esp_sha(SHA1, input_buffer, sizeof(input_buffer), output_buffer);
#endif // SOC_SHA_SUPPORT_SHA1
#if SOC_SHA_SUPPORT_SHA256
esp_sha(SHA2_256, input_buffer, sizeof(input_buffer), output_buffer);
#endif // SOC_SHA_SUPPORT_SHA256
#if SOC_SHA_SUPPORT_SHA512
esp_sha(SHA2_512, input_buffer, sizeof(input_buffer), output_buffer);
#endif // SOC_SHA_SUPPORT_SHA512
#endif // SOC_SHA_SUPPORTED
#if defined(CONFIG_MBEDTLS_HARDWARE_MPI)
esp_mpi_enable_hardware_hw_op();
esp_mpi_disable_hardware_hw_op();
#endif // CONFIG_MBEDTLS_HARDWARE_MPI
#if SOC_AES_SUPPORTED
// Execute mbedtls_aes_init operation to allocate AES interrupt
// allocation memory which is considered as leak otherwise
const uint8_t plaintext[16] = {0};
uint8_t ciphertext[32];
const uint8_t key[16] = { 0 };
psa_status_t status;
psa_key_id_t key_id = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_import_key(&attributes, key, sizeof(key), &key_id);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
size_t output_len = 0;
status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, plaintext, sizeof(plaintext), ciphertext, sizeof(ciphertext), &output_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
const uint8_t plaintext_long[256] = {0};
uint8_t ciphertext_long[272];
output_len = 0;
status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, plaintext_long, sizeof(plaintext_long), ciphertext_long, sizeof(ciphertext_long), &output_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
psa_destroy_key(key_id);
#endif // SOC_AES_SUPPORTED
test_utils_record_free_mem();
test_utils_set_leak_level(CONFIG_UNITY_CRITICAL_LEAK_LEVEL_GENERAL, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL);
test_utils_set_leak_level(CONFIG_UNITY_WARN_LEAK_LEVEL_GENERAL, ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_GENERAL);

View File

@@ -7,10 +7,8 @@
#include "esp_log.h"
#include "esp_heap_caps.h"
#include "mbedtls/ecp.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
#include "psa/crypto.h"
#include "esp_tee.h"
#include "esp_tee_attestation.h"
@@ -24,6 +22,7 @@
/* Note: negative value here so that assert message prints a grep-able
error hex value (mbedTLS uses -N for error codes) */
#define TEST_ASSERT_MBEDTLS_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X))
#define TEST_ASSERT_PSA_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X))
#define SHA256_DIGEST_SZ (32)
#define ECDSA_SECP256R1_KEY_LEN (32)
@@ -165,19 +164,13 @@ static void prehash_token_data(const char *token_json, uint8_t *digest, size_t l
char *eat_str = cJSON_PrintUnformatted(eat);
char *public_key_str = cJSON_PrintUnformatted(public_key);
mbedtls_sha256_context sha256_ctx;
mbedtls_sha256_init(&sha256_ctx);
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_starts(&sha256_ctx, false));
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_update(&sha256_ctx, (const unsigned char *)header_str, strlen(header_str)));
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_update(&sha256_ctx, (const unsigned char *)eat_str, strlen(eat_str)));
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_update(&sha256_ctx, (const unsigned char *)public_key_str, strlen(public_key_str)));
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_finish(&sha256_ctx, digest));
mbedtls_sha256_free(&sha256_ctx);
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
TEST_ASSERT_PSA_OK(psa_hash_setup(&operation, PSA_ALG_SHA_256));
size_t digest_len = 0;
TEST_ASSERT_PSA_OK(psa_hash_update(&operation, (const unsigned char *)header_str, strlen(header_str)));
TEST_ASSERT_PSA_OK(psa_hash_update(&operation, (const unsigned char *)eat_str, strlen(eat_str)));
TEST_ASSERT_PSA_OK(psa_hash_update(&operation, (const unsigned char *)public_key_str, strlen(public_key_str)));
TEST_ASSERT_PSA_OK(psa_hash_finish(&operation, digest, SHA256_DIGEST_SZ, &digest_len));
free(public_key_str);
free(eat_str);
@@ -239,13 +232,13 @@ static void fetch_signature(const char *token_json, esp_tee_sec_storage_ecdsa_si
uint8_t *sign_r_buf = NULL;
size_t sign_r_buf_sz = 0;
hexstr_to_bytes(sign_r->valuestring, &sign_r_buf, &sign_r_buf_sz);
memcpy(sign_ctx->sign_r, sign_r_buf, sign_r_buf_sz);
memcpy(sign_ctx->signature, sign_r_buf, sign_r_buf_sz);
free(sign_r_buf);
uint8_t *sign_s_buf = NULL;
size_t sign_s_buf_sz = 0;
hexstr_to_bytes(sign_s->valuestring, &sign_s_buf, &sign_s_buf_sz);
memcpy(sign_ctx->sign_s, sign_s_buf, sign_s_buf_sz);
memcpy(sign_ctx->signature + sign_r_buf_sz, sign_s_buf, sign_s_buf_sz);
free(sign_s_buf);
cJSON_Delete(root);

View File

@@ -8,11 +8,6 @@
#include "esp_log.h"
#include "esp_heap_caps.h"
#include "esp_partition.h"
#include "mbedtls/ecp.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "ecdsa/ecdsa_alt.h"
#include "esp_tee.h"
@@ -26,6 +21,7 @@
#include "nvs.h"
#include "unity.h"
#include "sdkconfig.h"
#include "ecdsa/ecdsa_alt.h"
/* Note: negative value here so that assert message prints a grep-able
error hex value (mbedTLS uses -N for error codes) */
@@ -58,49 +54,70 @@ int verify_ecdsa_sign(const esp_tee_sec_storage_type_t key_type, const uint8_t *
TEST_ASSERT_NOT_NULL(sign);
TEST_ASSERT_NOT_EQUAL(0, len);
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
int err = ESP_FAIL;
mbedtls_ecdsa_context ecdsa_context;
mbedtls_ecdsa_init(&ecdsa_context);
psa_key_id_t key_id = 0;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_NONE;
size_t pub_key_len;
size_t signature_size;
/* 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) {
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
curve_id = MBEDTLS_ECP_DP_SECP256R1;
break;
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
case ESP_SEC_STG_KEY_ECDSA_SECP192R1:
curve_id = MBEDTLS_ECP_DP_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;
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;
#endif
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN
case ESP_SEC_STG_KEY_ECDSA_SECP384R1:
curve_id = MBEDTLS_ECP_DP_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
#endif // CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN
default:
ESP_LOGE(TAG, "Unsupported key type: %d", key_type);
return -1;
ESP_LOGE(TAG, "Unsupported ECDSA curve type");
err = ESP_ERR_INVALID_ARG;
goto exit;
}
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, 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;
goto exit;
}
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);
status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, sign->signature, signature_size);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to verify ECDSA signature: %ld", status);
err = ESP_ERR_INVALID_ARG;
goto exit;
}
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&r, sign->sign_r, plen));
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&s, sign->sign_s, plen));
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), pubkey->pub_x, plen));
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pubkey->pub_y, plen));
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1));
TEST_ASSERT_MBEDTLS_OK(mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), digest, len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s));
psa_destroy_key(key_id);
psa_reset_key_attributes(&key_attributes);
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa_context);
err = ESP_OK;
return 0;
exit:
return err;
}
TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_storage]")
@@ -112,7 +129,9 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_stora
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));
size_t msg_digest_len = 0;
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, message, buf_sz, msg_digest, sizeof(msg_digest), &msg_digest_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
free(message);
esp_tee_sec_storage_key_cfg_t key_cfg = {
@@ -130,12 +149,12 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_stora
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));
TEST_ESP_OK(esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, msg_digest_len, &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(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));
}
@@ -151,7 +170,10 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp192r1)", "[sec_stora
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));
size_t msg_digest_len = 0;
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, message, buf_sz, msg_digest, sizeof(msg_digest), &msg_digest_len);
(void)msg_digest_len;
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
free(message);
esp_tee_sec_storage_key_cfg_t key_cfg = {
@@ -191,7 +213,11 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp384r1)", "[sec_stora
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));
// 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 = {
@@ -284,7 +310,9 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys",
TEST_ASSERT_NOT_NULL(message);
esp_fill_random(message, SZ);
uint8_t msg_digest[SHA256_DIGEST_SZ];
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256(message, SZ, msg_digest, false));
size_t msg_digest_len = 0;
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, message, SZ, msg_digest, sizeof(msg_digest), &msg_digest_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
free(message);
const char *key_id = "key_id_misc";
@@ -586,18 +614,18 @@ static void test_ecdsa_sign(mbedtls_ecp_group_id gid)
};
TEST_ASSERT_EQUAL(0, esp_ecdsa_tee_set_pk_context(&key_ctx, &conf));
mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(key_ctx);
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, sha_len, NULL, NULL));
esp_tee_sec_storage_ecdsa_sign_t sign = {};
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&r, sign.sign_r, key_len));
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&s, sign.sign_s, key_len));
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(key_type, sha, sha_len, &pubkey, &sign));
mbedtls_pk_free(&key_ctx);
esp_ecdsa_free_pk_context(&key_ctx);
mbedtls_ecdsa_free(&ecdsa_context);
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);

View File

@@ -11,3 +11,6 @@ CONFIG_SECURE_TEE_TEST_MODE=y
# Setting partition table
CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y
CONFIG_PARTITION_TABLE_OFFSET=0xF000
# TEE IRAM size
CONFIG_SECURE_TEE_IRAM_SIZE=0xC400

View File

@@ -83,9 +83,21 @@
#define MBEDTLS_ECP_VERIFY_ALT
#endif
#if !SOC_HMAC_SUPPORTED
#define MBEDTLS_MD_C
#endif
#define PSA_WANT_ECC_SECP_R1_192 1
#define PSA_WANT_ECC_SECP_R1_384 1
#undef PSA_WANT_ECC_SECP_K1_192
#undef PSA_WANT_ECC_SECP_K1_256
#undef PSA_WANT_ECC_SECP_R1_224
#undef PSA_WANT_ECC_SECP_R1_521
#undef PSA_WANT_ECC_BRAINPOOL_P_R1_256
#undef PSA_WANT_ECC_BRAINPOOL_P_R1_384
#undef PSA_WANT_ECC_BRAINPOOL_P_R1_512
#undef MBEDTLS_ECP_DP_BP256R1_ENABLED
#undef MBEDTLS_ECP_DP_BP384R1_ENABLED
#undef MBEDTLS_ECP_DP_BP512R1_ENABLED
#undef MBEDTLS_ECP_DP_SECP192K1_ENABLED
#undef MBEDTLS_ECP_DP_SECP224K1_ENABLED
#undef MBEDTLS_ECP_DP_SECP256K1_ENABLED
#define MBEDTLS_ENTROPY_C

View File

@@ -8,7 +8,7 @@
#include "esp_err.h"
#include "esp_log.h"
#include "mbedtls/gcm.h"
#include "psa/crypto.h"
#include "esp_tee.h"
#include "secure_service_num.h"
@@ -45,42 +45,72 @@ static esp_err_t aes_gcm_crypt_common(example_aes_gcm_ctx_t *ctx, uint8_t *tag,
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;
psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
psa_status_t status;
psa_key_id_t key_id;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t alg = PSA_ALG_GCM;
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&key_attributes, alg);
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&key_attributes, AES256_KEY_BITS);
status = psa_import_key(&key_attributes, key, sizeof(key), &key_id);
psa_reset_key_attributes(&key_attributes);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in importing key: %d", status);
return ESP_ERR_INVALID_STATE;
}
if (is_encrypt) {
status = psa_aead_encrypt_setup(&operation, key_id, alg);
} else {
status = psa_aead_decrypt_setup(&operation, key_id, alg);
}
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in AEAD setup: %d", status);
goto cleanup;
}
status = psa_aead_set_lengths(&operation, ctx->aad_len, ctx->input_len);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in setting lengths: %d", status);
goto cleanup;
}
psa_aead_set_nonce(&operation, nonce, AES256_NONCE_LEN);
if (ctx->aad_len > 0) {
status = psa_aead_update_ad(&operation, ctx->aad, ctx->aad_len);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in updating AAD: %d", status);
goto cleanup;
}
}
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);
size_t output_len = 0;
status = psa_aead_update(&operation, ctx->input, ctx->input_len, output, ctx->input_len, &output_len);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in updating aead: %d", status);
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);
size_t output_tag_len = 0;
status = psa_aead_finish(&operation, output + output_len, ctx->input_len + tag_len - output_len, &output_len, tag, tag_len, &output_tag_len);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in finishing encryption: %d", status);
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);
size_t plaintext_len = 0;
status = psa_aead_verify(&operation, output, ctx->input_len, &plaintext_len, tag, tag_len);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in verifying decryption: %d", status);
goto cleanup;
}
}
err = ESP_OK;
cleanup:
mbedtls_gcm_free(&gcm);
psa_aead_abort(&operation);
psa_destroy_key(key_id);
return err;
}

View File

@@ -17,7 +17,7 @@
#include "example_service.h"
#define EXAMPLE_BUF_SZ (32)
#define AES256_GCM_TAG_LEN (12)
#define AES256_GCM_TAG_LEN (16)
#define AES256_GCM_AAD_LEN (16)
static const char *TAG = "example_tee_basic";

View File

@@ -4,3 +4,4 @@ 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
CONFIG_SECURE_TEE_IRAM_SIZE=0xC000

View File

@@ -29,7 +29,9 @@ Before the project configuration and build, be sure to set the correct chip targ
Open the project configuration menu (`idf.py menuconfig`).
- Configure the secure storage example key ID at `Example Configuration → TEE: Secure Storage Key ID`.
- Configure unique secure storage key IDs for each workflow:
- `Example Configuration → TEE: Secure Storage Key ID for signing`
- `Example Configuration → TEE: Secure Storage Key ID for encryption`
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`:

View File

@@ -1,11 +1,17 @@
menu "Example Configuration"
config EXAMPLE_TEE_SEC_STG_KEY_STR_ID
string "TEE: Secure Storage Key ID"
default "key_id_0"
config EXAMPLE_TEE_SEC_STG_SIGN_KEY_STR_ID
string "TEE: Secure Storage Key ID for signing"
default "sign_key_id_0"
help
This configuration sets the key string identifier from the TEE secure storage
storing the ECDSA keypair for executing sign/verify operations
from the TEE side
Identifier for the ECDSA keypair stored in secure storage and used for
sign/verify operations in this example.
config EXAMPLE_TEE_SEC_STG_ENC_KEY_STR_ID
string "TEE: Secure Storage Key ID for encryption"
default "aes_key_id_0"
help
Identifier for the AES-256 key stored in secure storage and used for
the AEAD encryption/decryption part of this example.
endmenu

View File

@@ -15,9 +15,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "mbedtls/ecp.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
#include "psa/crypto.h"
#include "esp_tee_sec_storage.h"
#include "secure_service_num.h"
@@ -28,7 +26,8 @@
#define AES256_GCM_TAG_LEN (16)
#define AES256_GCM_AAD_LEN (16)
#define KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_KEY_STR_ID)
#define SIGN_KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_SIGN_KEY_STR_ID)
#define ENC_KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_ENC_KEY_STR_ID)
#define MAX_AES_PLAINTEXT_LEN (128)
static const char *message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
@@ -47,56 +46,33 @@ static esp_err_t verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len,
esp_err_t err = ESP_FAIL;
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
psa_key_id_t key_id = 0;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(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));
mbedtls_ecdsa_context ecdsa_context;
mbedtls_ecdsa_init(&ecdsa_context);
uint8_t pub_key[2 * ECDSA_SECP256R1_KEY_LEN + 1];
pub_key[0] = 0x04;
memcpy(pub_key + 1, pubkey->pub_x, ECDSA_SECP256R1_KEY_LEN);
memcpy(pub_key + 1 + ECDSA_SECP256R1_KEY_LEN, pubkey->pub_y, ECDSA_SECP256R1_KEY_LEN);
int ret = mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
if (ret != 0) {
psa_status_t status = psa_import_key(&key_attributes, pub_key, sizeof(pub_key), &key_id);
if (status != PSA_SUCCESS) {
goto exit;
}
size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P);
ret = mbedtls_mpi_read_binary(&r, sign->sign_r, plen);
if (ret != 0) {
status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, sign->signature, sizeof(sign->signature));
if (status != PSA_SUCCESS) {
goto exit;
}
ret = mbedtls_mpi_read_binary(&s, sign->sign_s, plen);
if (ret != 0) {
goto exit;
}
ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), pubkey->pub_x, plen);
if (ret != 0) {
goto exit;
}
ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pubkey->pub_y, plen);
if (ret != 0) {
goto exit;
}
ret = mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1);
if (ret != 0) {
goto exit;
}
ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), digest, len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s);
if (ret != 0) {
goto exit;
}
psa_destroy_key(key_id);
psa_reset_key_attributes(&key_attributes);
err = ESP_OK;
exit:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa_context);
return err;
}
@@ -107,14 +83,15 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter)
ESP_LOGI(TAG, "Message-to-be-signed: %s", msg);
uint8_t msg_digest[SHA256_DIGEST_SZ];
int ret = mbedtls_sha256((const unsigned char *)msg, strlen(msg), msg_digest, false);
if (ret != 0) {
size_t msg_digest_len = 0;
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, (const uint8_t *)msg, strlen(msg), msg_digest, sizeof(msg_digest), &msg_digest_len);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to calculate message hash!");
goto exit;
}
esp_tee_sec_storage_key_cfg_t cfg = {
.id = (const char *)(KEY_STR_ID),
.id = (const char *)(SIGN_KEY_STR_ID),
.type = ESP_SEC_STG_KEY_ECDSA_SECP256R1
};
@@ -131,7 +108,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter)
}
esp_tee_sec_storage_ecdsa_sign_t sign = {};
err = esp_tee_sec_storage_ecdsa_sign(&cfg, msg_digest, sizeof(msg_digest), &sign);
err = esp_tee_sec_storage_ecdsa_sign(&cfg, msg_digest, msg_digest_len, &sign);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate signature!");
goto exit;
@@ -146,7 +123,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter)
goto exit;
}
err = verify_ecdsa_secp256r1_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign);
err = verify_ecdsa_secp256r1_sign(msg_digest, msg_digest_len, &pubkey, &sign);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to verify signature!");
goto exit;
@@ -182,7 +159,7 @@ static void example_tee_sec_stg_encrypt_decrypt(void *pvParameter)
}
esp_tee_sec_storage_key_cfg_t cfg = {
.id = (const char *)(KEY_STR_ID),
.id = (const char *)(ENC_KEY_STR_ID),
.type = ESP_SEC_STG_KEY_AES256
};