Merge branch 'fix/partial-hardware-aes-gcm-and-software-non-aes-ciphers_v6.0' into 'release/v6.0'

Fix partial hardware AES-GCM, software-fallback for non-AES ciphers (v6.0)

See merge request espressif/esp-idf!44752
This commit is contained in:
Mahavir Jain
2026-01-12 09:10:49 +05:30
20 changed files with 642 additions and 314 deletions
+12 -11
View File
@@ -343,6 +343,7 @@ if(CONFIG_SOC_AES_SUPPORTED)
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_xts.c"
"${COMPONENT_DIR}/port/aes/esp_aes_common.c"
"${COMPONENT_DIR}/port/aes/esp_aes.c"
"${COMPONENT_DIR}/port/aes/esp_aes_gcm.c"
)
endif()
@@ -362,6 +363,13 @@ 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_DIG_SIGN_SUPPORTED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c"
@@ -393,17 +401,14 @@ 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.c"
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c"
)
if(CONFIG_MBEDTLS_HARDWARE_SHA)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c"
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c"
)
endif()
if(CONFIG_SOC_AES_SUPPORT_GCM)
target_sources(tfpsacrypto PRIVATE "$ENV{IDF_PATH}/components/mbedtls/port/aes/esp_aes_gcm.c"
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c")
endif()
endif()
if(CONFIG_MBEDTLS_HARDWARE_ECC)
@@ -450,10 +455,6 @@ CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY OR CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN)
endif()
endif()
# if(CONFIG_MBEDTLS_ROM_MD5)
# target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/md/esp_md.c")
# endif()
# if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL)
# target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/mbedtls_rom/mbedtls_rom_osi.c")
# target_link_libraries(${COMPONENT_LIB} PRIVATE "-u mbedtls_rom_osi_functions_init")
+10 -17
View File
@@ -886,22 +886,6 @@ menu "mbedTLS"
3DES is vulnerable to the Sweet32 attack and should only be enabled
if absolutely necessary.
config MBEDTLS_BLOWFISH_C
bool "Blowfish block cipher (read help)"
default n
help
Enables the Blowfish block cipher (not used for TLS sessions.)
The Blowfish cipher is not used for mbedTLS TLS sessions but can be
used for other purposes. Read up on the limitations of Blowfish (including
Sweet32) before enabling.
config MBEDTLS_XTEA_C
bool "XTEA block cipher"
default n
help
Enables the XTEA block cipher.
config MBEDTLS_CCM_C
bool "CCM (Counter with CBC-MAC) block cipher modes"
default y
@@ -1427,6 +1411,15 @@ menu "mbedTLS"
Note that if the ESP32 CPU is running at 240MHz, hardware AES does not
offer any speed boost over software AES.
config MBEDTLS_AES_SOFT_FALLBACK
bool "Enable software fallback for AES"
default n
depends on MBEDTLS_HARDWARE_AES
help
Enable software fallback for AES.
This option is used to fallback to software implementation of AES if the
hardware AES does not support the requested operation.
config MBEDTLS_HARDWARE_GCM
bool "Enable partially hardware accelerated GCM"
depends on SOC_AES_SUPPORT_GCM && MBEDTLS_HARDWARE_AES
@@ -1447,7 +1440,7 @@ menu "mbedTLS"
Enable this config to support fallback to software definitions for a non-AES
cipher GCM operation as we support hardware acceleration only for AES cipher.
Some of the non-AES ciphers used in a GCM operation are DES, ARIA, CAMELLIA,
CHACHA20, BLOWFISH.
CHACHA20.
If this config is disabled, performing a non-AES cipher GCM operation with
the config MBEDTLS_HARDWARE_AES enabled will result in calculation of an
@@ -94,8 +94,6 @@ CONFIG_MBEDTLS_AES_C=y
CONFIG_MBEDTLS_CAMELLIA_C=n
CONFIG_MBEDTLS_ARIA_C=y
CONFIG_MBEDTLS_DES_C=n
CONFIG_MBEDTLS_BLOWFISH_C=n
CONFIG_MBEDTLS_XTEA_C=n
CONFIG_MBEDTLS_CCM_C=y
CONFIG_MBEDTLS_CIPHER_MODE_CBC=y
CONFIG_MBEDTLS_CIPHER_MODE_CFB=y
@@ -46,7 +46,6 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=n
# Symmetric Ciphers
CONFIG_MBEDTLS_ARIA_C=n
CONFIG_MBEDTLS_BLOWFISH_C=n
CONFIG_MBEDTLS_CCM_C=n
CONFIG_MBEDTLS_CIPHER_MODE_OFB=n
CONFIG_MBEDTLS_CIPHER_MODE_XTS=y
@@ -71,23 +71,24 @@ target_include_directories(tfpsacrypto PUBLIC "${COMPONENT_DIR}/port/psa_driver/
# AES implementation
if(CONFIG_SOC_AES_SUPPORTED)
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes.c"
"${COMPONENT_DIR}/port/aes/dma/esp_aes_dma_core.c")
target_compile_definitions(tfpsacrypto PRIVATE ESP_AES_DRIVER_ENABLED)
"${COMPONENT_DIR}/port/aes/dma/esp_aes_dma_core.c"
"${COMPONENT_DIR}/port/aes/esp_aes_gcm.c"
"${COMPONENT_DIR}/port/aes/esp_aes_common.c"
"${COMPONENT_DIR}/port/aes/esp_aes_xts.c")
target_include_directories(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/include/aes")
if(CONFIG_MBEDTLS_HARDWARE_SHA)
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_cmac.c"
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c"
)
endif()
if(CONFIG_SOC_AES_SUPPORT_GCM)
target_sources(tfpsacrypto PRIVATE "$ENV{IDF_PATH}/components/mbedtls/port/aes/esp_aes_gcm.c"
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c")
if(CONFIG_MBEDTLS_HARDWARE_SHA)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c"
)
endif()
endif()
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_common.c"
"${COMPONENT_DIR}/port/aes/esp_aes_xts.c"
"${COMPONENT_DIR}/port/aes/esp_aes_gcm.c")
endif()
# SHA implementation
if(CONFIG_SOC_SHA_SUPPORTED)
@@ -101,6 +102,13 @@ if(CONFIG_SOC_SHA_SUPPORTED)
"${COMPONENT_DIR}/port/sha/esp_sha.c")
endif()
if(CONFIG_MBEDTLS_ROM_MD5)
target_compile_definitions(tfpsacrypto PRIVATE ESP_MD5_DRIVER_ENABLED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_md/psa_crypto_driver_esp_md5.c"
)
endif()
if(CONFIG_SOC_ECC_SUPPORTED)
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/ecc/esp_ecc.c"
"${COMPONENT_DIR}/port/ecc/ecc_alt.c")
@@ -212,12 +212,10 @@
/* MBEDTLS_MDx_ALT to enable ROM MD support
with software fallback.
*/
/* TODO: IDF-15029 */
// #ifdef CONFIG_MBEDTLS_ROM_MD5
// #define MBEDTLS_MD5_ALT
// #else
// #undef MBEDTLS_MD5_ALT
// #endif
#ifdef CONFIG_MBEDTLS_ROM_MD5
#define MBEDTLS_PSA_ACCEL_ALG_MD5
#undef MBEDTLS_PSA_BUILTIN_ALG_MD5
#endif
/* The following MPI (bignum) functions have hardware support.
* Uncommenting these macros will use the hardware-accelerated
@@ -1812,19 +1810,6 @@
#undef MBEDTLS_BIGNUM_C
#endif
/**
* \def MBEDTLS_BLOWFISH_C
*
* Enable the Blowfish block cipher.
*
* Module: library/blowfish.c
*/
#ifdef CONFIG_MBEDTLS_BLOWFISH_C
#define MBEDTLS_BLOWFISH_C
#else
#undef MBEDTLS_BLOWFISH_C
#endif
/**
* \def MBEDTLS_CAMELLIA_C
*
@@ -1879,7 +1864,7 @@
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
*/
#ifdef CONFIG_MBEDTLS_CAMELLIA_C
#define MBEDTLS_CAMELLIA_C
#define PSA_WANT_KEY_TYPE_CAMELLIA 1
#else
#undef MBEDTLS_CAMELLIA_C
#undef PSA_WANT_KEY_TYPE_CAMELLIA
@@ -1938,6 +1923,7 @@
#ifdef CONFIG_MBEDTLS_ARIA_C
#define PSA_WANT_KEY_TYPE_ARIA 1
#else
#undef MBEDTLS_ARIA_C
#undef PSA_WANT_KEY_TYPE_ARIA
#endif
@@ -1980,9 +1966,10 @@
* Module: library/chacha20.c
*/
#ifdef CONFIG_MBEDTLS_CHACHA20_C
#define MBEDTLS_CHACHA20_C
#define PSA_WANT_KEY_TYPE_CHACHA20 1
#else
#undef MBEDTLS_CHACHA20_C
#undef PSA_WANT_KEY_TYPE_CHACHA20
#endif
/**
@@ -1995,9 +1982,10 @@
* This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C
*/
#ifdef CONFIG_MBEDTLS_CHACHAPOLY_C
#define MBEDTLS_CHACHAPOLY_C
#define PSA_WANT_ALG_CHACHA20_POLY1305 1
#else
#undef MBEDTLS_CHACHAPOLY_C
#undef PSA_WANT_ALG_CHACHA20_POLY1305
#endif
/**
@@ -3035,20 +3023,6 @@
#undef MBEDTLS_X509_CSR_WRITE_C
#endif
/**
* \def MBEDTLS_XTEA_C
*
* Enable the XTEA block cipher.
*
* Module: library/xtea.c
* Caller:
*/
#ifdef CONFIG_MBEDTLS_XTEA_C
#define MBEDTLS_XTEA_C
#else
#undef MBEDTLS_XTEA_C
#endif
/* \} name SECTION: mbed TLS modules */
/**
-119
View File
@@ -1,119 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_rom_md5.h"
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_IDF_TARGET_ESP32C2
typedef struct mbedtls_md5_context mbedtls_md5_context;
#else
typedef struct MD5Context mbedtls_md5_context;
#endif
/**
* \brief Initialize MD5 context
*
* \param ctx MD5 context to be initialized
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void esp_md5_init( mbedtls_md5_context *ctx );
/**
* \brief Clear MD5 context
*
* \param ctx MD5 context to be cleared
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void esp_md5_free( mbedtls_md5_context *ctx );
/**
* \brief Clone (the state of) an MD5 context
*
* \param dst The destination context
* \param src The context to be cloned
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void esp_md5_clone( mbedtls_md5_context *dst, const mbedtls_md5_context *src );
/**
* \brief MD5 context setup
*
* \param ctx context to be initialized
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_starts( mbedtls_md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int esp_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD5 final digest
*
* \param ctx MD5 context
* \param output MD5 checksum result
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int esp_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] );
/**
* \brief MD5 process data block (internal use only)
*
* \param ctx MD5 context
* \param data buffer holding one block of data
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int esp_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
-35
View File
@@ -1,35 +0,0 @@
/*
* md5_alt.h: MD5 block cipher
*
* SPDX-FileCopyrightText: The Mbed TLS Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
*/
#ifndef MD5_ALT_H
#define MD5_ALT_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_MD5_ALT)
#include "md/esp_md.h"
#define mbedtls_md5_init esp_md5_init
#define mbedtls_md5_update esp_md5_update
#define mbedtls_md5_finish esp_md5_finish
#define mbedtls_md5_starts esp_md5_starts
#define mbedtls_md5_free esp_md5_free
#define mbedtls_md5_clone esp_md5_clone
#define mbedtls_internal_md5_process esp_md5_process
#endif /* MBEDTLS_MD5_ALT */
#ifdef __cplusplus
}
#endif
#endif
-61
View File
@@ -1,61 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include "mbedtls/md5.h"
#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_MD5_ALT)
#include "md/esp_md.h"
int esp_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] )
{
esp_rom_md5_final(output, ctx);
return 0;
}
int esp_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen )
{
esp_rom_md5_update(ctx, input, ilen);
return 0;
}
void esp_md5_init( mbedtls_md5_context *ctx )
{
esp_rom_md5_init(ctx);
}
int esp_md5_starts( mbedtls_md5_context *ctx )
{
esp_md5_init(ctx);
return 0;
}
void esp_md5_free( mbedtls_md5_context *ctx )
{
if (ctx == NULL) {
return;
}
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) );
}
int esp_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] )
{
esp_md5_update(ctx, data, 64);
return 0;
}
void esp_md5_clone( mbedtls_md5_context *dst, const mbedtls_md5_context *src )
{
*dst = *src;
}
#endif
@@ -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
*/
@@ -458,10 +458,10 @@ static psa_status_t esp_crypto_aes_setup(
goto exit;
}
// if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) {
// 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:
@@ -529,8 +529,6 @@ psa_status_t esp_aes_cipher_encrypt(
memset(&esp_aes_driver_ctx, 0, sizeof(esp_aes_operation_t));
size_t update_output_length, finish_output_length;
// ESP_LOGI("esp_aes_cipher_encrypt", "Starting encryption");
status = esp_aes_cipher_encrypt_setup(&esp_aes_driver_ctx, attributes,
key_buffer, key_buffer_size,
alg);
@@ -642,8 +640,6 @@ exit:
esp_crypto_aes_abort(&esp_aes_driver_ctx);
}
// printf("AES decryption finished with status: %ld\n", status);
return status;
}
@@ -14,7 +14,7 @@
#include "../include/psa_crypto_driver_esp_aes_contexts.h"
// #ifdef ESP_MBEDTLS_AES_ACCEL
#if (defined(ESP_AES_DRIVER_ENABLED) || defined(MBEDTLS_HARDWARE_GCM))
#if defined(ESP_AES_DRIVER_ENABLED)
#define ESP_AES_GCM_TAG_LENGTH 16
@@ -271,4 +271,4 @@ exit:
return status;
}
// #endif /* ESP_MBEDTLS_AES_ACCEL */
#endif /* ESP_AES_DRIVER_ENABLED && MBEDTLS_HARDWARE_GCM */
#endif /* ESP_AES_DRIVER_ENABLED */
@@ -0,0 +1,101 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "psa_crypto_driver_esp_md5.h"
psa_status_t esp_md5_hash_compute(psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *hash,
size_t hash_size,
size_t *hash_length)
{
if (hash == NULL || hash_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (input_length > 0 && input == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (hash_size < PSA_HASH_LENGTH(PSA_ALG_MD5)) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
if (alg != PSA_ALG_MD5) {
return PSA_ERROR_NOT_SUPPORTED;
}
md5_context_t operation = {0};
esp_rom_md5_init(&operation);
esp_rom_md5_update(&operation, input, input_length);
esp_rom_md5_final(hash, &operation);
*hash_length = PSA_HASH_LENGTH(PSA_ALG_MD5);
return PSA_SUCCESS;
}
psa_status_t esp_md5_hash_setup(md5_context_t *operation,
psa_algorithm_t alg)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (alg != PSA_ALG_MD5) {
return PSA_ERROR_NOT_SUPPORTED;
}
esp_rom_md5_init(operation);
return PSA_SUCCESS;
}
psa_status_t esp_md5_hash_update(
md5_context_t *operation,
const uint8_t *input,
size_t input_length )
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (input_length > 0 && input == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
esp_rom_md5_update(operation, input, input_length);
return PSA_SUCCESS;
}
psa_status_t esp_md5_hash_finish(
md5_context_t *operation,
uint8_t *hash,
size_t hash_size,
size_t *hash_length)
{
if (operation == NULL || hash == NULL || hash_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (hash_size < PSA_HASH_LENGTH(PSA_ALG_MD5)) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
esp_rom_md5_final(hash, operation);
*hash_length = PSA_HASH_LENGTH(PSA_ALG_MD5);
return PSA_SUCCESS;
}
psa_status_t esp_md5_hash_abort(md5_context_t *operation)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memset(operation, 0, sizeof(*operation));
return PSA_SUCCESS;
}
psa_status_t esp_md5_hash_clone(
const md5_context_t *source_operation,
md5_context_t *target_operation)
{
if (source_operation == NULL || target_operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(target_operation, source_operation, sizeof(md5_context_t));
return PSA_SUCCESS;
}
@@ -12,7 +12,7 @@
extern "C" {
#endif
#if (defined(ESP_AES_DRIVER_ENABLED) || defined(MBEDTLS_HARDWARE_GCM))
#if defined(ESP_AES_DRIVER_ENABLED)
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_aes_contexts.h"
@@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include "psa/crypto.h"
#include "esp_rom_md5.h"
#ifdef CONFIG_MBEDTLS_ROM_MD5
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif
#endif // CONFIG_MBEDTLS_ROM_MD5
psa_status_t esp_md5_hash_compute(psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *hash,
size_t hash_size,
size_t *hash_length);
psa_status_t esp_md5_hash_setup(md5_context_t *operation,
psa_algorithm_t alg);
psa_status_t esp_md5_hash_update(
md5_context_t *operation,
const uint8_t *input,
size_t input_length );
psa_status_t esp_md5_hash_finish(
md5_context_t *operation,
uint8_t *hash,
size_t hash_size,
size_t *hash_length);
psa_status_t esp_md5_hash_abort(md5_context_t *operation);
psa_status_t esp_md5_hash_clone(
const md5_context_t *source_operation,
md5_context_t *target_operation);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,263 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "psa/crypto.h"
#include "esp_types.h"
#include "esp_log.h"
#include "ccomp_timer.h"
#include "unity.h"
#include "test_utils.h"
#include "esp_heap_caps.h"
#include "test_mbedtls_utils.h"
#define TAG "md5_test"
#define MD5_HASH_LEN 16
TEST_CASE("Test PSA MD5 with known test vectors", "[hw_crypto][psa]")
{
ESP_LOGI(TAG, "Testing MD5 implementation with known test vectors");
uint8_t input[128] = {0};
for (int i = 0; i < 128; i++) {
input[i] = i;
}
uint8_t hash_output[MD5_HASH_LEN] = {0};
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
size_t hash_len = 0;
status = psa_hash_setup(&operation, PSA_ALG_MD5);
TEST_ASSERT_EQUAL(status, PSA_SUCCESS);
status = psa_hash_update(&operation, input, sizeof(input));
TEST_ASSERT_EQUAL(status, PSA_SUCCESS);
status = psa_hash_finish(&operation, hash_output, MD5_HASH_LEN, &hash_len);
TEST_ASSERT_EQUAL(status, PSA_SUCCESS);
uint8_t expected_hash[MD5_HASH_LEN] = {
0x37, 0xEF, 0xF0, 0x18, 0x66, 0xBA, 0x3F, 0x53, 0x84, 0x21, 0xB3, 0x0B, 0x7C, 0xBE, 0xFC, 0xAC
};
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_hash, hash_output, MD5_HASH_LEN);
}
TEST_CASE("Test PSA MD5 error cases", "[hw_crypto][psa]")
{
ESP_LOGI(TAG, "Testing MD5 error handling");
uint8_t input[64] = {0};
uint8_t hash_output[MD5_HASH_LEN] = {0};
size_t hash_len = 0;
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
psa_status_t status;
// Test 1: NULL hash buffer in hash_compute
status = psa_hash_compute(PSA_ALG_MD5, input, sizeof(input), NULL, MD5_HASH_LEN, &hash_len);
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status);
// Test 2: NULL input with non-zero length in hash_compute
status = psa_hash_compute(PSA_ALG_MD5, NULL, 10, hash_output, MD5_HASH_LEN, &hash_len);
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status);
// Test 3: Buffer too small in hash_compute
status = psa_hash_compute(PSA_ALG_MD5, input, sizeof(input), hash_output, MD5_HASH_LEN - 1, &hash_len);
TEST_ASSERT_EQUAL(PSA_ERROR_BUFFER_TOO_SMALL, status);
// Test 4: NULL input with non-zero length in hash_update
operation = psa_hash_operation_init();
status = psa_hash_setup(&operation, PSA_ALG_MD5);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_update(&operation, NULL, 10);
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status);
psa_hash_abort(&operation);
// Test 5: NULL hash buffer in hash_finish
operation = psa_hash_operation_init();
status = psa_hash_setup(&operation, PSA_ALG_MD5);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_finish(&operation, NULL, MD5_HASH_LEN, &hash_len);
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status);
psa_hash_abort(&operation);
// Test 6: Buffer too small in hash_finish
operation = psa_hash_operation_init();
status = psa_hash_setup(&operation, PSA_ALG_MD5);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_update(&operation, input, sizeof(input));
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_finish(&operation, hash_output, 8, &hash_len);
TEST_ASSERT_EQUAL(PSA_ERROR_BUFFER_TOO_SMALL, status);
psa_hash_abort(&operation);
// Test 7: Multiple aborts should be safe
operation = psa_hash_operation_init();
status = psa_hash_setup(&operation, PSA_ALG_MD5);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_abort(&operation);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_abort(&operation);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
ESP_LOGI(TAG, "All MD5 error cases passed");
}
TEST_CASE("Test PSA MD5 clone operation", "[hw_crypto][psa]")
{
ESP_LOGI(TAG, "Testing MD5 clone operation");
uint8_t input_part1[32];
uint8_t input_part2[32];
for (int i = 0; i < 32; i++) {
input_part1[i] = i;
input_part2[i] = i + 32;
}
uint8_t hash_output1[MD5_HASH_LEN] = {0};
uint8_t hash_output2[MD5_HASH_LEN] = {0};
size_t hash_len1 = 0, hash_len2 = 0;
psa_hash_operation_t operation1 = PSA_HASH_OPERATION_INIT;
psa_hash_operation_t operation2 = PSA_HASH_OPERATION_INIT;
psa_status_t status;
// Setup and update first operation
status = psa_hash_setup(&operation1, PSA_ALG_MD5);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_update(&operation1, input_part1, sizeof(input_part1));
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
// Clone the operation
status = psa_hash_clone(&operation1, &operation2);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
// Continue both operations with the same data
status = psa_hash_update(&operation1, input_part2, sizeof(input_part2));
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_update(&operation2, input_part2, sizeof(input_part2));
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
// Finish both operations
status = psa_hash_finish(&operation1, hash_output1, MD5_HASH_LEN, &hash_len1);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_finish(&operation2, hash_output2, MD5_HASH_LEN, &hash_len2);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
// Both should produce the same hash
TEST_ASSERT_EQUAL_HEX8_ARRAY(hash_output1, hash_output2, MD5_HASH_LEN);
ESP_LOGI(TAG, "MD5 clone operation test passed");
}
TEST_CASE("Test PSA MD5 with zero-length input", "[hw_crypto][psa]")
{
ESP_LOGI(TAG, "Testing MD5 with zero-length input");
uint8_t hash_output[MD5_HASH_LEN] = {0};
size_t hash_len = 0;
psa_status_t status;
// Empty string MD5 hash: d41d8cd98f00b204e9800998ecf8427e
uint8_t expected_hash[MD5_HASH_LEN] = {
0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E
};
// Test with hash_compute
status = psa_hash_compute(PSA_ALG_MD5, NULL, 0, hash_output, MD5_HASH_LEN, &hash_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(MD5_HASH_LEN, hash_len);
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_hash, hash_output, MD5_HASH_LEN);
// Test with hash_setup/update/finish
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
memset(hash_output, 0, MD5_HASH_LEN);
status = psa_hash_setup(&operation, PSA_ALG_MD5);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_update(&operation, NULL, 0);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = psa_hash_finish(&operation, hash_output, MD5_HASH_LEN, &hash_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(MD5_HASH_LEN, hash_len);
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_hash, hash_output, MD5_HASH_LEN);
ESP_LOGI(TAG, "Zero-length input test passed");
}
TEST_CASE("Test PSA MD5 incremental updates", "[hw_crypto][psa]")
{
ESP_LOGI(TAG, "Testing MD5 incremental updates");
uint8_t input[128];
for (int i = 0; i < 128; i++) {
input[i] = i;
}
uint8_t hash_full[MD5_HASH_LEN] = {0};
uint8_t hash_incremental[MD5_HASH_LEN] = {0};
size_t hash_len = 0;
psa_status_t status;
// Compute hash in one go
status = psa_hash_compute(PSA_ALG_MD5, input, sizeof(input), hash_full, MD5_HASH_LEN, &hash_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
// Compute hash incrementally in small chunks
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
status = psa_hash_setup(&operation, PSA_ALG_MD5);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
for (int i = 0; i < 128; i += 16) {
status = psa_hash_update(&operation, input + i, 16);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
}
status = psa_hash_finish(&operation, hash_incremental, MD5_HASH_LEN, &hash_len);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
// Both methods should produce the same hash
TEST_ASSERT_EQUAL_HEX8_ARRAY(hash_full, hash_incremental, MD5_HASH_LEN);
ESP_LOGI(TAG, "Incremental updates test passed");
}
TEST_CASE("psa MD5 performance", "[mbedtls]")
{
const unsigned CALLS = 256;
const unsigned CALL_SZ = 16 * 1024;
float elapsed_usec;
uint8_t hash_output[MD5_HASH_LEN] = {0};
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
psa_status_t status = psa_hash_setup(&operation, PSA_ALG_MD5);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
// allocate internal memory
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
TEST_ASSERT_NOT_NULL(buf);
memset(buf, 0x55, CALL_SZ);
ccomp_timer_start();
for (int c = 0; c < CALLS; c++) {
status = psa_hash_update(&operation, buf, CALL_SZ);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
}
size_t hash_length;
status = psa_hash_finish(&operation, hash_output, MD5_HASH_LEN, &hash_length);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
elapsed_usec = ccomp_timer_stop();
free(buf);
const char *expected_hash = "9a9819e47b2014589ae2057458664df7";
char hash_str[MD5_HASH_LEN * 2 + 1];
utils_bin2hex(hash_str, sizeof(hash_str), hash_output, MD5_HASH_LEN);
TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str);
float mb_sec = (CALL_SZ * CALLS) / elapsed_usec;
printf("MD5 rate %.3fMB/sec\n", mb_sec);
}
@@ -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
*/
@@ -867,3 +867,77 @@ TEST_CASE("PSA AES-CBC one-shot", "[psa-aes]")
/* Destroy the key */
psa_destroy_key(key_id);
}
static const uint8_t key_192[24] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
};
TEST_CASE("PSA AES-CBC-192", "[psa-aes]")
{
const size_t SZ = 1008;
const size_t iv_SZ = 16;
const uint8_t expected_cipher_end[] = {
0x57, 0x6a, 0x75, 0xb4, 0x5d, 0xbc, 0x96, 0xf8,
0xa4, 0xb7, 0xb6, 0x0c, 0x6b, 0xa5, 0x1e, 0x02,
};
const uint8_t iv_seed[] = {
0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09,
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
};
uint8_t iv[iv_SZ];
uint8_t *plaintext = malloc(SZ);
uint8_t *ciphertext = malloc(SZ);
uint8_t *decryptedtext = malloc(SZ);
memcpy(iv, iv_seed, iv_SZ);
memset(plaintext, 0x3A, SZ);
memset(decryptedtext, 0x0, SZ);
psa_key_id_t key_id;
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_CBC_NO_PADDING);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 192);
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_192, sizeof(key_192), &key_id));
psa_reset_key_attributes(&attributes);
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
size_t out_len = 0, total_out = 0;
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, PSA_ALG_CBC_NO_PADDING));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext, SZ, ciphertext, SZ, &out_len));
total_out += out_len;
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out, SZ - total_out, &out_len));
total_out += out_len;
TEST_ASSERT_EQUAL_size_t(SZ, total_out);
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - sizeof(expected_cipher_end), sizeof(expected_cipher_end));
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
total_out = 0;
memcpy(iv, iv_seed, iv_SZ);
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, PSA_ALG_CBC_NO_PADDING));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext, SZ, decryptedtext, SZ, &out_len));
total_out += out_len;
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out, SZ - total_out, &out_len));
total_out += out_len;
TEST_ASSERT_EQUAL_size_t(SZ, total_out);
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
psa_cipher_abort(&enc_op);
psa_cipher_abort(&dec_op);
psa_destroy_key(key_id);
free(plaintext);
free(ciphertext);
free(decryptedtext);
}
@@ -0,0 +1,92 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <string.h>
#include <stdio.h>
#include "psa/crypto.h"
#include "unity.h"
#include "esp_log.h"
/*
ARIA-256-ECB Encrypt - RFC 5794 test vector
Key: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Input: 00112233445566778899aabbccddeeff
Output:f92bd7c79fb72e2f2b8f80c1972d24fc
*/
static const uint8_t aria_256_key[32] = {
0x00,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
};
static const uint8_t aria_ecb_input[16] = {
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
};
static const uint8_t aria_ecb_expected_output[16] = {
0xf9,0x2b,0xd7,0xc7,0x9f,0xb7,0x2e,0x2f,
0x2b,0x8f,0x80,0xc1,0x97,0x2d,0x24,0xfc
};
TEST_CASE("PSA ARIA-256-ECB encrypt test vector", "[psa][psa_cipher][aria]")
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id = 0;
uint8_t output[16] = {0};
size_t output_len = 0;
status = psa_crypto_init();
TEST_ASSERT_EQUAL_HEX32(PSA_SUCCESS, status);
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ARIA);
psa_set_key_bits(&key_attr, 256);
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
status = psa_import_key(&key_attr, aria_256_key, sizeof(aria_256_key), &key_id);
TEST_ASSERT_EQUAL_HEX32_MESSAGE(PSA_SUCCESS, status, "psa_import_key failed");
status = psa_cipher_encrypt(
key_id,
PSA_ALG_ECB_NO_PADDING,
aria_ecb_input, sizeof(aria_ecb_input),
output, sizeof(output), &output_len
);
TEST_ASSERT_EQUAL_HEX32_MESSAGE(PSA_SUCCESS, status, "psa_cipher_encrypt failed");
TEST_ASSERT_EQUAL_UINT_MESSAGE(sizeof(aria_ecb_expected_output), output_len, "Output length mismatch");
TEST_ASSERT_EQUAL_UINT8_ARRAY(aria_ecb_expected_output, output, sizeof(aria_ecb_expected_output));
psa_destroy_key(key_id);
// Test decryption: decrypt the previously encrypted ciphertext and compare with original plaintext
uint8_t decrypted[16] = {0};
size_t decrypted_len = 0;
// To decrypt, we need a key with PSA_KEY_USAGE_DECRYPT usage
psa_key_attributes_t dec_key_attr = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_type(&dec_key_attr, PSA_KEY_TYPE_ARIA);
psa_set_key_bits(&dec_key_attr, 256);
psa_set_key_usage_flags(&dec_key_attr, PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&dec_key_attr, PSA_ALG_ECB_NO_PADDING);
psa_key_id_t dec_key_id = 0;
status = psa_import_key(&dec_key_attr, aria_256_key, sizeof(aria_256_key), &dec_key_id);
TEST_ASSERT_EQUAL_HEX32_MESSAGE(PSA_SUCCESS, status, "psa_import_key (decrypt key) failed");
status = psa_cipher_decrypt(
dec_key_id,
PSA_ALG_ECB_NO_PADDING,
output, sizeof(output),
decrypted, sizeof(decrypted), &decrypted_len
);
TEST_ASSERT_EQUAL_HEX32_MESSAGE(PSA_SUCCESS, status, "psa_cipher_decrypt failed");
TEST_ASSERT_EQUAL_UINT_MESSAGE(sizeof(aria_ecb_input), decrypted_len, "Decrypted length mismatch");
TEST_ASSERT_EQUAL_UINT8_ARRAY(aria_ecb_input, decrypted, sizeof(aria_ecb_input));
psa_destroy_key(dec_key_id);
}
@@ -49,8 +49,6 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=n
#
CONFIG_MBEDTLS_CAMELLIA_C=n
CONFIG_MBEDTLS_DES_C=n
CONFIG_MBEDTLS_BLOWFISH_C=n
CONFIG_MBEDTLS_XTEA_C=n
CONFIG_MBEDTLS_CCM_C=n
CONFIG_MBEDTLS_GCM_C=n
CONFIG_MBEDTLS_NIST_KW_C=n
-5
View File
@@ -429,11 +429,6 @@ CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y
CONFIG_MBEDTLS_AES_C=y
CONFIG_MBEDTLS_CAMELLIA_C=
CONFIG_MBEDTLS_DES_C=
CONFIG_MBEDTLS_RC4_DISABLED=y
CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT=
CONFIG_MBEDTLS_RC4_ENABLED=
CONFIG_MBEDTLS_BLOWFISH_C=
CONFIG_MBEDTLS_XTEA_C=
CONFIG_MBEDTLS_CCM_C=y
CONFIG_MBEDTLS_GCM_C=y
CONFIG_MBEDTLS_RIPEMD160_C=