Merge branch 'fix/esp_mac_drivers_v6.0' into 'release/v6.0'

Enable and separate ESP-MAC driver (v6.0)

See merge request espressif/esp-idf!45577
This commit is contained in:
Jiang Jiang Jian
2026-02-03 01:16:42 +08:00
44 changed files with 2052 additions and 1551 deletions
@@ -5,6 +5,7 @@
*/
#include <string.h>
#include <stdlib.h>
#include "soc/soc_caps.h"
#include "esp_log.h"
@@ -14,9 +15,11 @@
#include "esp_random.h"
#include "spi_flash_mmap.h"
#if SOC_HMAC_SUPPORTED
#include "esp_hmac.h"
#endif
#include "psa_crypto_driver_esp_hmac_opaque.h"
#else
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
#endif
#include "esp_hmac_pbkdf2.h"
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
@@ -135,8 +138,9 @@ static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_c
{
const uint32_t ekey_seed[8] = {[0 ... 7] = EKEY_SEED};
const uint32_t tkey_seed[8] = {[0 ... 7] = TKEY_SEED};
esp_err_t err = ESP_FAIL;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_id_t psa_key_id = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
memset(cfg, 0x00, sizeof(nvs_sec_cfg_t));
#if SOC_HMAC_SUPPORTED
@@ -145,43 +149,82 @@ static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_c
return ESP_ERR_INVALID_ARG;
}
err = esp_hmac_calculate(hmac_key_id, ekey_seed, sizeof(ekey_seed), (uint8_t *)cfg->eky);
err |= esp_hmac_calculate(hmac_key_id, tkey_seed, sizeof(tkey_seed), (uint8_t *)cfg->tky);
if (err != ESP_OK) {
memset(cfg, 0x00, sizeof(nvs_sec_cfg_t));
ESP_LOGE(TAG, "Failed to calculate seed HMAC");
return err;
}
ESP_FAULT_ASSERT(err == ESP_OK);
#else
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
if (md_info == NULL) {
return ESP_FAIL;
}
// Setup key attributes for ESP-HMAC opaque driver
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256));
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
psa_set_key_bits(&attributes, 256);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_HMAC_VOLATILE);
// Create opaque key reference
esp_hmac_opaque_key_t opaque_key = {
.use_km_key = false,
.efuse_block = (uint8_t)key_blk,
};
// Import the opaque key
status = psa_import_key(&attributes, (uint8_t *)&opaque_key,
sizeof(opaque_key), &psa_key_id);
psa_reset_key_attributes(&attributes);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to import HMAC opaque key: %d", status);
return ESP_ERR_INVALID_ARG;
}
#else
uint8_t key_buf[SHA256_DIGEST_SZ] = {0};
/* NOTE: The eFuse key for SoCs without HMAC support should NOT be
* read-protected when burning in the eFuse
*/
err = esp_efuse_read_block(key_blk, key_buf, 0, sizeof(key_buf) * 8);
esp_err_t err = esp_efuse_read_block(key_blk, key_buf, 0, sizeof(key_buf) * 8);
if (err != ESP_OK) {
return err;
}
int ret = mbedtls_md_hmac(md_info, key_buf, sizeof(key_buf),
(const uint8_t *)ekey_seed, sizeof(ekey_seed),
cfg->eky);
ret |= mbedtls_md_hmac(md_info, key_buf, sizeof(key_buf),
(const uint8_t *)tkey_seed, sizeof(tkey_seed),
cfg->tky);
if (ret != 0) {
// Setup PSA key attributes for transparent HMAC driver
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256));
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
psa_set_key_bits(&attributes, 256);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
// Import the HMAC key
status = psa_import_key(&attributes, key_buf, sizeof(key_buf), &psa_key_id);
psa_reset_key_attributes(&attributes);
// Zero out the key buffer after import
memset(key_buf, 0x00, sizeof(key_buf));
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to import HMAC key: %d", status);
return ESP_ERR_INVALID_ARG;
}
#endif
// Compute HMAC for ekey
size_t mac_length = 0;
status = psa_mac_compute(psa_key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
(const uint8_t *)ekey_seed, sizeof(ekey_seed),
(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));
ESP_LOGE(TAG, "Failed to calculate seed HMAC");
return ESP_FAIL;
}
ESP_FAULT_ASSERT(ret == 0);
memset(key_buf, 0x00, sizeof(key_buf));
#endif
ESP_FAULT_ASSERT(status == PSA_SUCCESS);
// Compute HMAC for tkey
status = psa_mac_compute(psa_key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
(const uint8_t *)tkey_seed, sizeof(tkey_seed),
(uint8_t *)cfg->tky, SHA256_DIGEST_SZ, &mac_length);
psa_destroy_key(psa_key_id);
if (status != PSA_SUCCESS) {
memset(cfg, 0x00, sizeof(nvs_sec_cfg_t));
return ESP_FAIL;
}
ESP_FAULT_ASSERT(status == PSA_SUCCESS);
/* NOTE: If the XTS E-key and T-key are the same, we have a hash collision */
ESP_FAULT_ASSERT(memcmp(cfg->eky, cfg->tky, NVS_KEY_SIZE) != 0);
@@ -625,38 +668,84 @@ static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t
return ESP_ERR_INVALID_STATE;
}
mbedtls_gcm_context gcm;
mbedtls_gcm_init(&gcm);
// Setup PSA key attributes
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&attributes, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_len));
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, AES256_KEY_BITS);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
int ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, keyctx.aes256.key, AES256_KEY_BITS);
if (ret != 0) {
ESP_LOGE(TAG, "Error in setting key: %d", ret);
err = ESP_FAIL;
goto exit;
// 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_reset_key_attributes(&attributes);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to import AES key: %d", status);
return ESP_FAIL;
}
if (is_encrypt) {
ret = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, len, keyctx.aes256.iv, AES256_GCM_IV_LEN,
aad, aad_len, input, output, tag_len, tag);
if (ret != 0) {
ESP_LOGE(TAG, "Error in encrypting data: %d", ret);
err = ESP_FAIL;
goto exit;
// PSA AEAD encrypt outputs ciphertext+tag concatenated
uint8_t *output_with_tag = malloc(len + tag_len);
if (!output_with_tag) {
ESP_LOGE(TAG, "Failed to allocate memory");
psa_destroy_key(key_id_psa);
return ESP_ERR_NO_MEM;
}
size_t output_length = 0;
status = psa_aead_encrypt(key_id_psa, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_len),
keyctx.aes256.iv, AES256_GCM_IV_LEN,
aad, aad_len,
input, len,
output_with_tag, len + tag_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;
}
// 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);
} else {
ret = mbedtls_gcm_auth_decrypt(&gcm, len, keyctx.aes256.iv, AES256_GCM_IV_LEN,
aad, aad_len, tag, tag_len, input, output);
if (ret != 0) {
ESP_LOGE(TAG, "Error in decrypting data: %d", ret);
err = ESP_FAIL;
goto exit;
// For decryption, PSA expects ciphertext + tag concatenated
uint8_t *input_with_tag = malloc(len + tag_len);
if (!input_with_tag) {
ESP_LOGE(TAG, "Failed to allocate memory");
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);
size_t output_length = 0;
status = psa_aead_decrypt(key_id_psa, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_len),
keyctx.aes256.iv, AES256_GCM_IV_LEN,
aad, aad_len,
input_with_tag, len + tag_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_OK;
exit:
mbedtls_gcm_free(&gcm);
return err;
psa_destroy_key(key_id_psa);
return ESP_OK;
}
esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output)
@@ -685,12 +774,10 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2
esp_err_t err = ESP_FAIL;
size_t key_len;
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_NONE;
switch (ctx->key_type) {
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
key_len = ECDSA_SECP256R1_KEY_LEN;
curve_id = MBEDTLS_ECP_DP_SECP256R1;
break;
default:
ESP_LOGE(TAG, "Unsupported key type");
@@ -723,82 +810,74 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2
goto exit;
}
mbedtls_ecp_keypair keypair;
mbedtls_mpi r, s;
psa_key_id_t psa_key_id = 0;
psa_status_t status;
mbedtls_ecp_keypair_init(&keypair);
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
// Setup PSA key attributes for ECC private key
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT);
psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&attributes, 256);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
int ret = -1;
// Import the private key
status = psa_import_key(&attributes, derived_key, key_len, &psa_key_id);
psa_reset_key_attributes(&attributes);
ret = mbedtls_ecp_group_load(&keypair.MBEDTLS_PRIVATE(grp), curve_id);
if (ret != 0) {
err = ESP_FAIL;
goto exit;
}
ret = mbedtls_mpi_read_binary(&keypair.MBEDTLS_PRIVATE(d), derived_key, key_len);
if (ret != 0) {
err = ESP_FAIL;
goto exit;
}
ret = mbedtls_ecp_check_privkey(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(d));
if (ret != 0) {
ESP_LOGE(TAG, "Invalid private key!");
err = ESP_FAIL;
goto exit;
}
ret = mbedtls_ecp_keypair_calc_public(&keypair, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE);
if (ret != 0) {
err = ESP_FAIL;
goto exit;
}
ret = mbedtls_ecdsa_sign(&keypair.MBEDTLS_PRIVATE(grp), &r, &s,
&keypair.MBEDTLS_PRIVATE(d), hash, hlen,
mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE);
if (ret != 0) {
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to import ECC private key: %d", status);
err = ESP_FAIL;
goto exit;
}
// Sign the hash
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
ret = mbedtls_mpi_write_binary(&r, out_sign->signature, key_len);
if (ret == 0) {
ret = mbedtls_mpi_write_binary(&s, out_sign->signature + key_len, key_len);
}
if (ret != 0) {
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) {
ESP_LOGE(TAG, "Failed to sign hash: %d", status);
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));
ret = mbedtls_mpi_write_binary(&keypair.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), out_pubkey->pub_x, key_len);
if (ret == 0) {
ret = mbedtls_mpi_write_binary(&keypair.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), out_pubkey->pub_y, key_len);
}
if (ret != 0) {
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) {
ESP_LOGE(TAG, "Failed to export public key: %d", status);
memset(out_pubkey, 0x00, sizeof(esp_tee_sec_storage_ecdsa_pubkey_t));
err = ESP_FAIL;
goto exit;
}
// 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) {
ESP_LOGE(TAG, "Unexpected public key format");
memset(out_pubkey, 0x00, sizeof(esp_tee_sec_storage_ecdsa_pubkey_t));
err = ESP_FAIL;
goto exit;
}
memcpy(out_pubkey->pub_x, public_key + 1, key_len);
memcpy(out_pubkey->pub_y, public_key + 1 + key_len, key_len);
err = ESP_OK;
exit:
if (psa_key_id != 0) {
psa_destroy_key(psa_key_id);
}
if (derived_key) {
memset(derived_key, 0x00, key_len);
free(derived_key);
}
mbedtls_ecp_keypair_free(&keypair);
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
return err;
}
#endif
+12 -19
View File
@@ -188,10 +188,6 @@ set(mbedtls_targets mbedtls mbedx509 tfpsacrypto builtin)
target_include_directories(tfpsacrypto PUBLIC "port/include")
if(CONFIG_MBEDTLS_HARDWARE_SHA OR CONFIG_MBEDTLS_HARDWARE_AES)
target_include_directories(tfpsacrypto PUBLIC "${COMPONENT_DIR}/port/psa_driver/include")
endif()
message(STATUS "Setting up mbedtls configuration")
foreach(target ${mbedtls_targets})
target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h")
@@ -356,13 +352,13 @@ endif()
if(CONFIG_SOC_SHA_SUPPORTED)
if(CONFIG_MBEDTLS_HARDWARE_SHA)
target_compile_definitions(tfpsacrypto PRIVATE ESP_SHA_DRIVER_ENABLED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c"
"${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha256.c"
"${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha512.c"
"${COMPONENT_DIR}/port/sha/esp_sha.c")
"${COMPONENT_DIR}/port/sha/esp_sha.c"
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c"
)
endif()
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha1.c"
@@ -371,12 +367,18 @@ if(CONFIG_SOC_SHA_SUPPORTED)
endif()
if(CONFIG_MBEDTLS_ROM_MD5)
target_compile_definitions(tfpsacrypto PRIVATE ESP_MD5_DRIVER_ENABLED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_md/psa_crypto_driver_esp_md5.c"
)
endif()
if(CONFIG_SOC_HMAC_SUPPORTED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c"
)
target_link_libraries(tfpsacrypto PRIVATE idf::efuse)
endif()
if(CONFIG_SOC_DIG_SIGN_SUPPORTED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c"
@@ -405,15 +407,14 @@ if(CONFIG_MBEDTLS_HARDWARE_MPI)
endif()
if(CONFIG_MBEDTLS_HARDWARE_GCM OR CONFIG_MBEDTLS_HARDWARE_AES)
target_compile_definitions(tfpsacrypto PRIVATE ESP_AES_DRIVER_ENABLED)
target_include_directories(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/include/aes")
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c"
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c"
)
if(CONFIG_MBEDTLS_HARDWARE_SHA)
if(CONFIG_MBEDTLS_CMAC_C)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c"
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c"
)
endif()
endif()
@@ -427,14 +428,6 @@ if(CONFIG_SOC_ECC_SUPPORTED)
endif()
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY OR CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN)
# ESP_ECDSA_DRIVER_ENABLED needs to be public because users would use OPAQUE key contexts in their applications.
target_compile_definitions(tfpsacrypto PUBLIC ESP_ECDSA_DRIVER_ENABLED)
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN)
target_compile_definitions(tfpsacrypto PRIVATE ESP_ECDSA_SIGN_DRIVER_ENABLED)
endif()
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
target_compile_definitions(tfpsacrypto PRIVATE ESP_ECDSA_VERIFY_DRIVER_ENABLED)
endif()
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c")
target_include_directories(tfpsacrypto PUBLIC "${COMPONENT_DIR}/port/psa_driver/include")
target_link_libraries(tfpsacrypto PRIVATE idf::efuse)
+1 -1
View File
@@ -1235,7 +1235,7 @@ menu "mbedTLS"
config MBEDTLS_SHA3_C
bool "Enable the SHA3 cryptographic hash algorithm"
default y
default n
help
Enabling MBEDTLS_SHA3_C adds support for SHA3.
Enabling this configuration option increases the flash footprint
@@ -28,6 +28,9 @@ set(GEN_FILES OFF CACHE BOOL "mbedtls: use pre-generated source files")
# Needed to for include_next includes to work from within mbedtls
include_directories("${COMPONENT_DIR}/port/include")
# Add PSA driver include directory globally for mbedtls targets
include_directories("${COMPONENT_DIR}/port/psa_driver/include")
# Import mbedtls library targets
add_subdirectory(mbedtls)
@@ -77,33 +80,27 @@ if(CONFIG_SOC_AES_SUPPORTED)
"${COMPONENT_DIR}/port/aes/esp_aes_xts.c")
target_include_directories(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/include/aes")
if(CONFIG_MBEDTLS_HARDWARE_AES)
target_compile_definitions(tfpsacrypto PRIVATE ESP_AES_DRIVER_ENABLED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c"
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c"
)
if(CONFIG_MBEDTLS_HARDWARE_SHA)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c"
)
endif()
endif()
endif()
# SHA implementation
if(CONFIG_SOC_SHA_SUPPORTED)
target_compile_definitions(tfpsacrypto PRIVATE ESP_SHA_DRIVER_ENABLED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c"
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c"
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c"
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c"
"${COMPONENT_DIR}/port/sha/core/sha.c"
"${COMPONENT_DIR}/port/sha/esp_sha.c")
"${COMPONENT_DIR}/port/sha/esp_sha.c"
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c"
)
endif()
if(CONFIG_MBEDTLS_ROM_MD5)
target_compile_definitions(tfpsacrypto PRIVATE ESP_MD5_DRIVER_ENABLED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_md/psa_crypto_driver_esp_md5.c"
)
@@ -116,7 +113,9 @@ endif()
if(CONFIG_SOC_HMAC_SUPPORTED)
# HMAC-based PBKDF2 implementation
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c")
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c")
target_link_libraries(tfpsacrypto PRIVATE idf::efuse)
endif()
# PSA Attestation
@@ -40,7 +40,10 @@
#undef MBEDTLS_TIMING_C
#define MBEDTLS_PLATFORM_C
#if CONFIG_MBEDTLS_HARDWARE_AES
#define ESP_AES_DRIVER_ENABLED
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_AES
#endif
#define MBEDTLS_CIPHER_MODE_XTS
#define MBEDTLS_ASN1_WRITE_C
@@ -71,6 +74,9 @@
#define MBEDTLS_SHA256_C
#if SOC_SHA_SUPPORTED
#define ESP_SHA_DRIVER_ENABLED
#define ESP_HMAC_TRANSPARENT_DRIVER_ENABLED
#undef MBEDTLS_PSA_BUILTIN_ALG_HMAC
#if CONFIG_MBEDTLS_SHA1_C
#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_1
@@ -89,6 +95,21 @@
#define MBEDTLS_ECP_VERIFY_ALT
#endif
#if SOC_HMAC_SUPPORTED
#define ESP_HMAC_OPAQUE_DRIVER_ENABLED
#else
#undef MBEDTLS_PSA_ACCEL_KEY_TYPE_HMAC
#endif
#if CONFIG_MBEDTLS_ROM_MD5
#define ESP_MD5_DRIVER_ENABLED
#define MBEDTLS_PSA_ACCEL_ALG_MD5
#undef MBEDTLS_PSA_BUILTIN_ALG_MD5
#else
#undef PSA_WANT_ALG_MD5
#undef MBEDTLS_MD5_C
#endif
#undef PSA_WANT_ECC_SECP_R1_192
#undef PSA_WANT_ECC_SECP_K1_192
#undef PSA_WANT_ECC_SECP_K1_256
@@ -109,7 +130,6 @@
#undef MBEDTLS_ECP_DP_CURVE25519_ENABLED
#undef MBEDTLS_ECP_DP_CURVE448_ENABLED
#undef PSA_WANT_KEY_TYPE_HMAC
#undef PSA_WANT_KEY_TYPE_ARIA
#undef MBEDTLS_ARIA_C
#undef PSA_WANT_KEY_TYPE_CAMELLIA
@@ -118,8 +138,6 @@
#undef MBEDTLS_DES_C
#undef PSA_WANT_ALG_RIPEMD160
#undef MBEDTLS_RIPEMD160_C
#undef PSA_WANT_ALG_MD5
#undef MBEDTLS_MD5_C
#undef PSA_WANT_ALG_CHACHA20
#undef MBEDTLS_CHACHA20_C
#undef PSA_WANT_ALG_SHA3_224
@@ -15,7 +15,6 @@
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
#include <string.h>
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
#include "aes/esp_aes.h"
#include "aes/esp_aes_gcm.h"
#include "esp_aes_internal.h"
+46 -6
View File
@@ -1,13 +1,17 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include <string.h>
#include "esp_hmac.h"
#include <stdlib.h>
#include "sdkconfig.h"
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_hmac_opaque.h"
#include "esp_efuse.h"
#include "esp_efuse_chip.h"
#include "esp_hmac_pbkdf2.h"
@@ -33,22 +37,55 @@ esp_err_t esp_hmac_derive_pbkdf2_key(hmac_key_id_t key_id, const uint8_t *salt,
}
esp_err_t err = ESP_FAIL;
psa_status_t status;
psa_key_id_t psa_key_id = 0;
size_t remaining = key_len;
uint8_t *out_p = out_key;
// Setup key attributes for ESP-HMAC opaque driver
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256));
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
psa_set_key_bits(&attributes, 256);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_HMAC_VOLATILE);
// Create opaque key reference
esp_hmac_opaque_key_t opaque_key = {
.use_km_key = false,
.efuse_block = (uint8_t)(EFUSE_BLK_KEY0 + key_id),
};
// Import the opaque key
status = psa_import_key(&attributes, (uint8_t *)&opaque_key,
sizeof(opaque_key), &psa_key_id);
psa_reset_key_attributes(&attributes);
if (status != PSA_SUCCESS) {
err = ESP_ERR_INVALID_ARG;
goto cleanup;
}
while (remaining > 0) {
memcpy(hmac_input, salt, salt_len);
memcpy(hmac_input + salt_len, counter, sizeof(counter));
err = esp_hmac_calculate(key_id, hmac_input, salt_len + sizeof(counter), U);
if (err != ESP_OK) {
size_t mac_length = 0;
status = psa_mac_compute(psa_key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
hmac_input, salt_len + sizeof(counter),
U, SHA256_DIGEST_SZ, &mac_length);
if (status != PSA_SUCCESS) {
err = ESP_FAIL;
goto cleanup;
}
memcpy(T, U, SHA256_DIGEST_SZ);
for (int i = 1; i < iterations; i++) {
err = esp_hmac_calculate(key_id, U, SHA256_DIGEST_SZ, U);
if (err != ESP_OK) {
status = psa_mac_compute(psa_key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
U, SHA256_DIGEST_SZ,
U, SHA256_DIGEST_SZ, &mac_length);
if (status != PSA_SUCCESS) {
err = ESP_FAIL;
goto cleanup;
}
@@ -72,6 +109,9 @@ esp_err_t esp_hmac_derive_pbkdf2_key(hmac_key_id_t key_id, const uint8_t *salt,
err = ESP_OK;
cleanup:
if (psa_key_id != 0) {
psa_destroy_key(psa_key_id);
}
memset(U, 0x00, sizeof(U));
memset(T, 0x00, sizeof(T));
if (hmac_input) {
-69
View File
@@ -1,69 +0,0 @@
/**
* \file aes_alt.h
*
* \brief AES block cipher
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
#ifndef AES_ALT_H
#define AES_ALT_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_AES_ALT)
#include "aes/esp_aes.h"
typedef esp_aes_context mbedtls_aes_context;
#define mbedtls_aes_init esp_aes_init
#define mbedtls_aes_free esp_aes_free
#define mbedtls_aes_setkey_enc esp_aes_setkey
#define mbedtls_aes_setkey_dec esp_aes_setkey
#define mbedtls_aes_crypt_ecb esp_aes_crypt_ecb
#if defined(MBEDTLS_CIPHER_MODE_CBC)
#define mbedtls_aes_crypt_cbc esp_aes_crypt_cbc
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
#define mbedtls_aes_crypt_cfb128 esp_aes_crypt_cfb128
#define mbedtls_aes_crypt_cfb8 esp_aes_crypt_cfb8
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
#define mbedtls_aes_crypt_ctr esp_aes_crypt_ctr
#endif
#if defined(MBEDTLS_CIPHER_MODE_OFB)
#define mbedtls_aes_crypt_ofb esp_aes_crypt_ofb
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
typedef esp_aes_xts_context mbedtls_aes_xts_context;
#define mbedtls_aes_xts_init esp_aes_xts_init
#define mbedtls_aes_xts_free esp_aes_xts_free
#define mbedtls_aes_xts_setkey_enc esp_aes_xts_setkey_enc
#define mbedtls_aes_xts_setkey_dec esp_aes_xts_setkey_dec
#define mbedtls_aes_crypt_xts esp_aes_crypt_xts
#endif
#define mbedtls_internal_aes_encrypt esp_internal_aes_encrypt
#define mbedtls_internal_aes_decrypt esp_internal_aes_decrypt
#endif /* MBEDTLS_AES_ALT */
#ifdef __cplusplus
}
#endif
#endif
-43
View File
@@ -1,43 +0,0 @@
/*
* gcm_alt.h: AES block cipher
*
* SPDX-FileCopyrightText: The Mbed TLS Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
*/
#ifndef GCM_ALT_H
#define GCM_ALT_H
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_GCM_ALT)
#include "aes/esp_aes_gcm.h"
typedef esp_gcm_context mbedtls_gcm_context;
#define mbedtls_gcm_init esp_aes_gcm_init
#define mbedtls_gcm_free esp_aes_gcm_free
#define mbedtls_gcm_setkey esp_aes_gcm_setkey
#define mbedtls_gcm_starts esp_aes_gcm_starts
#define mbedtls_gcm_update_ad esp_aes_gcm_update_ad
#define mbedtls_gcm_update esp_aes_gcm_update
#define mbedtls_gcm_finish esp_aes_gcm_finish
#define mbedtls_gcm_auth_decrypt esp_aes_gcm_auth_decrypt
#define mbedtls_gcm_crypt_and_tag esp_aes_gcm_crypt_and_tag
#endif /* MBEDTLS_GCM_ALT */
#ifdef __cplusplus
}
#endif
#endif
@@ -191,18 +191,29 @@
with software fallback.
*/
#ifdef CONFIG_MBEDTLS_HARDWARE_SHA
#define ESP_SHA_DRIVER_ENABLED
#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_1
#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_224
#define MBEDTLS_PSA_ACCEL_ALG_SHA_256
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_256
#undef MBEDTLS_SHA1_C
#undef MBEDTLS_SHA224_C
#define ESP_HMAC_TRANSPARENT_DRIVER_ENABLED
#define MBEDTLS_PSA_ACCEL_ALG_HMAC
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC
#if SOC_SHA_SUPPORT_SHA512
#define MBEDTLS_PSA_ACCEL_ALG_SHA_384
#undef MBEDTLS_PSA_ACCEL_ALG_SHA_384
#define MBEDTLS_PSA_ACCEL_ALG_SHA_512
#endif
#if SOC_SHA_SUPPORT_SHA512
#undef MBEDTLS_PSA_ACCEL_ALG_SHA_512
#undef MBEDTLS_SHA512_C
#undef MBEDTLS_SHA384_C
#undef MBEDTLS_PSA_BUILTIN_ALG_HMAC
#else
#undef MBEDTLS_SHA512_ALT
#endif
#else
#undef MBEDTLS_SHA1_ALT
#undef MBEDTLS_SHA256_ALT
@@ -213,9 +224,15 @@
with software fallback.
*/
#ifdef CONFIG_MBEDTLS_ROM_MD5
#define ESP_MD5_DRIVER_ENABLED
#define MBEDTLS_PSA_ACCEL_ALG_MD5
#undef MBEDTLS_PSA_BUILTIN_ALG_MD5
#else
#if !defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
/* If ROM MD5 is not enabled, use the builtin HMAC algorithm for HMAC(MD5) operations */
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC
#endif
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
/* The following MPI (bignum) functions have hardware support.
* Uncommenting these macros will use the hardware-accelerated
@@ -237,18 +254,14 @@
#undef MBEDTLS_MPI_MUL_MPI_ALT
#endif
#ifdef MBEDTLS_HARDWARE_ECDSA_SIGN
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256
#if SOC_ECDSA_SUPPORT_CURVE_P384
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384
#if defined(CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY) || defined(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN) || defined(CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN)
#define ESP_ECDSA_DRIVER_ENABLED
#ifdef MBEDTLS_HARDWARE_ECDSA_VERIFY
#define ESP_ECDSA_VERIFY_DRIVER_ENABLED
#endif
#if defined(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN) || defined(CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN)
#define ESP_ECDSA_SIGN_DRIVER_ENABLED
#endif
#define MBEDTLS_PSA_ACCEL_ALG_ECDSA
#define MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT
#endif
#ifdef CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN
@@ -279,6 +292,10 @@
#undef MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK
#endif
#ifdef SOC_HMAC_SUPPORTED
#define ESP_HMAC_OPAQUE_DRIVER_ENABLED
#endif
/**
* \def MBEDTLS_AES_ROM_TABLES
*
@@ -491,6 +508,9 @@
*/
#ifdef CONFIG_MBEDTLS_CMAC_C
#define PSA_WANT_ALG_CMAC 1
#ifdef CONFIG_MBEDTLS_HARDWARE_AES
#define ESP_CMAC_DRIVER_ENABLED
#endif
#else
#ifdef CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL
/* The mbedtls present in ROM is built with the MBEDTLS_CMAC_C symbol being enabled,
@@ -1729,6 +1749,7 @@
uncommenting each _ALT macro will use the
hardware-accelerated implementation. */
#ifdef CONFIG_MBEDTLS_HARDWARE_AES
#define ESP_AES_DRIVER_ENABLED
#define MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING
#undef MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING
#define MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7
@@ -2655,34 +2676,6 @@
#undef PSA_WANT_ALG_SHA_224
#endif
/* MBEDTLS_SHAxx_ALT to enable hardware SHA support
with software fallback.
*/
#ifdef CONFIG_MBEDTLS_HARDWARE_SHA
#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_1
#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_224
#define MBEDTLS_PSA_ACCEL_ALG_SHA_256
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_256
#undef MBEDTLS_SHA1_C
#undef MBEDTLS_SHA224_C
#if SOC_SHA_SUPPORT_SHA512
#define MBEDTLS_PSA_ACCEL_ALG_SHA_512
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_512
#define MBEDTLS_PSA_ACCEL_ALG_SHA_384
#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_384
#undef MBEDTLS_SHA512_C
#undef MBEDTLS_SHA384_C
#else
#undef MBEDTLS_SHA512_ALT
#endif
#else
#undef MBEDTLS_SHA1_ALT
#undef MBEDTLS_SHA256_ALT
#undef MBEDTLS_SHA512_ALT
#endif
/* MBEDTLS_MD_CAN_SHA* macros indicate whether a hash algorithm is available
* either via legacy implementation (MBEDTLS_SHA*_C) or via PSA (PSA_WANT_ALG_SHA_*).
* These are used for TLS 1.3 signature algorithm configuration.
@@ -2721,6 +2714,10 @@
#define PSA_WANT_ALG_SHA3_256 1
#define PSA_WANT_ALG_SHA3_384 1
#define PSA_WANT_ALG_SHA3_512 1
#if !defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
/* If SHA3 is enabled, use the builtin HMAC algorithm for HMAC(SHA3) operations */
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
#else
#undef PSA_WANT_ALG_SHA3_224
#undef PSA_WANT_ALG_SHA3_256
@@ -1,98 +0,0 @@
/*
* SHA-1 implementation with hardware ESP32 support added.
* Uses mbedTLS software implementation for failover when concurrent
* SHA operations are in use.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef _SHA1_ALT_H_
#define _SHA1_ALT_H_
#if defined(MBEDTLS_SHA1_ALT)
#include "hal/sha_types.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_SHA_SUPPORT_PARALLEL_ENG
typedef enum {
ESP_MBEDTLS_SHA1_UNUSED, /* first block hasn't been processed yet */
ESP_MBEDTLS_SHA1_HARDWARE, /* using hardware SHA engine */
ESP_MBEDTLS_SHA1_SOFTWARE, /* using software SHA */
} esp_mbedtls_sha1_mode;
/**
* \brief SHA-1 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
esp_mbedtls_sha1_mode mode;
} mbedtls_sha1_context;
/**
* \brief Set the SHA-1 mode for a mbedtls_sha1_context.
*
* \param ctx The SHA-1 context structure.
* \param mode The SHA-1 mode to be set. It can be one of the following:
* - ESP_MBEDTLS_SHA1_UNUSED: Indicates that the first block hasn't been processed yet.
* - ESP_MBEDTLS_SHA1_HARDWARE: Specifies the use of hardware SHA engine for SHA-1 calculations.
* - ESP_MBEDTLS_SHA1_SOFTWARE: Specifies the use of software-based SHA-1 calculations.
*
* \return None.
*/
static inline void esp_mbedtls_set_sha1_mode(mbedtls_sha1_context *ctx, esp_mbedtls_sha1_mode mode)
{
if (ctx) {
ctx->mode = mode;
}
}
#elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME
typedef enum {
ESP_SHA1_STATE_INIT,
ESP_SHA1_STATE_IN_PROCESS
} esp_sha1_state;
/**
* \brief SHA-1 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true else false */
esp_sha_type mode;
esp_sha1_state sha_state;
} mbedtls_sha1_context;
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -1,79 +0,0 @@
/*
* SHA-256 implementation with hardware ESP32 support added.
* Uses mbedTLS software implementation for failover when concurrent
* SHA operations are in use.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef _SHA256_ALT_H_
#define _SHA256_ALT_H_
#if defined(MBEDTLS_SHA256_ALT)
#include "hal/sha_types.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_SHA_SUPPORT_PARALLEL_ENG
typedef enum {
ESP_MBEDTLS_SHA256_UNUSED, /* first block hasn't been processed yet */
ESP_MBEDTLS_SHA256_HARDWARE, /* using hardware SHA engine */
ESP_MBEDTLS_SHA256_SOFTWARE, /* using software SHA */
} esp_mbedtls_sha256_mode;
/**
* \brief SHA-256 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int is224; /*!< 0 => SHA-256, else SHA-224 */
esp_mbedtls_sha256_mode mode;
} mbedtls_sha256_context;
#elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME
typedef enum {
ESP_SHA256_STATE_INIT,
ESP_SHA256_STATE_IN_PROCESS
} esp_sha256_state;
/**
* \brief SHA-256 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true, else false */
esp_sha_type mode;
esp_sha256_state sha_state;
} mbedtls_sha256_context;
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -1,97 +0,0 @@
/*
* SHA-512 implementation with hardware ESP32 support added.
* Uses mbedTLS software implementation for failover when concurrent
* SHA operations are in use.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef _SHA512_ALT_H_
#define _SHA512_ALT_H_
#if defined(MBEDTLS_SHA512_ALT)
#include "hal/sha_types.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_SHA_SUPPORT_PARALLEL_ENG
typedef enum {
ESP_MBEDTLS_SHA512_UNUSED, /* first block hasn't been processed yet */
ESP_MBEDTLS_SHA512_HARDWARE, /* using hardware SHA engine */
ESP_MBEDTLS_SHA512_SOFTWARE, /* using software SHA */
} esp_mbedtls_sha512_mode;
/**
* \brief SHA-512 context structure
*/
typedef struct {
uint64_t total[2]; /*!< number of bytes processed */
uint64_t state[8]; /*!< intermediate digest state */
unsigned char buffer[128]; /*!< data block being processed */
int is384; /*!< 0 => SHA-512, else SHA-384 */
esp_mbedtls_sha512_mode mode;
} mbedtls_sha512_context;
#elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME
typedef enum {
ESP_SHA512_STATE_INIT,
ESP_SHA512_STATE_IN_PROCESS
} esp_sha512_state;
/**
* \brief SHA-512 context structure
*/
typedef struct {
uint64_t total[2]; /*!< number of bytes processed */
uint64_t state[8]; /*!< intermediate digest state */
unsigned char buffer[128]; /*!< data block being processed */
int first_block;
esp_sha_type mode;
uint32_t t_val; /*!< t_val for 512/t mode */
esp_sha512_state sha_state;
} mbedtls_sha512_context;
/**
* @brief Sets the specific algorithm for SHA512
*
* @param ctx The mbedtls sha512 context
*
* @param type The mode, used for setting SHA2_512224 and SHA2_512256:
*
*/
void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type);
/* For SHA512/t mode the initial hash value will depend on t */
void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val);
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -14,7 +14,99 @@
#include "constant_time_internal.h"
#include "esp_log.h"
static psa_status_t esp_crypto_aes_ecb_update(
static const char *TAG = "psa_crypto_driver_esp_aes";
static psa_status_t esp_aes_cipher_setup(
esp_aes_operation_t *esp_aes_driver_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg, psa_encrypt_or_decrypt_t mode)
{
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
if (!PSA_ALG_IS_CIPHER(alg)) {
status = PSA_ERROR_INVALID_ARGUMENT;
goto exit;
}
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) {
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
switch (alg) {
case PSA_ALG_ECB_NO_PADDING:
case PSA_ALG_CBC_NO_PADDING:
case PSA_ALG_CBC_PKCS7:
case PSA_ALG_CTR:
case PSA_ALG_XTS:
case PSA_ALG_CFB:
case PSA_ALG_OFB:
break;
default:
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
esp_aes_context *ctx = (esp_aes_context *) malloc(sizeof(esp_aes_context));
if (ctx == NULL) {
status = PSA_ERROR_INSUFFICIENT_MEMORY;
goto exit;
}
esp_aes_init(ctx);
status = mbedtls_to_psa_error(esp_aes_setkey(ctx, key_buffer, key_buffer_size * 8));
if (status != PSA_SUCCESS) {
free(ctx);
goto exit;
}
esp_aes_driver_ctx->aes_alg = alg;
esp_aes_driver_ctx->mode = mode;
esp_aes_driver_ctx->esp_aes_ctx = (void *) ctx;
esp_aes_driver_ctx->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 : PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES));
exit:
return status;
}
psa_status_t esp_aes_cipher_encrypt_setup(
esp_aes_operation_t *esp_aes_driver_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg)
{
return esp_aes_cipher_setup(esp_aes_driver_ctx, attributes,
key_buffer, key_buffer_size,
alg, PSA_CRYPTO_DRIVER_ENCRYPT);
}
psa_status_t esp_aes_cipher_decrypt_setup(
esp_aes_operation_t *esp_aes_driver_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg)
{
return esp_aes_cipher_setup(esp_aes_driver_ctx, attributes,
key_buffer, key_buffer_size,
alg, PSA_CRYPTO_DRIVER_DECRYPT);
}
psa_status_t esp_aes_cipher_set_iv(
esp_aes_operation_t *esp_aes_driver_ctx,
const uint8_t *iv,
size_t iv_length)
{
if (iv_length != PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, esp_aes_driver_ctx->aes_alg)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(esp_aes_driver_ctx->iv, iv, iv_length);
return PSA_SUCCESS;
}
static psa_status_t esp_aes_ecb_update(
esp_aes_operation_t *esp_aes_driver_ctx,
const uint8_t *input, size_t input_length,
uint8_t *output, size_t *output_length)
@@ -74,7 +166,7 @@ exit:
return status;
}
static psa_status_t esp_crypto_aes_cbc_update(
static psa_status_t esp_aes_cbc_update(
esp_aes_operation_t *esp_aes_driver_ctx,
const uint8_t *input, size_t input_length,
uint8_t *output, size_t output_size,
@@ -166,10 +258,12 @@ exit:
return mbedtls_to_psa_error(ret);
}
psa_status_t esp_crypto_aes_update(
psa_status_t esp_aes_cipher_update(
esp_aes_operation_t *esp_aes_driver_ctx,
const uint8_t *input, size_t input_length,
uint8_t *output, size_t output_size,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
int ret = -1;
@@ -187,7 +281,7 @@ psa_status_t esp_crypto_aes_update(
}
if (output_size < expected_output_size) {
ESP_LOGE("TAG", "Output buffer too small: have %zu, need %zu", output_size, expected_output_size);
ESP_LOGE(TAG, "Output buffer too small: have %zu, need %zu", output_size, expected_output_size);
return PSA_ERROR_BUFFER_TOO_SMALL;
}
@@ -199,7 +293,7 @@ psa_status_t esp_crypto_aes_update(
else if (esp_aes_driver_ctx->aes_alg == PSA_ALG_ECB_NO_PADDING) {
/* esp_aes_crypt_ecb will only process a single block at a time in
* ECB mode. Abstract this away to match the PSA API behaviour. */
ret = esp_crypto_aes_ecb_update(esp_aes_driver_ctx,
ret = esp_aes_ecb_update(esp_aes_driver_ctx,
input,
input_length,
output,
@@ -249,7 +343,7 @@ psa_status_t esp_crypto_aes_update(
#endif /* CONFIG_MBEDTLS_CIPHER_MODE_OFB */
case PSA_ALG_CBC_NO_PADDING:
case PSA_ALG_CBC_PKCS7:
ret = esp_crypto_aes_cbc_update(esp_aes_driver_ctx,
ret = esp_aes_cbc_update(esp_aes_driver_ctx,
input,
input_length,
output,
@@ -314,9 +408,10 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len, size_t *data
return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
}
psa_status_t esp_crypto_aes_finish(
psa_status_t esp_aes_cipher_finish(
esp_aes_operation_t *esp_aes_driver_ctx,
uint8_t *output, size_t output_size,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
int ret = -1;
@@ -421,7 +516,8 @@ exit:
return status;
}
psa_status_t esp_crypto_aes_abort(esp_aes_operation_t *esp_aes_driver_ctx)
psa_status_t esp_aes_cipher_abort(
esp_aes_operation_t *esp_aes_driver_ctx)
{
esp_aes_context *ctx = (esp_aes_context *) esp_aes_driver_ctx->esp_aes_ctx;
if (ctx == NULL) {
@@ -432,85 +528,6 @@ psa_status_t esp_crypto_aes_abort(esp_aes_operation_t *esp_aes_driver_ctx)
return PSA_SUCCESS;
}
psa_status_t esp_crypto_aes_set_iv(
esp_aes_operation_t *esp_aes_driver_ctx,
const uint8_t *iv, size_t iv_length)
{
if (iv_length != PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, esp_aes_driver_ctx->aes_alg)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(esp_aes_driver_ctx->iv, iv, iv_length);
return PSA_SUCCESS;
}
static psa_status_t esp_crypto_aes_setup(
esp_aes_operation_t *esp_aes_driver_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg, psa_encrypt_or_decrypt_t mode)
{
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
if (!PSA_ALG_IS_CIPHER(alg)) {
status = PSA_ERROR_INVALID_ARGUMENT;
goto exit;
}
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) {
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
switch (alg) {
case PSA_ALG_ECB_NO_PADDING:
case PSA_ALG_CBC_NO_PADDING:
case PSA_ALG_CBC_PKCS7:
case PSA_ALG_CTR:
case PSA_ALG_XTS:
case PSA_ALG_CFB:
case PSA_ALG_OFB:
break;
default:
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
esp_aes_context *ctx = (esp_aes_context *) malloc(sizeof(esp_aes_context));
if (ctx == NULL) {
status = PSA_ERROR_INSUFFICIENT_MEMORY;
goto exit;
}
esp_aes_init(ctx);
status = mbedtls_to_psa_error(esp_aes_setkey(ctx, key_buffer, key_buffer_size * 8));
if (status != PSA_SUCCESS) {
free(ctx);
goto exit;
}
esp_aes_driver_ctx->aes_alg = alg;
esp_aes_driver_ctx->mode = mode;
esp_aes_driver_ctx->esp_aes_ctx = (void *) ctx;
esp_aes_driver_ctx->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 : PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES));
exit:
return status;
}
psa_status_t esp_aes_cipher_encrypt_setup(
esp_aes_operation_t *esp_aes_driver_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg)
{
return esp_crypto_aes_setup(esp_aes_driver_ctx, attributes,
key_buffer, key_buffer_size,
alg, PSA_CRYPTO_DRIVER_ENCRYPT);
}
psa_status_t esp_aes_cipher_encrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
@@ -533,58 +550,42 @@ psa_status_t esp_aes_cipher_encrypt(
key_buffer, key_buffer_size,
alg);
if (status != PSA_SUCCESS) {
ESP_LOGE("esp_aes_cipher_encrypt", "Failed to setup encryption: %ld", status);
ESP_LOGE(TAG, "Failed to setup encryption: %ld", status);
goto exit;
}
if (iv_length > 0) {
status = esp_crypto_aes_set_iv(&esp_aes_driver_ctx, iv, iv_length);
status = esp_aes_cipher_set_iv(&esp_aes_driver_ctx, iv, iv_length);
if (status != PSA_SUCCESS) {
ESP_LOGE("esp_aes_cipher_encrypt", "Failed to set IV: %ld", status);
ESP_LOGE(TAG, "Failed to set IV: %ld", status);
goto exit;
}
}
status = esp_crypto_aes_update(&esp_aes_driver_ctx, input, input_length,
status = esp_aes_cipher_update(&esp_aes_driver_ctx, input, input_length,
output, output_size,
&update_output_length);
if (status != PSA_SUCCESS) {
ESP_LOGE("esp_aes_cipher_encrypt", "Failed to update: %ld", status);
ESP_LOGE(TAG, "Failed to update: %ld", status);
goto exit;
}
status = esp_crypto_aes_finish(&esp_aes_driver_ctx,
status = esp_aes_cipher_finish(&esp_aes_driver_ctx,
mbedtls_buffer_offset(output, update_output_length),
output_size - update_output_length, &finish_output_length);
if (status != PSA_SUCCESS) {
ESP_LOGE("esp_aes_cipher_encrypt", "Failed to finish: %ld", status);
ESP_LOGE(TAG, "Failed to finish: %ld", status);
goto exit;
}
*output_length = update_output_length + finish_output_length;
exit:
if (status == PSA_SUCCESS) {
status = esp_crypto_aes_abort(&esp_aes_driver_ctx);
} else {
ESP_LOGE("esp_aes_cipher_encrypt", "Failed to abort: %ld", status);
esp_crypto_aes_abort(&esp_aes_driver_ctx);
}
esp_aes_cipher_abort(&esp_aes_driver_ctx);
return status;
}
psa_status_t esp_aes_cipher_decrypt_setup(
esp_aes_operation_t *esp_aes_driver_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg)
{
return esp_crypto_aes_setup(esp_aes_driver_ctx, attributes,
key_buffer, key_buffer_size,
alg, PSA_CRYPTO_DRIVER_DECRYPT);
}
psa_status_t esp_aes_cipher_decrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
@@ -601,85 +602,44 @@ psa_status_t esp_aes_cipher_decrypt(
key, key_length,
alg);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to setup decryption: %ld", status);
goto exit;
}
uint8_t iv_length = PSA_CIPHER_IV_LENGTH(psa_get_key_type(attributes), alg);
if (iv_length > 0) {
status = esp_crypto_aes_set_iv(&esp_aes_driver_ctx,
status = esp_aes_cipher_set_iv(&esp_aes_driver_ctx,
input, iv_length);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to set IV: %ld", status);
goto exit;
}
}
status = esp_crypto_aes_update(&esp_aes_driver_ctx,
status = esp_aes_cipher_update(&esp_aes_driver_ctx,
mbedtls_buffer_offset_const(input, iv_length),
input_length - iv_length,
output, output_size, &olength);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to update: %ld", status);
goto exit;
}
accumulated_length = olength;
status = esp_crypto_aes_finish(&esp_aes_driver_ctx,
status = esp_aes_cipher_finish(&esp_aes_driver_ctx,
mbedtls_buffer_offset(output, accumulated_length),
output_size - accumulated_length, &olength);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to finish: %ld", status);
goto exit;
}
*output_length = accumulated_length + olength;
exit:
if (status == PSA_SUCCESS) {
status = esp_crypto_aes_abort(&esp_aes_driver_ctx);
} else {
esp_crypto_aes_abort(&esp_aes_driver_ctx);
}
esp_aes_cipher_abort(&esp_aes_driver_ctx);
return status;
}
psa_status_t esp_aes_cipher_set_iv(
esp_aes_operation_t *operation,
const uint8_t *iv,
size_t iv_length)
{
return esp_crypto_aes_set_iv(operation, iv, iv_length);
}
psa_status_t esp_aes_cipher_update(
esp_aes_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
return esp_crypto_aes_update(operation, input, input_length,
output, output_size, output_length);
}
psa_status_t esp_aes_cipher_finish(
esp_aes_operation_t *operation,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
return esp_crypto_aes_finish(operation, output, output_size, output_length);
}
psa_status_t esp_aes_cipher_abort(
esp_aes_operation_t *operation)
{
esp_aes_context *ctx = (esp_aes_context *) operation->esp_aes_ctx;
if (ctx == NULL) {
return PSA_SUCCESS;
}
esp_aes_free(ctx);
free(ctx);
return PSA_SUCCESS;
}
@@ -1,22 +1,18 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "esp_log.h"
// #include "mbedtls/aes.h"
#include "psa_crypto_core.h"
// #include "mbedtls/cipher.h"
#include "aes/esp_aes_gcm.h"
#include "psa_crypto_driver_esp_aes_gcm.h"
#include "../include/psa_crypto_driver_esp_aes_contexts.h"
// #ifdef ESP_MBEDTLS_AES_ACCEL
#if defined(ESP_AES_DRIVER_ENABLED)
#define ESP_AES_GCM_TAG_LENGTH 16
#define ESP_AES_GCM_TAG_LENGTH_DEFAULT 16
static psa_status_t esp_crypto_aes_gcm_setup(
esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx,
@@ -26,12 +22,18 @@ static psa_status_t esp_crypto_aes_gcm_setup(
{
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
esp_gcm_context *ctx = NULL;
size_t tag_length;
if (alg != PSA_ALG_GCM) {
/* Extract the base algorithm and tag length */
psa_algorithm_t base_alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
if (base_alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0)) {
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
/* Get the tag length from the algorithm */
tag_length = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) {
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
@@ -54,6 +56,7 @@ static psa_status_t esp_crypto_aes_gcm_setup(
esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx = (void *) ctx;
esp_aes_gcm_driver_ctx->mode = mode;
esp_aes_gcm_driver_ctx->tag_length = tag_length;
exit:
return status;
@@ -129,18 +132,29 @@ psa_status_t esp_crypto_aes_gcm_finish(
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t finish_output_size = 0;
size_t requested_tag_length = esp_aes_gcm_driver_ctx->tag_length;
if (tag_size < ESP_AES_GCM_TAG_LENGTH) {
if (tag_size < requested_tag_length) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
if (requested_tag_length > ESP_AES_GCM_TAG_LENGTH_DEFAULT) {
return PSA_ERROR_INVALID_ARGUMENT;
}
esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx;
status = mbedtls_to_psa_error(esp_aes_gcm_finish(ctx, output, output_size, output_length, tag, tag_size));
/* esp_aes_gcm_finish always generates a 16-byte tag, but we'll only use
* the first requested_tag_length bytes */
uint8_t full_tag[ESP_AES_GCM_TAG_LENGTH_DEFAULT];
status = mbedtls_to_psa_error(esp_aes_gcm_finish(ctx, output, output_size, output_length, full_tag, sizeof(full_tag)));
if (status == PSA_SUCCESS) {
/* This will be zero for all supported algorithms currently, but left
* here for future support. */
*output_length = finish_output_size;
*tag_length = ESP_AES_GCM_TAG_LENGTH;
*tag_length = requested_tag_length;
/* Copy only the requested tag length */
memcpy(tag, full_tag, requested_tag_length);
}
return status;
}
@@ -178,13 +192,18 @@ psa_status_t esp_crypto_aes_gcm_encrypt(
goto exit;
}
size_t tag_length = esp_aes_gcm_driver_ctx.tag_length;
/* For all currently supported modes, the tag is at the end of the
* ciphertext. */
if (ciphertext_size < (plaintext_length + ESP_AES_GCM_TAG_LENGTH)) {
if (ciphertext_size < (plaintext_length + tag_length)) {
status = PSA_ERROR_BUFFER_TOO_SMALL;
goto exit;
}
tag = ciphertext + plaintext_length;
/* esp_aes_gcm_crypt_and_tag always generates a 16-byte tag */
uint8_t full_tag[ESP_AES_GCM_TAG_LENGTH_DEFAULT];
status = mbedtls_to_psa_error(
esp_aes_gcm_crypt_and_tag((esp_gcm_context *) esp_aes_gcm_driver_ctx.esp_aes_gcm_ctx,
PSA_CRYPTO_DRIVER_ENCRYPT,
@@ -192,10 +211,12 @@ psa_status_t esp_crypto_aes_gcm_encrypt(
nonce, nonce_length,
additional_data, additional_data_length,
plaintext, ciphertext,
ESP_AES_GCM_TAG_LENGTH, tag));
ESP_AES_GCM_TAG_LENGTH_DEFAULT, full_tag));
if (status == PSA_SUCCESS) {
*ciphertext_length = plaintext_length + ESP_AES_GCM_TAG_LENGTH;
/* Copy only the requested tag length */
memcpy(tag, full_tag, tag_length);
*ciphertext_length = plaintext_length + tag_length;
}
exit:
@@ -248,22 +269,26 @@ psa_status_t esp_crypto_aes_gcm_decrypt(
goto exit;
}
status = psa_aead_unpadded_locate_tag(ESP_AES_GCM_TAG_LENGTH, ciphertext, ciphertext_length, plaintext_size, &tag);
size_t tag_length = esp_aes_gcm_driver_ctx.tag_length;
status = psa_aead_unpadded_locate_tag(tag_length, ciphertext, ciphertext_length, plaintext_size, &tag);
if (status != PSA_SUCCESS) {
goto exit;
}
}
/* esp_aes_gcm_auth_decrypt supports variable tag lengths (4-16 bytes)
* and will compare only the first tag_length bytes */
status = mbedtls_to_psa_error(
esp_aes_gcm_auth_decrypt((esp_gcm_context *) esp_aes_gcm_driver_ctx.esp_aes_gcm_ctx,
ciphertext_length - ESP_AES_GCM_TAG_LENGTH,
ciphertext_length - tag_length,
nonce, nonce_length,
additional_data,
additional_data_length,
tag, ESP_AES_GCM_TAG_LENGTH,
tag, tag_length,
ciphertext, plaintext));
if (status == PSA_SUCCESS) {
*plaintext_length = ciphertext_length - ESP_AES_GCM_TAG_LENGTH;
*plaintext_length = ciphertext_length - tag_length;
}
exit:
@@ -1,623 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_cmac.h"
#include "psa_crypto_driver_esp_cmac_contexts.h"
#include "mbedtls/constant_time.h"
#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 16
#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)
#define MBEDTLS_IS_BIG_ENDIAN 1
#else
#define MBEDTLS_IS_BIG_ENDIAN 0
#endif
#define MBEDTLS_BSWAP32 __builtin_bswap32
static inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
{
uint32_t r;
#if defined(UINT_UNALIGNED)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
r = *p32;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
r = p32->x;
#else
memcpy(&r, p, sizeof(r));
#endif
return r;
}
static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
{
#if defined(UINT_UNALIGNED)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
*p32 = x;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
p32->x = x;
#else
memcpy(p, &x, sizeof(x));
#endif
}
#define MBEDTLS_GET_UINT32_BE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
? mbedtls_get_unaligned_uint32((data) + (offset)) \
: MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
)
#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \
do { \
mbedtls_put_unaligned_uint32((data) + (offset), \
(MBEDTLS_IS_BIG_ENDIAN) \
? (uint32_t) (n) \
: MBEDTLS_BSWAP32((uint32_t) (n))); \
} while (0)
psa_status_t esp_cmac_mac_abort(esp_cmac_operation_t *operation)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_destroy_key(operation->key_id);
if (status != PSA_SUCCESS) {
return status;
}
status = psa_cipher_abort(&operation->cipher_ctx);
if (status != PSA_SUCCESS) {
return status;
}
mbedtls_platform_zeroize(&operation->cipher_ctx, sizeof(psa_cipher_operation_t));
return status;
}
static psa_status_t mac_init(
esp_cmac_operation_t *operation,
psa_algorithm_t alg)
{
memset(operation, 0, sizeof(*operation));
return PSA_SUCCESS;
}
static psa_status_t esp_cmac_setup_internal(esp_cmac_operation_t *cmac,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size)
{
int status = PSA_ERROR_CORRUPTION_DETECTED;
#if defined(PSA_WANT_KEY_TYPE_DES)
/* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept
* to do CMAC with pure DES, so return NOT_SUPPORTED here. */
if (psa_get_key_type(attributes) == PSA_KEY_TYPE_DES &&
(psa_get_key_bits(attributes) == 64 ||
psa_get_key_bits(attributes) == 128)) {
return PSA_ERROR_NOT_SUPPORTED;
}
#endif
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t key_type = psa_get_key_type(attributes);
size_t key_bits = psa_get_key_bits(attributes);
psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING;
/* Set up key attributes for PSA import */
psa_set_key_type(&key_attributes, key_type);
psa_set_key_bits(&key_attributes, key_bits);
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&key_attributes, alg);
/* Import key for cipher operations */
status = psa_import_key(&key_attributes, key_buffer, key_buffer_size, &cmac->key_id);
if (status != PSA_SUCCESS) {
return status;
}
status = psa_cipher_encrypt_setup(&cmac->cipher_ctx, cmac->key_id, alg);
if (status != 0) {
return status;
}
cmac->unprocessed_len = 0;
cmac->cipher_block_length = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type);
mbedtls_platform_zeroize(cmac->state, sizeof(cmac->state));
mbedtls_platform_zeroize(cmac->unprocessed_block, sizeof(cmac->unprocessed_block));
return PSA_SUCCESS;
}
static psa_status_t esp_cmac_mac_setup_cmac(esp_cmac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = mac_init(operation, alg);
if (status != PSA_SUCCESS) {
return status;
}
status = esp_cmac_setup_internal(operation, attributes, key_buffer, key_buffer_size);
if (status != PSA_SUCCESS) {
esp_cmac_mac_abort(operation);
}
return status;
}
psa_status_t esp_cmac_mac_setup(esp_cmac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if (PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) {
status = esp_cmac_mac_setup_cmac(operation, attributes, key_buffer, key_buffer_size, alg);
operation->alg = alg;
} else if (PSA_ALG_IS_HMAC(alg)) {
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(alg);
uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
size_t i;
size_t hash_size = PSA_HASH_LENGTH(hash_alg);
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
/* Sanity checks on block_size, to guarantee that there won't be a buffer
* overflow below. This should never trigger if the hash algorithm
* is implemented correctly. */
/* The size checks against the ipad and opad buffers cannot be written
* `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
* because that triggers -Wlogical-op on GCC 7.3. */
if (block_size > sizeof(ipad)) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (block_size > sizeof(operation->opad)) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (block_size < hash_size) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (key_buffer_size > block_size) {
status = esp_sha_hash_compute(hash_alg, key_buffer, key_buffer_size,
ipad, sizeof(ipad), &key_buffer_size);
if (status != PSA_SUCCESS) {
return status;
}
/* After hashing, key_buffer_size is set to the hash size, which
* should be <= block_size. Verify this for static analysis. */
if (key_buffer_size > block_size) {
return PSA_ERROR_CORRUPTION_DETECTED;
}
}
/* A 0-length key is not commonly used in HMAC when used as a MAC,
* but it is permitted. It is common when HMAC is used in HKDF, for
* example. Don't call `memcpy` in the 0-length because `key` could be
* an invalid pointer which would make the behavior undefined. */
else if (key_buffer_size != 0) {
/* Additional safety check: ensure key fits in ipad buffer */
if (key_buffer_size > sizeof(ipad)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(ipad, key_buffer, key_buffer_size);
}
/* ipad contains the key followed by garbage. Xor and fill with 0x36
* to create the ipad value. */
for (i = 0; i < key_buffer_size; i++) {
ipad[i] ^= 0x36;
}
/* Only fill remaining bytes if key_buffer_size < block_size.
* When key_buffer_size == block_size, the entire buffer is already
* processed, so no padding is needed. This check also prevents
* out-of-bounds pointer arithmetic (ipad + key_buffer_size would be
* out of bounds when key_buffer_size == block_size == sizeof(ipad)). */
if (key_buffer_size < block_size) {
/* At this point: key_buffer_size < block_size <= sizeof(ipad),
* so ipad + key_buffer_size is guaranteed to be within bounds. */
size_t fill_size = block_size - key_buffer_size;
memset(ipad + key_buffer_size, 0x36, fill_size);
}
/* Copy the key material from ipad to opad, flipping the requisite bits,
* and filling the rest of opad with the requisite constant. */
for (i = 0; i < key_buffer_size; i++) {
operation->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
}
/* Only fill remaining bytes if key_buffer_size < block_size.
* When key_buffer_size == block_size, the entire buffer is already
* processed, so no padding is needed. This check also prevents
* out-of-bounds pointer arithmetic (operation->opad + key_buffer_size
* would be out of bounds when key_buffer_size == block_size == sizeof(operation->opad)). */
if (key_buffer_size < block_size) {
/* At this point: key_buffer_size < block_size <= sizeof(operation->opad),
* so operation->opad + key_buffer_size is guaranteed to be within bounds. */
size_t fill_size = block_size - key_buffer_size;
memset(operation->opad + key_buffer_size, 0x5C, fill_size);
}
status = esp_sha_hash_setup(&operation->hmac_operation, hash_alg);
if (status != PSA_SUCCESS) {
return status;
}
status = esp_sha_hash_update(&operation->hmac_operation, ipad, block_size);
if (status != PSA_SUCCESS) {
return status;
}
operation->alg = alg;
} else {
(void) attributes;
(void) key_buffer;
(void) key_buffer_size;
status = PSA_ERROR_NOT_SUPPORTED;
}
return status;
}
static void xor_no_simd(unsigned char *output, const unsigned char *input1, const unsigned char *input2, size_t length)
{
for (size_t i = 0; i < length; i++) {
output[i] = input1[i] ^ input2[i];
}
}
static psa_status_t esp_cmac_mac_update_internal(esp_cmac_operation_t *cmac, const uint8_t *data, size_t data_length)
{
unsigned char *state = cmac->state;
int ret = 0;
size_t n, j, olen, block_size;
if (cmac == NULL || data == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
block_size = cmac->cipher_block_length;
/* Is there data still to process from the last call, that's greater in
* size than a block? */
if (cmac->unprocessed_len > 0 && data_length > block_size - cmac->unprocessed_len) {
memcpy(&cmac->unprocessed_block[cmac->unprocessed_len], data, block_size - cmac->unprocessed_len);
xor_no_simd(state, cmac->unprocessed_block, state, block_size);
if ((ret = psa_cipher_update(&cmac->cipher_ctx, state, block_size, state, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != 0) {
goto exit;
}
data += block_size - cmac->unprocessed_len;
data_length -= block_size - cmac->unprocessed_len;
cmac->unprocessed_len = 0;
}
/* n is the number of blocks including any final partial block */
n = (data_length + block_size - 1) / block_size;
/* Iterate across the input data in block sized chunks, excluding any
* final partial or complete block */
for (j = 1; j < n; j++) {
xor_no_simd(state, data, state, block_size);
if ((ret = psa_cipher_update(&cmac->cipher_ctx, state, block_size, state, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != 0) {
goto exit;
}
data_length -= block_size;
data += block_size;
}
/* If there is data left over that wasn't aligned to a block */
if (data_length > 0) {
memcpy(&cmac->unprocessed_block[cmac->unprocessed_len], data, data_length);
cmac->unprocessed_len += data_length;
}
exit:
return ret;
}
psa_status_t esp_cmac_mac_update(esp_cmac_operation_t *cmac, const uint8_t *data, size_t data_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if (PSA_ALG_FULL_LENGTH_MAC(cmac->alg) == PSA_ALG_CMAC) {
status = esp_cmac_mac_update_internal(cmac, data, data_length);
} else if (PSA_ALG_IS_HMAC(cmac->alg)) {
status = esp_sha_hash_update(&cmac->hmac_operation, data, data_length);
} else {
(void) cmac;
(void) data;
(void) data_length;
status = PSA_ERROR_NOT_SUPPORTED;
}
return status;
}
static inline unsigned mbedtls_ct_uint_if_else_0(uint32_t condition, unsigned if1)
{
return (unsigned) (condition & if1);
}
static int cmac_multiply_by_u(unsigned char *output,
const unsigned char *input,
size_t blocksize)
{
const unsigned char R_128 = 0x87;
unsigned char R_n;
uint32_t overflow = 0x00;
int i;
if (blocksize == PSA_AES_BLOCK_SIZE) {
R_n = R_128;
}
#if defined(PSA_WANT_KEY_TYPE_DES)
else if (blocksize == PSA_DES_BLOCK_SIZE) {
const unsigned char R_64 = 0x1B;
R_n = R_64;
}
#endif
else {
return PSA_ERROR_INVALID_ARGUMENT;
}
for (i = (int) blocksize - 4; i >= 0; i -= 4) {
uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0);
uint32_t new_overflow = i32 >> 31;
i32 = (i32 << 1) | overflow;
MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0);
overflow = new_overflow;
}
unsigned char msb = (input[0] >> 7) & 1;
output[blocksize - 1] ^= (unsigned char)(msb * R_n);
return 0;
}
static int cmac_generate_subkeys(psa_cipher_operation_t *ctx, size_t block_size,
unsigned char *K1, unsigned char *K2)
{
int ret = PSA_ERROR_CORRUPTION_DETECTED;
unsigned char L[PSA_CMAC_MAX_BLOCK_SIZE];
size_t olen;
mbedtls_platform_zeroize(L, sizeof(L));
/* Calculate Ek(0) */
if ((ret = psa_cipher_update(ctx, L, block_size, L, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != 0) {
goto exit;
}
/*
* Generate K1 and K2
*/
if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
goto exit;
}
if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
goto exit;
}
exit:
mbedtls_platform_zeroize(L, sizeof(L));
return ret;
}
static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],
size_t padded_block_len,
const unsigned char *last_block,
size_t last_block_len)
{
size_t j;
for (j = 0; j < padded_block_len; j++) {
if (j < last_block_len) {
padded_block[j] = last_block[j];
} else if (j == last_block_len) {
padded_block[j] = 0x80;
} else {
padded_block[j] = 0x00;
}
}
}
static psa_status_t esp_cmac_mac_finish_internal(
esp_cmac_operation_t *cmac,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t olen, block_size;
unsigned char *state, *last_block;
unsigned char K1[PSA_CMAC_MAX_BLOCK_SIZE];
unsigned char K2[PSA_CMAC_MAX_BLOCK_SIZE];
unsigned char M_last[PSA_CMAC_MAX_BLOCK_SIZE];
if (cmac == NULL || mac == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
state = cmac->state;
block_size = cmac->cipher_block_length;
mbedtls_platform_zeroize(K1, sizeof(K1));
mbedtls_platform_zeroize(K2, sizeof(K2));
cmac_generate_subkeys(&cmac->cipher_ctx, block_size, K1, K2);
last_block = cmac->unprocessed_block;
/* Calculate last block */
if (cmac->unprocessed_len < block_size) {
cmac_pad(M_last, block_size, last_block, cmac->unprocessed_len);
xor_no_simd(M_last, M_last, K2, block_size);
} else {
/* Last block is complete block */
xor_no_simd(M_last, last_block, K1, block_size);
}
xor_no_simd(state, M_last, state, block_size);
if ((status = psa_cipher_update(&cmac->cipher_ctx, state, block_size, state, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != 0) {
goto exit;
}
/* CMAC output is always the cipher block size, regardless of requested mac_size */
size_t output_length = (mac_size < block_size) ? mac_size : block_size;
memcpy(mac, state, output_length);
*mac_length = output_length;
exit:
mbedtls_platform_zeroize(K1, sizeof(K1));
mbedtls_platform_zeroize(K2, sizeof(K2));
cmac->unprocessed_len = 0;
mbedtls_platform_zeroize(cmac->unprocessed_block, sizeof(cmac->unprocessed_block));
mbedtls_platform_zeroize(state, PSA_CMAC_MAX_BLOCK_SIZE);
return status;
}
psa_status_t esp_cmac_mac_finish(
esp_cmac_operation_t *cmac,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if (PSA_ALG_FULL_LENGTH_MAC(cmac->alg) == PSA_ALG_CMAC) {
status = esp_cmac_mac_finish_internal(cmac, mac, mac_size, mac_length);
} else if (PSA_ALG_IS_HMAC(cmac->alg)) {
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(cmac->alg);
uint8_t tmp[PSA_HASH_MAX_SIZE];
size_t hash_size = 0;
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
status = esp_sha_hash_finish(&cmac->hmac_operation, tmp, sizeof(tmp), &hash_size);
if (status != PSA_SUCCESS) {
return status;
}
/* From here on, tmp needs to be wiped. */
status = esp_sha_hash_setup(&cmac->hmac_operation, hash_alg);
if (status != PSA_SUCCESS) {
goto exit;
}
status = esp_sha_hash_update(&cmac->hmac_operation, cmac->opad, block_size);
if (status != PSA_SUCCESS) {
goto exit;
}
status = esp_sha_hash_update(&cmac->hmac_operation, tmp, hash_size);
if (status != PSA_SUCCESS) {
goto exit;
}
status = esp_sha_hash_finish(&cmac->hmac_operation, tmp, sizeof(tmp), &hash_size);
if (status != PSA_SUCCESS) {
goto exit;
}
memcpy(mac, tmp, mac_size);
*mac_length = mac_size;
exit:
mbedtls_platform_zeroize(tmp, hash_size);
} else {
(void) cmac;
(void) mac;
(void) mac_length;
(void) mac_size;
status = PSA_ERROR_NOT_SUPPORTED;
}
return status;
}
psa_status_t esp_cmac_mac_compute(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
esp_cmac_operation_t operation = {0};
memset(&operation, 0, sizeof(operation));
status = esp_cmac_mac_setup(&operation,
attributes, key_buffer, key_buffer_size,
alg);
if (status != PSA_SUCCESS) {
goto exit;
}
if (input_length > 0) {
status = esp_cmac_mac_update(&operation, input, input_length);
if (status != PSA_SUCCESS) {
goto exit;
}
}
size_t actual_mac_length = 0;
status = esp_cmac_mac_finish(&operation, mac, mac_size, &actual_mac_length);
if (status == PSA_SUCCESS) {
*mac_length = actual_mac_length;
}
exit:
esp_cmac_mac_abort(&operation);
return status;
}
psa_status_t esp_cmac_mac_verify_finish(
esp_cmac_operation_t *operation,
const uint8_t *mac,
size_t mac_length)
{
uint8_t actual_mac[PSA_MAC_MAX_SIZE];
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if (operation == NULL || mac == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (mac_length > sizeof(actual_mac)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
size_t actual_mac_length = 0;
status = esp_cmac_mac_finish(operation, actual_mac, sizeof(actual_mac), &actual_mac_length);
if (status == PSA_SUCCESS) {
if (memcmp(actual_mac, mac, mac_length) == 0) {
return PSA_SUCCESS;
} else {
return PSA_ERROR_INVALID_SIGNATURE;
}
}
return status;
}
@@ -0,0 +1,403 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <stdint.h>
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_cmac.h"
#include "psa_crypto_driver_esp_cmac_contexts.h"
#include "psa_crypto_driver_esp_aes.h"
#include "mbedtls/constant_time.h"
#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 16
#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)
#define MBEDTLS_IS_BIG_ENDIAN 1
#else
#define MBEDTLS_IS_BIG_ENDIAN 0
#endif
#define MBEDTLS_BSWAP32 __builtin_bswap32
static inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
{
uint32_t r;
#if defined(UINT_UNALIGNED)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
r = *p32;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
r = p32->x;
#else
memcpy(&r, p, sizeof(r));
#endif
return r;
}
static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
{
#if defined(UINT_UNALIGNED)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
*p32 = x;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
p32->x = x;
#else
memcpy(p, &x, sizeof(x));
#endif
}
#define MBEDTLS_GET_UINT32_BE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
? mbedtls_get_unaligned_uint32((data) + (offset)) \
: MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
)
#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \
do { \
mbedtls_put_unaligned_uint32((data) + (offset), \
(MBEDTLS_IS_BIG_ENDIAN) \
? (uint32_t) (n) \
: MBEDTLS_BSWAP32((uint32_t) (n))); \
} while (0)
psa_status_t esp_cmac_abort(esp_cmac_operation_t *esp_cmac_ctx)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_destroy_key(esp_cmac_ctx->key_id);
if (status != PSA_SUCCESS) {
return status;
}
status = esp_aes_cipher_abort(&esp_cmac_ctx->esp_aes_ctx);
if (status != PSA_SUCCESS) {
return status;
}
mbedtls_platform_zeroize(esp_cmac_ctx, sizeof(esp_cmac_operation_t));
return status;
}
psa_status_t esp_cmac_setup(esp_cmac_operation_t *esp_cmac_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
memset(esp_cmac_ctx, 0, sizeof(*esp_cmac_ctx));
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t key_type = psa_get_key_type(attributes);
size_t key_bits = psa_get_key_bits(attributes);
psa_algorithm_t cmac_aes_key_alg = PSA_ALG_ECB_NO_PADDING;
/* Set up key attributes for PSA import */
psa_set_key_type(&key_attributes, key_type);
psa_set_key_bits(&key_attributes, key_bits);
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&key_attributes, cmac_aes_key_alg);
/* Import key for cipher operations */
status = psa_import_key(&key_attributes, key_buffer, key_buffer_size, &esp_cmac_ctx->key_id);
if (status != PSA_SUCCESS) {
goto exit;
}
status = esp_aes_cipher_encrypt_setup(&esp_cmac_ctx->esp_aes_ctx, &key_attributes, key_buffer, key_buffer_size, cmac_aes_key_alg);
if (status != PSA_SUCCESS) {
psa_destroy_key(esp_cmac_ctx->key_id);
goto exit;
}
psa_reset_key_attributes(&key_attributes);
esp_cmac_ctx->alg = alg;
esp_cmac_ctx->unprocessed_len = 0;
esp_cmac_ctx->cipher_block_length = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type);
mbedtls_platform_zeroize(esp_cmac_ctx->state, sizeof(esp_cmac_ctx->state));
mbedtls_platform_zeroize(esp_cmac_ctx->unprocessed_block, sizeof(esp_cmac_ctx->unprocessed_block));
exit:
psa_reset_key_attributes(&key_attributes);
return status;
}
static void xor_no_simd(unsigned char *output, const unsigned char *input1, const unsigned char *input2, size_t length)
{
for (size_t i = 0; i < length; i++) {
output[i] = input1[i] ^ input2[i];
}
}
psa_status_t esp_cmac_update(esp_cmac_operation_t *esp_cmac_ctx, const uint8_t *data, size_t data_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t n, j, olen, block_size;
unsigned char *state;
if (esp_cmac_ctx == NULL || data == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
state = esp_cmac_ctx->state;
block_size = esp_cmac_ctx->cipher_block_length;
/* Is there data still to process from the last call, that's greater in
* size than a block? */
if (esp_cmac_ctx->unprocessed_len > 0 && data_length > block_size - esp_cmac_ctx->unprocessed_len) {
memcpy(&esp_cmac_ctx->unprocessed_block[esp_cmac_ctx->unprocessed_len], data, block_size - esp_cmac_ctx->unprocessed_len);
xor_no_simd(state, esp_cmac_ctx->unprocessed_block, state, block_size);
if ((status = esp_aes_cipher_update(&esp_cmac_ctx->esp_aes_ctx, state, block_size, state, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != PSA_SUCCESS) {
goto exit;
}
data += block_size - esp_cmac_ctx->unprocessed_len;
data_length -= block_size - esp_cmac_ctx->unprocessed_len;
esp_cmac_ctx->unprocessed_len = 0;
}
/* n is the number of blocks including any final partial block */
n = (data_length + block_size - 1) / block_size;
/* Iterate across the input data in block sized chunks, excluding any
* final partial or complete block */
for (j = 1; j < n; j++) {
xor_no_simd(state, data, state, block_size);
if ((status = esp_aes_cipher_update(&esp_cmac_ctx->esp_aes_ctx, state, block_size, state, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != PSA_SUCCESS) {
goto exit;
}
data_length -= block_size;
data += block_size;
}
/* If there is data left over that wasn't aligned to a block */
if (data_length > 0) {
memcpy(&esp_cmac_ctx->unprocessed_block[esp_cmac_ctx->unprocessed_len], data, data_length);
esp_cmac_ctx->unprocessed_len += data_length;
}
status = PSA_SUCCESS;
exit:
return status;
}
static psa_status_t cmac_multiply_by_u(unsigned char *output,
const unsigned char *input,
size_t blocksize)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
const unsigned char R_128 = 0x87;
unsigned char R_n;
uint32_t overflow = 0x00;
int i;
if (blocksize == PSA_AES_BLOCK_SIZE) {
R_n = R_128;
}
#if defined(PSA_WANT_KEY_TYPE_DES)
else if (blocksize == PSA_DES_BLOCK_SIZE) {
const unsigned char R_64 = 0x1B;
R_n = R_64;
}
#endif
else {
status = PSA_ERROR_INVALID_ARGUMENT;
goto exit;
}
for (i = (int) blocksize - 4; i >= 0; i -= 4) {
uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0);
uint32_t new_overflow = i32 >> 31;
i32 = (i32 << 1) | overflow;
MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0);
overflow = new_overflow;
}
unsigned char msb = (input[0] >> 7) & 1;
output[blocksize - 1] ^= (unsigned char)(msb * R_n);
status = PSA_SUCCESS;
exit:
return status;
}
static psa_status_t cmac_generate_subkeys(esp_aes_operation_t *esp_aes_driver_ctx, size_t block_size,
uint8_t *K1, uint8_t *K2)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
uint8_t L[PSA_CMAC_MAX_BLOCK_SIZE];
size_t olen;
mbedtls_platform_zeroize(L, sizeof(L));
/* Calculate Ek(0) */
if ((status = esp_aes_cipher_update(esp_aes_driver_ctx, L, block_size, L, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != PSA_SUCCESS) {
goto exit;
}
/*
* Generate K1 and K2
*/
if ((status = cmac_multiply_by_u(K1, L, block_size)) != PSA_SUCCESS) {
goto exit;
}
if ((status = cmac_multiply_by_u(K2, K1, block_size)) != PSA_SUCCESS) {
goto exit;
}
exit:
mbedtls_platform_zeroize(L, sizeof(L));
return status;
}
static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],
size_t padded_block_len,
const unsigned char *last_block,
size_t last_block_len)
{
size_t j;
for (j = 0; j < padded_block_len; j++) {
if (j < last_block_len) {
padded_block[j] = last_block[j];
} else if (j == last_block_len) {
padded_block[j] = 0x80;
} else {
padded_block[j] = 0x00;
}
}
}
psa_status_t esp_cmac_finish(
esp_cmac_operation_t *esp_cmac_ctx,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t olen, block_size;
unsigned char *state, *last_block;
unsigned char K1[PSA_CMAC_MAX_BLOCK_SIZE];
unsigned char K2[PSA_CMAC_MAX_BLOCK_SIZE];
unsigned char M_last[PSA_CMAC_MAX_BLOCK_SIZE];
if (esp_cmac_ctx == NULL || mac == NULL || mac_size == 0) {
return PSA_ERROR_INVALID_ARGUMENT;
}
state = esp_cmac_ctx->state;
block_size = esp_cmac_ctx->cipher_block_length;
mbedtls_platform_zeroize(K1, sizeof(K1));
mbedtls_platform_zeroize(K2, sizeof(K2));
cmac_generate_subkeys(&esp_cmac_ctx->esp_aes_ctx, block_size, K1, K2);
last_block = esp_cmac_ctx->unprocessed_block;
/* Calculate last block */
if (esp_cmac_ctx->unprocessed_len < block_size) {
cmac_pad(M_last, block_size, last_block, esp_cmac_ctx->unprocessed_len);
xor_no_simd(M_last, M_last, K2, block_size);
} else {
/* Last block is complete block */
xor_no_simd(M_last, last_block, K1, block_size);
}
xor_no_simd(state, M_last, state, block_size);
if ((status = esp_aes_cipher_update(&esp_cmac_ctx->esp_aes_ctx, state, block_size, state, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != PSA_SUCCESS) {
goto exit;
}
/* CMAC output is always the cipher block size, regardless of requested mac_size */
size_t output_length = (mac_size < block_size) ? mac_size : block_size;
memcpy(mac, state, output_length);
*mac_length = output_length;
exit:
mbedtls_platform_zeroize(K1, sizeof(K1));
mbedtls_platform_zeroize(K2, sizeof(K2));
esp_cmac_ctx->unprocessed_len = 0;
mbedtls_platform_zeroize(esp_cmac_ctx->unprocessed_block, sizeof(esp_cmac_ctx->unprocessed_block));
mbedtls_platform_zeroize(state, PSA_CMAC_MAX_BLOCK_SIZE);
return status;
}
psa_status_t esp_cmac_compute(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
esp_cmac_operation_t esp_cmac_ctx = {0};
status = esp_cmac_setup(&esp_cmac_ctx,
attributes, key_buffer, key_buffer_size,
alg);
if (status != PSA_SUCCESS) {
goto exit;
}
if (input_length > 0) {
status = esp_cmac_update(&esp_cmac_ctx, input, input_length);
if (status != PSA_SUCCESS) {
goto exit;
}
}
size_t actual_mac_length = 0;
status = esp_cmac_finish(&esp_cmac_ctx, mac, mac_size, &actual_mac_length);
if (status == PSA_SUCCESS) {
*mac_length = actual_mac_length;
}
exit:
esp_cmac_abort(&esp_cmac_ctx);
return status;
}
psa_status_t esp_cmac_verify_finish(
esp_cmac_operation_t *esp_cmac_ctx,
const uint8_t *mac,
size_t mac_length)
{
uint8_t actual_mac[PSA_MAC_MAX_SIZE];
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if (esp_cmac_ctx == NULL || mac == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (mac_length > sizeof(actual_mac)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
size_t actual_mac_length = 0;
status = esp_cmac_finish(esp_cmac_ctx, actual_mac, sizeof(actual_mac), &actual_mac_length);
if (status == PSA_SUCCESS) {
if (memcmp(actual_mac, mac, mac_length) == 0) {
return PSA_SUCCESS;
} else {
return PSA_ERROR_INVALID_SIGNATURE;
}
}
return status;
}
@@ -0,0 +1,224 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <string.h>
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_hmac_opaque.h"
#include "esp_efuse.h"
#include "esp_efuse_chip.h"
#include "hal/hmac_types.h"
#include "esp_hmac.h"
static bool validate_hmac_opaque_key_attributes(const esp_hmac_opaque_key_t *opaque_key)
{
// efuse_block is uint8_t, so it's always >= 0 (EFUSE_BLK0)
if (opaque_key->efuse_block < EFUSE_BLK_MAX && esp_efuse_get_key_purpose(opaque_key->efuse_block) == ESP_EFUSE_KEY_PURPOSE_HMAC_UP) {
return true;
}
return false;
}
psa_status_t esp_hmac_import_key_opaque(
const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length,
size_t *bits)
{
if (!attributes || !data || !key_buffer || !key_buffer_length || !bits) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (key_buffer_size < sizeof(esp_hmac_opaque_key_t) || data_length < sizeof(esp_hmac_opaque_key_t)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
const esp_hmac_opaque_key_t *opaque_key = (const esp_hmac_opaque_key_t *) data;
bool valid = validate_hmac_opaque_key_attributes(opaque_key);
if (!valid) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(key_buffer, opaque_key, sizeof(esp_hmac_opaque_key_t));
*key_buffer_length = sizeof(esp_hmac_opaque_key_t);
*bits = psa_get_key_bits(attributes);
return PSA_SUCCESS;
}
psa_status_t esp_hmac_abort_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx)
{
if (!esp_hmac_ctx) {
mbedtls_platform_zeroize(esp_hmac_ctx, sizeof(esp_hmac_opaque_operation_t));
}
return PSA_SUCCESS;
}
psa_status_t esp_hmac_setup_opaque(
esp_hmac_opaque_operation_t *esp_hmac_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
if (!esp_hmac_ctx || !attributes || !key_buffer || !key_buffer_size || !alg) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (key_buffer_size < sizeof(esp_hmac_opaque_key_t)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (!PSA_ALG_IS_HMAC(alg)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(alg);
if (hash_alg != PSA_ALG_SHA_256) {
return PSA_ERROR_NOT_SUPPORTED;
}
memset(esp_hmac_ctx, 0, sizeof(esp_hmac_opaque_operation_t));
const esp_hmac_opaque_key_t *opaque_key = (const esp_hmac_opaque_key_t *) key_buffer;
if (!validate_hmac_opaque_key_attributes(opaque_key)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
esp_hmac_ctx->opaque_key = opaque_key;
return PSA_SUCCESS;
}
static hmac_key_id_t translate_efuse_block_to_hmac_key_id(uint8_t efuse_block)
{
return (hmac_key_id_t) (efuse_block - EFUSE_BLK_KEY0);
}
psa_status_t esp_hmac_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length)
{
if (!esp_hmac_ctx || !data || data_length == 0) {
return PSA_ERROR_INVALID_ARGUMENT;
}
hmac_key_id_t hmac_key_id = HMAC_KEY_MAX;
#if SOC_KEY_MANAGER_HMAC_KEY_DEPLOY
if (esp_hmac_ctx->opaque_key->use_km_key) {
hmac_key_id = HMAC_KEY_KM;
} else
#endif /* SOC_KEY_MANAGER_HMAC_KEY_DEPLOY */
{
hmac_key_id = translate_efuse_block_to_hmac_key_id(esp_hmac_ctx->opaque_key->efuse_block);
}
esp_err_t hmac_ret = esp_hmac_calculate(hmac_key_id, data, data_length, esp_hmac_ctx->hmac);
if (hmac_ret == ESP_ERR_INVALID_ARG) {
return PSA_ERROR_INVALID_ARGUMENT;
} else if (hmac_ret == ESP_FAIL) {
return PSA_ERROR_HARDWARE_FAILURE;
} else if (hmac_ret == ESP_OK) {
return PSA_SUCCESS;
}
return PSA_ERROR_CORRUPTION_DETECTED;
}
psa_status_t esp_hmac_finish_opaque(
esp_hmac_opaque_operation_t *esp_hmac_ctx,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
if (!esp_hmac_ctx || !mac || !mac_length) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (mac_size < ESP_HMAC_RESULT_SIZE) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
memcpy(mac, esp_hmac_ctx->hmac, ESP_HMAC_RESULT_SIZE);
*mac_length = ESP_HMAC_RESULT_SIZE;
return PSA_SUCCESS;
}
psa_status_t esp_hmac_compute_opaque(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
esp_hmac_opaque_operation_t esp_hmac_ctx = {0};
status = esp_hmac_setup_opaque(&esp_hmac_ctx, attributes, key_buffer, key_buffer_size, alg);
if (status != PSA_SUCCESS) {
return status;
}
status = esp_hmac_update_opaque(&esp_hmac_ctx, input, input_length);
if (status != PSA_SUCCESS) {
return status;
}
status = esp_hmac_finish_opaque(&esp_hmac_ctx, mac, mac_size, mac_length);
if (status != PSA_SUCCESS) {
return status;
}
return PSA_SUCCESS;
}
psa_status_t esp_hmac_verify_finish_opaque(
esp_hmac_opaque_operation_t *esp_hmac_ctx,
const uint8_t *mac,
size_t mac_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
uint8_t actual_mac[ESP_HMAC_RESULT_SIZE];
size_t actual_mac_length = 0;
status = esp_hmac_finish_opaque(esp_hmac_ctx, actual_mac, sizeof(actual_mac), &actual_mac_length);
if (status != PSA_SUCCESS) {
return status;
}
if (memcmp(mac, actual_mac, mac_length) != 0) {
return PSA_ERROR_INVALID_SIGNATURE;
}
return PSA_SUCCESS;
}
/**
* @brief Get the size of the ESP HMAC opaque key
*
* @param key_type Key type
* @param key_bits Key bits
* @return size_t Size of the ESP HMAC opaque key
*/
size_t esp_hmac_opaque_size_function(
psa_key_type_t key_type,
size_t key_bits)
{
(void)key_type;
(void)key_bits;
// Opaque keys always use the same size structure
return sizeof(esp_hmac_opaque_key_t);
}
@@ -0,0 +1,374 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <stdlib.h>
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_hmac_transparent.h"
#include "psa_crypto_driver_esp_sha.h"
#include "psa_crypto_driver_esp_md5.h"
#include "sdkconfig.h"
psa_status_t esp_hmac_abort_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
#if CONFIG_MBEDTLS_ROM_MD5
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(esp_hmac_ctx->alg);
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_abort(&esp_hmac_ctx->md5_ctx);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
status = esp_sha_hash_abort(&esp_hmac_ctx->esp_sha_ctx);
}
if (status != PSA_SUCCESS) {
return status;
}
// Free dynamically allocated opad buffer
if (esp_hmac_ctx->opad != NULL) {
mbedtls_platform_zeroize(esp_hmac_ctx->opad, PSA_HMAC_MAX_HASH_BLOCK_SIZE);
free(esp_hmac_ctx->opad);
esp_hmac_ctx->opad = NULL;
}
mbedtls_platform_zeroize(esp_hmac_ctx, sizeof(esp_hmac_transparent_operation_t));
return status;
}
psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(alg);
uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
size_t i;
size_t hash_size = PSA_HASH_LENGTH(hash_alg);
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
if (esp_hmac_ctx == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memset(esp_hmac_ctx, 0, sizeof(esp_hmac_transparent_operation_t));
// Allocate opad buffer dynamically
esp_hmac_ctx->opad = (uint8_t *)malloc(PSA_HMAC_MAX_HASH_BLOCK_SIZE);
if (esp_hmac_ctx->opad == NULL) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
memset(esp_hmac_ctx->opad, 0, PSA_HMAC_MAX_HASH_BLOCK_SIZE);
if (
#if CONFIG_MBEDTLS_ROM_MD5
hash_alg != PSA_ALG_MD5 &&
#endif // CONFIG_MBEDTLS_ROM_MD5
(hash_alg < PSA_ALG_SHA_1
#if SOC_SHA_SUPPORT_SHA512
|| hash_alg > PSA_ALG_SHA_512
#else
|| hash_alg > PSA_ALG_SHA_256
#endif // SOC_SHA_SUPPORT_SHA512
)) {
status = PSA_ERROR_NOT_SUPPORTED;
goto error;
}
esp_hmac_ctx->alg = alg;
/* Sanity checks on block_size, to guarantee that there won't be a buffer
* overflow below. This should never trigger if the hash algorithm
* is implemented correctly. */
/* The size check against the ipad buffer also covers opad since both
* have the same size (PSA_HMAC_MAX_HASH_BLOCK_SIZE). */
if ((block_size > sizeof(ipad)) || (block_size < hash_size)) {
status = PSA_ERROR_NOT_SUPPORTED;
goto error;
}
if (key_buffer_size > block_size) {
#if CONFIG_MBEDTLS_ROM_MD5
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_compute(hash_alg, key_buffer, key_buffer_size,
ipad, sizeof(ipad), &key_buffer_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
status = esp_sha_hash_compute(hash_alg, key_buffer, key_buffer_size,
ipad, sizeof(ipad), &key_buffer_size);
}
if (status != PSA_SUCCESS) {
goto error;
}
/* After hashing, key_buffer_size is set to the hash size, which
* should be <= block_size. Verify this for static analysis. */
if (key_buffer_size > block_size) {
status = PSA_ERROR_CORRUPTION_DETECTED;
goto error;
}
}
/* A 0-length key is not commonly used in HMAC when used as a MAC,
* but it is permitted. It is common when HMAC is used in HKDF, for
* example. Don't call `memcpy` in the 0-length because `key` could be
* an invalid pointer which would make the behavior undefined. */
else if (key_buffer_size != 0) {
/* Additional safety check: ensure key fits in ipad buffer */
if (key_buffer_size > sizeof(ipad)) {
status = PSA_ERROR_INVALID_ARGUMENT;
goto error;
}
memcpy(ipad, key_buffer, key_buffer_size);
}
/* ipad contains the key followed by garbage. Xor and fill with 0x36
* to create the ipad value. */
for (i = 0; i < key_buffer_size; i++) {
ipad[i] ^= 0x36;
}
/* Only fill remaining bytes if key_buffer_size < block_size.
* When key_buffer_size == block_size, the entire buffer is already
* processed, so no padding is needed. This check also prevents
* out-of-bounds pointer arithmetic (ipad + key_buffer_size would be
* out of bounds when key_buffer_size == block_size == sizeof(ipad)). */
if (key_buffer_size < block_size) {
/* At this point: key_buffer_size < block_size <= sizeof(ipad),
* so ipad + key_buffer_size is guaranteed to be within bounds. */
size_t fill_size = block_size - key_buffer_size;
memset(ipad + key_buffer_size, 0x36, fill_size);
}
/* Copy the key material from ipad to opad, flipping the requisite bits,
* and filling the rest of opad with the requisite constant. */
for (i = 0; i < key_buffer_size; i++) {
esp_hmac_ctx->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
}
/* Only fill remaining bytes if key_buffer_size < block_size.
* When key_buffer_size == block_size, the entire buffer is already
* processed, so no padding is needed. This check also prevents
* out-of-bounds pointer arithmetic (esp_hmac_ctx->opad + key_buffer_size
* would be out of bounds when key_buffer_size == block_size == sizeof(esp_hmac_ctx->opad)). */
if (key_buffer_size < block_size) {
/* At this point: key_buffer_size < block_size <= sizeof(esp_hmac_ctx->opad),
* so esp_hmac_ctx->opad + key_buffer_size is guaranteed to be within bounds. */
size_t fill_size = block_size - key_buffer_size;
memset(esp_hmac_ctx->opad + key_buffer_size, 0x5C, fill_size);
}
#if CONFIG_MBEDTLS_ROM_MD5
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_setup(&esp_hmac_ctx->md5_ctx, hash_alg);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg);
}
if (status != PSA_SUCCESS) {
goto error;
}
#if CONFIG_MBEDTLS_ROM_MD5
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_update(&esp_hmac_ctx->md5_ctx, ipad, block_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, ipad, block_size);
}
if (status != PSA_SUCCESS) {
goto error;
}
return status;
error:
esp_hmac_abort_transparent(esp_hmac_ctx);
return status;
}
psa_status_t esp_hmac_update_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length)
{
if (esp_hmac_ctx == NULL || data == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
#if CONFIG_MBEDTLS_ROM_MD5
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(esp_hmac_ctx->alg);
if (hash_alg == PSA_ALG_MD5) {
return esp_md5_hash_update(&esp_hmac_ctx->md5_ctx, data, data_length);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
return esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, data, data_length);
}
}
psa_status_t esp_hmac_finish_transparent(
esp_hmac_transparent_operation_t *esp_hmac_ctx,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if (esp_hmac_ctx == NULL || mac == NULL || mac_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(esp_hmac_ctx->alg);
uint8_t tmp[PSA_HASH_MAX_SIZE];
size_t hash_size = 0;
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
#if CONFIG_MBEDTLS_ROM_MD5
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_finish(&esp_hmac_ctx->md5_ctx, tmp, sizeof(tmp), &hash_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
status = esp_sha_hash_finish(&esp_hmac_ctx->esp_sha_ctx, tmp, sizeof(tmp), &hash_size);
}
if (status != PSA_SUCCESS) {
return status;
}
/* From here on, tmp needs to be wiped. */
#if CONFIG_MBEDTLS_ROM_MD5
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_setup(&esp_hmac_ctx->md5_ctx, hash_alg);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg);
}
if (status != PSA_SUCCESS) {
goto exit;
}
#if CONFIG_MBEDTLS_ROM_MD5
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_update(&esp_hmac_ctx->md5_ctx, esp_hmac_ctx->opad, block_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, esp_hmac_ctx->opad, block_size);
}
if (status != PSA_SUCCESS) {
goto exit;
}
#if CONFIG_MBEDTLS_ROM_MD5
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_update(&esp_hmac_ctx->md5_ctx, tmp, hash_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, tmp, hash_size);
}
if (status != PSA_SUCCESS) {
goto exit;
}
#if CONFIG_MBEDTLS_ROM_MD5
if (hash_alg == PSA_ALG_MD5) {
status = esp_md5_hash_finish(&esp_hmac_ctx->md5_ctx, tmp, sizeof(tmp), &hash_size);
} else
#endif // CONFIG_MBEDTLS_ROM_MD5
{
status = esp_sha_hash_finish(&esp_hmac_ctx->esp_sha_ctx, tmp, sizeof(tmp), &hash_size);
}
if (status != PSA_SUCCESS) {
goto exit;
}
if (mac_size < hash_size) {
status = PSA_ERROR_BUFFER_TOO_SMALL;
goto exit;
}
memcpy(mac, tmp, hash_size);
*mac_length = hash_size;
exit:
mbedtls_platform_zeroize(tmp, hash_size);
return status;
}
psa_status_t esp_hmac_compute_transparent(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
esp_hmac_transparent_operation_t esp_hmac_ctx = {0};
status = esp_hmac_setup_transparent(&esp_hmac_ctx,
attributes, key_buffer, key_buffer_size,
alg);
if (status != PSA_SUCCESS) {
goto exit;
}
if (input_length > 0) {
status = esp_hmac_update_transparent(&esp_hmac_ctx, input, input_length);
if (status != PSA_SUCCESS) {
goto exit;
}
}
size_t actual_mac_length = 0;
status = esp_hmac_finish_transparent(&esp_hmac_ctx, mac, mac_size, &actual_mac_length);
if (status == PSA_SUCCESS) {
*mac_length = actual_mac_length;
}
exit:
esp_hmac_abort_transparent(&esp_hmac_ctx);
return status;
}
psa_status_t esp_hmac_verify_finish_transparent(
esp_hmac_transparent_operation_t *esp_hmac_ctx,
const uint8_t *mac,
size_t mac_length)
{
uint8_t actual_mac[PSA_MAC_MAX_SIZE];
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if (esp_hmac_ctx == NULL || mac == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (mac_length > sizeof(actual_mac)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
size_t actual_mac_length = 0;
status = esp_hmac_finish_transparent(esp_hmac_ctx, actual_mac, sizeof(actual_mac), &actual_mac_length);
if (status == PSA_SUCCESS) {
if (memcmp(actual_mac, mac, mac_length) != 0) {
status = PSA_ERROR_INVALID_SIGNATURE;
}
}
mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
return status;
}
@@ -1,10 +1,13 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_aes_contexts.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -14,9 +17,6 @@ extern "C" {
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_aes_contexts.h"
psa_status_t esp_aes_cipher_encrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
@@ -30,29 +30,6 @@ psa_status_t esp_aes_cipher_encrypt(
size_t output_size,
size_t *output_length);
psa_status_t esp_crypto_aes_encrypt_setup(
esp_aes_operation_t *esp_aes_driver_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t esp_crypto_aes_set_iv(
esp_aes_operation_t *esp_aes_driver_ctx,
const uint8_t *iv, size_t iv_length);
psa_status_t esp_crypto_aes_update(
esp_aes_operation_t *esp_aes_driver_ctx,
const uint8_t *input, size_t input_length,
uint8_t *output, size_t output_size,
size_t *output_length);
psa_status_t esp_crypto_aes_finish(
esp_aes_operation_t *esp_aes_driver_ctx,
uint8_t *output, size_t output_size,
size_t *output_length);
psa_status_t esp_crypto_aes_abort(esp_aes_operation_t *esp_aes_driver_ctx);
psa_status_t esp_aes_cipher_decrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
@@ -73,12 +50,12 @@ psa_status_t esp_aes_cipher_encrypt_setup(
psa_algorithm_t alg);
psa_status_t esp_aes_cipher_set_iv(
esp_aes_operation_t *operation,
esp_aes_operation_t *esp_aes_driver_ctx,
const uint8_t *iv,
size_t iv_length);
psa_status_t esp_aes_cipher_update(
esp_aes_operation_t *operation,
esp_aes_operation_t *esp_aes_driver_ctx,
const uint8_t *input,
size_t input_length,
uint8_t *output,
@@ -86,13 +63,13 @@ psa_status_t esp_aes_cipher_update(
size_t *output_length);
psa_status_t esp_aes_cipher_finish(
esp_aes_operation_t *operation,
esp_aes_operation_t *esp_aes_driver_ctx,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t esp_aes_cipher_abort(
esp_aes_operation_t *operation);
esp_aes_operation_t *esp_aes_driver_ctx);
#endif /* ESP_AES_DRIVER_ENABLED */
#ifdef __cplusplus
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -23,9 +23,8 @@ extern "C" {
* crypto_driver_contexts_primitives.h.
*/
#include <stdint.h>
#include <stdbool.h>
#include "esp_types.h"
#include "psa/crypto_driver_common.h"
#if defined(ESP_AES_DRIVER_ENABLED)
#define ESP_MBEDTLS_AES_MAX_BLOCK_LENGTH 16
@@ -44,6 +43,7 @@ typedef struct {
typedef struct {
void *esp_aes_gcm_ctx;
psa_encrypt_or_decrypt_t mode;
size_t tag_length; /* GCM authentication tag length (4, 8, 12-16 bytes) */
} esp_aes_gcm_operation_t;
#endif /* ESP_AES_DRIVER_ENABLED */
@@ -1,20 +1,18 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
// #include_next "mbedtls/gcm.h"
#include "sdkconfig.h"
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_aes_contexts.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ESP_AES_DRIVER_ENABLED)
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_aes_contexts.h"
psa_status_t esp_crypto_aes_gcm_encrypt_setup(
esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx,
@@ -1,54 +1,51 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_cmac_contexts.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ESP_AES_DRIVER_ENABLED)
#if defined(ESP_CMAC_DRIVER_ENABLED)
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_cmac_contexts.h"
psa_status_t esp_cmac_compute(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t esp_cmac_abort(esp_cmac_operation_t *esp_cmac_ctx);
psa_status_t esp_cmac_mac_compute(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t esp_cmac_setup(esp_cmac_operation_t *esp_cmac_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t esp_cmac_mac_abort(esp_cmac_operation_t *operation);
psa_status_t esp_cmac_update(esp_cmac_operation_t *esp_cmac_ctx,
const uint8_t *data,
size_t data_length);
psa_status_t esp_cmac_mac_setup(esp_cmac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t esp_cmac_finish(esp_cmac_operation_t *esp_cmac_ctx,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t esp_cmac_mac_update(esp_cmac_operation_t *cmac,
const uint8_t *data,
size_t data_length);
psa_status_t esp_cmac_verify_finish(esp_cmac_operation_t *esp_cmac_ctx,
const uint8_t *mac,
size_t mac_length);
psa_status_t esp_cmac_mac_finish(
esp_cmac_operation_t *hmac,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t esp_cmac_mac_verify_finish(
esp_cmac_operation_t *operation,
const uint8_t *mac,
size_t mac_length);
#endif /* ESP_AES_DRIVER_ENABLED */
#endif /* ESP_CMAC_DRIVER_ENABLED */
#ifdef __cplusplus
}
@@ -1,30 +1,24 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_types.h"
#include "psa/crypto_driver_common.h"
#include "psa_crypto_driver_esp_aes_contexts.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ESP_AES_DRIVER_ENABLED) || defined(PSA_CRYPTO_DRIVER_TEST)
#if defined(ESP_SHA_DRIVER_ENABLED)
#include "psa_crypto_driver_esp_sha_contexts.h"
#include "psa_crypto_driver_esp_sha.h"
#endif /* ESP_SHA_DRIVER_ENABLED */
#if defined(ESP_CMAC_DRIVER_ENABLED)
#define PSA_AES_BLOCK_SIZE PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES)
#define PSA_DES_BLOCK_SIZE PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_DES)
#if defined(PSA_WANT_KEY_TYPE_AES)
#define PSA_CMAC_MAX_BLOCK_SIZE PSA_AES_BLOCK_SIZE /**< The longest block used by CMAC is that of AES. */
#else
#define PSA_CMAC_MAX_BLOCK_SIZE PSA_DES_BLOCK_SIZE /**< The longest block used by CMAC is that of 3DES. */
#endif
#define PSA_CMAC_MAX_BLOCK_SIZE PSA_AES_BLOCK_SIZE
typedef struct {
/** The CMAC key identifier for cipher operations */
@@ -42,16 +36,12 @@ typedef struct {
uint8_t cipher_block_length;
struct psa_cipher_operation_s cipher_ctx;
esp_aes_operation_t esp_aes_ctx;
psa_algorithm_t alg;
#if defined(ESP_SHA_DRIVER_ENABLED)
esp_sha_hash_operation_t hmac_operation;
uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
#endif /* ESP_SHA_DRIVER_ENABLED */
} esp_cmac_operation_t;
#endif /* ESP_AES_DRIVER_ENABLED */
#endif /* ESP_CMAC_DRIVER_ENABLED */
#ifdef __cplusplus
}
@@ -6,17 +6,17 @@
#pragma once
#if defined(ESP_ECDSA_DRIVER_ENABLED)
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif
#include "psa/crypto.h"
#include "psa/crypto_types.h"
#include "soc/soc_caps.h"
#include "psa_crypto_driver_esp_ecdsa_contexts.h"
#if defined(ESP_ECDSA_DRIVER_ENABLED)
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -6,16 +6,15 @@
#pragma once
#include "stdint.h"
#include "stdbool.h"
#include "esp_types.h"
#include "soc/soc_caps.h"
#include "psa/crypto.h"
#include "psa/crypto_driver_common.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ESP_ECDSA_DRIVER_ENABLED)
#if SOC_ECDSA_SUPPORT_CURVE_P384
#define MAX_ECDSA_COMPONENT_LEN 48
#define MAX_ECDSA_SHA_LEN 48
@@ -75,6 +74,7 @@ typedef struct {
size_t key_len;
} esp_ecdsa_opaque_sign_hash_operation_t;
#endif /* !(__DOXYGEN__) */
#endif /* ESP_ECDSA_DRIVER_ENABLED */
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,104 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_hmac_opaque_contexts.h"
#if defined(ESP_HMAC_OPAQUE_DRIVER_ENABLED)
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief ESP HMAC opaque PSA driver location
*
* Vendor-specific location for ESP hardware HMAC keys.
* Bits 8-31 are location, using vendor flag (0x800000) + ESP vendor ID.
*/
#define PSA_KEY_LOCATION_ESP_HMAC ((psa_key_location_t) 0x800002)
/**
* @brief Construct a lifetime for ESP HMAC keys with default persistence
*/
#define PSA_KEY_LIFETIME_ESP_HMAC \
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \
PSA_KEY_PERSISTENCE_DEFAULT, \
PSA_KEY_LOCATION_ESP_HMAC)
/**
* @brief Construct a volatile lifetime for ESP HMAC keys
*/
#define PSA_KEY_LIFETIME_ESP_HMAC_VOLATILE \
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \
PSA_KEY_PERSISTENCE_VOLATILE, \
PSA_KEY_LOCATION_ESP_HMAC)
/**
* @brief Import an ESP HMAC key reference (not actual key material)
*
* This function imports an opaque reference to a key stored in eFuse or Key Manager.
* The import data should contain the esp_hmac_opaque_key_t structure.
*
* @param attributes Key attributes
* @param data Import data (esp_hmac_opaque_key_t)
* @param data_length Length of import data
* @param key_buffer Output buffer for opaque key
* @param key_buffer_size Size of output buffer
* @param key_buffer_length Actual key buffer length
* @param bits Key size in bits
* @return psa_status_t
*/
psa_status_t esp_hmac_import_key_opaque(const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length,
size_t *bits);
size_t esp_hmac_opaque_size_function(psa_key_type_t key_type, size_t key_bits);
psa_status_t esp_hmac_compute_opaque(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t esp_hmac_abort_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx);
psa_status_t esp_hmac_setup_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t esp_hmac_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx,
const uint8_t *data,
size_t data_length);
psa_status_t esp_hmac_finish_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t esp_hmac_verify_finish_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx,
const uint8_t *mac,
size_t mac_length);
#ifdef __cplusplus
}
#endif
#endif /* ESP_HMAC_OPAQUE_DRIVER_ENABLED */
@@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_types.h"
#include "soc/soc_caps.h"
#include "psa/crypto_driver_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ESP_HMAC_OPAQUE_DRIVER_ENABLED)
/**
* @brief Size of HMAC result in bytes (the opaque driver only supports SHA-256 based HMAC)
*/
#define ESP_HMAC_RESULT_SIZE PSA_HASH_LENGTH(PSA_ALG_HMAC(PSA_ALG_SHA_256))
/**
* @brief Structure to store opaque HMAC key.
*/
typedef struct {
bool use_km_key; /**< Use key deployed in the key manager */
uint8_t efuse_block; /**< eFuse block id for HMAC key */
} esp_hmac_opaque_key_t;
/**
* @brief Structure to store opaque HMAC operation context.
*/
typedef struct {
const esp_hmac_opaque_key_t *opaque_key; /**< Pointer to the opaque key structure */
uint8_t hmac[ESP_HMAC_RESULT_SIZE]; /**< Buffer to store the HMAC result */
} esp_hmac_opaque_operation_t;
#endif /* ESP_HMAC_OPAQUE_DRIVER_ENABLED */
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_hmac_transparent_contexts.h"
#if defined(ESP_HMAC_TRANSPARENT_DRIVER_ENABLED)
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif
#ifdef __cplusplus
extern "C" {
#endif
psa_status_t esp_hmac_compute_transparent(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t esp_hmac_abort_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx);
psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t esp_hmac_update_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
const uint8_t *data,
size_t data_length);
psa_status_t esp_hmac_finish_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t esp_hmac_verify_finish_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
const uint8_t *mac,
size_t mac_length);
#ifdef __cplusplus
}
#endif
#endif /* ESP_HMAC_TRANSPARENT_DRIVER_ENABLED */
@@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_types.h"
#include "soc/soc_caps.h"
#include "psa/crypto_driver_common.h"
#include "psa_crypto_driver_esp_sha_contexts.h"
#include "esp_rom_md5.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ESP_HMAC_TRANSPARENT_DRIVER_ENABLED)
typedef struct {
psa_algorithm_t alg;
uint8_t *opad; // Dynamically allocated to save space
union {
md5_context_t md5_ctx;
esp_sha_hash_operation_t esp_sha_ctx;
};
} esp_hmac_transparent_operation_t;
#endif /* ESP_HMAC_TRANSPARENT_DRIVER_ENABLED */
#ifdef __cplusplus
}
#endif
@@ -5,14 +5,15 @@
*/
#pragma once
#include "esp_types.h"
#include "psa/crypto.h"
#include "esp_rom_md5.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include "psa/crypto.h"
#include "esp_rom_md5.h"
#ifdef CONFIG_MBEDTLS_ROM_MD5
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
@@ -1,18 +1,17 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_sha_contexts.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "psa_crypto_driver_esp_sha_contexts.h"
#include <stdbool.h>
#include "psa/crypto.h"
#ifdef CONFIG_MBEDTLS_HARDWARE_SHA
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
@@ -1,11 +1,16 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_types.h"
#include <stdbool.h>
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -23,10 +28,6 @@ extern "C" {
* crypto_driver_contexts_primitives.h.
*/
#include <stdint.h>
#include <stdbool.h>
#include "sdkconfig.h"
typedef enum {
ESP_SHA_OPERATION_TYPE_SHA1,
ESP_SHA_OPERATION_TYPE_SHA256,
@@ -53,13 +54,13 @@ typedef enum {
ESP_SHA512_STATE_IN_PROCESS
} esp_sha512_state;
#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG
#if SOC_SHA_SUPPORT_PARALLEL_ENG
typedef enum {
ESP_SHA_MODE_UNUSED,
ESP_SHA_MODE_HARDWARE,
ESP_SHA_MODE_SOFTWARE
} esp_sha_mode_t;
#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */
#endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */
/**
* \brief ESP SHA1 context structure
@@ -70,9 +71,9 @@ typedef struct {
unsigned char buffer[64]; /*!< The data block being processed. */
bool first_block; /*!< First block flag for hardware initialization */
int sha_state; /*!< SHA operation state */
#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG
#if SOC_SHA_SUPPORT_PARALLEL_ENG
esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */
#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */
#endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */
} esp_sha1_context;
/**
@@ -85,9 +86,9 @@ typedef struct {
bool first_block; /*!< First block flag for hardware initialization */
int sha_state; /*!< SHA operation state */
int mode; /*!< SHA2_224 or SHA2_256 */
#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG
#if SOC_SHA_SUPPORT_PARALLEL_ENG
esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */
#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */
#endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */
} esp_sha256_context;
/**
@@ -102,9 +103,9 @@ typedef struct {
int sha_state;
int mode;
uint32_t t_val; /*!< t_val for 512/t mode */
#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG
#if SOC_SHA_SUPPORT_PARALLEL_ENG
esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */
#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */
#endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */
} esp_sha512_context;
typedef void *esp_sha_context_t;
@@ -8,7 +8,9 @@
#include "psa/crypto.h"
#include "unity.h"
#include "esp_log.h"
#include "sdkconfig.h"
#if CONFIG_MBEDTLS_ARIA_C
/*
ARIA-256-ECB Encrypt - RFC 5794 test vector
Key: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
@@ -90,3 +92,4 @@ TEST_CASE("PSA ARIA-256-ECB encrypt test vector", "[psa][psa_cipher][aria]")
psa_destroy_key(dec_key_id);
}
#endif /* CONFIG_MBEDTLS_ARIA_C */
@@ -85,10 +85,9 @@ TEST_CASE("PSA CMAC AES-128 test", "[psa_cmac]")
test_data, sizeof(test_data),
cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC),
&cmac_length);
ESP_LOGI("PSA CMAC AES-128", "Status: %ld", status);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(16, cmac_length);
ESP_LOG_BUFFER_HEXDUMP("CMAC AES-128", cmac, cmac_length, ESP_LOG_INFO);
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac, 16);
// Verify CMAC
@@ -75,6 +75,18 @@ const uint8_t sha[] = {
0xb2, 0x60, 0xb2, 0x38, 0x93, 0xa6, 0x27, 0x14
};
#if !defined(ESP_ECDSA_DRIVER_ENABLED)
/**
* @brief ECDSA curve options
*/
typedef enum {
ESP_ECDSA_CURVE_SECP192R1,
ESP_ECDSA_CURVE_SECP256R1,
ESP_ECDSA_CURVE_SECP384R1,
ESP_ECDSA_CURVE_MAX,
} esp_ecdsa_curve_t;
#endif /* !defined(ESP_ECDSA_DRIVER_ENABLED) */
#if CONFIG_MBEDTLS_HARDWARE_ECC || CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
/* Big endian */
@@ -11,6 +11,9 @@
#include "psa/crypto.h"
#include "unity.h"
#include "sdkconfig.h"
#if CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER
static const uint8_t key_256[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -206,3 +209,4 @@ TEST_CASE("PSA ARIA-GCM one-shot", "[psa-gcm]")
/* Destroy the key */
psa_destroy_key(key_id);
}
#endif /* CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER */
+154 -30
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -8,9 +8,13 @@
#include "psa/crypto.h"
#include "unity.h"
static const uint8_t key_128[] = {
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
#include "esp_log.h"
static const uint8_t key_256[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
};
static const uint8_t test_data[] = {
@@ -20,44 +24,164 @@ static const uint8_t test_data[] = {
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51
};
static const uint8_t expected_hmac_128[] = {
0x00, 0x7a, 0x5a, 0xd6, 0x54, 0x96, 0x5b, 0xcd,
0x30, 0xc1, 0x60, 0x62, 0xec, 0xac, 0x75, 0xfb,
0x87, 0x71, 0x0e, 0x13
static const uint8_t expected_hmac_sha1[] = {
0xb7, 0xb4, 0x9b, 0xc1, 0x8a, 0x88, 0x43, 0xa2,
0xbb, 0x34, 0xdf, 0x27, 0xfe, 0x6c, 0x9b, 0x1b,
0xbf, 0x4b, 0x57, 0xb5,
};
static const uint8_t expected_hmac_sha256[] = {
0xc4, 0x45, 0xa1, 0xfc, 0x3f, 0x7e, 0x1b, 0xfc,
0x4a, 0x33, 0x19, 0xfc, 0x68, 0xa5, 0x8e, 0xf1,
0x81, 0x0f, 0x99, 0x70, 0x32, 0x06, 0x2c, 0xcb,
0x50, 0xd7, 0x15, 0x78, 0x82, 0x10, 0xbe, 0xc6,
};
// Helper function to set up key attributes for HMAC
static void setup_hmac_key_attributes(psa_key_attributes_t *attributes,
psa_algorithm_t alg,
psa_key_lifetime_t lifetime)
{
psa_set_key_usage_flags(attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
psa_set_key_algorithm(attributes, alg);
psa_set_key_type(attributes, PSA_KEY_TYPE_HMAC);
psa_set_key_bits(attributes, 256);
psa_set_key_lifetime(attributes, lifetime);
}
// Helper function to perform HMAC compute and verify (single-shot)
static void test_hmac_compute_and_verify(psa_key_id_t key_id,
psa_algorithm_t alg,
const uint8_t *data,
size_t data_len,
const uint8_t *expected_mac,
size_t expected_mac_len)
{
psa_status_t status;
size_t hmac_length = PSA_HASH_LENGTH(alg);
uint8_t *hmac = malloc(hmac_length);
TEST_ASSERT_NOT_NULL(hmac);
size_t mac_length = 0;
status = psa_mac_compute(key_id, alg, data, data_len,
hmac, hmac_length, &mac_length);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_mac_verify(key_id, alg, data, data_len,
expected_mac, expected_mac_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
free(hmac);
}
// Helper function to perform HMAC multipart sign operation
static void test_hmac_multipart_sign(psa_mac_operation_t *op,
psa_key_id_t key_id,
psa_algorithm_t alg,
const uint8_t *data,
size_t data_len,
uint8_t *mac,
size_t mac_size,
size_t *mac_len)
{
psa_status_t status;
status = psa_mac_sign_setup(op, key_id, alg);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_mac_update(op, data, data_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_mac_sign_finish(op, mac, mac_size, mac_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
}
// Helper function to perform HMAC multipart verify operation
static void test_hmac_multipart_verify(psa_mac_operation_t *op,
psa_key_id_t key_id,
psa_algorithm_t alg,
const uint8_t *data,
size_t data_len,
const uint8_t *mac,
size_t mac_len)
{
psa_status_t status;
status = psa_mac_verify_setup(op, key_id, alg);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_mac_update(op, data, data_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_mac_verify_finish(op, mac, mac_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
}
TEST_CASE("PSA HMAC SHA-1 test", "[psa_hmac]")
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id = 0;
psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_1);
// Initialize PSA Crypto
status = PSA_SUCCESS;
// TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
setup_hmac_key_attributes(&attributes, alg, PSA_KEY_LIFETIME_VOLATILE);
// Set up key attributes
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_1));
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
psa_set_key_bits(&attributes, 128);
uint8_t *hmac = malloc(PSA_HASH_LENGTH(PSA_ALG_SHA_1));
TEST_ASSERT_NOT_NULL(hmac);
status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
size_t mac_length = 0;
status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_1),
test_data, sizeof(test_data),
hmac, PSA_HASH_LENGTH(PSA_ALG_SHA_1), &mac_length);
status = psa_import_key(&attributes, key_256, sizeof(key_256), &key_id);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_mac_verify(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_1),
test_data, sizeof(test_data),
expected_hmac_128, sizeof(expected_hmac_128));
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
test_hmac_compute_and_verify(key_id, alg, test_data, sizeof(test_data),
expected_hmac_sha1, sizeof(expected_hmac_sha1));
psa_destroy_key(key_id);
psa_reset_key_attributes(&attributes);
}
TEST_CASE("PSA HMAC SHA-256 test", "[psa_hmac]")
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id = 0;
psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
setup_hmac_key_attributes(&attributes, alg, PSA_KEY_LIFETIME_VOLATILE);
status = psa_import_key(&attributes, key_256, sizeof(key_256), &key_id);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
test_hmac_compute_and_verify(key_id, alg, test_data, sizeof(test_data),
expected_hmac_sha256, sizeof(expected_hmac_sha256));
psa_destroy_key(key_id);
psa_reset_key_attributes(&attributes);
}
TEST_CASE("PSA HMAC SHA-256 multipart test", "[psa_hmac]")
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id = 0;
psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
size_t hmac_length = PSA_HASH_LENGTH(alg);
size_t mac_len = 0;
setup_hmac_key_attributes(&attributes, alg, PSA_KEY_LIFETIME_VOLATILE);
uint8_t *hmac = malloc(hmac_length);
TEST_ASSERT_NOT_NULL(hmac);
status = psa_import_key(&attributes, key_256, sizeof(key_256), &key_id);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
psa_mac_operation_t op = PSA_MAC_OPERATION_INIT;
test_hmac_multipart_sign(&op, key_id, alg, test_data, sizeof(test_data),
hmac, hmac_length, &mac_len);
test_hmac_multipart_verify(&op, key_id, alg, test_data, sizeof(test_data),
expected_hmac_sha256, sizeof(expected_hmac_sha256));
psa_reset_key_attributes(&attributes);
psa_mac_abort(&op);
psa_destroy_key(key_id);
free(hmac);
}
@@ -61,7 +61,7 @@
#error "SHA256 is disabled in mbedtls config"
#endif
#if !defined(MBEDTLS_AES_C)
#if (!defined(MBEDTLS_AES_C) && !defined(PSA_WANT_KEY_TYPE_AES))
#error "AES support is disabled in mbedtls config"
#endif