fix(mbedtls): Support partial hardware AES-GCM and s/w fallback for non-AES ciphers

- Support software-fallback for unsupported hardware AES lengths
This commit is contained in:
harshal.patil
2025-12-27 00:03:46 +05:30
parent b15334600d
commit e91d50ed1e
13 changed files with 197 additions and 78 deletions
+5 -7
View File
@@ -342,6 +342,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()
@@ -392,17 +393,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)
+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
@@ -1812,19 +1812,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 +1866,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 +1925,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 +1968,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 +1984,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 +3025,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 */
/**
@@ -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 */
@@ -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"
@@ -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=