Merge branch 'feat/esp_tee_backports_v6.0' into 'release/v6.0'

feat(esp_tee): Feature/fixes backports to `release/v6.0`

See merge request espressif/esp-idf!48486
This commit is contained in:
Mahavir Jain
2026-06-29 11:21:13 +05:30
32 changed files with 877 additions and 719 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -174,8 +174,31 @@ esp_err_t esp_att_utils_eat_data_to_json(struct esp_att_sw_claim_list *head, con
free(auth_challenge_hexstr);
json_gen_obj_set_int(&json_gen, "client_id", cfg->client_id);
json_gen_obj_set_int(&json_gen, "chip_id", cfg->chip_id);
json_gen_obj_set_int(&json_gen, "device_ver", cfg->device_ver);
json_gen_push_object(&json_gen, "ueid");
char mac_hexstr[ESP_ATT_EAT_UEID_MAC_SZ * 2 + 1] = {0};
err = esp_att_utils_hexbuf_to_hexstr(cfg->ueid_mac, sizeof(cfg->ueid_mac),
mac_hexstr, sizeof(mac_hexstr));
if (err != ESP_OK) {
free(json_buf);
return err;
}
json_gen_obj_set_string(&json_gen, "mac", mac_hexstr);
char opt_id_hexstr[ESP_ATT_EAT_UEID_OPT_ID_SZ * 2 + 1] = {0};
err = esp_att_utils_hexbuf_to_hexstr(cfg->ueid_opt_id, sizeof(cfg->ueid_opt_id),
opt_id_hexstr, sizeof(opt_id_hexstr));
if (err != ESP_OK) {
free(json_buf);
return err;
}
json_gen_obj_set_string(&json_gen, "optional_id", opt_id_hexstr);
json_gen_pop_object(&json_gen);
char dev_id_hexstr[ESP_ATT_EAT_DEV_ID_SZ * 2 + 1] = {0};
err = esp_att_utils_hexbuf_to_hexstr(cfg->device_id, sizeof(cfg->device_id), dev_id_hexstr, sizeof(dev_id_hexstr));
if (err != ESP_OK) {
@@ -201,6 +224,7 @@ esp_err_t esp_att_utils_eat_data_to_json(struct esp_att_sw_claim_list *head, con
esp_err_t err = part_metadata_to_json(&claim->metadata, &claim_json);
if (err != ESP_OK || claim_json == NULL) {
ESP_LOGE(TAG, "Failed to format the FW metadata to JSON!");
free(json_buf);
return err;
}
@@ -48,44 +48,23 @@ static void free_sw_claim_list(void)
}
}
static esp_err_t fetch_device_id(uint8_t *devid_buf)
static esp_err_t fetch_ueids(esp_att_token_cfg_t *cfg)
{
if (devid_buf == NULL) {
return ESP_ERR_INVALID_ARG;
}
uint8_t mac_addr[6] = {0};
esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_MAC, mac_addr, sizeof(mac_addr) * 8);
/* UEID: raw eFuse MAC */
esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_MAC, cfg->ueid_mac,
ESP_ATT_EAT_UEID_MAC_SZ * 8);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to read MAC from eFuse!");
goto exit;
return err;
}
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, mac_addr, sizeof(mac_addr));
if (status != PSA_SUCCESS) {
return ESP_FAIL;
}
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;
}
if (digest_len != SHA256_DIGEST_SZ) {
return ESP_ERR_INVALID_SIZE;
/* UEID: 128-bit OPTIONAL_UNIQUE_ID */
err = esp_efuse_read_field_blob(ESP_EFUSE_OPTIONAL_UNIQUE_ID, cfg->ueid_opt_id,
ESP_ATT_EAT_UEID_OPT_ID_SZ * 8);
if (err != ESP_OK) {
return err;
}
return ESP_OK;
exit:
return err;
}
static esp_err_t populate_att_token_cfg(esp_att_token_cfg_t *cfg, const esp_att_ecdsa_keypair_t *keypair)
@@ -94,18 +73,31 @@ static esp_err_t populate_att_token_cfg(esp_att_token_cfg_t *cfg, const esp_att_
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = fetch_device_id(cfg->device_id);
esp_err_t err = fetch_ueids(cfg);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to get the device ID!");
ESP_LOGE(TAG, "Failed to get the UEIDs!");
return err;
}
/* Device ID = SHA-256 of the MAC */
size_t digest_len = 0;
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, cfg->ueid_mac, sizeof(cfg->ueid_mac),
cfg->device_id, sizeof(cfg->device_id), &digest_len);
if (status != PSA_SUCCESS || digest_len != sizeof(cfg->device_id)) {
ESP_LOGE(TAG, "Failed to derive the device ID!");
return ESP_FAIL;
}
err = esp_att_utils_ecdsa_get_pubkey_digest(keypair, cfg->instance_id, sizeof(cfg->instance_id));
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to get ECDSA public key hash!");
return err;
}
/* Chip ID read from the ROM */
extern const uint32_t _rom_chip_id;
cfg->chip_id = _rom_chip_id;
/* Chip revision read from eFuse */
cfg->device_ver = efuse_hal_chip_revision();
/* TODO: Decide what all fields we need here */
cfg->device_stat = 0xA5;
@@ -191,6 +183,13 @@ esp_err_t esp_att_generate_token(const uint8_t *auth_challenge, size_t challenge
}
esp_att_ecdsa_keypair_t keypair = {};
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
psa_status_t status;
char *hdr_json = NULL;
char *eat_json = NULL;
char *pubkey_json = NULL;
char *sign_json = NULL;
err = esp_att_utils_ecdsa_gen_keypair_secp256r1(&keypair);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate ECDSA key-pair!");
@@ -214,10 +213,10 @@ esp_err_t esp_att_generate_token(const uint8_t *auth_challenge, size_t challenge
memset(token_buf, 0x00, token_buf_size);
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
err = ESP_FAIL;
goto exit;
}
json_gen_str_t jstr;
@@ -226,79 +225,84 @@ esp_err_t esp_att_generate_token(const uint8_t *auth_challenge, size_t challenge
/* Pushing the Header object */
const esp_att_token_hdr_t tk_hdr = {};
char *hdr_json = NULL;
int hdr_len = -1;
/* NOTE: Token header is not yet configurable */
err = esp_att_utils_header_to_json(&tk_hdr, &hdr_json, &hdr_len);
if (err != ESP_OK || hdr_json == NULL || hdr_len <= 0) {
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to format the token header as JSON!");
return err;
goto exit;
}
json_gen_push_object_str(&jstr, "header", hdr_json);
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;
err = ESP_FAIL;
goto exit;
}
free(hdr_json);
hdr_json = NULL;
/* Pushing the EAT object */
char *eat_json = NULL;
int eat_len = -1;
err = esp_att_utils_eat_data_to_json(&sw_claim_data, &cfg, &eat_json, &eat_len);
if (err != ESP_OK || eat_json == NULL || eat_len <= 0) {
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to format the EAT data to JSON!");
return err;
goto exit;
}
json_gen_push_object_str(&jstr, "eat", eat_json);
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;
err = ESP_FAIL;
goto exit;
}
free(eat_json);
eat_json = NULL;
char *pubkey_json = NULL;
int pubkey_len = -1;
err = esp_att_utils_pubkey_to_json(&keypair, &pubkey_json, &pubkey_len);
if (err != ESP_OK || pubkey_json == NULL || pubkey_len <= 0) {
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to format the public key data to JSON!");
return err;
goto exit;
}
json_gen_push_object_str(&jstr, "public_key", pubkey_json);
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;
err = ESP_FAIL;
goto exit;
}
free(pubkey_json);
pubkey_json = NULL;
uint8_t digest[SHA256_DIGEST_SZ] = {0};
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;
err = ESP_FAIL;
goto exit;
}
char *sign_json = NULL;
int sign_len = -1;
err = esp_att_utils_sign_to_json(&keypair, digest, sizeof(digest), &sign_json, &sign_len);
if (err != ESP_OK || sign_json == NULL || sign_len <= 0) {
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to format the token signature to JSON!");
return err;
goto exit;
}
json_gen_push_object_str(&jstr, "sign", sign_json);
free(sign_json);
sign_json = NULL;
json_gen_end_object(&jstr);
*token_size = json_gen_str_end(&jstr);
err = ESP_OK;
exit:
psa_hash_abort(&hash_op);
free(hdr_json);
free(eat_json);
free(pubkey_json);
free(sign_json);
free_sw_claim_list();
return err;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -37,8 +37,10 @@ extern "C" {
#define ESP_ATT_HDR_JSON_MAX_SZ (128)
#define ESP_ATT_EAT_DEV_ID_SZ (32)
#define ESP_ATT_EAT_UEID_MAC_SZ (6) /* eFuse MAC */
#define ESP_ATT_EAT_UEID_OPT_ID_SZ (16) /* eFuse OPTIONAL_UNIQUE_ID */
#define ESP_ATT_CLAIM_JSON_MAX_SZ (448)
#define ESP_ATT_EAT_JSON_MAX_SZ (1344)
#define ESP_ATT_EAT_JSON_MAX_SZ (1600)
#define ESP_ATT_PUBKEY_JSON_MAX_SZ (128)
#define ESP_ATT_SIGN_JSON_MAX_SZ (192)
@@ -119,14 +121,17 @@ typedef struct {
* @brief Structure to hold the Entity Attestation Token initial configuration
*/
typedef struct {
uint8_t *auth_challenge; /**< Authentication challenge */
size_t challenge_size; /**< Challenge size */
uint32_t client_id; /**< Client identifier (Attestation relying party) */
uint32_t device_ver; /**< Device version */
uint8_t device_id[SHA256_DIGEST_SZ]; /**< Device identifier */
uint8_t instance_id[SHA256_DIGEST_SZ]; /**< Instance identifier */
char psa_cert_ref[32]; /**< PSA certificate reference */
uint8_t device_stat; /**< Flags indicating device status */
uint8_t *auth_challenge; /**< Authentication challenge */
size_t challenge_size; /**< Challenge size */
uint32_t client_id; /**< Client identifier (Attestation relying party) */
uint32_t chip_id; /**< Chip identifier */
uint32_t device_ver; /**< Device version */
uint8_t ueid_mac[ESP_ATT_EAT_UEID_MAC_SZ]; /**< Device UEID: MAC from eFuse*/
uint8_t ueid_opt_id[ESP_ATT_EAT_UEID_OPT_ID_SZ]; /**< Device UEID: OPTIONAL_UNIQUE_ID from eFuse*/
uint8_t device_id[SHA256_DIGEST_SZ]; /**< Device identifier (SHA-256 of MAC) */
uint8_t instance_id[SHA256_DIGEST_SZ]; /**< Instance identifier */
char psa_cert_ref[32]; /**< PSA certificate reference */
uint8_t device_stat; /**< Flags indicating device status */
} esp_att_token_cfg_t;
/**
@@ -22,6 +22,7 @@
#include "esp_hmac_pbkdf2.h"
#include "psa/crypto.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/psa_util.h"
#include "esp_rom_sys.h"
@@ -193,7 +194,7 @@ static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_c
psa_reset_key_attributes(&attributes);
// Zero out the key buffer after import
memset(key_buf, 0x00, sizeof(key_buf));
mbedtls_platform_zeroize(key_buf, sizeof(key_buf));
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to import HMAC key: %d", status);
@@ -208,7 +209,7 @@ static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_c
(uint8_t *)cfg->eky, SHA256_DIGEST_SZ, &mac_length);
if (status != PSA_SUCCESS) {
psa_destroy_key(psa_key_id);
memset(cfg, 0x00, sizeof(nvs_sec_cfg_t));
mbedtls_platform_zeroize(cfg, sizeof(nvs_sec_cfg_t));
return ESP_FAIL;
}
ESP_FAULT_ASSERT(status == PSA_SUCCESS);
@@ -221,7 +222,7 @@ static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_c
psa_destroy_key(psa_key_id);
if (status != PSA_SUCCESS) {
memset(cfg, 0x00, sizeof(nvs_sec_cfg_t));
mbedtls_platform_zeroize(cfg, sizeof(nvs_sec_cfg_t));
return ESP_FAIL;
}
ESP_FAULT_ASSERT(status == PSA_SUCCESS);
@@ -322,20 +323,24 @@ esp_err_t esp_tee_sec_storage_clear_key(const char *key_id)
esp_err_t err = secure_storage_read(key_id, (void *)&keyctx, &keyctx_len);
if (err != ESP_OK) {
return err;
goto cleanup;
}
if (keyctx.flags & SEC_STORAGE_FLAG_WRITE_ONCE) {
ESP_LOGE(TAG, "Key is write-once only and cannot be cleared!");
return ESP_ERR_INVALID_STATE;
err = ESP_ERR_INVALID_STATE;
goto cleanup;
}
err = nvs_erase_key(tee_nvs_hdl, key_id);
if (err != ESP_OK) {
return err;
goto cleanup;
}
err = nvs_commit(tee_nvs_hdl);
cleanup:
mbedtls_platform_zeroize(&keyctx, sizeof(keyctx));
return err;
}
@@ -465,6 +470,7 @@ esp_err_t esp_tee_sec_storage_gen_key(const esp_tee_sec_storage_key_cfg_t *cfg)
return ESP_ERR_INVALID_STATE;
}
esp_err_t err;
sec_stg_key_t keyctx = {
.type = cfg->type,
.flags = cfg->flags,
@@ -477,21 +483,28 @@ esp_err_t esp_tee_sec_storage_gen_key(const esp_tee_sec_storage_key_cfg_t *cfg)
#endif
if (generate_ecdsa_key(&keyctx, cfg->type) != 0) {
ESP_LOGE(TAG, "Failed to generate ECDSA keypair");
return ESP_FAIL;
err = ESP_FAIL;
goto cleanup;
}
break;
case ESP_SEC_STG_KEY_AES256:
if (generate_aes256_key(&keyctx) != 0) {
ESP_LOGE(TAG, "Failed to generate AES key");
return ESP_FAIL;
err = ESP_FAIL;
goto cleanup;
}
break;
default:
ESP_LOGE(TAG, "Unsupported key-type!");
return ESP_ERR_NOT_SUPPORTED;
err = ESP_ERR_NOT_SUPPORTED;
goto cleanup;
}
return secure_storage_write(cfg->id, (void *)&keyctx, sizeof(keyctx));
err = secure_storage_write(cfg->id, (void *)&keyctx, sizeof(keyctx));
cleanup:
mbedtls_platform_zeroize(&keyctx, sizeof(keyctx));
return err;
}
esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cfg, const uint8_t *hash, size_t hlen, esp_tee_sec_storage_ecdsa_sign_t *out_sign)
@@ -514,19 +527,21 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cf
sec_stg_key_t keyctx;
size_t keyctx_len = sizeof(keyctx);
psa_key_id_t key_id = 0;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
err = secure_storage_read(cfg->id, (void *)&keyctx, &keyctx_len);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to fetch key from storage");
return err;
goto exit;
}
if (keyctx.type != cfg->type) {
ESP_LOGE(TAG, "Key type mismatch");
return ESP_ERR_INVALID_STATE;
err = ESP_ERR_INVALID_STATE;
goto exit;
}
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_algorithm_t ecdsa_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
@@ -571,6 +586,7 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cf
exit:
psa_destroy_key(key_id);
psa_reset_key_attributes(&key_attributes);
mbedtls_platform_zeroize(&keyctx, sizeof(keyctx));
return err;
}
@@ -594,12 +610,13 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg
err = secure_storage_read(cfg->id, (void *)&keyctx, &keyctx_len);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to read key from secure storage");
return err;
goto cleanup;
}
if (keyctx.type != cfg->type) {
ESP_LOGE(TAG, "Key type mismatch");
return ESP_ERR_INVALID_STATE;
err = ESP_ERR_INVALID_STATE;
goto cleanup;
}
/* Now determine the public key source and length based on key type */
@@ -619,13 +636,17 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg
#endif
default:
ESP_LOGE(TAG, "Unsupported key-type");
return ESP_ERR_INVALID_ARG;
err = ESP_ERR_INVALID_ARG;
goto cleanup;
}
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);
err = ESP_OK;
return ESP_OK;
cleanup:
mbedtls_platform_zeroize(&keyctx, sizeof(keyctx));
return err;
}
static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t *input, size_t len, const uint8_t *aad,
@@ -648,17 +669,22 @@ static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t
return err;
}
psa_key_id_t psa_key_id = 0;
uint8_t *aead_buf = NULL;
size_t aead_buf_len = 0;
sec_stg_key_t keyctx;
size_t keyctx_len = sizeof(keyctx);
err = secure_storage_read(key_id, (void *)&keyctx, &keyctx_len);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to fetch key from storage");
return err;
goto cleanup;
}
if (keyctx.type != ESP_SEC_STG_KEY_AES256) {
ESP_LOGE(TAG, "Key type mismatch");
return ESP_ERR_INVALID_STATE;
err = ESP_ERR_INVALID_STATE;
goto cleanup;
}
// Setup PSA key attributes
@@ -670,70 +696,66 @@ static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
// Import the AES key
psa_key_id_t key_id_psa = 0;
psa_status_t status = psa_import_key(&attributes, keyctx.aes256.key, AES256_KEY_LEN, &key_id_psa);
psa_status_t status = psa_import_key(&attributes, keyctx.aes256.key, AES256_KEY_LEN, &psa_key_id);
psa_reset_key_attributes(&attributes);
if (status != PSA_SUCCESS) {
return ESP_FAIL;
err = ESP_FAIL;
goto cleanup;
}
/* PSA AEAD wants ciphertext+tag concatenated in a single buffer for both
* encrypt (output) and decrypt (input). */
aead_buf_len = len + tag_len;
aead_buf = malloc(aead_buf_len);
if (!aead_buf) {
err = ESP_ERR_NO_MEM;
goto cleanup;
}
if (is_encrypt) {
// PSA AEAD encrypt outputs ciphertext+tag concatenated
uint8_t *output_with_tag = malloc(len + tag_len);
if (!output_with_tag) {
psa_destroy_key(key_id_psa);
return ESP_ERR_NO_MEM;
}
esp_fill_random(iv, iv_len);
size_t output_length = 0;
status = psa_aead_encrypt(key_id_psa, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_len),
status = psa_aead_encrypt(psa_key_id, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_len),
iv, iv_len, aad, aad_len, input, len,
output_with_tag, len + tag_len, &output_length);
aead_buf, aead_buf_len, &output_length);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in encrypting data: %d", status);
memset(output_with_tag, 0x00, len + tag_len);
free(output_with_tag);
psa_destroy_key(key_id_psa);
return ESP_FAIL;
err = ESP_FAIL;
goto cleanup;
}
// Separate ciphertext and tag
memcpy(output, output_with_tag, len);
memcpy(tag, output_with_tag + len, tag_len);
memset(output_with_tag, 0x00, len + tag_len);
free(output_with_tag);
memcpy(output, aead_buf, len);
memcpy(tag, aead_buf + len, tag_len);
} else {
// For decryption, PSA expects ciphertext + tag concatenated
uint8_t *input_with_tag = malloc(len + tag_len);
if (!input_with_tag) {
psa_destroy_key(key_id_psa);
return ESP_ERR_NO_MEM;
}
memcpy(input_with_tag, input, len);
memcpy(input_with_tag + len, tag, tag_len);
memcpy(aead_buf, input, len);
memcpy(aead_buf + len, tag, tag_len);
size_t output_length = 0;
status = psa_aead_decrypt(key_id_psa, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_len),
iv, iv_len, aad, aad_len, input_with_tag, len + tag_len,
status = psa_aead_decrypt(psa_key_id, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_len),
iv, iv_len, aad, aad_len, aead_buf, aead_buf_len,
output, len, &output_length);
memset(input_with_tag, 0x00, len + tag_len);
free(input_with_tag);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in decrypting data: %d", status);
psa_destroy_key(key_id_psa);
return ESP_FAIL;
err = ESP_FAIL;
goto cleanup;
}
}
psa_destroy_key(key_id_psa);
return ESP_OK;
err = ESP_OK;
cleanup:
if (aead_buf) {
mbedtls_platform_zeroize(aead_buf, aead_buf_len);
free(aead_buf);
}
if (psa_key_id != 0) {
psa_destroy_key(psa_key_id);
}
mbedtls_platform_zeroize(&keyctx, sizeof(keyctx));
return err;
}
esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *iv, size_t iv_len, uint8_t *tag, size_t tag_len, uint8_t *output)
@@ -819,24 +841,20 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2
}
// Sign the hash
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
size_t signature_length = 0;
status = psa_sign_hash(psa_key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256),
hash, hlen,
out_sign->signature, sizeof(out_sign->signature), &signature_length);
if (status != PSA_SUCCESS) {
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
err = ESP_FAIL;
goto exit;
}
// Export public key
memset(out_pubkey, 0x00, sizeof(esp_tee_sec_storage_ecdsa_pubkey_t));
uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
size_t public_key_length = 0;
status = psa_export_public_key(psa_key_id, public_key, sizeof(public_key), &public_key_length);
if (status != PSA_SUCCESS) {
memset(out_pubkey, 0x00, sizeof(esp_tee_sec_storage_ecdsa_pubkey_t));
err = ESP_FAIL;
goto exit;
}
@@ -844,7 +862,6 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2
// PSA exports public key in uncompressed format: 0x04 || X || Y
// Skip the first byte (0x04) and copy X and Y coordinates
if (public_key_length != (1 + 2 * key_len) || public_key[0] != 0x04) {
memset(out_pubkey, 0x00, sizeof(esp_tee_sec_storage_ecdsa_pubkey_t));
err = ESP_FAIL;
goto exit;
}
@@ -859,7 +876,7 @@ exit:
psa_destroy_key(psa_key_id);
}
if (derived_key) {
memset(derived_key, 0x00, key_len);
mbedtls_platform_zeroize(derived_key, key_len);
free(derived_key);
}
return err;
@@ -0,0 +1,223 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Shared assembly helpers (macros + assembler-time constants) for the TEE
* M-mode runtime. Included from esp_tee_vectors_{plic,clic}.S
*/
#pragma once
#include "sdkconfig.h"
#include "riscv/rvruntime-frames.h"
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#include "esp_private/hw_stack_guard.h"
#endif
/* Shared assembler-time constants used by the macros */
.equ SAVE_REGS, 32
.equ CONTEXT_SIZE, (SAVE_REGS * 4)
.equ MAGIC, 0x1f
/* Macro which first allocates space on the stack to save general
* purpose registers, and then save them. GP register is excluded.
* The default size allocated on the stack is CONTEXT_SIZE, but it
* can be overridden. */
.macro save_general_regs cxt_size=CONTEXT_SIZE
addi sp, sp, -\cxt_size
sw ra, RV_STK_RA(sp)
sw tp, RV_STK_TP(sp)
sw t0, RV_STK_T0(sp)
sw t1, RV_STK_T1(sp)
sw t2, RV_STK_T2(sp)
sw s0, RV_STK_S0(sp)
sw s1, RV_STK_S1(sp)
sw a0, RV_STK_A0(sp)
sw a1, RV_STK_A1(sp)
sw a2, RV_STK_A2(sp)
sw a3, RV_STK_A3(sp)
sw a4, RV_STK_A4(sp)
sw a5, RV_STK_A5(sp)
sw a6, RV_STK_A6(sp)
sw a7, RV_STK_A7(sp)
sw s2, RV_STK_S2(sp)
sw s3, RV_STK_S3(sp)
sw s4, RV_STK_S4(sp)
sw s5, RV_STK_S5(sp)
sw s6, RV_STK_S6(sp)
sw s7, RV_STK_S7(sp)
sw s8, RV_STK_S8(sp)
sw s9, RV_STK_S9(sp)
sw s10, RV_STK_S10(sp)
sw s11, RV_STK_S11(sp)
sw t3, RV_STK_T3(sp)
sw t4, RV_STK_T4(sp)
sw t5, RV_STK_T5(sp)
sw t6, RV_STK_T6(sp)
.endm
.macro save_mepc
csrr t0, mepc
sw t0, RV_STK_MEPC(sp)
.endm
.macro save_mcsr
csrr t0, mstatus
sw t0, RV_STK_MSTATUS(sp)
csrr t0, mtvec
sw t0, RV_STK_MTVEC(sp)
csrr t0, mtval
sw t0, RV_STK_MTVAL(sp)
csrr t0, mhartid
sw t0, RV_STK_MHARTID(sp)
csrr t0, mcause
sw t0, RV_STK_MCAUSE(sp)
.endm
/* Restore the general purpose registers (excluding gp) from the context on
* the stack. The context is then deallocated. The default size is CONTEXT_SIZE
* but it can be overridden. */
.macro restore_general_regs cxt_size=CONTEXT_SIZE
lw ra, RV_STK_RA(sp)
lw tp, RV_STK_TP(sp)
lw t0, RV_STK_T0(sp)
lw t1, RV_STK_T1(sp)
lw t2, RV_STK_T2(sp)
lw s0, RV_STK_S0(sp)
lw s1, RV_STK_S1(sp)
lw a0, RV_STK_A0(sp)
lw a1, RV_STK_A1(sp)
lw a2, RV_STK_A2(sp)
lw a3, RV_STK_A3(sp)
lw a4, RV_STK_A4(sp)
lw a5, RV_STK_A5(sp)
lw a6, RV_STK_A6(sp)
lw a7, RV_STK_A7(sp)
lw s2, RV_STK_S2(sp)
lw s3, RV_STK_S3(sp)
lw s4, RV_STK_S4(sp)
lw s5, RV_STK_S5(sp)
lw s6, RV_STK_S6(sp)
lw s7, RV_STK_S7(sp)
lw s8, RV_STK_S8(sp)
lw s9, RV_STK_S9(sp)
lw s10, RV_STK_S10(sp)
lw s11, RV_STK_S11(sp)
lw t3, RV_STK_T3(sp)
lw t4, RV_STK_T4(sp)
lw t5, RV_STK_T5(sp)
lw t6, RV_STK_T6(sp)
addi sp, sp, \cxt_size
.endm
.macro restore_mepc
lw t0, RV_STK_MEPC(sp)
csrw mepc, t0
.endm
.macro store_magic_general_regs
lui ra, MAGIC
lui tp, MAGIC
lui t0, MAGIC
lui t1, MAGIC
lui t2, MAGIC
lui s0, MAGIC
lui s1, MAGIC
lui a0, MAGIC
lui a1, MAGIC
lui a2, MAGIC
lui a3, MAGIC
lui a4, MAGIC
lui a5, MAGIC
lui a6, MAGIC
lui a7, MAGIC
lui s2, MAGIC
lui s3, MAGIC
lui s4, MAGIC
lui s5, MAGIC
lui s6, MAGIC
lui s7, MAGIC
lui s8, MAGIC
lui s9, MAGIC
lui s10, MAGIC
lui s11, MAGIC
lui t3, MAGIC
lui t4, MAGIC
lui t5, MAGIC
lui t6, MAGIC
.endm
/**
* STACK_GUARD_PRE_SWITCH
* Stops HW stack-guard monitoring and optionally saves current bounds.
*
* Args:
* op_reg – output register for "monitoring enabled" state (must be reused)
* to_save – 1=save bounds to memory, 0=skip saving
* sp_min – symbol to store lower bound (if to_save=1)
* sp_max – symbol to store upper bound (if to_save=1)
*
* Clobbers: t0, t1, t2, op_reg
*/
.macro STACK_GUARD_PRE_SWITCH op_reg, to_save, sp_min, sp_max
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
/* Query if monitoring is enabled: result goes into \op_reg */
ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 \op_reg
beqz \op_reg, 1f
.if \to_save
/* Save current REE/U-mode stack bounds */
ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 t0 t1
la t2, \sp_min
sw t0, 0(t2)
la t2, \sp_max
sw t1, 0(t2)
.endif
/* Stop monitoring */
ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1
fence
1:
#endif
.endm
/**
* STACK_GUARD_POST_SWITCH
* Restores or applies new bounds after switching stacks, then restarts monitoring.
*
* Args:
* op_reg – saved monitoring state from PRE_SWITCH
* to_restore – 1=restore from memory, 0=set static bounds
* sp_min – saved bound (restore) or static lower bound (S-mode)
* sp_max – saved bound (restore) or static upper bound (S-mode)
*
* Clobbers: t0, t1, t2
*/
.macro STACK_GUARD_POST_SWITCH op_reg, to_restore, sp_min, sp_max
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
/* Check if monitoring was enabled (using saved state from op_reg) */
beqz \op_reg, 1f
.if \to_restore
/* Restore saved REE/U-mode bounds from memory */
la t2, \sp_min
lw t0, 0(t2)
la t2, \sp_max
lw t1, 0(t2)
.else
/* Use new TEE/S-mode stack bounds (static symbols) */
la t0, \sp_min
la t1, \sp_max
.endif
/* Apply bounds to hardware stack guard */
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 t0 t1
/* Restart monitoring */
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1
1:
#endif
.endm
@@ -16,15 +16,10 @@
#include "esp_tee_intr_defs.h"
#include "sdkconfig.h"
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#include "esp_private/hw_stack_guard.h"
#endif
#include "esp_tee_asm_utils.inc"
.equ SAVE_REGS, 32
.equ CONTEXT_SIZE, (SAVE_REGS * 4)
.equ panic_from_exception, tee_panic_from_exc
.equ panic_from_isr, tee_panic_from_isr
.equ MAGIC, 0x1f
.equ RTNVAL, 0xc0de
.equ ECALL_U_MODE, 0x8
.equ ECALL_M_MODE, 0xb
@@ -60,205 +55,6 @@ _ns_sp_min:
_ns_sp_max:
.word 0
/**
* STACK_GUARD_PRE_SWITCH
* Stops HW stack-guard monitoring and optionally saves current bounds.
*
* Args:
* op_reg – output register for “monitoring enabled” state (must be reused)
* to_save – 1=save bounds to memory, 0=skip saving
* sp_min – symbol to store lower bound (if to_save=1)
* sp_max – symbol to store upper bound (if to_save=1)
*
* Clobbers: t0, t1, t2, op_reg
*/
.macro STACK_GUARD_PRE_SWITCH op_reg, to_save, sp_min, sp_max
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
/* Query if monitoring is enabled: result goes into \op_reg */
ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 \op_reg
beqz \op_reg, 1f
.if \to_save
/* Save current REE/U-mode stack bounds */
ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 t0 t1
la t2, \sp_min
sw t0, 0(t2)
la t2, \sp_max
sw t1, 0(t2)
.endif
/* Stop monitoring */
ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1
fence
1:
#endif
.endm
/**
* STACK_GUARD_POST_SWITCH
* Restores or applies new bounds after switching stacks, then restarts monitoring.
*
* Args:
* op_reg – saved monitoring state from PRE_SWITCH
* to_restore – 1=restore from memory, 0=set static bounds
* sp_min – saved bound (restore) or static lower bound (S-mode)
* sp_max – saved bound (restore) or static upper bound (S-mode)
*
* Clobbers: t0, t1, t2
*/
.macro STACK_GUARD_POST_SWITCH op_reg, to_restore, sp_min, sp_max
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
/* Check if monitoring was enabled (using saved state from op_reg) */
beqz \op_reg, 1f
.if \to_restore
/* Restore saved REE/U-mode bounds from memory */
la t2, \sp_min
lw t0, 0(t2)
la t2, \sp_max
lw t1, 0(t2)
.else
/* Use new TEE/S-mode stack bounds (static symbols) */
la t0, \sp_min
la t1, \sp_max
.endif
/* Apply bounds to hardware stack guard */
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 t0 t1
/* Restart monitoring */
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1
1:
#endif
.endm
/* Macro which first allocates space on the stack to save general
* purpose registers, and then save them. GP register is excluded.
* The default size allocated on the stack is CONTEXT_SIZE, but it
* can be overridden. */
.macro save_general_regs cxt_size=CONTEXT_SIZE
addi sp, sp, -\cxt_size
sw ra, RV_STK_RA(sp)
sw tp, RV_STK_TP(sp)
sw t0, RV_STK_T0(sp)
sw t1, RV_STK_T1(sp)
sw t2, RV_STK_T2(sp)
sw s0, RV_STK_S0(sp)
sw s1, RV_STK_S1(sp)
sw a0, RV_STK_A0(sp)
sw a1, RV_STK_A1(sp)
sw a2, RV_STK_A2(sp)
sw a3, RV_STK_A3(sp)
sw a4, RV_STK_A4(sp)
sw a5, RV_STK_A5(sp)
sw a6, RV_STK_A6(sp)
sw a7, RV_STK_A7(sp)
sw s2, RV_STK_S2(sp)
sw s3, RV_STK_S3(sp)
sw s4, RV_STK_S4(sp)
sw s5, RV_STK_S5(sp)
sw s6, RV_STK_S6(sp)
sw s7, RV_STK_S7(sp)
sw s8, RV_STK_S8(sp)
sw s9, RV_STK_S9(sp)
sw s10, RV_STK_S10(sp)
sw s11, RV_STK_S11(sp)
sw t3, RV_STK_T3(sp)
sw t4, RV_STK_T4(sp)
sw t5, RV_STK_T5(sp)
sw t6, RV_STK_T6(sp)
.endm
.macro save_mepc
csrr t0, mepc
sw t0, RV_STK_MEPC(sp)
.endm
.macro save_mcsr
csrr t0, mstatus
sw t0, RV_STK_MSTATUS(sp)
csrr t0, mtvec
sw t0, RV_STK_MTVEC(sp)
csrr t0, mtval
sw t0, RV_STK_MTVAL(sp)
csrr t0, mhartid
sw t0, RV_STK_MHARTID(sp)
csrr t0, mcause
sw t0, RV_STK_MCAUSE(sp)
.endm
/* Restore the general purpose registers (excluding gp) from the context on
* the stack. The context is then deallocated. The default size is CONTEXT_SIZE
* but it can be overridden. */
.macro restore_general_regs cxt_size=CONTEXT_SIZE
lw ra, RV_STK_RA(sp)
lw tp, RV_STK_TP(sp)
lw t0, RV_STK_T0(sp)
lw t1, RV_STK_T1(sp)
lw t2, RV_STK_T2(sp)
lw s0, RV_STK_S0(sp)
lw s1, RV_STK_S1(sp)
lw a0, RV_STK_A0(sp)
lw a1, RV_STK_A1(sp)
lw a2, RV_STK_A2(sp)
lw a3, RV_STK_A3(sp)
lw a4, RV_STK_A4(sp)
lw a5, RV_STK_A5(sp)
lw a6, RV_STK_A6(sp)
lw a7, RV_STK_A7(sp)
lw s2, RV_STK_S2(sp)
lw s3, RV_STK_S3(sp)
lw s4, RV_STK_S4(sp)
lw s5, RV_STK_S5(sp)
lw s6, RV_STK_S6(sp)
lw s7, RV_STK_S7(sp)
lw s8, RV_STK_S8(sp)
lw s9, RV_STK_S9(sp)
lw s10, RV_STK_S10(sp)
lw s11, RV_STK_S11(sp)
lw t3, RV_STK_T3(sp)
lw t4, RV_STK_T4(sp)
lw t5, RV_STK_T5(sp)
lw t6, RV_STK_T6(sp)
addi sp,sp, \cxt_size
.endm
.macro restore_mepc
lw t0, RV_STK_MEPC(sp)
csrw mepc, t0
.endm
.macro store_magic_general_regs
lui ra, MAGIC
lui tp, MAGIC
lui t0, MAGIC
lui t1, MAGIC
lui t2, MAGIC
lui s0, MAGIC
lui s1, MAGIC
lui a0, MAGIC
lui a1, MAGIC
lui a2, MAGIC
lui a3, MAGIC
lui a4, MAGIC
lui a5, MAGIC
lui a6, MAGIC
lui a7, MAGIC
lui s2, MAGIC
lui s3, MAGIC
lui s4, MAGIC
lui s5, MAGIC
lui s6, MAGIC
lui s7, MAGIC
lui s8, MAGIC
lui s9, MAGIC
lui s10, MAGIC
lui s11, MAGIC
lui t3, MAGIC
lui t4, MAGIC
lui t5, MAGIC
lui t6, MAGIC
.endm
.section .exception_vectors.text, "ax"
/* Exception handler. */
@@ -394,13 +190,14 @@ _skip_thresh_restore:
STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max
fence
call syscall_exit_tee
/* Backup the A0 register
* This point is reached after an ecall is triggered after executing the secure service.
* The A0 register contains the return value of the corresponding service.
* After restoring the entire register context, we assign A0 the value back to the return value. */
csrw mscratch, a0
call syscall_exit_tee
restore_general_regs
csrrw a0, mscratch, zero
@@ -16,15 +16,10 @@
#include "esp_tee_intr_defs.h"
#include "sdkconfig.h"
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#include "esp_private/hw_stack_guard.h"
#endif
#include "esp_tee_asm_utils.inc"
.equ SAVE_REGS, 32
.equ CONTEXT_SIZE, (SAVE_REGS * 4)
.equ panic_from_exception, tee_panic_from_exc
.equ panic_from_isr, tee_panic_from_isr
.equ MAGIC, 0x1f
.equ RTNVAL, 0xc0de
.equ ECALL_U_MODE, 0x8
.equ ECALL_M_MODE, 0xb
@@ -65,205 +60,6 @@ _ns_sp_min:
_ns_sp_max:
.word 0
/**
* STACK_GUARD_PRE_SWITCH
* Stops HW stack-guard monitoring and optionally saves current bounds.
*
* Args:
* op_reg – output register for “monitoring enabled” state (must be reused)
* to_save – 1=save bounds to memory, 0=skip saving
* sp_min – symbol to store lower bound (if to_save=1)
* sp_max – symbol to store upper bound (if to_save=1)
*
* Clobbers: t0, t1, t2, op_reg
*/
.macro STACK_GUARD_PRE_SWITCH op_reg, to_save, sp_min, sp_max
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
/* Query if monitoring is enabled: result goes into \op_reg */
ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 \op_reg
beqz \op_reg, 1f
.if \to_save
/* Save current REE/U-mode stack bounds */
ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 t0 t1
la t2, \sp_min
sw t0, 0(t2)
la t2, \sp_max
sw t1, 0(t2)
.endif
/* Stop monitoring */
ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1
fence
1:
#endif
.endm
/**
* STACK_GUARD_POST_SWITCH
* Restores or applies new bounds after switching stacks, then restarts monitoring.
*
* Args:
* op_reg – saved monitoring state from PRE_SWITCH
* to_restore – 1=restore from memory, 0=set static bounds
* sp_min – saved bound (restore) or static lower bound (S-mode)
* sp_max – saved bound (restore) or static upper bound (S-mode)
*
* Clobbers: t0, t1, t2
*/
.macro STACK_GUARD_POST_SWITCH op_reg, to_restore, sp_min, sp_max
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
/* Check if monitoring was enabled (using saved state from op_reg) */
beqz \op_reg, 1f
.if \to_restore
/* Restore saved REE/U-mode bounds from memory */
la t2, \sp_min
lw t0, 0(t2)
la t2, \sp_max
lw t1, 0(t2)
.else
/* Use new TEE/S-mode stack bounds (static symbols) */
la t0, \sp_min
la t1, \sp_max
.endif
/* Apply bounds to hardware stack guard */
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 t0 t1
/* Restart monitoring */
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1
1:
#endif
.endm
/* Macro which first allocates space on the stack to save general
* purpose registers, and then save them. GP register is excluded.
* The default size allocated on the stack is CONTEXT_SIZE, but it
* can be overridden. */
.macro save_general_regs cxt_size=CONTEXT_SIZE
addi sp, sp, -\cxt_size
sw ra, RV_STK_RA(sp)
sw tp, RV_STK_TP(sp)
sw t0, RV_STK_T0(sp)
sw t1, RV_STK_T1(sp)
sw t2, RV_STK_T2(sp)
sw s0, RV_STK_S0(sp)
sw s1, RV_STK_S1(sp)
sw a0, RV_STK_A0(sp)
sw a1, RV_STK_A1(sp)
sw a2, RV_STK_A2(sp)
sw a3, RV_STK_A3(sp)
sw a4, RV_STK_A4(sp)
sw a5, RV_STK_A5(sp)
sw a6, RV_STK_A6(sp)
sw a7, RV_STK_A7(sp)
sw s2, RV_STK_S2(sp)
sw s3, RV_STK_S3(sp)
sw s4, RV_STK_S4(sp)
sw s5, RV_STK_S5(sp)
sw s6, RV_STK_S6(sp)
sw s7, RV_STK_S7(sp)
sw s8, RV_STK_S8(sp)
sw s9, RV_STK_S9(sp)
sw s10, RV_STK_S10(sp)
sw s11, RV_STK_S11(sp)
sw t3, RV_STK_T3(sp)
sw t4, RV_STK_T4(sp)
sw t5, RV_STK_T5(sp)
sw t6, RV_STK_T6(sp)
.endm
.macro save_mepc
csrr t0, mepc
sw t0, RV_STK_MEPC(sp)
.endm
.macro save_mcsr
csrr t0, mstatus
sw t0, RV_STK_MSTATUS(sp)
csrr t0, mtvec
sw t0, RV_STK_MTVEC(sp)
csrr t0, mtval
sw t0, RV_STK_MTVAL(sp)
csrr t0, mhartid
sw t0, RV_STK_MHARTID(sp)
csrr t0, mcause
sw t0, RV_STK_MCAUSE(sp)
.endm
/* Restore the general purpose registers (excluding gp) from the context on
* the stack. The context is then deallocated. The default size is CONTEXT_SIZE
* but it can be overridden. */
.macro restore_general_regs cxt_size=CONTEXT_SIZE
lw ra, RV_STK_RA(sp)
lw tp, RV_STK_TP(sp)
lw t0, RV_STK_T0(sp)
lw t1, RV_STK_T1(sp)
lw t2, RV_STK_T2(sp)
lw s0, RV_STK_S0(sp)
lw s1, RV_STK_S1(sp)
lw a0, RV_STK_A0(sp)
lw a1, RV_STK_A1(sp)
lw a2, RV_STK_A2(sp)
lw a3, RV_STK_A3(sp)
lw a4, RV_STK_A4(sp)
lw a5, RV_STK_A5(sp)
lw a6, RV_STK_A6(sp)
lw a7, RV_STK_A7(sp)
lw s2, RV_STK_S2(sp)
lw s3, RV_STK_S3(sp)
lw s4, RV_STK_S4(sp)
lw s5, RV_STK_S5(sp)
lw s6, RV_STK_S6(sp)
lw s7, RV_STK_S7(sp)
lw s8, RV_STK_S8(sp)
lw s9, RV_STK_S9(sp)
lw s10, RV_STK_S10(sp)
lw s11, RV_STK_S11(sp)
lw t3, RV_STK_T3(sp)
lw t4, RV_STK_T4(sp)
lw t5, RV_STK_T5(sp)
lw t6, RV_STK_T6(sp)
addi sp,sp, \cxt_size
.endm
.macro restore_mepc
lw t0, RV_STK_MEPC(sp)
csrw mepc, t0
.endm
.macro store_magic_general_regs
lui ra, MAGIC
lui tp, MAGIC
lui t0, MAGIC
lui t1, MAGIC
lui t2, MAGIC
lui s0, MAGIC
lui s1, MAGIC
lui a0, MAGIC
lui a1, MAGIC
lui a2, MAGIC
lui a3, MAGIC
lui a4, MAGIC
lui a5, MAGIC
lui a6, MAGIC
lui a7, MAGIC
lui s2, MAGIC
lui s3, MAGIC
lui s4, MAGIC
lui s5, MAGIC
lui s6, MAGIC
lui s7, MAGIC
lui s8, MAGIC
lui s9, MAGIC
lui s10, MAGIC
lui s11, MAGIC
lui t3, MAGIC
lui t4, MAGIC
lui t5, MAGIC
lui t6, MAGIC
.endm
.section .exception_vectors.text, "ax"
/* Exception handler. */
@@ -386,13 +182,14 @@ _skip_thresh_restore:
STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max
fence
call syscall_exit_tee
/* Backup the A0 register
* This point is reached after an ecall is triggered after executing the secure service.
* The A0 register contains the return value of the corresponding service.
* After restoring the entire register context, we assign A0 the value back to the return value. */
csrw mscratch, a0
call syscall_exit_tee
restore_general_regs
csrrw a0, mscratch, zero
@@ -4,6 +4,8 @@ components/esp_tee/test_apps/tee_cli_app:
disable:
- if: IDF_TARGET not in ["esp32c6", "esp32c5", "esp32c61"]
reason: only supported with c6, c5 and c61
depends_components:
- esp_tee
components/esp_tee/test_apps/tee_test_fw:
disable:
@@ -138,9 +138,9 @@ help [<string>] [-v <0|1>]
```log
esp32c6> tee_att_info
I (8180) tee_attest: Attestation token - Length: 1587
I (8180) tee_attest: Attestation token - Length: 1705
I (8180) tee_attest: Attestation token - Data:
'{"header":{"magic":"44fef7cc","encr_alg":"","sign_alg":"ecdsa_secp256r1_sha256","key_id":"tee_att_key0"},"eat":{"auth_challenge":"dcb9b53143ad6b081dad1a05c7ebda4e314d388762215799cf24ed52e9387678","client_id":262974944,"device_ver":0,"device_id":"cd9c173cb3675c7adfae243f0cd9841e4bce003237cb5321927a85a86cb4b32e","instance_id":"9616ef0ecf02cdc89a3749f8fc16b3103d5100bd42d9312fcd04593baa7bac64","psa_cert_ref":"0716053550477-10100","device_status":165,"sw_claims":{"tee":{"type":1,"ver":"v0.3.0","idf_ver":"v5.1.4-241-g7ff01fd46f-dirty","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"94536998e1dcb2a036477cb2feb01ed4fff67ba6208f30482346c62bca64b280","digest_validated":true,"sign_verified":true}},"app":{"type":2,"ver":"v0.1.0","idf_ver":"v5.1.4-241-g7ff01fd46f-dirty","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"3d4c038fcec76852b4d07acb9e94afaf5fca69fc2eb212a32032d09ce5b4f2b3","digest_validated":true,"sign_verified":true,"secure_padding":true}},"bootloader":{"type":0,"ver":"","idf_ver":"","secure_ver":-1,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"1bef421beb1a4642c6fcefb3e37fd4afad60cb4074e538f42605b012c482b946","digest_validated":true,"sign_verified":true}}}},"public_key":{"compressed":"02039c4bfab0762af1aff2fe5596b037f629cf839da8c4a9c0018afedfccf519a6"},"sign":{"r":"915e749f5a780bc21a2b21821cfeb54286dc742e9f12f2387e3de9b8b1a70bc9","s":"1e583236f2630b0fe8e291645ffa35d429f14035182e19868508d4dac0e1a441"}}'
'{"header":{"magic":"44fef7cc","encr_alg":"","sign_alg":"ecdsa_secp256r1_sha256","key_id":"tee_att_key0"},"eat":{"auth_challenge":"dcb9b53143ad6b081dad1a05c7ebda4e314d388762215799cf24ed52e9387678","client_id":262974944,"chip_id":13,"device_ver":0,"ueid":{"mac":"d885ac67c978","optional_id":"94fa4d7e305682714d48e7bbd710c961"},"device_id":"cd9c173cb3675c7adfae243f0cd9841e4bce003237cb5321927a85a86cb4b32e","instance_id":"9616ef0ecf02cdc89a3749f8fc16b3103d5100bd42d9312fcd04593baa7bac64","psa_cert_ref":"0716053550477-10100","device_status":165,"sw_claims":{"tee":{"type":1,"ver":"v0.3.0","idf_ver":"v5.1.4-241-g7ff01fd46f-dirty","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"94536998e1dcb2a036477cb2feb01ed4fff67ba6208f30482346c62bca64b280","digest_validated":true,"sign_verified":true}},"app":{"type":2,"ver":"v0.1.0","idf_ver":"v5.1.4-241-g7ff01fd46f-dirty","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"3d4c038fcec76852b4d07acb9e94afaf5fca69fc2eb212a32032d09ce5b4f2b3","digest_validated":true,"sign_verified":true,"secure_padding":true}},"bootloader":{"type":0,"ver":"","idf_ver":"","secure_ver":-1,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"1bef421beb1a4642c6fcefb3e37fd4afad60cb4074e538f42605b012c482b946","digest_validated":true,"sign_verified":true}}}},"public_key":{"compressed":"02039c4bfab0762af1aff2fe5596b037f629cf839da8c4a9c0018afedfccf519a6"},"sign":{"r":"915e749f5a780bc21a2b21821cfeb54286dc742e9f12f2387e3de9b8b1a70bc9","s":"1e583236f2630b0fe8e291645ffa35d429f14035182e19868508d4dac0e1a441"}}'
```
</details>
@@ -20,3 +20,6 @@ CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=30000
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="test_certs/server_cert.pem"
# Takes effect only when Secure boot is enabled
CONFIG_SECURE_BOOT_FLASH_BOOTLOADER_DEFAULT=y
@@ -77,3 +77,7 @@ secure_services:
type: custom
function: esp_tee_test_stack_underflow
args: 0
- id: 219
type: custom
function: esp_tee_test_read_sec_stg
args: 1
@@ -1,13 +1,21 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stddef.h>
#include "esp_cpu.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_tee.h"
#include "esp_tee_flash.h"
#include "esp_tee_memory_utils.h"
#include "esp_tee_test.h"
#include "esp_attr.h"
#include "esp_flash_partitions.h"
static const char *TAG = "test_sec_srv";
/* Sample Trusted App */
@@ -54,3 +62,23 @@ uint32_t _ss_esp_tee_test_priv_mode_switch(uint32_t *a, uint32_t *b)
return c;
}
esp_err_t _ss_esp_tee_test_read_sec_stg(uint8_t *buf)
{
if (!esp_tee_buf_in_ree(buf, FLASH_SECTOR_SIZE)) {
return ESP_ERR_INVALID_ARG;
}
esp_partition_info_t pinfo;
esp_err_t err = esp_tee_flash_find_partition(PART_TYPE_DATA, PART_SUBTYPE_DATA_WIFI,
ESP_TEE_SEC_STG_PART_LABEL, &pinfo);
if (err != ESP_OK) {
return err;
}
if (pinfo.pos.size < FLASH_SECTOR_SIZE) {
return ESP_ERR_INVALID_SIZE;
}
return (esp_err_t)esp_tee_flash_read(pinfo.pos.offset, (uint32_t *)buf, FLASH_SECTOR_SIZE, false);
}
@@ -4,6 +4,7 @@
import base64
import csv
import os
import re
import shutil
import subprocess
import sys
@@ -202,25 +203,6 @@ class TEESerial(IdfSerial):
def _get_flash_size(self) -> Any:
return self.app.sdkconfig.get('ESPTOOLPY_FLASHSIZE', '')
@EspSerial.use_esptool()
def bootloader_force_flash_if_req(self) -> None:
# Forcefully flash the bootloader only if security features are enabled
if any(
(
self.app.sdkconfig.get('SECURE_BOOT', True),
self.app.sdkconfig.get('SECURE_FLASH_ENC_ENABLED', True),
)
):
offs = int(self.app.sdkconfig.get('BOOTLOADER_OFFSET_IN_FLASH', 0))
bootloader_path = os.path.join(self.app.binary_path, 'bootloader', 'bootloader.bin')
encrypt = '--encrypt' if self.app.sdkconfig.get('SECURE_FLASH_ENC_ENABLED') else ''
flash_size = self._get_flash_size()
esptool.main(
f'--no-stub write-flash {offs} {bootloader_path} --force {encrypt} --flash-size {flash_size}'.split(),
esp=self.esp,
)
@EspSerial.use_esptool()
def custom_erase_partition(self, partition: str) -> None:
if self.app.sdkconfig.get('SECURE_ENABLE_SECURE_ROM_DL_MODE'):
@@ -294,29 +276,133 @@ class TEESerial(IdfSerial):
if os.path.exists(file):
os.remove(file)
@EspSerial.use_esptool()
def custom_flash(self) -> None:
self.bootloader_force_flash_if_req()
self.flash()
@EspSerial.use_esptool()
def custom_flash_w_test_tee_img_gen(self) -> None:
self.bootloader_force_flash_if_req()
self.flash()
self.copy_test_tee_img('ota_1', False)
@EspSerial.use_esptool()
def custom_flash_w_test_tee_img_rb(self) -> None:
self.bootloader_force_flash_if_req()
self.flash()
self.copy_test_tee_img('ota_1', True)
@EspSerial.use_esptool()
def custom_flash_with_empty_sec_stg(self) -> None:
self.bootloader_force_flash_if_req()
self.flash()
self.custom_erase_partition('secure_storage')
KEY_DEFS_ENCRYPTION_TEST: list[str] = [
'aes256_key0',
'aes256_key1',
'attest_key',
'ecdsa_p256_key0',
]
# TEE Secure Storage Development mode
# NVS XTS-AES keys: E-key=0x33*32 || T-key=0xCC*32
NVS_KEYS_DEV_B64 = 'MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzA=='
@property
def nvs_partition_gen(self) -> str:
return str(
Path(os.environ['IDF_PATH'])
/ 'components'
/ 'nvs_flash'
/ 'nvs_partition_generator'
/ 'nvs_partition_gen.py'
)
def derive_sec_stg_nvs_keys(self, out_path: Path) -> None:
out_path.parent.mkdir(parents=True, exist_ok=True)
if self.app.sdkconfig.get('SECURE_TEE_SEC_STG_MODE_RELEASE'):
hmac_key_src = self.TEST_KEYS_DIR / 'tee_sec_stg_hmac_key.bin'
self.run_command(
[
sys.executable,
self.nvs_partition_gen,
'generate-key',
'--key_protect_hmac',
'--kp_hmac_inputkey',
str(hmac_key_src),
'--keyfile',
out_path.name,
'--outdir',
str(out_path.parent),
]
)
(out_path.parent / 'keys' / out_path.name).replace(out_path)
else:
self.write_keys_to_file(self.NVS_KEYS_DEV_B64, out_path)
def decrypt_sec_stg_partition(self, dump_path: Path, keys_path: Path, decrypted_path: Path) -> None:
self.run_command(
[sys.executable, self.nvs_partition_gen, 'decrypt', str(dump_path), str(keys_path), str(decrypted_path)]
)
_SEC_STG_HEX_LINE_RE = re.compile(
rb'test_esp_tee_sec_storage:\s+((?:[0-9a-f]{2} ){0,15}[0-9a-f]{2})',
)
SEC_STG_DUMP_SZ = 4096
def capture_sec_stg_partition_dump(self, dut: Any, timeout: float = 60) -> bytes:
dut.expect_exact('SEC_STG_DUMP_BEGIN', timeout=timeout)
blob = dut.expect_exact('SEC_STG_DUMP_END', timeout=timeout, return_what_before_match=True)
raw = bytearray()
for match in self._SEC_STG_HEX_LINE_RE.finditer(blob):
for tok in match.group(1).split():
raw.append(int(tok, 16))
if len(raw) != self.SEC_STG_DUMP_SZ:
raise RuntimeError(
f'Hex dump parse mismatch: got {len(raw)} bytes, expected {self.SEC_STG_DUMP_SZ}.\n'
f'Blob (first 256 bytes): {blob[:256]!r}'
)
# Make sure the Unity case actually passed before we trust the dump.
m = dut.expect(re.compile(rb'(\d+) Tests (\d+) Failures (\d+) Ignored'), timeout=timeout)
if int(m.group(2)) != 0:
raise RuntimeError(f'Unity reported {m.group(2).decode()} failures while running encryption test')
return bytes(raw)
def _run_nvs_tool_minimal(self, partition_file: Path) -> subprocess.CompletedProcess:
nvs_tool = Path(os.environ['IDF_PATH']) / 'components' / 'nvs_flash' / 'nvs_partition_tool' / 'nvs_tool.py'
return subprocess.run(
[sys.executable, str(nvs_tool), '-d', 'minimal', '--color', 'never', str(partition_file)],
capture_output=True,
text=True,
)
def verify_tee_sec_stg_encryption(self, dut: Any) -> None:
tmp_dir = self.TMP_DIR / 'sec_stg_encryption'
tmp_dir.mkdir(parents=True, exist_ok=True)
raw_path = tmp_dir / 'tee_sec_stg_dump.bin'
keys_path = tmp_dir / self.NVS_KEYS_FILE
decrypted_path = tmp_dir / 'tee_sec_stg_decr.bin'
expected_key_ids = self.KEY_DEFS_ENCRYPTION_TEST
print('Verifying TEE Secure Storage NVS partition encryption (XTS-AES-512: 256-bit AES, 512-bit total key)')
try:
raw_bytes = self.capture_sec_stg_partition_dump(dut)
raw_path.write_bytes(raw_bytes)
self.derive_sec_stg_nvs_keys(keys_path)
self.decrypt_sec_stg_partition(raw_path, keys_path, decrypted_path)
print('Confirming key IDs are NOT present in the raw (encrypted) NVS dump')
raw_parse = self._run_nvs_tool_minimal(raw_path)
for key_id in expected_key_ids:
assert key_id not in raw_parse.stdout, f'{key_id!r} surfaced in raw dump (not encrypted)'
print('Confirming key IDs ARE present after XTS-AES decrypt with the derived NVS keys')
decrypted_parse = self._run_nvs_tool_minimal(decrypted_path)
assert decrypted_parse.returncode == 0, f'nvs_tool exit {decrypted_parse.returncode} on decrypted dump'
for key_id in expected_key_ids:
assert key_id in decrypted_parse.stdout, f'{key_id!r} missing after decrypt (wrong XTS-AES key?)'
finally:
shutil.rmtree(tmp_dir, ignore_errors=True)
KEY_DEFS: list[dict[str, Any]] = [
{'key': 'aes256_key0', 'type': 'aes256', 'input': None, 'write_once': True},
{
@@ -354,12 +440,11 @@ class TEESerial(IdfSerial):
},
]
NVS_KEYS_B64 = 'MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzA=='
TEST_KEYS_DIR = Path(__file__).parent / 'test_keys'
TMP_DIR = Path('tmp')
NVS_KEYS_PATH = TMP_DIR / 'nvs_keys.bin'
NVS_CSV_PATH = TMP_DIR / 'tee_sec_stg_val.csv'
NVS_BIN_PATH = TMP_DIR / 'tee_sec_stg_nvs.bin'
NVS_KEYS_FILE = 'tee_sec_stg_nvs_keys.bin'
def run_command(self, command: list[str]) -> None:
try:
@@ -391,16 +476,19 @@ class TEESerial(IdfSerial):
input_path = tmp_dir / entry['input']
self.write_keys_to_file(entry['b64'], input_path)
entry['input'] = str(input_path)
self.write_keys_to_file(self.NVS_KEYS_B64, self.NVS_KEYS_PATH)
idf_path = Path(os.environ['IDF_PATH'])
ESP_TEE_SEC_STG_KEYGEN = os.path.join(
idf_path, 'components', 'esp_tee', 'scripts', 'esp_tee_sec_stg_keygen', 'esp_tee_sec_stg_keygen.py'
)
NVS_PARTITION_GEN = os.path.join(
idf_path, 'components', 'nvs_flash', 'nvs_partition_generator', 'nvs_partition_gen.py'
os.environ['IDF_PATH'],
'components',
'esp_tee',
'scripts',
'esp_tee_sec_stg_keygen',
'esp_tee_sec_stg_keygen.py',
)
nvs_keys = tmp_dir / self.NVS_KEYS_FILE
self.derive_sec_stg_nvs_keys(nvs_keys)
cmds = [
[sys.executable, ESP_TEE_SEC_STG_KEYGEN, '-k', entry['type'], '-o', str(tmp_dir / f'{entry["key"]}.bin')]
+ (['-i', entry['input']] if entry['input'] else [])
@@ -410,13 +498,12 @@ class TEESerial(IdfSerial):
csv_path = self.create_tee_sec_stg_csv(tmp_dir)
nvs_bin = self.NVS_BIN_PATH
nvs_keys = self.NVS_KEYS_PATH
size = self.app.partition_table['secure_storage']['size']
cmds.append(
[
sys.executable,
NVS_PARTITION_GEN,
self.nvs_partition_gen,
'encrypt',
str(csv_path),
str(nvs_bin),
@@ -430,10 +517,9 @@ class TEESerial(IdfSerial):
for cmd in cmds:
self.run_command(cmd)
self.bootloader_force_flash_if_req()
self.flash()
self.custom_erase_partition('secure_storage')
self.custom_write_partition('secure_storage', nvs_bin)
self.custom_write_partition('secure_storage', str(nvs_bin))
finally:
shutil.rmtree(tmp_dir)
@@ -127,8 +127,8 @@ TEST_CASE("Test TEE OTA - Corrupted image", "[ota_neg_2]")
/* Corrupting the image */
ESP_LOGI(TAG, "Corrupting the image at some offset...");
uint32_t corrupt[8] = {[0 ... 7] = 0x0BADC0DE};
curr_write_offset -= (2 * FLASH_SECTOR_SIZE + sizeof(corrupt));
TEST_ESP_OK(esp_tee_ota_write(curr_write_offset, (const void *)corrupt, sizeof(corrupt)));
uint32_t offs = SOC_MMU_PAGE_SIZE + 0x200;
TEST_ESP_OK(esp_tee_ota_write(offs, (const void *)corrupt, sizeof(corrupt)));
TEST_ESP_ERR(ESP_ERR_IMAGE_INVALID, esp_tee_ota_end());
}
@@ -3,6 +3,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include "esp_log.h"
@@ -364,6 +365,45 @@ TEST_CASE("Test TEE Secure Storage - Null Pointer and Zero Length", "[sec_storag
TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id));
}
TEST_CASE("Test TEE Secure Storage - Verify data encryption", "[sec_storage_encr]")
{
ESP_LOGI(TAG, "Populating NVS-based TEE Secure Storage; encrypted with XTS-AES-512");
static const struct {
const char *id;
esp_tee_sec_storage_type_t type;
uint32_t flags;
} key_cfgs[] = {
{ "aes256_key0", ESP_SEC_STG_KEY_AES256, SEC_STORAGE_FLAG_WRITE_ONCE },
{ "aes256_key1", ESP_SEC_STG_KEY_AES256, SEC_STORAGE_FLAG_NONE },
{ "attest_key", ESP_SEC_STG_KEY_ECDSA_SECP256R1, SEC_STORAGE_FLAG_WRITE_ONCE },
{ "ecdsa_p256_key0", ESP_SEC_STG_KEY_ECDSA_SECP256R1, SEC_STORAGE_FLAG_NONE },
};
for (size_t i = 0; i < sizeof(key_cfgs) / sizeof(key_cfgs[0]); i++) {
esp_tee_sec_storage_key_cfg_t cfg = {
.id = key_cfgs[i].id,
.type = key_cfgs[i].type,
.flags = key_cfgs[i].flags,
};
if ((cfg.flags & SEC_STORAGE_FLAG_WRITE_ONCE) == 0) {
esp_err_t err = esp_tee_sec_storage_clear_key(cfg.id);
TEST_ASSERT_TRUE(err == ESP_OK || err == ESP_ERR_NOT_FOUND);
}
TEST_ESP_OK(esp_tee_sec_storage_gen_key(&cfg));
}
const size_t dump_sz = 4096;
uint8_t *buf = heap_caps_malloc(dump_sz, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
TEST_ASSERT_NOT_NULL(buf);
TEST_ESP_OK((esp_err_t)esp_tee_service_call(2, SS_ESP_TEE_TEST_READ_SEC_STG, buf));
printf("\nSEC_STG_DUMP_BEGIN\n");
ESP_LOG_BUFFER_HEX(TAG, buf, dump_sz);
printf("SEC_STG_DUMP_END\n");
free(buf);
}
TEST_CASE("Test TEE Secure Storage - WRITE_ONCE keys", "[sec_storage]")
{
const char *key_id = "key_id_test_wo";
@@ -425,6 +465,10 @@ static void do_ecdsa_sign_and_verify(const esp_tee_sec_storage_key_cfg_t *cfg, c
TEST_ESP_OK(verify_ecdsa_sign(cfg->type, digest, digest_len, &pubkey, &sign));
}
/* NOTE: In release mode (CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE), the test expects
* the eFuse-burned HMAC key used for TEE secure storage to be available at
* the path "test_keys/tee_sec_stg_hmac_key.bin"
*/
TEST_CASE("Test TEE Secure Storage - Host-generated keys", "[sec_storage_host_keygen]")
{
const char *aes_key_ids[] = { "aes256_key0", "aes256_key1" };
@@ -6,7 +6,7 @@ from enum import Enum
import pytest
from pytest_embedded_idf import IdfDut
from pytest_embedded_idf.utils import idf_parametrize
from tee_exception_cfg import TEE_EXCEPTION_TEST_MAP
from tee_exception_test_map import TEE_EXCEPTION_TEST_MAP
# ---------------- Pytest build parameters ----------------
@@ -20,6 +20,12 @@ CONFIG_DEFAULT = [
]
CONFIG_OTA = [
# 'config, target, markers',
('tee_ota', target, (pytest.mark.generic,))
for target in TESTING_TARGETS
]
CONFIG_OTA_NO_AUTOFLASH = [
# 'config, target, skip_autoflash, markers',
('tee_ota', target, 'y', (pytest.mark.generic,))
for target in TESTING_TARGETS
@@ -50,8 +56,10 @@ def test_esp_tee(dut: IdfDut) -> None:
CONFIG_ALL,
indirect=['config', 'target'],
)
@pytest.mark.skipif(targets=['esp32c61'], reason='Not supported')
def test_esp_tee_crypto_aes(dut: IdfDut) -> None:
if dut.target == 'esp32c61':
pytest.skip(f'AES not supported on {dut.target}')
dut.run_all_single_board_cases(group='aes')
dut.run_all_single_board_cases(group='aes-gcm')
@@ -72,8 +80,10 @@ def test_esp_tee_crypto_sha(dut: IdfDut) -> None:
CONFIG_ALL,
indirect=['config', 'target'],
)
@pytest.mark.skipif(targets=['esp32c61'], reason='Not supported')
def test_esp_tee_aes_perf(dut: IdfDut) -> None:
if dut.target == 'esp32c61':
pytest.skip(f'AES not supported on {dut.target}')
for i in range(10):
dut.run_all_single_board_cases(name=['mbedtls AES performance'])
@@ -121,6 +131,13 @@ def test_esp_tee_isolation_checks(dut: IdfDut) -> None:
for test_name, expected in cfg.items():
run_exception_case(dut, 'Test REE-TEE isolation', test_name, expected, check_origin=True)
# ESP32-C61: MMU-spillover gracefully reboots instead of panicking
if dut.target == 'esp32c61':
dut.skip_decode_panic = True
dut.expect_exact('Press ENTER to see the list of tests')
dut.write('"Test REE-TEE isolation: MMU-spillover"')
dut.expect_exact('Failed MMU operation, rebooting!', timeout=10)
@idf_parametrize(
'config, target, markers',
@@ -238,8 +255,6 @@ def run_flash_access_test(dut: IdfDut, api: TeeFlashAccessApi, test_name: str) -
# Panics are expected during these tests
dut.skip_decode_panic = True
dut.serial.custom_flash()
extra_data = dut._parse_test_menu()
test_case = next((tc for tc in extra_data if tc.name == test_name), None)
@@ -250,9 +265,9 @@ def run_flash_access_test(dut: IdfDut, api: TeeFlashAccessApi, test_name: str) -
@idf_parametrize(
'config, target, skip_autoflash, markers',
'config, target, markers',
CONFIG_OTA,
indirect=['config', 'target', 'skip_autoflash'],
indirect=['config', 'target'],
)
def test_esp_tee_flash_prot_esp_partition_mmap(dut: IdfDut) -> None:
run_flash_access_test(
@@ -261,9 +276,9 @@ def test_esp_tee_flash_prot_esp_partition_mmap(dut: IdfDut) -> None:
@idf_parametrize(
'config, target, skip_autoflash, markers',
'config, target, markers',
CONFIG_OTA,
indirect=['config', 'target', 'skip_autoflash'],
indirect=['config', 'target'],
)
def test_esp_tee_flash_prot_spi_flash_mmap(dut: IdfDut) -> None:
run_flash_access_test(
@@ -272,9 +287,9 @@ def test_esp_tee_flash_prot_spi_flash_mmap(dut: IdfDut) -> None:
@idf_parametrize(
'config, target, skip_autoflash, markers',
'config, target, markers',
CONFIG_OTA,
indirect=['config', 'target', 'skip_autoflash'],
indirect=['config', 'target'],
)
def test_esp_tee_flash_prot_esp_rom_spiflash(dut: IdfDut) -> None:
run_flash_access_test(
@@ -283,18 +298,18 @@ def test_esp_tee_flash_prot_esp_rom_spiflash(dut: IdfDut) -> None:
@idf_parametrize(
'config, target, skip_autoflash, markers',
'config, target, markers',
CONFIG_OTA,
indirect=['config', 'target', 'skip_autoflash'],
indirect=['config', 'target'],
)
def test_esp_tee_flash_prot_esp_partition(dut: IdfDut) -> None:
run_flash_access_test(dut, TeeFlashAccessApi.ESP_PARTITION, 'Test REE-TEE isolation: Flash - SPI1 (esp_partition)')
@idf_parametrize(
'config, target, skip_autoflash, markers',
'config, target, markers',
CONFIG_OTA,
indirect=['config', 'target', 'skip_autoflash'],
indirect=['config', 'target'],
)
def test_esp_tee_flash_prot_esp_flash(dut: IdfDut) -> None:
run_flash_access_test(dut, TeeFlashAccessApi.ESP_FLASH, 'Test REE-TEE isolation: Flash - SPI1 (esp_flash)')
@@ -303,9 +318,11 @@ def test_esp_tee_flash_prot_esp_flash(dut: IdfDut) -> None:
# ---------------- TEE Local OTA tests ----------------
@pytest.mark.generic
@idf_parametrize('config', ['tee_ota'], indirect=['config'])
@idf_parametrize('target', TESTING_TARGETS, indirect=['target'])
@idf_parametrize(
'config, target, markers',
CONFIG_OTA,
indirect=['config', 'target'],
)
def test_esp_tee_ota_negative(dut: IdfDut) -> None:
# start test
dut.run_all_single_board_cases(group='ota_neg_1', timeout=10)
@@ -313,7 +330,7 @@ def test_esp_tee_ota_negative(dut: IdfDut) -> None:
@idf_parametrize(
'config, target, skip_autoflash, markers',
CONFIG_OTA,
CONFIG_OTA_NO_AUTOFLASH,
indirect=['config', 'target', 'skip_autoflash'],
)
def test_esp_tee_ota_corrupted_img(dut: IdfDut) -> None:
@@ -347,7 +364,7 @@ def tee_ota_stage_checks(dut: IdfDut, stage: TeeOtaStage, offset: str) -> None:
@idf_parametrize(
'config, target, skip_autoflash, markers',
CONFIG_OTA,
CONFIG_OTA_NO_AUTOFLASH,
indirect=['config', 'target', 'skip_autoflash'],
)
def test_esp_tee_ota_reboot_without_ota_end(dut: IdfDut) -> None:
@@ -370,7 +387,7 @@ def test_esp_tee_ota_reboot_without_ota_end(dut: IdfDut) -> None:
@idf_parametrize(
'config, target, skip_autoflash, markers',
CONFIG_OTA,
CONFIG_OTA_NO_AUTOFLASH,
indirect=['config', 'target', 'skip_autoflash'],
)
def test_esp_tee_ota_valid_img(dut: IdfDut) -> None:
@@ -401,7 +418,7 @@ def test_esp_tee_ota_valid_img(dut: IdfDut) -> None:
@idf_parametrize(
'config, target, skip_autoflash, markers',
CONFIG_OTA,
CONFIG_OTA_NO_AUTOFLASH,
indirect=['config', 'target', 'skip_autoflash'],
)
def test_esp_tee_ota_rollback(dut: IdfDut) -> None:
@@ -440,7 +457,7 @@ def test_esp_tee_ota_rollback(dut: IdfDut) -> None:
@idf_parametrize(
'config, target, skip_autoflash, markers',
CONFIG_OTA,
CONFIG_OTA_NO_AUTOFLASH,
indirect=['config', 'target', 'skip_autoflash'],
)
def test_esp_tee_secure_storage(dut: IdfDut) -> None:
@@ -452,22 +469,43 @@ def test_esp_tee_secure_storage(dut: IdfDut) -> None:
@idf_parametrize(
'config, target, skip_autoflash, markers',
CONFIG_OTA,
CONFIG_OTA_NO_AUTOFLASH,
indirect=['config', 'target', 'skip_autoflash'],
)
def test_esp_tee_secure_storage_with_host_img(dut: IdfDut) -> None:
# Flash image and write the secure_storage partition with host-generated keys
# NOTE: In release mode (CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE), the test
# expects the eFuse-burned HMAC key used for TEE secure storage to be available
# at the path "test_keys/tee_sec_stg_hmac_key.bin"
dut.serial.custom_flash_with_host_gen_sec_stg_img()
dut.run_all_single_board_cases(group='sec_storage_host_keygen')
@idf_parametrize(
'config, target, skip_autoflash, markers',
CONFIG_OTA_NO_AUTOFLASH,
indirect=['config', 'target', 'skip_autoflash'],
)
def test_esp_tee_secure_storage_encryption(dut: IdfDut) -> None:
dut.serial.custom_flash_with_empty_sec_stg()
# NOTE: In release mode (CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE), the test
# expects the eFuse-burned HMAC key used for TEE secure storage to be available
# at the path "test_keys/tee_sec_stg_hmac_key.bin"
dut.expect_exact('Press ENTER to see the list of tests')
dut.write('"Test TEE Secure Storage - Verify data encryption"')
dut.serial.verify_tee_sec_stg_encryption(dut)
# ---------------- TEE Attestation tests ----------------
@idf_parametrize(
'config, target, skip_autoflash, markers',
CONFIG_OTA,
CONFIG_OTA_NO_AUTOFLASH,
indirect=['config', 'target', 'skip_autoflash'],
)
def test_esp_tee_attestation(dut: IdfDut) -> None:
@@ -15,3 +15,6 @@ CONFIG_PARTITION_TABLE_OFFSET=0xF000
# Increasing TEE I/DRAM size
CONFIG_SECURE_TEE_IRAM_SIZE=0x8800
CONFIG_SECURE_TEE_DRAM_SIZE=0x5800
# Takes effect only when Secure boot is enabled
CONFIG_SECURE_BOOT_FLASH_BOOTLOADER_DEFAULT=y
@@ -78,6 +78,12 @@ _TARGET_OVERRIDES: dict[str, dict[str, Any]] = {
},
},
'esp32c61': {
# NOTE: On ESP32-C61, MMU-spillover does not raise a CPU panic — the TEE
# test fills the bad mapping with a poison pattern and calls esp_restart().
# Verified separately in the pytest, so drop it from the panic-driven map.
'ree_isolation': {
'_remove': ['MMU-spillover'],
},
# NOTE: ESP32-C61 does not support the following peripherals
'apm_violation': {
'_remove': ['AES', 'HMAC', 'DS'],
@@ -83,31 +83,29 @@ if(CONFIG_SOC_AES_SUPPORTED)
"${COMPONENT_DIR}/port/aes/esp_aes_common.c"
"${COMPONENT_DIR}/port/aes/esp_aes_xts.c")
target_include_directories(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/include/aes")
if(CONFIG_MBEDTLS_HARDWARE_AES)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c"
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c"
)
endif()
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c"
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c"
)
endif()
# SHA implementation
if(CONFIG_SOC_SHA_SUPPORTED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c"
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c"
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c"
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c"
"${COMPONENT_DIR}/port/sha/core/sha.c"
"${COMPONENT_DIR}/port/sha/esp_sha.c"
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c"
)
endif()
if(CONFIG_MBEDTLS_ROM_MD5)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_md/psa_crypto_driver_esp_md5.c"
)
if(CONFIG_MBEDTLS_SHA1_C)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c"
)
endif()
if(CONFIG_SOC_SHA_SUPPORT_SHA512 AND CONFIG_MBEDTLS_SHA512_C)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c"
)
endif()
endif()
if(CONFIG_SOC_ECC_SUPPORTED)
@@ -120,6 +118,9 @@ if(CONFIG_SOC_HMAC_SUPPORTED)
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c")
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c")
target_link_libraries(tfpsacrypto PRIVATE idf::efuse)
else()
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c")
endif()
# PSA Attestation
@@ -40,7 +40,7 @@
#undef MBEDTLS_TIMING_C
#define MBEDTLS_PLATFORM_C
#if CONFIG_MBEDTLS_HARDWARE_AES
#if SOC_AES_SUPPORTED
#define ESP_AES_DRIVER_ENABLED
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_AES
#endif
@@ -59,29 +59,41 @@
#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
#else
#undef PSA_WANT_ALG_DETERMINISTIC_ECDSA
#undef MBEDTLS_HMAC_DRBG_C
#endif
#if CONFIG_MBEDTLS_SHA1_C
#define MBEDTLS_SHA1_C
#endif
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#if SOC_SHA_SUPPORTED
#define ESP_SHA_DRIVER_ENABLED
#define ESP_HMAC_TRANSPARENT_DRIVER_ENABLED
#undef MBEDTLS_PSA_BUILTIN_ALG_HMAC
#if CONFIG_MBEDTLS_SHA1_C
#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_1
#undef MBEDTLS_SHA1_C
#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_1
#undef MBEDTLS_SHA1_C
#else
#undef PSA_WANT_ALG_SHA_1
#endif
#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_224
#undef MBEDTLS_SHA224_C
#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_256
#define MBEDTLS_PSA_ACCEL_ALG_SHA_256
#undef MBEDTLS_SHA256_C
#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C
#define MBEDTLS_PSA_ACCEL_ALG_SHA_384
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_384
#define MBEDTLS_PSA_ACCEL_ALG_SHA_512
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_512
#undef MBEDTLS_SHA384_C
#undef MBEDTLS_SHA512_C
#else
#undef PSA_WANT_ALG_SHA_384
#undef PSA_WANT_ALG_SHA_512
#undef MBEDTLS_SHA512_ALT
#endif
#if !SOC_HMAC_SUPPORTED
#define ESP_HMAC_TRANSPARENT_DRIVER_ENABLED
#define MBEDTLS_PSA_ACCEL_ALG_HMAC
#undef MBEDTLS_PSA_BUILTIN_ALG_HMAC
#endif
#endif
#if SOC_ECC_SUPPORTED
@@ -91,17 +103,6 @@
#if SOC_HMAC_SUPPORTED
#define ESP_HMAC_OPAQUE_DRIVER_ENABLED
#else
#undef MBEDTLS_PSA_ACCEL_KEY_TYPE_HMAC
#endif
#if CONFIG_MBEDTLS_ROM_MD5
#define ESP_MD5_DRIVER_ENABLED
#define MBEDTLS_PSA_ACCEL_ALG_MD5
#undef MBEDTLS_PSA_BUILTIN_ALG_MD5
#else
#undef PSA_WANT_ALG_MD5
#undef MBEDTLS_MD5_C
#endif
#undef PSA_WANT_ECC_SECP_R1_192
@@ -122,21 +123,23 @@
#undef PSA_WANT_KEY_TYPE_DES
#undef PSA_WANT_ALG_RIPEMD160
#undef PSA_WANT_ALG_CHACHA20
#undef MBEDTLS_CHACHA20_C
#undef PSA_WANT_ALG_CHACHA20_POLY1305
#undef MBEDTLS_CHACHAPOLY_C
#undef PSA_WANT_ALG_CCM
#undef PSA_WANT_ALG_CMAC
#define MBEDTLS_AES_ROM_TABLES
#if SOC_AES_SUPPORTED
#define MBEDTLS_AES_FEWER_TABLES
#endif
/* Disable unused hash algorithms */
#undef PSA_WANT_ALG_MD5
#undef MBEDTLS_MD5_C
#undef PSA_WANT_ALG_SHA3_224
#undef MBEDTLS_SHA3_224_C
#undef PSA_WANT_ALG_SHA3_256
#undef MBEDTLS_SHA3_256_C
#undef PSA_WANT_ALG_SHA3_384
#undef MBEDTLS_SHA3_384_C
#undef PSA_WANT_ALG_SHA3_512
#undef MBEDTLS_SHA3_512_C
/* Disable RSA — not used by TEE */
#undef PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
@@ -164,11 +167,9 @@
#undef MBEDTLS_SSL_CLI_C
#undef MBEDTLS_SSL_SRV_C
#undef PSA_WANT_ALG_PBKDF2_HMAC
#undef PSA_WANT_ALG_TLS12_PRF
#undef PSA_WANT_ALG_PBKDF2_HMAC
#undef PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128
#undef PSA_WANT_ALG_CCM
#undef PSA_WANT_ALG_CMAC
#undef MBEDTLS_AES_C
#define MBEDTLS_AES_ROM_TABLES
@@ -244,6 +244,7 @@ static int esp_aes_process_dma_ext_ram(esp_aes_context *ctx, const unsigned char
unsigned char *output_buf = NULL;
const unsigned char *dma_input;
chunk_len = MIN(AES_MAX_CHUNK_WRITE_SIZE, len);
const size_t alloc_chunk_len = chunk_len;
size_t input_alignment = 1;
size_t output_alignment = 1;
@@ -313,10 +314,12 @@ static int esp_aes_process_dma_ext_ram(esp_aes_context *ctx, const unsigned char
cleanup:
if (realloc_input) {
if (realloc_input && input_buf) {
mbedtls_platform_zeroize(input_buf, alloc_chunk_len);
free(input_buf);
}
if (realloc_output) {
if (realloc_output && output_buf) {
mbedtls_platform_zeroize(output_buf, alloc_chunk_len);
free(output_buf);
}
@@ -459,7 +462,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le
dma_descriptors = (crypto_dma_desc_t *) aes_dma_calloc(dma_descs_needed, sizeof(crypto_dma_desc_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL, NULL);
if (dma_descriptors == NULL) {
ESP_LOGE(TAG, "Failed to allocate memory for the array of DMA descriptors");
return ESP_FAIL;
goto err;
}
size_t populated_dma_descs = 0;
@@ -468,7 +471,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le
start_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS | (esp_ptr_external_ram(buffer) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_INTERNAL) , NULL);
if (start_alignment_stream_buffer == NULL) {
ESP_LOGE(TAG, "Failed to allocate memory for start alignment buffer");
return ESP_FAIL;
goto err;
}
memset(start_alignment_stream_buffer, 0, unaligned_start_bytes);
@@ -490,7 +493,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le
end_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS | (esp_ptr_external_ram(buffer) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_INTERNAL), NULL);
if (end_alignment_stream_buffer == NULL) {
ESP_LOGE(TAG, "Failed to allocate memory for end alignment buffer");
return ESP_FAIL;
goto err;
}
memset(end_alignment_stream_buffer, 0, unaligned_end_bytes);
@@ -504,7 +507,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le
if (dma_desc_link(dma_descriptors, dma_descs_needed, cache_line_size) != ESP_OK) {
ESP_LOGE(TAG, "DMA descriptors cache sync C2M failed");
return ESP_FAIL;
goto err;
}
ret:
@@ -525,6 +528,18 @@ ret:
*end_alignment_buffer = end_alignment_stream_buffer;
return ESP_OK;
err:
if (start_alignment_stream_buffer) {
mbedtls_platform_zeroize(start_alignment_stream_buffer, alignment_buffer_size);
free(start_alignment_stream_buffer);
}
if (end_alignment_stream_buffer) {
mbedtls_platform_zeroize(end_alignment_stream_buffer, alignment_buffer_size);
free(end_alignment_stream_buffer);
}
free(dma_descriptors);
return ESP_FAIL;
}
int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsigned char *output, size_t len, uint8_t *stream_out)
@@ -589,19 +604,12 @@ int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsign
}
size_t input_alignment_buffer_size = MAX(2 * input_cache_line_size, AES_BLOCK_BYTES);
size_t output_alignment_buffer_size = MAX(2 * output_cache_line_size, AES_BLOCK_BYTES);
crypto_dma_desc_t *input_desc = NULL;
uint8_t *input_start_stream_buffer = NULL;
uint8_t *input_end_stream_buffer = NULL;
if (generate_descriptor_list(input, len, &input_start_stream_buffer, &input_end_stream_buffer, input_alignment_buffer_size, input_cache_line_size, NULL, NULL, &input_desc, NULL, false) != ESP_OK) {
mbedtls_platform_zeroize(output, len);
ESP_LOGE(TAG, "Generating input DMA descriptors failed");
return -1;
}
size_t output_alignment_buffer_size = MAX(2 * output_cache_line_size, AES_BLOCK_BYTES);
crypto_dma_desc_t *output_desc = NULL;
uint8_t *output_start_stream_buffer = NULL;
uint8_t *output_end_stream_buffer = NULL;
@@ -609,10 +617,16 @@ int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsign
size_t output_end_alignment = 0;
size_t output_dma_desc_num = 0;
if (generate_descriptor_list(input, len, &input_start_stream_buffer, &input_end_stream_buffer, input_alignment_buffer_size, input_cache_line_size, NULL, NULL, &input_desc, NULL, false) != ESP_OK) {
ESP_LOGE(TAG, "Generating input DMA descriptors failed");
ret = -1;
goto cleanup;
}
if (generate_descriptor_list(output, len, &output_start_stream_buffer, &output_end_stream_buffer, output_alignment_buffer_size, output_cache_line_size, &output_start_alignment, &output_end_alignment, &output_desc, &output_dma_desc_num, true) != ESP_OK) {
mbedtls_platform_zeroize(output, len);
ESP_LOGE(TAG, "Generating output DMA descriptors failed");
return -1;
ret = -1;
goto cleanup;
}
crypto_dma_desc_t *out_desc_tail = &output_desc[output_dma_desc_num - 1];
@@ -705,11 +719,23 @@ cleanup:
mbedtls_platform_zeroize(output, len);
}
free(input_start_stream_buffer);
free(input_end_stream_buffer);
if (input_start_stream_buffer) {
mbedtls_platform_zeroize(input_start_stream_buffer, input_alignment_buffer_size);
free(input_start_stream_buffer);
}
if (input_end_stream_buffer) {
mbedtls_platform_zeroize(input_end_stream_buffer, input_alignment_buffer_size);
free(input_end_stream_buffer);
}
free(output_start_stream_buffer);
free(output_end_stream_buffer);
if (output_start_stream_buffer) {
mbedtls_platform_zeroize(output_start_stream_buffer, output_alignment_buffer_size);
free(output_start_stream_buffer);
}
if (output_end_stream_buffer) {
mbedtls_platform_zeroize(output_end_stream_buffer, output_alignment_buffer_size);
free(output_end_stream_buffer);
}
free(input_desc);
free(output_desc);
@@ -918,12 +944,24 @@ cleanup:
free(aad_end_stream_buffer);
free(aad_desc);
free(input_start_stream_buffer);
free(input_end_stream_buffer);
if (input_start_stream_buffer) {
mbedtls_platform_zeroize(input_start_stream_buffer, input_alignment_buffer_size);
free(input_start_stream_buffer);
}
if (input_end_stream_buffer) {
mbedtls_platform_zeroize(input_end_stream_buffer, input_alignment_buffer_size);
free(input_end_stream_buffer);
}
free(input_desc);
free(output_start_stream_buffer);
free(output_end_stream_buffer);
if (output_start_stream_buffer) {
mbedtls_platform_zeroize(output_start_stream_buffer, output_alignment_buffer_size);
free(output_start_stream_buffer);
}
if (output_end_stream_buffer) {
mbedtls_platform_zeroize(output_end_stream_buffer, output_alignment_buffer_size);
free(output_end_stream_buffer);
}
free(output_desc);
free(len_buf);
@@ -50,6 +50,7 @@ static psa_status_t esp_crypto_aes_gcm_setup(
status = mbedtls_to_psa_error(esp_aes_gcm_setkey(ctx, 2, key_buffer, key_buffer_size * 8));
if (status != PSA_SUCCESS) {
esp_aes_gcm_free(ctx);
free(ctx);
goto exit;
}
@@ -17,12 +17,12 @@ psa_status_t esp_hmac_abort_transparent(esp_hmac_transparent_operation_t *esp_hm
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(esp_hmac_ctx->alg);
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_abort(&esp_hmac_ctx->md5_ctx);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
status = esp_sha_hash_abort(&esp_hmac_ctx->esp_sha_ctx);
}
@@ -69,9 +69,9 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
memset(esp_hmac_ctx->opad, 0, PSA_HMAC_MAX_HASH_BLOCK_SIZE);
if (
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
hash_alg != PSA_ALG_MD5 &&
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
(hash_alg < PSA_ALG_SHA_1
#if SOC_SHA_SUPPORT_SHA512
|| hash_alg > PSA_ALG_SHA_512
@@ -96,12 +96,12 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
}
if (key_buffer_size > block_size) {
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_compute(hash_alg, key_buffer, key_buffer_size,
ipad, sizeof(ipad), &key_buffer_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
status = esp_sha_hash_compute(hash_alg, key_buffer, key_buffer_size,
ipad, sizeof(ipad), &key_buffer_size);
@@ -164,11 +164,11 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
memset(esp_hmac_ctx->opad + key_buffer_size, 0x5C, fill_size);
}
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_setup(&esp_hmac_ctx->md5_ctx, hash_alg);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg);
}
@@ -176,11 +176,11 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
goto error;
}
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_update(&esp_hmac_ctx->md5_ctx, ipad, block_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, ipad, block_size);
}
@@ -202,12 +202,12 @@ psa_status_t esp_hmac_update_transparent(esp_hmac_transparent_operation_t *esp_h
return PSA_ERROR_INVALID_ARGUMENT;
}
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(esp_hmac_ctx->alg);
if (hash_alg == PSA_ALG_MD5) {
return esp_md5_hash_update(&esp_hmac_ctx->md5_ctx, data, data_length);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
return esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, data, data_length);
}
@@ -231,11 +231,11 @@ psa_status_t esp_hmac_finish_transparent(
size_t hash_size = 0;
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_finish(&esp_hmac_ctx->md5_ctx, tmp, sizeof(tmp), &hash_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
status = esp_sha_hash_finish(&esp_hmac_ctx->esp_sha_ctx, tmp, sizeof(tmp), &hash_size);
}
@@ -244,11 +244,11 @@ psa_status_t esp_hmac_finish_transparent(
}
/* From here on, tmp needs to be wiped. */
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_setup(&esp_hmac_ctx->md5_ctx, hash_alg);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg);
}
@@ -256,11 +256,11 @@ psa_status_t esp_hmac_finish_transparent(
goto exit;
}
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_update(&esp_hmac_ctx->md5_ctx, esp_hmac_ctx->opad, block_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, esp_hmac_ctx->opad, block_size);
}
@@ -268,11 +268,11 @@ psa_status_t esp_hmac_finish_transparent(
goto exit;
}
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_update(&esp_hmac_ctx->md5_ctx, tmp, hash_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, tmp, hash_size);
}
@@ -280,11 +280,11 @@ psa_status_t esp_hmac_finish_transparent(
goto exit;
}
#if CONFIG_MBEDTLS_ROM_MD5
#if defined(ESP_MD5_DRIVER_ENABLED)
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_finish(&esp_hmac_ctx->md5_ctx, tmp, sizeof(tmp), &hash_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
#endif // defined(ESP_MD5_DRIVER_ENABLED)
{
status = esp_sha_hash_finish(&esp_hmac_ctx->esp_sha_ctx, tmp, sizeof(tmp), &hash_size);
}
@@ -19,6 +19,8 @@
#include "esp_assert.h"
#include "soc/soc_caps.h"
#include "mbedtls/platform_util.h"
#if SOC_KEY_MANAGER_SUPPORTED
#include "esp_key_mgr.h"
#endif /* SOC_KEY_MANAGER_SUPPORTED */
@@ -500,6 +502,7 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_start(
error:
if (em) {
mbedtls_platform_zeroize(em, rsa_len_bytes);
heap_caps_free(em);
em = NULL;
}
@@ -830,6 +833,7 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
err = esp_key_mgr_activate_key(km_ri);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to activate key: 0x%x", err);
mbedtls_platform_zeroize(em_words, sizeof(uint32_t) * data_len);
heap_caps_free(em_words);
esp_rsa_ds_release_ds_lock();
return PSA_ERROR_INVALID_HANDLE;
@@ -844,6 +848,7 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
hmac_key_id,
&ds_ctx);
if (err != ESP_OK) {
mbedtls_platform_zeroize(em_words, sizeof(uint32_t) * data_len);
heap_caps_free(em_words);
#if SOC_KEY_MANAGER_SUPPORTED
if (is_km_key_active) {
@@ -863,6 +868,7 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
#endif /* SOC_KEY_MANAGER_SUPPORTED */
if (err != ESP_OK) {
mbedtls_platform_zeroize(em_words, sizeof(uint32_t) * data_len);
heap_caps_free(em_words);
esp_rsa_ds_release_ds_lock();
return PSA_ERROR_GENERIC_ERROR;
@@ -12,6 +12,7 @@
#include "include/psa_crypto_driver_esp_sha512.h"
#include "psa/crypto.h"
#include "psa/crypto_sizes.h"
#include "mbedtls/platform_util.h"
#include "esp_log.h"
#include "esp_heap_caps.h"
@@ -229,6 +230,7 @@ psa_status_t esp_sha_hash_finish(
if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) {
esp_sha1_context *ctx = (esp_sha1_context *)operation->sha_ctx;
int ret = esp_sha1_driver_finish(ctx, hash, hash_size, hash_length);
mbedtls_platform_zeroize(ctx, sizeof(esp_sha1_context));
free(ctx); // Free the context after use
operation->sha_ctx = NULL;
return ret;
@@ -239,6 +241,7 @@ psa_status_t esp_sha_hash_finish(
operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA224) {
esp_sha256_context *ctx = (esp_sha256_context *)operation->sha_ctx;
int ret = esp_sha256_driver_finish(ctx, hash, hash_size, hash_length, operation->sha_type);
mbedtls_platform_zeroize(ctx, sizeof(esp_sha256_context));
free(ctx); // Free the context after use
operation->sha_ctx = NULL;
return ret;
@@ -249,6 +252,7 @@ psa_status_t esp_sha_hash_finish(
operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA512) {
esp_sha512_context *ctx = (esp_sha512_context *)operation->sha_ctx;
int ret = esp_sha512_driver_finish(ctx, hash, hash_size, hash_length, operation->sha_type);
mbedtls_platform_zeroize(ctx, sizeof(esp_sha512_context));
free(ctx); // Free the context after use
operation->sha_ctx = NULL;
return ret;
+13 -1
View File
@@ -27,6 +27,7 @@
#include "esp_crypto_dma.h"
#include "esp_heap_caps.h"
#include "hal/dma_types.h"
#include "mbedtls/platform_util.h"
#include "soc/ext_mem_defs.h"
#include "soc/periph_defs.h"
@@ -186,6 +187,10 @@ static esp_err_t esp_sha_dma_process_ext(esp_sha_type sha_type, const void *inpu
buf_copy = heap_caps_aligned_alloc(SOC_GDMA_EXT_MEM_ENC_ALIGNMENT, buf_len, heap_caps);
if (buf_copy == NULL) {
ESP_LOGE(TAG, "Failed to allocate aligned internal memory");
if (input_copy) {
mbedtls_platform_zeroize(input_copy, ilen);
free(input_copy);
}
return ret;
}
memcpy(buf_copy, buf, buf_len);
@@ -197,10 +202,12 @@ static esp_err_t esp_sha_dma_process_ext(esp_sha_type sha_type, const void *inpu
ret = esp_sha_dma_process(sha_type, dma_input, ilen, dma_buf, buf_len, is_first_block);
if (realloc_input) {
mbedtls_platform_zeroize(input_copy, ilen);
free(input_copy);
}
if (realloc_buf) {
mbedtls_platform_zeroize(buf_copy, buf_len);
free(buf_copy);
}
@@ -318,6 +325,7 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
{
int ret = 0;
unsigned char *dma_cap_buf = NULL;
uint32_t dma_cap_buf_len = 0;
if (buf_len > block_length(sha_type)) {
ESP_LOGE(TAG, "SHA DMA buf_len cannot exceed max size for a single block");
@@ -339,6 +347,7 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
goto cleanup;
}
memcpy(dma_cap_buf, buf, buf_len);
dma_cap_buf_len = buf_len;
buf = dma_cap_buf;
}
@@ -375,7 +384,10 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
}
cleanup:
free(dma_cap_buf);
if (dma_cap_buf) {
mbedtls_platform_zeroize(dma_cap_buf, dma_cap_buf_len);
free(dma_cap_buf);
}
return ret;
}
#endif /* SOC_SHA_SUPPORT_DMA */
+12 -1
View File
@@ -107,6 +107,12 @@ EAT: Claim Table
* - Client ID
- Relying Party identification
-
* - Chip ID
- SoC chip identifier
-
* - UEID
- Universal Entity Identifiers, factory-burnt in eFuse
- Device MAC address and the Optional Unique ID from eFuse
* - Device ID
- Device identification (should be unique)
- SHA256 digest of the device MAC address
@@ -176,9 +182,14 @@ Sample EAT in JSON format
"key_id": "tee_att_key0"
},
"eat": {
"auth_challenge":"dcb9b53143ad6b081dad1a05c7ebda4e314d388762215799cf24ed52e9387678"
"auth_challenge":"dcb9b53143ad6b081dad1a05c7ebda4e314d388762215799cf24ed52e9387678",
"client_id": 262974944,
"chip_id": 13,
"device_ver": 1,
"ueid": {
"mac": "d885ac67c978",
"optional_id": "94fa4d7e305682714d48e7bbd710c961"
},
"device_id": "e8cddb2a7f9a5a7c61735d6dda26e4bd153c6d772a9be6f26bd321dfe25e0ac8",
"instance_id": "1adba85e0df997fd961f25a9e312430cef162b5c69466cd5b172f1e65ac7360c",
"psa_cert_ref": "0716053550477-10100",
-4
View File
@@ -60,7 +60,6 @@ examples/security/tee/tee_attestation:
disable:
- if: IDF_TARGET not in ["esp32c6", "esp32c61"]
depends_components:
- *common_components
- esp_tee
depends_filepatterns:
- examples/security/tee/tee_attestation/**/*
@@ -69,7 +68,6 @@ examples/security/tee/tee_basic:
disable:
- if: IDF_TARGET not in ["esp32c6", "esp32c61"]
depends_components:
- *common_components
- esp_tee
depends_filepatterns:
- examples/security/tee/tee_basic/**/*
@@ -78,7 +76,6 @@ examples/security/tee/tee_secure_ota:
disable:
- if: IDF_TARGET not in ["esp32c6", "esp32c61"]
depends_components:
- *common_components
- esp_tee
- protocol_examples_common
depends_filepatterns:
@@ -88,7 +85,6 @@ examples/security/tee/tee_secure_storage:
disable:
- if: IDF_TARGET not in ["esp32c6", "esp32c61"]
depends_components:
- *common_components
- esp_tee
depends_filepatterns:
- examples/security/tee/tee_secure_storage/**/*
@@ -28,7 +28,12 @@
"eat": {
"auth_challenge": "dcb9b53143ad6b081dad1a05c7ebda4e314d388762215799cf24ed52e9387678",
"client_id": 262974944,
"chip_id": 13,
"device_ver": 1,
"ueid": {
"mac": "d885ac67c978",
"optional_id": "94fa4d7e305682714d48e7bbd710c961"
},
"device_id": "e8cddb2a7f9a5a7c61735d6dda26e4bd153c6d772a9be6f26bd321dfe25e0ac8",
"instance_id": "1adba85e0df997fd961f25a9e312430cef162b5c69466cd5b172f1e65ac7360c",
"psa_cert_ref": "0716053550477-10100",
@@ -127,9 +132,9 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
```log
I (438) example_tee_attest: TEE Attestation Service
I (1008) example_tee_attest: Attestation token - Length: 1538
I (1008) example_tee_attest: Attestation token - Length: 1705
I (1018) example_tee_attest: Attestation token - Data:
'{"header":{"magic":"44fef7cc","encr_alg":"","sign_alg":"ecdsa_secp256r1_sha256","key_id":"tee_att_key0"},"eat":{"nonce":-1582119980,"client_id":262974944,"device_ver":1,"device_id":"4ecc458ef4290329552b4dcdccb99d55e5ea7624f24c87b27b71515e1666f39c","instance_id":"66571b78918f4bb7ae2723f235a9e4fe1c7070ae6261ce5df7049b44b1f8a318","psa_cert_ref":"0716053550477-10100","device_status":165,"sw_claims":{"tee":{"type":1,"ver":"1.0.0","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"5213904fd8ca7538776bdf372c08c13138f20b2fac3503bc878f19c6e36a710d","digest_validated":true,"sign_verified":false,"secure_padding":false}},"app":{"type":2,"ver":"v0.1.0","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"65c905fc0fc135fdfa8def210d1c186627cb3a17ecb2e7f020b56411b2d2fc76","digest_validated":true,"sign_verified":false,"secure_padding":false}},"bootloader":{"type":0,"ver":"01000000","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"9efd37d29266f3239f7c6a095df880f1e85e41505f154cfd3bbfad4b8a2b18dd","digest_validated":true,"sign_verified":false}}}},"public_key":{"compressed":"02ce0188c61b0118c86ca20af7e01185dd687c6698b2265a288fee845d083e9066"},"sign":{"r":"362e2053bab26c779559793b2eae89e96c1a058e5fffc49d544d07b934ce3b32","s":"fc5f0e4d329fc6e031cbf425ef62d4756b728392b2a77282baa1f15b554d2716"}}'
'{"header":{"magic":"44fef7cc","encr_alg":"","sign_alg":"ecdsa_secp256r1_sha256","key_id":"tee_att_key0"},"eat":{"nonce":-1582119980,"client_id":262974944,"chip_id":13,"device_ver":1,"ueid":{"mac":"d885ac67c978","optional_id":"94fa4d7e305682714d48e7bbd710c961"},"device_id":"4ecc458ef4290329552b4dcdccb99d55e5ea7624f24c87b27b71515e1666f39c","instance_id":"66571b78918f4bb7ae2723f235a9e4fe1c7070ae6261ce5df7049b44b1f8a318","psa_cert_ref":"0716053550477-10100","device_status":165,"sw_claims":{"tee":{"type":1,"ver":"1.0.0","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"5213904fd8ca7538776bdf372c08c13138f20b2fac3503bc878f19c6e36a710d","digest_validated":true,"sign_verified":false,"secure_padding":false}},"app":{"type":2,"ver":"v0.1.0","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"65c905fc0fc135fdfa8def210d1c186627cb3a17ecb2e7f020b56411b2d2fc76","digest_validated":true,"sign_verified":false,"secure_padding":false}},"bootloader":{"type":0,"ver":"01000000","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"9efd37d29266f3239f7c6a095df880f1e85e41505f154cfd3bbfad4b8a2b18dd","digest_validated":true,"sign_verified":false}}}},"public_key":{"compressed":"02ce0188c61b0118c86ca20af7e01185dd687c6698b2265a288fee845d083e9066"},"sign":{"r":"362e2053bab26c779559793b2eae89e96c1a058e5fffc49d544d07b934ce3b32","s":"fc5f0e4d329fc6e031cbf425ef62d4756b728392b2a77282baa1f15b554d2716"}}'
I (1148) main_task: Returned from app_main()
```
+2
View File
@@ -155,6 +155,8 @@ components_not_formatted_permanent:
- /components/esp_system/openocd_stub_bins/*.inc
- /components/esp_system/openocd_stub_bins/esp32c6/*.inc
- /components/esp_system/openocd_stub_bins/esp32h2/*.inc
# TEE ASM helper macros — .inc file, not C include files
- /components/esp_tee/subproject/main/arch/riscv/*.inc
docs:
# Docs directory contains some .inc files, which are not C include files