From 4d2e7fb4d3e67b144118a91c534c020513e98c7e Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Tue, 20 Jan 2026 18:51:56 +0530 Subject: [PATCH 1/9] fix(mbedtls): Enable h/w accel for CMAC and HMAC operations - Refactor ESP-MAC drivers --- components/mbedtls/CMakeLists.txt | 14 +- .../mbedtls/esp_tee/esp_tee_mbedtls.cmake | 12 +- components/mbedtls/mbedtls | 2 +- components/mbedtls/port/aes/esp_aes_gcm.c | 1 - .../esp_aes/psa_crypto_driver_esp_aes.c | 286 ++++---- .../esp_aes/psa_crypto_driver_esp_cmac.c | 623 ------------------ .../esp_mac/psa_crypto_driver_esp_cmac.c | 403 +++++++++++ .../esp_mac/psa_crypto_driver_esp_hmac.c | 250 +++++++ .../include/psa_crypto_driver_esp_aes.h | 33 +- .../include/psa_crypto_driver_esp_cmac.h | 59 +- .../psa_crypto_driver_esp_cmac_contexts.h | 25 +- .../include/psa_crypto_driver_esp_hmac.h | 52 ++ .../psa_crypto_driver_esp_hmac_contexts.h | 28 + .../mbedtls/test_apps/main/test_psa_cipher.c | 3 + .../mbedtls/test_apps/main/test_psa_cmac.c | 3 +- .../mbedtls/test_apps/main/test_psa_gcm.c | 4 + .../esp_supplicant/src/crypto/tls_mbedtls.c | 2 +- tools/ci/check_copyright_ignore.txt | 4 - 18 files changed, 920 insertions(+), 884 deletions(-) delete mode 100644 components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c create mode 100644 components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c create mode 100644 components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac.h create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_contexts.h diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index e75d155f17..7da61c5b47 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -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") @@ -361,8 +357,9 @@ if(CONFIG_SOC_SHA_SUPPORTED) "${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.c" + ) endif() target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha1.c" @@ -411,9 +408,10 @@ if(CONFIG_MBEDTLS_HARDWARE_GCM OR CONFIG_MBEDTLS_HARDWARE_AES) "${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_compile_definitions(tfpsacrypto PRIVATE ESP_CMAC_DRIVER_ENABLED) 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() diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake index f309b888e5..d22d421a21 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake @@ -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) @@ -82,9 +85,10 @@ if(CONFIG_SOC_AES_SUPPORTED) "${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_compile_definitions(tfpsacrypto PRIVATE ESP_CMAC_DRIVER_ENABLED) 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() @@ -99,7 +103,9 @@ if(CONFIG_SOC_SHA_SUPPORTED) "${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.c" + ) endif() if(CONFIG_MBEDTLS_ROM_MD5) diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index 1d21564333..5baeb30f6f 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 1d215643330bb13857a13e3d1403693f6a71976d +Subproject commit 5baeb30f6f46395a1b82360c5e323e66e28395ee diff --git a/components/mbedtls/port/aes/esp_aes_gcm.c b/components/mbedtls/port/aes/esp_aes_gcm.c index 02a6f2c856..b118817ee4 100644 --- a/components/mbedtls/port/aes/esp_aes_gcm.c +++ b/components/mbedtls/port/aes/esp_aes_gcm.c @@ -15,7 +15,6 @@ * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf */ #include -#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "aes/esp_aes.h" #include "aes/esp_aes_gcm.h" #include "esp_aes_internal.h" diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c index a44c584e9c..c6fdf384d2 100644 --- a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c @@ -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; -} diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c deleted file mode 100644 index 0387a1bff0..0000000000 --- a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c +++ /dev/null @@ -1,623 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#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; -} diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c new file mode 100644 index 0000000000..bd3f8bde0e --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c @@ -0,0 +1,403 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#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; +} diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c new file mode 100644 index 0000000000..2e32aab4b7 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c @@ -0,0 +1,250 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD +* +* SPDX-License-Identifier: Apache-2.0 +*/ + +#include +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_hmac.h" +#include "psa_crypto_driver_esp_hmac_contexts.h" + + +psa_status_t esp_hmac_abort(esp_hmac_operation_t *esp_hmac_ctx) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + status = esp_sha_hash_abort(&esp_hmac_ctx->esp_sha_ctx); + if (status != PSA_SUCCESS) { + return status; + } + + mbedtls_platform_zeroize(esp_hmac_ctx, sizeof(esp_hmac_operation_t)); + return status; +} + +psa_status_t esp_hmac_setup(esp_hmac_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_operation_t)); + + /* 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)) { + 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++) { + 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); + } + + status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg); + if (status != PSA_SUCCESS) { + return status; + } + + status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, ipad, block_size); + if (status != PSA_SUCCESS) { + return status; + } + + esp_hmac_ctx->alg = alg; + + return status; +} + +psa_status_t esp_hmac_update(esp_hmac_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length) +{ + return esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, data, data_length); +} + +psa_status_t esp_hmac_finish( + esp_hmac_operation_t *esp_hmac_ctx, + uint8_t *mac, + size_t mac_size, + size_t *mac_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + 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); + + 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. */ + + status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg); + if (status != PSA_SUCCESS) { + goto exit; + } + + status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, esp_hmac_ctx->opad, block_size); + if (status != PSA_SUCCESS) { + goto exit; + } + + status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, tmp, hash_size); + if (status != PSA_SUCCESS) { + goto exit; + } + + status = esp_sha_hash_finish(&esp_hmac_ctx->esp_sha_ctx, 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); + return status; +} + +psa_status_t esp_hmac_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_hmac_operation_t esp_hmac_ctx = {0}; + + status = esp_hmac_setup(&esp_hmac_ctx, + attributes, key_buffer, key_buffer_size, + alg); + if (status != PSA_SUCCESS) { + goto exit; + } + + if (input_length > 0) { + status = esp_hmac_update(&esp_hmac_ctx, input, input_length); + if (status != PSA_SUCCESS) { + goto exit; + } + } + + size_t actual_mac_length = 0; + status = esp_hmac_finish(&esp_hmac_ctx, mac, mac_size, &actual_mac_length); + if (status == PSA_SUCCESS) { + *mac_length = actual_mac_length; + } + +exit: + esp_hmac_abort(&esp_hmac_ctx); + + return status; + +} + +psa_status_t esp_hmac_verify_finish( + esp_hmac_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(esp_hmac_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; +} diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h index 5d24896213..c7244837b2 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h @@ -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 */ @@ -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 diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h index c50322a389..4eb87dc240 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h @@ -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 */ @@ -9,46 +9,43 @@ 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_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_abort(esp_cmac_operation_t *esp_cmac_ctx); -psa_status_t esp_cmac_mac_abort(esp_cmac_operation_t *operation); +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_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_update(esp_cmac_operation_t *esp_cmac_ctx, + const uint8_t *data, + size_t data_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_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_finish( - esp_cmac_operation_t *hmac, - uint8_t *mac, - size_t mac_size, - size_t *mac_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_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 } diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h index d3427c64d0..7fa24ec59d 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h @@ -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 */ @@ -10,21 +10,12 @@ extern "C" { #endif -#if defined(ESP_AES_DRIVER_ENABLED) || defined(PSA_CRYPTO_DRIVER_TEST) +#if defined(ESP_CMAC_DRIVER_ENABLED) -#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 */ +#include "psa_crypto_driver_esp_aes_contexts.h" #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 +33,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 } diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac.h new file mode 100644 index 0000000000..809784481e --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac.h @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ESP_SHA_DRIVER_ENABLED) + +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_hmac_contexts.h" + +psa_status_t esp_hmac_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_hmac_abort(esp_hmac_operation_t *esp_hmac_ctx); + +psa_status_t esp_hmac_setup(esp_hmac_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(esp_hmac_operation_t *esp_hmac_ctx, + const uint8_t *data, + size_t data_length); + +psa_status_t esp_hmac_finish(esp_hmac_operation_t *esp_hmac_ctx, + uint8_t *mac, + size_t mac_size, + size_t *mac_length); + +psa_status_t esp_hmac_verify_finish(esp_hmac_operation_t *esp_hmac_ctx, + const uint8_t *mac, + size_t mac_length); + +#endif /* ESP_SHA_DRIVER_ENABLED */ + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_contexts.h new file mode 100644 index 0000000000..6d4a761437 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_contexts.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ESP_SHA_DRIVER_ENABLED) + +#include "psa_crypto_driver_esp_sha_contexts.h" +#include "psa_crypto_driver_esp_sha.h" + +typedef struct { + uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; + psa_algorithm_t alg; + esp_sha_hash_operation_t esp_sha_ctx; +} esp_hmac_operation_t; + +#endif /* ESP_SHA_DRIVER_ENABLED */ + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/test_apps/main/test_psa_cipher.c b/components/mbedtls/test_apps/main/test_psa_cipher.c index 5b5c8e21da..2d756dc7b4 100644 --- a/components/mbedtls/test_apps/main/test_psa_cipher.c +++ b/components/mbedtls/test_apps/main/test_psa_cipher.c @@ -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 */ diff --git a/components/mbedtls/test_apps/main/test_psa_cmac.c b/components/mbedtls/test_apps/main/test_psa_cmac.c index 3d464f1210..a1f0d9e0c5 100644 --- a/components/mbedtls/test_apps/main/test_psa_cmac.c +++ b/components/mbedtls/test_apps/main/test_psa_cmac.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 diff --git a/components/mbedtls/test_apps/main/test_psa_gcm.c b/components/mbedtls/test_apps/main/test_psa_gcm.c index d66c611cea..5bc858a0c5 100644 --- a/components/mbedtls/test_apps/main/test_psa_gcm.c +++ b/components/mbedtls/test_apps/main/test_psa_gcm.c @@ -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 */ diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c index f8d09c7f47..d6644da586 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c @@ -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 diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index b4e556183a..b06b5ee731 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -466,11 +466,7 @@ components/log/host_test/log_test/main/log_test.cpp components/mbedtls/esp_crt_bundle/test_gen_crt_bundle/test_gen_crt_bundle.py components/mbedtls/port/aes/esp_aes_xts.c components/mbedtls/port/include/aes/esp_aes.h -components/mbedtls/port/include/aes_alt.h components/mbedtls/port/include/bignum_impl.h -components/mbedtls/port/include/sha1_alt.h -components/mbedtls/port/include/sha256_alt.h -components/mbedtls/port/include/sha512_alt.h components/mbedtls/port/sha/parallel_engine/sha.c components/protocomm/include/transports/protocomm_console.h components/protocomm/include/transports/protocomm_httpd.h From 3163ed4167224444bd30c19364579a7cbdaf5774 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Tue, 27 Jan 2026 08:18:59 +0530 Subject: [PATCH 2/9] feat(mbedtls): Introduce ESP-HMAC PSA opaque driver --- components/mbedtls/CMakeLists.txt | 11 +- .../mbedtls/esp_tee/esp_tee_mbedtls.cmake | 3 +- components/mbedtls/mbedtls | 2 +- .../mbedtls/port/include/mbedtls/esp_config.h | 2 + .../psa_crypto_driver_esp_hmac_opaque.c | 224 ++++++++++++++++++ ... psa_crypto_driver_esp_hmac_transparent.c} | 86 ++++--- .../include/psa_crypto_driver_esp_hmac.h | 52 ---- .../psa_crypto_driver_esp_hmac_opaque.h | 104 ++++++++ ...a_crypto_driver_esp_hmac_opaque_contexts.h | 41 ++++ .../psa_crypto_driver_esp_hmac_transparent.h | 55 +++++ ...to_driver_esp_hmac_transparent_contexts.h} | 16 +- .../mbedtls/test_apps/main/test_psa_hmac.c | 184 +++++++++++--- docs/doxygen/Doxyfile | 2 +- docs/en/api-reference/peripherals/hmac.rst | 45 +++- docs/zh_CN/api-reference/peripherals/hmac.rst | 43 +++- 15 files changed, 729 insertions(+), 141 deletions(-) create mode 100644 components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c rename components/mbedtls/port/psa_driver/esp_mac/{psa_crypto_driver_esp_hmac.c => psa_crypto_driver_esp_hmac_transparent.c} (76%) delete mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac.h create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque.h create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent.h rename components/mbedtls/port/psa_driver/include/{psa_crypto_driver_esp_hmac_contexts.h => psa_crypto_driver_esp_hmac_transparent_contexts.h} (63%) diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 7da61c5b47..53bf8aae1b 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -353,12 +353,13 @@ endif() if(CONFIG_SOC_SHA_SUPPORTED) if(CONFIG_MBEDTLS_HARDWARE_SHA) target_compile_definitions(tfpsacrypto PRIVATE ESP_SHA_DRIVER_ENABLED) + target_compile_definitions(tfpsacrypto PRIVATE ESP_HMAC_TRANSPARENT_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/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c" + "${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c" ) endif() target_sources(tfpsacrypto PRIVATE @@ -374,6 +375,14 @@ if(CONFIG_MBEDTLS_ROM_MD5) ) endif() +if(CONFIG_SOC_HMAC_SUPPORTED) + target_compile_definitions(tfpsacrypto PRIVATE ESP_HMAC_OPAQUE_DRIVER_ENABLED) + 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" diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake index d22d421a21..9e6f3bc0c5 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake @@ -97,6 +97,7 @@ endif() # SHA implementation if(CONFIG_SOC_SHA_SUPPORTED) target_compile_definitions(tfpsacrypto PRIVATE ESP_SHA_DRIVER_ENABLED) + target_compile_definitions(tfpsacrypto PRIVATE ESP_HMAC_TRANSPARENT_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" @@ -104,7 +105,7 @@ if(CONFIG_SOC_SHA_SUPPORTED) "${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c" "${COMPONENT_DIR}/port/sha/core/sha.c" "${COMPONENT_DIR}/port/sha/esp_sha.c" - "${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c" + "${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c" ) endif() diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index 5baeb30f6f..582ff48203 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 5baeb30f6f46395a1b82360c5e323e66e28395ee +Subproject commit 582ff482038db6e4010dbf6f943d97b05ad06ea5 diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 22b4217978..6e27e020a0 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -194,6 +194,8 @@ #define MBEDTLS_PSA_ACCEL_ALG_SHA_1 #define MBEDTLS_PSA_ACCEL_ALG_SHA_224 #define MBEDTLS_PSA_ACCEL_ALG_SHA_256 +#define MBEDTLS_PSA_ACCEL_ALG_HMAC +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC #if SOC_SHA_SUPPORT_SHA512 #define MBEDTLS_PSA_ACCEL_ALG_SHA_384 #define MBEDTLS_PSA_ACCEL_ALG_SHA_512 diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c new file mode 100644 index 0000000000..3a2de7e112 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c @@ -0,0 +1,224 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD +* +* SPDX-License-Identifier: Apache-2.0 +*/ + +#include +#include +#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); +} diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c similarity index 76% rename from components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c rename to components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c index 2e32aab4b7..c1c6d7b356 100644 --- a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c @@ -6,11 +6,10 @@ #include #include "psa/crypto.h" -#include "psa_crypto_driver_esp_hmac.h" -#include "psa_crypto_driver_esp_hmac_contexts.h" +#include "psa_crypto_driver_esp_hmac_transparent.h" +#include "psa_crypto_driver_esp_sha.h" - -psa_status_t esp_hmac_abort(esp_hmac_operation_t *esp_hmac_ctx) +psa_status_t esp_hmac_abort_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -19,11 +18,11 @@ psa_status_t esp_hmac_abort(esp_hmac_operation_t *esp_hmac_ctx) return status; } - mbedtls_platform_zeroize(esp_hmac_ctx, sizeof(esp_hmac_operation_t)); + mbedtls_platform_zeroize(esp_hmac_ctx, sizeof(esp_hmac_transparent_operation_t)); return status; } -psa_status_t esp_hmac_setup(esp_hmac_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, @@ -40,7 +39,12 @@ psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx, return PSA_ERROR_INVALID_ARGUMENT; } - memset(esp_hmac_ctx, 0, sizeof(esp_hmac_operation_t)); + memset(esp_hmac_ctx, 0, sizeof(esp_hmac_transparent_operation_t)); + + status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg); + if (status != PSA_SUCCESS) { + goto error; + } /* Sanity checks on block_size, to guarantee that there won't be a buffer * overflow below. This should never trigger if the hash algorithm @@ -48,19 +52,21 @@ psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx, /* 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)) { - return PSA_ERROR_NOT_SUPPORTED; + status = PSA_ERROR_NOT_SUPPORTED; + goto error; } 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; + 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) { - return PSA_ERROR_CORRUPTION_DETECTED; + status = PSA_ERROR_CORRUPTION_DETECTED; + goto error; } } /* A 0-length key is not commonly used in HMAC when used as a MAC, @@ -70,7 +76,8 @@ psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx, 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; + status = PSA_ERROR_INVALID_ARGUMENT; + goto error; } memcpy(ipad, key_buffer, key_buffer_size); } @@ -110,28 +117,29 @@ psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx, memset(esp_hmac_ctx->opad + key_buffer_size, 0x5C, fill_size); } - status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg); - if (status != PSA_SUCCESS) { - return status; - } - status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, ipad, block_size); if (status != PSA_SUCCESS) { - return status; + goto error; } esp_hmac_ctx->alg = alg; + return status; +error: + esp_hmac_abort_transparent(esp_hmac_ctx); return status; } -psa_status_t esp_hmac_update(esp_hmac_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length) +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; + } return esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, data, data_length); } -psa_status_t esp_hmac_finish( - esp_hmac_operation_t *esp_hmac_ctx, +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) @@ -143,6 +151,10 @@ psa_status_t esp_hmac_finish( size_t hash_size = 0; size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg); + if (esp_hmac_ctx == NULL || mac == NULL || mac_length == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + status = esp_sha_hash_finish(&esp_hmac_ctx->esp_sha_ctx, tmp, sizeof(tmp), &hash_size); if (status != PSA_SUCCESS) { return status; @@ -169,16 +181,19 @@ psa_status_t esp_hmac_finish( goto exit; } - memcpy(mac, tmp, mac_size); - - *mac_length = mac_size; + 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( +psa_status_t esp_hmac_compute_transparent( const psa_key_attributes_t *attributes, const uint8_t *key_buffer, size_t key_buffer_size, @@ -190,9 +205,9 @@ psa_status_t esp_hmac_compute( size_t *mac_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - esp_hmac_operation_t esp_hmac_ctx = {0}; + esp_hmac_transparent_operation_t esp_hmac_ctx = {0}; - status = esp_hmac_setup(&esp_hmac_ctx, + status = esp_hmac_setup_transparent(&esp_hmac_ctx, attributes, key_buffer, key_buffer_size, alg); if (status != PSA_SUCCESS) { @@ -200,27 +215,27 @@ psa_status_t esp_hmac_compute( } if (input_length > 0) { - status = esp_hmac_update(&esp_hmac_ctx, input, input_length); + 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(&esp_hmac_ctx, mac, mac_size, &actual_mac_length); + 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(&esp_hmac_ctx); + esp_hmac_abort_transparent(&esp_hmac_ctx); return status; } -psa_status_t esp_hmac_verify_finish( - esp_hmac_operation_t *esp_hmac_ctx, +psa_status_t esp_hmac_verify_finish_transparent( + esp_hmac_transparent_operation_t *esp_hmac_ctx, const uint8_t *mac, size_t mac_length) { @@ -237,14 +252,13 @@ psa_status_t esp_hmac_verify_finish( size_t actual_mac_length = 0; - status = esp_hmac_finish(esp_hmac_ctx, actual_mac, sizeof(actual_mac), &actual_mac_length); + 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) { - return PSA_SUCCESS; - } else { - return PSA_ERROR_INVALID_SIGNATURE; + if (memcmp(actual_mac, mac, mac_length) != 0) { + status = PSA_ERROR_INVALID_SIGNATURE; } } + mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac)); return status; } diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac.h deleted file mode 100644 index 809784481e..0000000000 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(ESP_SHA_DRIVER_ENABLED) - -#include "psa/crypto.h" -#include "psa_crypto_driver_esp_hmac_contexts.h" - -psa_status_t esp_hmac_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_hmac_abort(esp_hmac_operation_t *esp_hmac_ctx); - -psa_status_t esp_hmac_setup(esp_hmac_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(esp_hmac_operation_t *esp_hmac_ctx, - const uint8_t *data, - size_t data_length); - -psa_status_t esp_hmac_finish(esp_hmac_operation_t *esp_hmac_ctx, - uint8_t *mac, - size_t mac_size, - size_t *mac_length); - -psa_status_t esp_hmac_verify_finish(esp_hmac_operation_t *esp_hmac_ctx, - const uint8_t *mac, - size_t mac_length); - -#endif /* ESP_SHA_DRIVER_ENABLED */ - -#ifdef __cplusplus -} -#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque.h new file mode 100644 index 0000000000..4aaadc1491 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque.h @@ -0,0 +1,104 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#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 + +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_hmac_opaque_contexts.h" + +/** + * @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 */ diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h new file mode 100644 index 0000000000..d8cca16acf --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "soc/soc_caps.h" +#include "psa/crypto_driver_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @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; + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent.h new file mode 100644 index 0000000000..ad8b39fcd1 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#if defined(ESP_HMAC_TRANSPARENT_DRIVER_ENABLED) +#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#endif + +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_hmac_transparent_contexts.h" + +#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 */ diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h similarity index 63% rename from components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_contexts.h rename to components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h index 6d4a761437..efade77eb9 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h @@ -6,22 +6,22 @@ #pragma once +#include +#include "soc/soc_caps.h" +#include "psa/crypto_driver_common.h" +#include "psa_crypto_driver_esp_sha_contexts.h" + #ifdef __cplusplus extern "C" { #endif -#if defined(ESP_SHA_DRIVER_ENABLED) - -#include "psa_crypto_driver_esp_sha_contexts.h" -#include "psa_crypto_driver_esp_sha.h" - +#if defined(ESP_HMAC_TRANSPARENT_DRIVER_ENABLED) typedef struct { uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; psa_algorithm_t alg; esp_sha_hash_operation_t esp_sha_ctx; -} esp_hmac_operation_t; - -#endif /* ESP_SHA_DRIVER_ENABLED */ +} esp_hmac_transparent_operation_t; +#endif /* ESP_HMAC_TRANSPARENT_DRIVER_ENABLED */ #ifdef __cplusplus } diff --git a/components/mbedtls/test_apps/main/test_psa_hmac.c b/components/mbedtls/test_apps/main/test_psa_hmac.c index 11f8695f3f..afc7a06705 100644 --- a/components/mbedtls/test_apps/main/test_psa_hmac.c +++ b/components/mbedtls/test_apps/main/test_psa_hmac.c @@ -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); } diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 052f005d20..2b11cb9f10 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -227,7 +227,6 @@ INPUT = \ $(PROJECT_PATH)/components/esp_ringbuf/include/freertos/ringbuf.h \ $(PROJECT_PATH)/components/esp_rom/include/esp_rom_sys.h \ $(PROJECT_PATH)/components/esp_security/include/esp_ds.h \ - $(PROJECT_PATH)/components/esp_security/include/esp_hmac.h \ $(PROJECT_PATH)/components/esp_system/include/esp_expression_with_stack.h \ $(PROJECT_PATH)/components/esp_system/include/esp_freertos_hooks.h \ $(PROJECT_PATH)/components/esp_system/include/esp_ipc_isr.h \ @@ -293,6 +292,7 @@ INPUT = \ $(PROJECT_PATH)/components/lwip/include/apps/ping/ping_sock.h \ $(PROJECT_PATH)/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h \ $(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h \ + $(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h \ $(PROJECT_PATH)/components/nvs_flash/include/nvs_flash.h \ $(PROJECT_PATH)/components/nvs_flash/include/nvs.h \ $(PROJECT_PATH)/components/nvs_flash/include/nvs_bootloader.h \ diff --git a/docs/en/api-reference/peripherals/hmac.rst b/docs/en/api-reference/peripherals/hmac.rst index 641eb161b2..3597246c84 100644 --- a/docs/en/api-reference/peripherals/hmac.rst +++ b/docs/en/api-reference/peripherals/hmac.rst @@ -71,7 +71,7 @@ Key purpose value: 8 In this case, the HMAC is given out to the software, e.g., to authenticate a message. -The API to calculate the HMAC is :cpp:func:`esp_hmac_calculate`. The input arguments for the function are the message, message length, and the eFuse key block ID which contains the secret and has the efuse key purpose set to Upstream mode. +The API to calculate the HMAC is :cpp:func:`psa_mac_compute` with an opaque PSA key with the eFuse key block ID which contains the secret and has the efuse key purpose set to Upstream mode. HMAC for Digital Signature ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,20 +160,53 @@ We use ``esp_efuse_write_key`` to set physical key block 4 in the eFuse for the // writing key failed, maybe written already } -Now we can use the saved key to calculate an HMAC for software usage. +Now we can use the saved key to calculate an HMAC for software usage using the PSA Crypto API. .. code-block:: c - #include "esp_hmac.h" + #include "psa/crypto.h" + #include "psa_crypto_driver_esp_hmac_opaque.h" uint8_t hmac[32]; + size_t hmac_length = 0; const char *message = "Hello, HMAC!"; const size_t msg_len = 12; - esp_err_t result = esp_hmac_calculate(HMAC_KEY4, message, msg_len, hmac); + // 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); - if (result == ESP_OK) { + // Create opaque key reference + esp_hmac_opaque_key_t opaque_key = { + .use_km_key = false, + .efuse_block = EFUSE_BLK_KEY4, + }; + + // Import the opaque key + psa_key_id_t key_id = 0; + psa_status_t status = psa_import_key(&attributes, (uint8_t *)&opaque_key, + sizeof(opaque_key), &key_id); + if (status != PSA_SUCCESS) { + // Failed to import key + psa_reset_key_attributes(&attributes); + return; + } + + // Compute HMAC + status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256), + (uint8_t *)message, msg_len, + hmac, sizeof(hmac), &hmac_length); + + // Clean up + psa_destroy_key(key_id); + psa_reset_key_attributes(&attributes); + + if (status == PSA_SUCCESS) { // HMAC written to hmac now } else { // failure calculating HMAC @@ -182,4 +215,4 @@ Now we can use the saved key to calculate an HMAC for software usage. API Reference ------------- -.. include-build-file:: inc/esp_hmac.inc +.. include-build-file:: inc/psa_crypto_driver_esp_hmac_opaque_contexts.inc diff --git a/docs/zh_CN/api-reference/peripherals/hmac.rst b/docs/zh_CN/api-reference/peripherals/hmac.rst index 4ac7d1551b..692f89a866 100644 --- a/docs/zh_CN/api-reference/peripherals/hmac.rst +++ b/docs/zh_CN/api-reference/peripherals/hmac.rst @@ -71,7 +71,7 @@ HMAC 支持软件使用 在此情况下,HMAC 支持软件使用,如验证消息真实性等。 -API :cpp:func:`esp_hmac_calculate` 用于计算 HMAC。输入参数包括消息、消息长度以及包含密钥的 eFuse 密钥块 ID,且该密钥块的 eFuse 密钥功能设置为上行模式。 +API :cpp:func:`psa_mac_compute` 用于计算 HMAC。输入参数包括消息、消息长度以及包含密钥的 eFuse 密钥块 ID,且该密钥块的 eFuse 密钥功能设置为上行模式。 HMAC 用作数字签名 (DS) 的密钥 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -164,16 +164,49 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接 .. code-block:: c - #include "esp_hmac.h" + #include "psa/crypto.h" + #include "psa_crypto_driver_esp_hmac_opaque.h" uint8_t hmac[32]; + size_t hmac_length = 0; const char *message = "Hello, HMAC!"; const size_t msg_len = 12; - esp_err_t result = esp_hmac_calculate(HMAC_KEY4, message, msg_len, hmac); + // 为 ESP-HMAC 不透明驱动设置密钥属性 + 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); - if (result == ESP_OK) { + // 创建不透明密钥引用 + esp_hmac_opaque_key_t opaque_key = { + .use_km_key = false, + .efuse_block = EFUSE_BLK_KEY4, + }; + + // 导入不透明密钥 + psa_key_id_t key_id = 0; + psa_status_t status = psa_import_key(&attributes, (uint8_t *)&opaque_key, + sizeof(opaque_key), &key_id); + if (status != PSA_SUCCESS) { + // 导入密钥失败 + psa_reset_key_attributes(&attributes); + return; + } + + // 计算 HMAC + status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256), + (uint8_t *)message, msg_len, + hmac, sizeof(hmac), &hmac_length); + + // 清理 + psa_destroy_key(key_id); + psa_reset_key_attributes(&attributes); + + if (status == PSA_SUCCESS) { // HMAC 已写入 hmac 数组 } else { // 计算 HMAC 失败 @@ -182,4 +215,4 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接 API 参考 ------------- -.. include-build-file:: inc/esp_hmac.inc +.. include-build-file:: inc/psa_crypto_driver_esp_hmac_opaque_contexts.inc From 086ba86c987addeda4e2cbf1d4efe84c2eb85fa2 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Tue, 20 Jan 2026 19:12:21 +0530 Subject: [PATCH 3/9] change(mbedtls): Remove legacy headers --- components/mbedtls/port/include/aes_alt.h | 69 -------------- components/mbedtls/port/include/gcm_alt.h | 43 --------- components/mbedtls/port/include/sha1_alt.h | 98 -------------------- components/mbedtls/port/include/sha256_alt.h | 79 ---------------- components/mbedtls/port/include/sha512_alt.h | 97 ------------------- 5 files changed, 386 deletions(-) delete mode 100644 components/mbedtls/port/include/aes_alt.h delete mode 100644 components/mbedtls/port/include/gcm_alt.h delete mode 100644 components/mbedtls/port/include/sha1_alt.h delete mode 100644 components/mbedtls/port/include/sha256_alt.h delete mode 100644 components/mbedtls/port/include/sha512_alt.h diff --git a/components/mbedtls/port/include/aes_alt.h b/components/mbedtls/port/include/aes_alt.h deleted file mode 100644 index 2f8e958b27..0000000000 --- a/components/mbedtls/port/include/aes_alt.h +++ /dev/null @@ -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 diff --git a/components/mbedtls/port/include/gcm_alt.h b/components/mbedtls/port/include/gcm_alt.h deleted file mode 100644 index f76970944b..0000000000 --- a/components/mbedtls/port/include/gcm_alt.h +++ /dev/null @@ -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 diff --git a/components/mbedtls/port/include/sha1_alt.h b/components/mbedtls/port/include/sha1_alt.h deleted file mode 100644 index 26039378b4..0000000000 --- a/components/mbedtls/port/include/sha1_alt.h +++ /dev/null @@ -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 diff --git a/components/mbedtls/port/include/sha256_alt.h b/components/mbedtls/port/include/sha256_alt.h deleted file mode 100644 index 641f5e8930..0000000000 --- a/components/mbedtls/port/include/sha256_alt.h +++ /dev/null @@ -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 diff --git a/components/mbedtls/port/include/sha512_alt.h b/components/mbedtls/port/include/sha512_alt.h deleted file mode 100644 index 51f6423494..0000000000 --- a/components/mbedtls/port/include/sha512_alt.h +++ /dev/null @@ -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 From 2da8ee13a1a892bb57147ecc1d5b19f105bd54b5 Mon Sep 17 00:00:00 2001 From: Shen Mengjing Date: Wed, 28 Jan 2026 19:12:40 +0800 Subject: [PATCH 4/9] docs: Update CN translation for hmac.rst --- docs/en/api-reference/peripherals/hmac.rst | 4 ++-- docs/zh_CN/api-reference/peripherals/hmac.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/api-reference/peripherals/hmac.rst b/docs/en/api-reference/peripherals/hmac.rst index 3597246c84..90e249406f 100644 --- a/docs/en/api-reference/peripherals/hmac.rst +++ b/docs/en/api-reference/peripherals/hmac.rst @@ -71,7 +71,7 @@ Key purpose value: 8 In this case, the HMAC is given out to the software, e.g., to authenticate a message. -The API to calculate the HMAC is :cpp:func:`psa_mac_compute` with an opaque PSA key with the eFuse key block ID which contains the secret and has the efuse key purpose set to Upstream mode. +The API to calculate the HMAC is :cpp:func:`psa_mac_compute`, which takes an opaque PSA key referencing an eFuse key block that contains the secret and has its purpose set to Upstream mode. HMAC for Digital Signature ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,7 +160,7 @@ We use ``esp_efuse_write_key`` to set physical key block 4 in the eFuse for the // writing key failed, maybe written already } -Now we can use the saved key to calculate an HMAC for software usage using the PSA Crypto API. +Now we can calculate an HMAC for software usage with the saved key through the PSA Crypto API. .. code-block:: c diff --git a/docs/zh_CN/api-reference/peripherals/hmac.rst b/docs/zh_CN/api-reference/peripherals/hmac.rst index 692f89a866..2c6a6c383e 100644 --- a/docs/zh_CN/api-reference/peripherals/hmac.rst +++ b/docs/zh_CN/api-reference/peripherals/hmac.rst @@ -71,7 +71,7 @@ HMAC 支持软件使用 在此情况下,HMAC 支持软件使用,如验证消息真实性等。 -API :cpp:func:`psa_mac_compute` 用于计算 HMAC。输入参数包括消息、消息长度以及包含密钥的 eFuse 密钥块 ID,且该密钥块的 eFuse 密钥功能设置为上行模式。 +:cpp:func:`psa_mac_compute` 用于计算 HMAC,该函数接收一个不透明的 PSA 密钥,该密钥引用了包含密钥机密的 eFuse 密钥块,并且该密钥块的用途被设置为上行模式。 HMAC 用作数字签名 (DS) 的密钥 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,7 +160,7 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接 // 密钥写入失败,可能已写入过 } -接下来可以使用已存储的密钥来计算 HMAC,供软件使用。 +接下来可以通过 PSA Crypto API,使用已存储的密钥来计算供软件使用的 HMAC。 .. code-block:: c From 82ff76eb416fff021d7e08b3263b8d4239ec304d Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Thu, 29 Jan 2026 12:19:31 +0530 Subject: [PATCH 5/9] feat(mbedlts/hmac): Support HMAC(MD5) using the MD5 driver --- components/mbedtls/Kconfig | 2 +- .../mbedtls/port/include/mbedtls/esp_config.h | 10 ++ .../psa_crypto_driver_esp_hmac_transparent.c | 142 ++++++++++++++++-- ...pto_driver_esp_hmac_transparent_contexts.h | 8 +- 4 files changed, 143 insertions(+), 19 deletions(-) diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 254a112b44..d06280fdf1 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -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 diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 6e27e020a0..8aeff6986c 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -199,6 +199,7 @@ #if SOC_SHA_SUPPORT_SHA512 #define MBEDTLS_PSA_ACCEL_ALG_SHA_384 #define MBEDTLS_PSA_ACCEL_ALG_SHA_512 +#undef MBEDTLS_PSA_BUILTIN_ALG_HMAC #endif #if SOC_SHA_SUPPORT_SHA512 #else @@ -217,7 +218,12 @@ #ifdef CONFIG_MBEDTLS_ROM_MD5 #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 @@ -2723,6 +2729,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 diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c index c1c6d7b356..d08533c9fe 100644 --- a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c @@ -5,19 +5,38 @@ */ #include +#include #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; - status = esp_sha_hash_abort(&esp_hmac_ctx->esp_sha_ctx); +#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; } @@ -41,11 +60,30 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm memset(esp_hmac_ctx, 0, sizeof(esp_hmac_transparent_operation_t)); - status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg); - if (status != PSA_SUCCESS) { + // 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. */ @@ -57,8 +95,16 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm } 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 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; } @@ -117,12 +163,30 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm memset(esp_hmac_ctx->opad + key_buffer_size, 0x5C, fill_size); } - status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, ipad, block_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; } - esp_hmac_ctx->alg = alg; return status; error: @@ -132,10 +196,20 @@ error: 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; } - return esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, data, data_length); + +#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( @@ -145,38 +219,74 @@ psa_status_t esp_hmac_finish_transparent( 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 (esp_hmac_ctx == NULL || mac == NULL || mac_length == NULL) { - return PSA_ERROR_INVALID_ARGUMENT; +#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); } - - 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. */ - status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg); +#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; } - status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, esp_hmac_ctx->opad, block_size); +#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; } - status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, tmp, hash_size); +#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; } - status = esp_sha_hash_finish(&esp_hmac_ctx->esp_sha_ctx, tmp, sizeof(tmp), &hash_size); +#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; } diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h index efade77eb9..8d24421619 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h @@ -10,6 +10,7 @@ #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" { @@ -17,9 +18,12 @@ extern "C" { #if defined(ESP_HMAC_TRANSPARENT_DRIVER_ENABLED) typedef struct { - uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; psa_algorithm_t alg; - esp_sha_hash_operation_t esp_sha_ctx; + 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 */ From de7f8c88b29ba7359d50576e01f39a3924bd809c Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Fri, 30 Jan 2026 23:02:14 +0530 Subject: [PATCH 6/9] fix(mbedtls): Make the driver define macros public to allow application access - Also, use the PSA HMAC opaque key interface for HMAC-PBKDF2 --- components/mbedtls/CMakeLists.txt | 14 ---- .../mbedtls/esp_tee/esp_tee_mbedtls.cmake | 12 +--- .../mbedtls/esp_tee/esp_tee_mbedtls_config.h | 24 ++++++- components/mbedtls/port/esp_hmac_pbkdf2.c | 52 ++++++++++++-- .../mbedtls/port/include/mbedtls/esp_config.h | 69 ++++++++----------- 5 files changed, 96 insertions(+), 75 deletions(-) diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 53bf8aae1b..e8eac5da22 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -352,8 +352,6 @@ endif() if(CONFIG_SOC_SHA_SUPPORTED) if(CONFIG_MBEDTLS_HARDWARE_SHA) - target_compile_definitions(tfpsacrypto PRIVATE ESP_SHA_DRIVER_ENABLED) - target_compile_definitions(tfpsacrypto PRIVATE ESP_HMAC_TRANSPARENT_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" @@ -369,14 +367,12 @@ 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_compile_definitions(tfpsacrypto PRIVATE ESP_HMAC_OPAQUE_DRIVER_ENABLED) target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c" ) @@ -411,14 +407,12 @@ 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_CMAC_C) - target_compile_definitions(tfpsacrypto PRIVATE ESP_CMAC_DRIVER_ENABLED) target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c" ) @@ -434,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) diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake index 9e6f3bc0c5..dec42ef523 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake @@ -80,24 +80,15 @@ 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_CMAC_C) - target_compile_definitions(tfpsacrypto PRIVATE ESP_CMAC_DRIVER_ENABLED) - target_sources(tfpsacrypto PRIVATE - "${COMPONENT_DIR}/port/psa_driver/esp_mac/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_compile_definitions(tfpsacrypto PRIVATE ESP_HMAC_TRANSPARENT_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" @@ -110,7 +101,6 @@ 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" ) @@ -123,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 diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h index c2695e7fac..563ab82f64 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -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 diff --git a/components/mbedtls/port/esp_hmac_pbkdf2.c b/components/mbedtls/port/esp_hmac_pbkdf2.c index 05dc5f2d44..0a8fb8f845 100644 --- a/components/mbedtls/port/esp_hmac_pbkdf2.c +++ b/components/mbedtls/port/esp_hmac_pbkdf2.c @@ -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 -#include "esp_hmac.h" +#include #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) { diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 8aeff6986c..64dd7635d7 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -191,21 +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 +#undef MBEDTLS_PSA_ACCEL_ALG_SHA_512 +#undef MBEDTLS_SHA512_C +#undef MBEDTLS_SHA384_C #undef MBEDTLS_PSA_BUILTIN_ALG_HMAC -#endif -#if SOC_SHA_SUPPORT_SHA512 #else #undef MBEDTLS_SHA512_ALT #endif - #else #undef MBEDTLS_SHA1_ALT #undef MBEDTLS_SHA256_ALT @@ -216,6 +224,7 @@ 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 @@ -245,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 @@ -287,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 * @@ -499,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, @@ -1737,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 @@ -2663,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. From 556350eea96150765153363d3c75fc355a5af921 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Thu, 29 Jan 2026 15:02:05 +0530 Subject: [PATCH 7/9] fix(mbedtls/include): Fix include libs in the driver's public headers --- .../include/psa_crypto_driver_esp_aes.h | 6 ++--- .../psa_crypto_driver_esp_aes_contexts.h | 7 +++-- .../include/psa_crypto_driver_esp_aes_gcm.h | 8 +++--- .../include/psa_crypto_driver_esp_cmac.h | 6 ++--- .../psa_crypto_driver_esp_cmac_contexts.h | 7 +++-- .../include/psa_crypto_driver_esp_ecdsa.h | 10 +++---- .../psa_crypto_driver_esp_ecdsa_contexts.h | 8 +++--- .../psa_crypto_driver_esp_hmac_opaque.h | 6 ++--- ...a_crypto_driver_esp_hmac_opaque_contexts.h | 6 ++--- .../psa_crypto_driver_esp_hmac_transparent.h | 6 ++--- ...pto_driver_esp_hmac_transparent_contexts.h | 2 +- .../include/psa_crypto_driver_esp_md5.h | 9 ++++--- .../include/psa_crypto_driver_esp_sha.h | 9 +++---- .../psa_crypto_driver_esp_sha_contexts.h | 27 ++++++++++--------- .../mbedtls/test_apps/main/test_psa_ecdsa.c | 12 +++++++++ 15 files changed, 71 insertions(+), 58 deletions(-) diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h index c7244837b2..dcae4979c4 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h @@ -5,6 +5,9 @@ */ #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, diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h index 48475730ac..e9dfd66436 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h @@ -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 -#include - +#include "esp_types.h" +#include "psa/crypto_driver_common.h" #if defined(ESP_AES_DRIVER_ENABLED) #define ESP_MBEDTLS_AES_MAX_BLOCK_LENGTH 16 diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_gcm.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_gcm.h index f8c18b068e..0184bb394e 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_gcm.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_gcm.h @@ -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, diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h index 4eb87dc240..7848db62cf 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h @@ -5,15 +5,15 @@ */ #pragma once +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_cmac_contexts.h" + #ifdef __cplusplus extern "C" { #endif #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, diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h index 7fa24ec59d..68aa25cb4b 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h @@ -6,14 +6,17 @@ #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_CMAC_DRIVER_ENABLED) -#include "psa_crypto_driver_esp_aes_contexts.h" - #define PSA_AES_BLOCK_SIZE PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES) #define PSA_CMAC_MAX_BLOCK_SIZE PSA_AES_BLOCK_SIZE diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa.h index 63e747e0c4..e9f0255efa 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa.h @@ -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 diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h index a1c9743850..2a4d28b5dd 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h @@ -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 diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque.h index 4aaadc1491..d0923d6332 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque.h @@ -5,6 +5,9 @@ */ #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 @@ -14,9 +17,6 @@ extern "C" { #endif -#include "psa/crypto.h" -#include "psa_crypto_driver_esp_hmac_opaque_contexts.h" - /** * @brief ESP HMAC opaque PSA driver location * diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h index d8cca16acf..19ce8d705a 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h @@ -6,15 +6,14 @@ #pragma once -#include -#include +#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) */ @@ -36,6 +35,7 @@ typedef struct { 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 diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent.h index ad8b39fcd1..b81a37d93e 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent.h @@ -5,14 +5,14 @@ */ #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 -#include "psa/crypto.h" -#include "psa_crypto_driver_esp_hmac_transparent_contexts.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h index 8d24421619..0ad70ca7b1 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h @@ -6,7 +6,7 @@ #pragma once -#include +#include "esp_types.h" #include "soc/soc_caps.h" #include "psa/crypto_driver_common.h" #include "psa_crypto_driver_esp_sha_contexts.h" diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5.h index 943f4edd1d..9705ae3319 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5.h @@ -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 -#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 diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h index 2c686a4554..8901ec7fd6 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h @@ -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 -#include "psa/crypto.h" - #ifdef CONFIG_MBEDTLS_HARDWARE_SHA #ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT #define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h index 658a1279f0..19c63c20ff 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h @@ -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 +#include "soc/soc_caps.h" + #ifdef __cplusplus extern "C" { #endif @@ -23,10 +28,6 @@ extern "C" { * crypto_driver_contexts_primitives.h. */ -#include -#include -#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; diff --git a/components/mbedtls/test_apps/main/test_psa_ecdsa.c b/components/mbedtls/test_apps/main/test_psa_ecdsa.c index 397089c532..1ebe7dfe6c 100644 --- a/components/mbedtls/test_apps/main/test_psa_ecdsa.c +++ b/components/mbedtls/test_apps/main/test_psa_ecdsa.c @@ -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 */ From 4122e0e04140f5a35d78685c3c1731cd90297230 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Sat, 31 Jan 2026 00:36:22 +0530 Subject: [PATCH 8/9] fix(mbedtls/psa_driver_aes_gcm): Support shortened tag length for AES-GCM --- .../esp_aes/psa_crypto_driver_esp_aes_gcm.c | 61 +++++++++++++------ .../psa_crypto_driver_esp_aes_contexts.h | 1 + 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c index bd7e4cd335..59e3b9cb66 100644 --- a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c @@ -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 #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: diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h index e9dfd66436..cbe889c41c 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h @@ -43,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 */ From d495ffb49142c44d0e568d310d769629e2e3dcc2 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Sat, 31 Jan 2026 00:37:42 +0530 Subject: [PATCH 9/9] feat(esp_tee/tee_sec_storage): Use PSA interface internally --- .../tee_sec_storage/tee_sec_storage.c | 287 +++++++++++------- 1 file changed, 183 insertions(+), 104 deletions(-) diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c index f9721f6ebb..e34a17307a 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c @@ -5,6 +5,7 @@ */ #include +#include #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