Make mbedtls_aesce_has_support more efficient

Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
This commit is contained in:
Dave Rodgman 2023-08-04 12:31:58 +01:00
parent 1fdc884ed8
commit 4566132163
2 changed files with 40 additions and 16 deletions

View File

@ -94,28 +94,40 @@
#endif /* !(__ARM_FEATURE_CRYPTO || __ARM_FEATURE_AES) || #endif /* !(__ARM_FEATURE_CRYPTO || __ARM_FEATURE_AES) ||
MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */ MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */
#if defined(__linux__) #if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
#include <asm/hwcap.h> #include <asm/hwcap.h>
#include <sys/auxv.h> #include <sys/auxv.h>
#endif
char mbedtls_aesce_has_support_result = 2;
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) #if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
/* /*
* AES instruction support detection routine * AES instruction support detection routine
*/ */
int mbedtls_aesce_has_support(void) int mbedtls_aesce_has_support_impl(void)
{ {
#if defined(__linux__) /* 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); unsigned long auxval = getauxval(AT_HWCAP);
return (auxval & (HWCAP_ASIMD | HWCAP_AES)) == if ((auxval & (HWCAP_ASIMD | HWCAP_AES)) ==
(HWCAP_ASIMD | HWCAP_AES); (HWCAP_ASIMD | HWCAP_AES)) {
#else mbedtls_aesce_has_support_result = 1;
/* Assume AES instructions are supported. */ } else {
return 1; mbedtls_aesce_has_support_result = 0;
#endif }
}
return mbedtls_aesce_has_support_result;
} }
#endif #endif
#endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */
/* Single round of AESCE encryption */ /* Single round of AESCE encryption */
#define AESCE_ENCRYPT_ROUND \ #define AESCE_ENCRYPT_ROUND \
block = vaeseq_u8(block, vld1q_u8(keys)); \ block = vaeseq_u8(block, vld1q_u8(keys)); \

View File

@ -42,17 +42,29 @@
extern "C" { extern "C" {
#endif #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. * \brief Internal function to detect the crypto extension in CPUs.
* *
* \return 1 if CPU has support for the feature, 0 otherwise * \return 1 if CPU has support for the feature, 0 otherwise
*/ */
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) int mbedtls_aesce_has_support_impl(void);
int mbedtls_aesce_has_support(void);
#else
#define mbedtls_aesce_has_support() 1
#endif
#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 * \brief Internal AES-ECB block encryption and decryption