diff --git a/components/esp_tee/subproject/components/attestation/esp_attestation.c b/components/esp_tee/subproject/components/attestation/esp_attestation.c index 6fe31813097..4f25ec5f614 100644 --- a/components/esp_tee/subproject/components/attestation/esp_attestation.c +++ b/components/esp_tee/subproject/components/attestation/esp_attestation.c @@ -183,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!"); @@ -206,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; @@ -218,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; } diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c index f0f3742bf48..d9bf42a9d0e 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c @@ -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; diff --git a/components/esp_tee/subproject/main/arch/riscv/esp_tee_asm_utils.inc b/components/esp_tee/subproject/main/arch/riscv/esp_tee_asm_utils.inc new file mode 100644 index 00000000000..6478f02e13a --- /dev/null +++ b/components/esp_tee/subproject/main/arch/riscv/esp_tee_asm_utils.inc @@ -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 diff --git a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_clic.S b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_clic.S index 79d1135cb1e..bf64ea045d5 100644 --- a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_clic.S +++ b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_clic.S @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,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 diff --git a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_plic.S b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_plic.S index 2684e6afc40..1274e5df3d6 100644 --- a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_plic.S +++ b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_plic.S @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,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 diff --git a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c index ac120a33630..544bb3a4e58 100644 --- a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c +++ b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c @@ -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); diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c index 59e3b9cb665..028c5a72e60 100644 --- a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c @@ -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; } diff --git a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c index 476cd5241c6..41706890aeb 100644 --- a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c @@ -215,6 +215,7 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_start( error: if (em) { + memset(em, 0, rsa_len_bytes); heap_caps_free(em); em = NULL; } @@ -471,6 +472,7 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt( err = esp_key_mgr_activate_key(km_key_recovery_info); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to activate key: 0x%x", err); + memset(em_words, 0, sizeof(uint32_t) * data_len); heap_caps_free(em_words); esp_rsa_ds_release_ds_lock(); return PSA_ERROR_INVALID_HANDLE; @@ -485,6 +487,7 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt( hmac_key_id, &operation.esp_rsa_ds_ctx); if (err != ESP_OK) { + memset(em_words, 0, sizeof(uint32_t) * data_len); heap_caps_free(em_words); #if SOC_KEY_MANAGER_SUPPORTED if (km_key_recovery_info && operation.is_km_key_active) { @@ -506,6 +509,7 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt( #endif /* SOC_KEY_MANAGER_SUPPORTED */ if (err != ESP_OK) { + memset(em_words, 0, sizeof(uint32_t) * data_len); heap_caps_free(em_words); esp_rsa_ds_release_ds_lock(); return PSA_ERROR_GENERIC_ERROR; diff --git a/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c index e3d4cf5aba0..8c3feda61d4 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c +++ b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c @@ -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; diff --git a/components/mbedtls/port/sha/core/sha.c b/components/mbedtls/port/sha/core/sha.c index 2e63b155df7..8544ddddb80 100644 --- a/components/mbedtls/port/sha/core/sha.c +++ b/components/mbedtls/port/sha/core/sha.c @@ -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 */ diff --git a/tools/ci/astyle-rules.yml b/tools/ci/astyle-rules.yml index 7282d46a6fd..2f089794fdd 100644 --- a/tools/ci/astyle-rules.yml +++ b/tools/ci/astyle-rules.yml @@ -156,6 +156,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