From 09bba150d0d822aad2e58d71723f5407da5c21e0 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Tue, 19 Dec 2023 13:28:05 +0530 Subject: [PATCH] gcm: Support software fallback for non-AES ciphers in a gcm operation. When MBEDTLS_HARDWARE_GCM is enabled, we ALT all the GCM functions that are declared in mbedtls/gcm.h with our H/W port functions, due to which even if non-AES ciphers such as ARIA, CAMELLIA, BLOWFISH, etc. are selected for a GCM operation, we perform an AES-GCM operation, thus resulting into an incorrect calculation. Thus in such cases we need to fallback to the software definitions of GCM. Currently, it is not directly possible to pull in software definitions of GCM related functions directly due to gcm_alt.h, but this commit renames the functions by appending `_soft` to their names, thus making them look different functions in all and thus they are made available to pull in during compilation. The change is configrable using the config MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK. As this config is enabled by default, building the mbedtls crypto library (libmbedcrypto.a) with this change increases its size by ~2.5KB. --- include/mbedtls/gcm.h | 22 +++++++++++++++------- library/gcm.c | 29 +++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h index 837cecc09..78f96022f 100644 --- a/include/mbedtls/gcm.h +++ b/include/mbedtls/gcm.h @@ -40,12 +40,21 @@ extern "C" { #endif -#if !defined(MBEDTLS_GCM_ALT) +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) +#define SOFT(name) name##_soft +#else +#define SOFT(name) name +#endif /* MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK */ +#if defined(MBEDTLS_GCM_ALT) +#include "gcm_alt.h" +#endif /* !MBEDTLS_GCM_ALT */ + +#if !defined(MBEDTLS_GCM_ALT) || defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) /** * \brief The GCM context structure. */ -typedef struct mbedtls_gcm_context { +typedef struct SOFT(mbedtls_gcm_context) { mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */ uint64_t MBEDTLS_PRIVATE(HL)[16]; /*!< Precalculated HTable low. */ uint64_t MBEDTLS_PRIVATE(HH)[16]; /*!< Precalculated HTable high. */ @@ -58,11 +67,7 @@ typedef struct mbedtls_gcm_context { #MBEDTLS_GCM_ENCRYPT or #MBEDTLS_GCM_DECRYPT. */ } -mbedtls_gcm_context; - -#else /* !MBEDTLS_GCM_ALT */ -#include "gcm_alt.h" -#endif /* !MBEDTLS_GCM_ALT */ +SOFT(mbedtls_gcm_context); /** * \brief This function initializes the specified GCM context, @@ -350,6 +355,9 @@ int mbedtls_gcm_finish(mbedtls_gcm_context *ctx, */ void mbedtls_gcm_free(mbedtls_gcm_context *ctx); +#endif /* !defined(MBEDTLS_GCM_ALT) || defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) */ + + #if defined(MBEDTLS_SELF_TEST) /** diff --git a/library/gcm.c b/library/gcm.c index 42fd02078..1296867d8 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -35,8 +35,33 @@ #include "aesce.h" #endif -#if !defined(MBEDTLS_GCM_ALT) +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) +#undef mbedtls_gcm_context +#undef mbedtls_gcm_init +#undef mbedtls_gcm_setkey +#undef mbedtls_gcm_starts +#undef mbedtls_gcm_update_ad +#undef mbedtls_gcm_update +#undef mbedtls_gcm_finish +#undef mbedtls_gcm_crypt_and_tag +#undef mbedtls_gcm_auth_decrypt +#undef mbedtls_gcm_free + +#define mbedtls_gcm_context mbedtls_gcm_context_soft +#define mbedtls_gcm_init mbedtls_gcm_init_soft +#define mbedtls_gcm_setkey mbedtls_gcm_setkey_soft +#define mbedtls_gcm_starts mbedtls_gcm_starts_soft +#define mbedtls_gcm_update_ad mbedtls_gcm_update_ad_soft +#define mbedtls_gcm_update mbedtls_gcm_update_soft +#define mbedtls_gcm_finish mbedtls_gcm_finish_soft +#define mbedtls_gcm_crypt_and_tag mbedtls_gcm_crypt_and_tag_soft +#define mbedtls_gcm_auth_decrypt mbedtls_gcm_auth_decrypt_soft +#define mbedtls_gcm_free mbedtls_gcm_free_soft + +#endif + +#if !defined(MBEDTLS_GCM_ALT) || defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) /* * Initialize a context */ @@ -618,7 +643,7 @@ void mbedtls_gcm_free(mbedtls_gcm_context *ctx) mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context)); } -#endif /* !MBEDTLS_GCM_ALT */ +#endif /* !defined(MBEDTLS_GCM_ALT) || defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) */ #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) /*