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