AES-NI: use target attributes for x86 32-bit intrinsics

This way we build with 32-bit gcc/clang out of the box.
We also fallback to assembly for 64-bit clang-cl if needed cpu
flags are not provided, instead of throwing an error.

Signed-off-by: Beniamin Sandu <beniaminsandu@gmail.com>
This commit is contained in:
Beniamin Sandu 2023-10-27 16:58:00 +01:00
parent 51328162e6
commit 800f2b7c02
2 changed files with 25 additions and 3 deletions

View File

@ -43,6 +43,17 @@
#include <immintrin.h> #include <immintrin.h>
#endif #endif
#if defined(MBEDTLS_ARCH_IS_X86)
#if defined(MBEDTLS_COMPILER_IS_GCC)
#pragma GCC push_options
#pragma GCC target ("pclmul,sse2,aes")
#define MBEDTLS_POP_TARGET_PRAGMA
#elif defined(__clang__)
#pragma clang attribute push (__attribute__((target("pclmul,sse2,aes"))), apply_to=function)
#define MBEDTLS_POP_TARGET_PRAGMA
#endif
#endif
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) #if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
/* /*
* AES-NI support detection routine * AES-NI support detection routine
@ -398,6 +409,15 @@ static void aesni_setkey_enc_256(unsigned char *rk_bytes,
} }
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
#if defined(MBEDTLS_POP_TARGET_PRAGMA)
#if defined(__clang__)
#pragma clang attribute pop
#elif defined(__GNUC__)
#pragma GCC pop_options
#endif
#undef MBEDTLS_POP_TARGET_PRAGMA
#endif
#else /* MBEDTLS_AESNI_HAVE_CODE == 1 */ #else /* MBEDTLS_AESNI_HAVE_CODE == 1 */
#if defined(__has_feature) #if defined(__has_feature)

View File

@ -50,6 +50,10 @@
#if (defined(__GNUC__) || defined(__clang__)) && defined(__AES__) && defined(__PCLMUL__) #if (defined(__GNUC__) || defined(__clang__)) && defined(__AES__) && defined(__PCLMUL__)
#define MBEDTLS_AESNI_HAVE_INTRINSICS #define MBEDTLS_AESNI_HAVE_INTRINSICS
#endif #endif
/* For 32-bit, we only support intrinsics */
#if defined(MBEDTLS_ARCH_IS_X86) && (defined(__GNUC__) || defined(__clang__))
#define MBEDTLS_AESNI_HAVE_INTRINSICS
#endif
/* Choose the implementation of AESNI, if one is available. /* Choose the implementation of AESNI, if one is available.
* *
@ -60,13 +64,11 @@
#if defined(MBEDTLS_AESNI_HAVE_INTRINSICS) #if defined(MBEDTLS_AESNI_HAVE_INTRINSICS)
#define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics #define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics
#elif defined(MBEDTLS_HAVE_ASM) && \ #elif defined(MBEDTLS_HAVE_ASM) && \
defined(__GNUC__) && defined(MBEDTLS_ARCH_IS_X64) (defined(__GNUC__) || defined(__clang__)) && defined(MBEDTLS_ARCH_IS_X64)
/* Can we do AESNI with inline assembly? /* Can we do AESNI with inline assembly?
* (Only implemented with gas syntax, only for 64-bit.) * (Only implemented with gas syntax, only for 64-bit.)
*/ */
#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly #define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly
#elif defined(__GNUC__) || defined(__clang__)
# error "Must use `-mpclmul -msse2 -maes` for MBEDTLS_AESNI_C"
#else #else
#error "MBEDTLS_AESNI_C defined, but neither intrinsics nor assembly available" #error "MBEDTLS_AESNI_C defined, but neither intrinsics nor assembly available"
#endif #endif