From 4566132163a11d4f98b0685a33587281f059ef18 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 4 Aug 2023 12:31:58 +0100 Subject: [PATCH 1/3] Make mbedtls_aesce_has_support more efficient Signed-off-by: Dave Rodgman --- library/aesce.c | 34 +++++++++++++++++++++++----------- library/aesce.h | 22 +++++++++++++++++----- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/library/aesce.c b/library/aesce.c index 8aa07894fe..42e04d3a45 100644 --- a/library/aesce.c +++ b/library/aesce.c @@ -94,28 +94,40 @@ #endif /* !(__ARM_FEATURE_CRYPTO || __ARM_FEATURE_AES) || MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */ -#if defined(__linux__) +#if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) + #include #include -#endif + +char mbedtls_aesce_has_support_result = 2; #if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) /* * AES instruction support detection routine */ -int mbedtls_aesce_has_support(void) +int mbedtls_aesce_has_support_impl(void) { -#if defined(__linux__) - unsigned long auxval = getauxval(AT_HWCAP); - return (auxval & (HWCAP_ASIMD | HWCAP_AES)) == - (HWCAP_ASIMD | HWCAP_AES); -#else - /* Assume AES instructions are supported. */ - return 1; -#endif + /* To avoid many calls to getauxval, cache the result. This is + * thread-safe, because we store the result in a char so cannot + * be vulnerable to non-atomic updates. + * It is possible that we could end up setting result more than + * once, but that is harmless. + */ + if (mbedtls_aesce_has_support_result == 2) { + unsigned long auxval = getauxval(AT_HWCAP); + if ((auxval & (HWCAP_ASIMD | HWCAP_AES)) == + (HWCAP_ASIMD | HWCAP_AES)) { + mbedtls_aesce_has_support_result = 1; + } else { + mbedtls_aesce_has_support_result = 0; + } + } + return mbedtls_aesce_has_support_result; } #endif +#endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */ + /* Single round of AESCE encryption */ #define AESCE_ENCRYPT_ROUND \ block = vaeseq_u8(block, vld1q_u8(keys)); \ diff --git a/library/aesce.h b/library/aesce.h index 9b8b0bcd67..1a0abb86f5 100644 --- a/library/aesce.h +++ b/library/aesce.h @@ -42,17 +42,29 @@ extern "C" { #endif +#if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) + +extern char mbedtls_aesce_has_support_result; + /** * \brief Internal function to detect the crypto extension in CPUs. * * \return 1 if CPU has support for the feature, 0 otherwise */ -#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) -int mbedtls_aesce_has_support(void); -#else -#define mbedtls_aesce_has_support() 1 -#endif +int mbedtls_aesce_has_support_impl(void); +#define mbedtls_aesce_has_support() (mbedtls_aesce_has_support_result == 2 ? \ + mbedtls_aesce_has_support_impl() : \ + mbedtls_aesce_has_support_result) + +#else /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */ + +/* If we are not on Linux, we can't detect support so assume that it's supported. + * Similarly, assume support if MBEDTLS_AES_USE_HARDWARE_ONLY is set. + */ +#define mbedtls_aesce_has_support() 1 + +#endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */ /** * \brief Internal AES-ECB block encryption and decryption From b30adce7fd5c66e0bb35c2d882215c43ae3b32d2 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 4 Aug 2023 12:52:51 +0100 Subject: [PATCH 2/3] Use -1 as uninitialised marker Signed-off-by: Dave Rodgman --- library/aesce.c | 4 ++-- library/aesce.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/aesce.c b/library/aesce.c index 42e04d3a45..6f75a67d7f 100644 --- a/library/aesce.c +++ b/library/aesce.c @@ -99,7 +99,7 @@ #include #include -char mbedtls_aesce_has_support_result = 2; +signed char mbedtls_aesce_has_support_result = -1; #if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) /* @@ -113,7 +113,7 @@ int mbedtls_aesce_has_support_impl(void) * It is possible that we could end up setting result more than * once, but that is harmless. */ - if (mbedtls_aesce_has_support_result == 2) { + if (mbedtls_aesce_has_support_result == -1) { unsigned long auxval = getauxval(AT_HWCAP); if ((auxval & (HWCAP_ASIMD | HWCAP_AES)) == (HWCAP_ASIMD | HWCAP_AES)) { diff --git a/library/aesce.h b/library/aesce.h index 1a0abb86f5..8d48c601bc 100644 --- a/library/aesce.h +++ b/library/aesce.h @@ -44,7 +44,7 @@ extern "C" { #if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) -extern char mbedtls_aesce_has_support_result; +extern signed char mbedtls_aesce_has_support_result; /** * \brief Internal function to detect the crypto extension in CPUs. @@ -53,7 +53,7 @@ extern char mbedtls_aesce_has_support_result; */ int mbedtls_aesce_has_support_impl(void); -#define mbedtls_aesce_has_support() (mbedtls_aesce_has_support_result == 2 ? \ +#define mbedtls_aesce_has_support() (mbedtls_aesce_has_support_result == -1 ? \ mbedtls_aesce_has_support_impl() : \ mbedtls_aesce_has_support_result) From f2249ec9058f276657cbe59750472798273b25b8 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 4 Aug 2023 14:27:58 +0100 Subject: [PATCH 3/3] Rename mbedtls_aesce_has_support macro to satisfy case rules Signed-off-by: Dave Rodgman --- library/aes.c | 8 ++++---- library/aesce.h | 4 ++-- library/gcm.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/aes.c b/library/aes.c index 774c2eed04..47a5e3e822 100644 --- a/library/aes.c +++ b/library/aes.c @@ -653,7 +653,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, #endif #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) - if (mbedtls_aesce_has_support()) { + if (MBEDTLS_AESCE_HAS_SUPPORT()) { return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits); } #endif @@ -765,7 +765,7 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, #endif #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) - if (mbedtls_aesce_has_support()) { + if (MBEDTLS_AESCE_HAS_SUPPORT()) { mbedtls_aesce_inverse_key( (unsigned char *) RK, (const unsigned char *) (cty.buf + cty.rk_offset), @@ -1092,7 +1092,7 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, #endif #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) - if (mbedtls_aesce_has_support()) { + if (MBEDTLS_AESCE_HAS_SUPPORT()) { return mbedtls_aesce_crypt_ecb(ctx, mode, input, output); } #endif @@ -1911,7 +1911,7 @@ int mbedtls_aes_self_test(int verbose) } else #endif #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) - if (mbedtls_aesce_has_support()) { + if (MBEDTLS_AESCE_HAS_SUPPORT()) { mbedtls_printf(" AES note: using AESCE.\n"); } else #endif diff --git a/library/aesce.h b/library/aesce.h index 8d48c601bc..735c8cfad2 100644 --- a/library/aesce.h +++ b/library/aesce.h @@ -53,7 +53,7 @@ extern signed char mbedtls_aesce_has_support_result; */ int mbedtls_aesce_has_support_impl(void); -#define mbedtls_aesce_has_support() (mbedtls_aesce_has_support_result == -1 ? \ +#define MBEDTLS_AESCE_HAS_SUPPORT() (mbedtls_aesce_has_support_result == -1 ? \ mbedtls_aesce_has_support_impl() : \ mbedtls_aesce_has_support_result) @@ -62,7 +62,7 @@ int mbedtls_aesce_has_support_impl(void); /* If we are not on Linux, we can't detect support so assume that it's supported. * Similarly, assume support if MBEDTLS_AES_USE_HARDWARE_ONLY is set. */ -#define mbedtls_aesce_has_support() 1 +#define MBEDTLS_AESCE_HAS_SUPPORT() 1 #endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */ diff --git a/library/gcm.c b/library/gcm.c index d49725c69c..786290f2f9 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -98,7 +98,7 @@ static int gcm_gen_table(mbedtls_gcm_context *ctx) #endif #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) - if (mbedtls_aesce_has_support()) { + if (MBEDTLS_AESCE_HAS_SUPPORT()) { return 0; } #endif @@ -209,7 +209,7 @@ static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16], #endif /* MBEDTLS_AESNI_HAVE_CODE */ #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) - if (mbedtls_aesce_has_support()) { + if (MBEDTLS_AESCE_HAS_SUPPORT()) { unsigned char h[16]; /* mbedtls_aesce_gcm_mult needs big-endian input */ @@ -886,7 +886,7 @@ int mbedtls_gcm_self_test(int verbose) #endif #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) - if (mbedtls_aesce_has_support()) { + if (MBEDTLS_AESCE_HAS_SUPPORT()) { mbedtls_printf(" GCM note: using AESCE.\n"); } else #endif