mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Submodule components/mbedtls/mbedtls updated: 1d21564333...582ff48203
@@ -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"
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
+41
@@ -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 */
|
||||
+32
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user