mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-28 16:46:31 +03:00
feat(esp_tee): Clear out all sensitive buffers explicitly after TEE crypto operations
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user