Skip to content

Commit 2c85399

Browse files
committed
fix(mbedtls/gcm): Add support for software fallback for non-AES ciphers in a GCM operation
- Even if the config MBEDTLS_HARDWARE_AES is enabled, we now support fallback to software implementation of GCM operations when non-AES ciphers are used.
1 parent 46ba89c commit 2c85399

File tree

6 files changed

+196
-21
lines changed

6 files changed

+196
-21
lines changed

Diff for: components/mbedtls/Kconfig

+23
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,29 @@ menu "mbedTLS"
402402
mbedTLS will still use the hardware accelerated AES block operation, but
403403
on a single block at a time.
404404

405+
config MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER
406+
bool "Enable support for non-AES ciphers in GCM operation"
407+
depends on MBEDTLS_HARDWARE_AES
408+
default n
409+
help
410+
Enable this config to support fallback to software definitions for a non-AES
411+
cipher GCM operation as we support hardware acceleration only for AES cipher.
412+
Some of the non-AES ciphers used in a GCM operation are DES, ARIA, CAMELLIA,
413+
CHACHA20, BLOWFISH.
414+
415+
If this config is disabled, performing a non-AES cipher GCM operation with
416+
the config MBEDTLS_HARDWARE_AES enabled will result in calculation of an
417+
AES-GCM operation instead for the given input values and thus could lead
418+
to failure in certificate validation which would ultimately lead to a SSL
419+
handshake failure.
420+
421+
This config being by-default enabled leads to an increase in binary size
422+
footprint of ~2.5KB.
423+
In case you are sure that your use case (for example, client and server
424+
configurations in case of a TLS handshake) would not involve any GCM
425+
operations using a non-AES cipher, you can safely disable this config,
426+
leading to reduction in binary size footprint.
427+
405428
config MBEDTLS_HARDWARE_MPI
406429
bool "Enable hardware MPI (bignum) acceleration"
407430
default y

Diff for: components/mbedtls/port/aes/esp_aes_gcm.c

+83-20
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* SPDX-License-Identifier: Apache-2.0
88
*
9-
* SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
9+
* SPDX-FileContributor: 2016-2024 Espressif Systems (Shanghai) CO LTD
1010
*/
1111
/*
1212
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
@@ -251,6 +251,27 @@ int esp_aes_gcm_setkey( esp_gcm_context *ctx,
251251
const unsigned char *key,
252252
unsigned int keybits )
253253
{
254+
/* Fallback to software implementation of GCM operation when a non-AES
255+
* cipher is selected, as we support hardware acceleration only for a
256+
* GCM operation using AES cipher.
257+
*/
258+
#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK)
259+
if (ctx->ctx_soft != NULL) {
260+
mbedtls_gcm_free_soft(ctx->ctx_soft);
261+
free(ctx->ctx_soft);
262+
ctx->ctx_soft = NULL;
263+
}
264+
265+
if (cipher != MBEDTLS_CIPHER_ID_AES) {
266+
ctx->ctx_soft = (mbedtls_gcm_context_soft*) malloc(sizeof(mbedtls_gcm_context_soft));
267+
if (ctx->ctx_soft == NULL) {
268+
return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
269+
}
270+
mbedtls_gcm_init_soft(ctx->ctx_soft);
271+
return mbedtls_gcm_setkey_soft(ctx->ctx_soft, cipher, key, keybits);
272+
}
273+
#endif
274+
254275
#if !SOC_AES_SUPPORT_AES_192
255276
if (keybits == 192) {
256277
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
@@ -332,6 +353,14 @@ void esp_aes_gcm_free( esp_gcm_context *ctx)
332353
if (ctx == NULL) {
333354
return;
334355
}
356+
#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK)
357+
if (ctx->ctx_soft != NULL) {
358+
mbedtls_gcm_free_soft(ctx->ctx_soft);
359+
free(ctx->ctx_soft);
360+
/* Note that the value of ctx->ctx_soft should be NULL'ed out
361+
and here it is taken care by the bzero call below */
362+
}
363+
#endif
335364
bzero(ctx, sizeof(esp_gcm_context));
336365
}
337366

@@ -341,18 +370,24 @@ int esp_aes_gcm_starts( esp_gcm_context *ctx,
341370
const unsigned char *iv,
342371
size_t iv_len )
343372
{
373+
if (!ctx) {
374+
ESP_LOGE(TAG, "No AES context supplied");
375+
return MBEDTLS_ERR_GCM_BAD_INPUT;
376+
}
377+
378+
#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK)
379+
if (ctx->ctx_soft != NULL) {
380+
return mbedtls_gcm_starts_soft(ctx->ctx_soft, mode, iv, iv_len);
381+
}
382+
#endif
383+
344384
/* IV is limited to 2^32 bits, so 2^29 bytes */
345385
/* IV is not allowed to be zero length */
346386
if ( iv_len == 0 ||
347387
( (uint32_t) iv_len ) >> 29 != 0 ) {
348388
return ( MBEDTLS_ERR_GCM_BAD_INPUT );
349389
}
350390

351-
if (!ctx) {
352-
ESP_LOGE(TAG, "No AES context supplied");
353-
return MBEDTLS_ERR_GCM_BAD_INPUT;
354-
}
355-
356391
if (!iv) {
357392
ESP_LOGE(TAG, "No IV supplied");
358393
return MBEDTLS_ERR_GCM_BAD_INPUT;
@@ -407,16 +442,22 @@ int esp_aes_gcm_update_ad( esp_gcm_context *ctx,
407442
const unsigned char *aad,
408443
size_t aad_len )
409444
{
410-
/* AD are limited to 2^32 bits, so 2^29 bytes */
411-
if ( ( (uint32_t) aad_len ) >> 29 != 0 ) {
412-
return ( MBEDTLS_ERR_GCM_BAD_INPUT );
413-
}
414-
415445
if (!ctx) {
416446
ESP_LOGE(TAG, "No AES context supplied");
417447
return MBEDTLS_ERR_GCM_BAD_INPUT;
418448
}
419449

450+
#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK)
451+
if (ctx->ctx_soft != NULL) {
452+
return mbedtls_gcm_update_ad_soft(ctx->ctx_soft, aad, aad_len);
453+
}
454+
#endif
455+
456+
/* AD are limited to 2^32 bits, so 2^29 bytes */
457+
if ( ( (uint32_t) aad_len ) >> 29 != 0 ) {
458+
return ( MBEDTLS_ERR_GCM_BAD_INPUT );
459+
}
460+
420461
if ( (aad_len > 0) && !aad) {
421462
ESP_LOGE(TAG, "No aad supplied");
422463
return MBEDTLS_ERR_GCM_BAD_INPUT;
@@ -442,6 +483,17 @@ int esp_aes_gcm_update( esp_gcm_context *ctx,
442483
unsigned char *output, size_t output_size,
443484
size_t *output_length )
444485
{
486+
if (!ctx) {
487+
ESP_LOGE(TAG, "No GCM context supplied");
488+
return MBEDTLS_ERR_GCM_BAD_INPUT;
489+
}
490+
491+
#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK)
492+
if (ctx->ctx_soft != NULL) {
493+
return mbedtls_gcm_update_soft(ctx->ctx_soft, input, input_length, output, output_size, output_length);
494+
}
495+
#endif
496+
445497
size_t nc_off = 0;
446498
uint8_t nonce_counter[AES_BLOCK_BYTES] = {0};
447499
uint8_t stream[AES_BLOCK_BYTES] = {0};
@@ -452,10 +504,6 @@ int esp_aes_gcm_update( esp_gcm_context *ctx,
452504
}
453505
*output_length = input_length;
454506

455-
if (!ctx) {
456-
ESP_LOGE(TAG, "No GCM context supplied");
457-
return MBEDTLS_ERR_GCM_BAD_INPUT;
458-
}
459507
if (!input) {
460508
ESP_LOGE(TAG, "No input supplied");
461509
return MBEDTLS_ERR_GCM_BAD_INPUT;
@@ -512,6 +560,11 @@ int esp_aes_gcm_finish( esp_gcm_context *ctx,
512560
size_t *output_length,
513561
unsigned char *tag, size_t tag_len )
514562
{
563+
#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK)
564+
if (ctx->ctx_soft != NULL) {
565+
return mbedtls_gcm_finish_soft(ctx->ctx_soft, output, output_size, output_length, tag, tag_len);
566+
}
567+
#endif
515568
size_t nc_off = 0;
516569
uint8_t len_block[AES_BLOCK_BYTES] = {0};
517570
uint8_t stream[AES_BLOCK_BYTES] = {0};
@@ -607,6 +660,16 @@ int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx,
607660
size_t tag_len,
608661
unsigned char *tag )
609662
{
663+
if (!ctx) {
664+
ESP_LOGE(TAG, "No AES context supplied");
665+
return MBEDTLS_ERR_GCM_BAD_INPUT;
666+
}
667+
668+
#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK)
669+
if (ctx->ctx_soft != NULL) {
670+
return mbedtls_gcm_crypt_and_tag_soft(ctx->ctx_soft, mode, length, iv, iv_len, aad, aad_len, input, output, tag_len, tag);
671+
}
672+
#endif
610673
#if CONFIG_MBEDTLS_HARDWARE_GCM
611674
int ret;
612675
lldesc_t aad_desc[2] = {};
@@ -635,11 +698,6 @@ int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx,
635698
return ( MBEDTLS_ERR_GCM_BAD_INPUT );
636699
}
637700

638-
if (!ctx) {
639-
ESP_LOGE(TAG, "No AES context supplied");
640-
return MBEDTLS_ERR_GCM_BAD_INPUT;
641-
}
642-
643701
if (!iv) {
644702
ESP_LOGE(TAG, "No IV supplied");
645703
return MBEDTLS_ERR_GCM_BAD_INPUT;
@@ -727,6 +785,11 @@ int esp_aes_gcm_auth_decrypt( esp_gcm_context *ctx,
727785
const unsigned char *input,
728786
unsigned char *output )
729787
{
788+
#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK)
789+
if (ctx->ctx_soft != NULL) {
790+
return mbedtls_gcm_auth_decrypt_soft(ctx->ctx_soft, length, iv, iv_len, aad, aad_len, tag, tag_len, input, output);
791+
}
792+
#endif
730793
int ret;
731794
unsigned char check_tag[16];
732795
size_t i;

Diff for: components/mbedtls/port/include/aes/esp_aes_gcm.h

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ typedef struct {
4242
const unsigned char *aad; /*!< The additional data. */
4343
esp_aes_context aes_ctx;
4444
esp_aes_gcm_state gcm_state;
45+
/* Software context needed for soft fallback for non-AES ciphers */
46+
void *ctx_soft;
4547
} esp_gcm_context;
4648

4749

Diff for: components/mbedtls/port/include/mbedtls/esp_config.h

+6
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@
155155

156156
#ifdef CONFIG_MBEDTLS_HARDWARE_AES
157157
#define MBEDTLS_GCM_ALT
158+
#ifdef CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER
159+
/* Prefer hardware and fallback to software */
160+
#define MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK
161+
#else
162+
#undef MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK
163+
#endif
158164
#endif
159165

160166
/* MBEDTLS_SHAxx_ALT to enable hardware SHA support

Diff for: components/mbedtls/port/include/mbedtls/gcm.h

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#pragma once
7+
8+
#include_next "mbedtls/gcm.h"
9+
#include "sdkconfig.h"
10+
11+
#ifdef __cplusplus
12+
extern "C" {
13+
#endif
14+
15+
#if defined(MBEDTLS_GCM_ALT) && defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK)
16+
17+
/**
18+
* When the MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK is defined, for non-AES GCM
19+
* operations we need to fallback to the software function definitions of the
20+
* mbedtls GCM layer.
21+
* Thus in this case we need declarations for the software funtions.
22+
* Please refer mbedtls/include/mbedtls/gcm.h for function documentations
23+
*/
24+
25+
void mbedtls_gcm_init_soft(mbedtls_gcm_context_soft *ctx);
26+
27+
28+
int mbedtls_gcm_setkey_soft(mbedtls_gcm_context_soft *ctx,
29+
mbedtls_cipher_id_t cipher,
30+
const unsigned char *key,
31+
unsigned int keybits);
32+
33+
int mbedtls_gcm_starts_soft(mbedtls_gcm_context_soft *ctx,
34+
int mode,
35+
const unsigned char *iv, size_t iv_len);
36+
37+
int mbedtls_gcm_update_ad_soft(mbedtls_gcm_context_soft *ctx,
38+
const unsigned char *add, size_t add_len);
39+
40+
int mbedtls_gcm_update_soft(mbedtls_gcm_context_soft *ctx,
41+
const unsigned char *input, size_t input_length,
42+
unsigned char *output, size_t output_size,
43+
size_t *output_length);
44+
45+
int mbedtls_gcm_finish_soft(mbedtls_gcm_context_soft *ctx,
46+
unsigned char *output, size_t output_size,
47+
size_t *output_length,
48+
unsigned char *tag, size_t tag_len);
49+
50+
51+
int mbedtls_gcm_crypt_and_tag_soft(mbedtls_gcm_context_soft *ctx,
52+
int mode,
53+
size_t length,
54+
const unsigned char *iv,
55+
size_t iv_len,
56+
const unsigned char *add,
57+
size_t add_len,
58+
const unsigned char *input,
59+
unsigned char *output,
60+
size_t tag_len,
61+
unsigned char *tag);
62+
63+
64+
int mbedtls_gcm_auth_decrypt_soft(mbedtls_gcm_context_soft *ctx,
65+
size_t length,
66+
const unsigned char *iv,
67+
size_t iv_len,
68+
const unsigned char *add,
69+
size_t add_len,
70+
const unsigned char *tag,
71+
size_t tag_len,
72+
const unsigned char *input,
73+
unsigned char *output);
74+
75+
void mbedtls_gcm_free_soft(mbedtls_gcm_context_soft *ctx);
76+
77+
#endif /* MBEDTLS_GCM_ALT && MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK*/
78+
79+
#ifdef __cplusplus
80+
}
81+
#endif

0 commit comments

Comments
 (0)