diff --git a/library/aes.c b/library/aes.c index 91b6d431e..69da5828a 100644 --- a/library/aes.c +++ b/library/aes.c @@ -511,7 +511,7 @@ void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx) * i.e. an offset of 1 means 4 bytes and so on. */ #if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \ - defined(MBEDTLS_HAVE_AESNI_INTRINSICS) + (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2) #define MAY_NEED_TO_ALIGN #endif static unsigned mbedtls_aes_rk_offset(uint32_t *buf) @@ -528,7 +528,7 @@ static unsigned mbedtls_aes_rk_offset(uint32_t *buf) } #endif -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_AESNI_INTRINSICS) +#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { align_16_bytes = 1; } diff --git a/library/aesni.c b/library/aesni.c index e24527c82..a23c5b595 100644 --- a/library/aesni.c +++ b/library/aesni.c @@ -30,9 +30,9 @@ #include -#if defined(MBEDTLS_HAVE_AESNI_INTRINSICS) || defined(MBEDTLS_HAVE_X86_64) +#if defined(MBEDTLS_AESNI_HAVE_CODE) -#if defined(MBEDTLS_HAVE_AESNI_INTRINSICS) +#if MBEDTLS_AESNI_HAVE_CODE == 2 #if !defined(_WIN32) #include #endif @@ -48,7 +48,7 @@ int mbedtls_aesni_has_support(unsigned int what) static unsigned int c = 0; if (!done) { -#if defined(MBEDTLS_HAVE_AESNI_INTRINSICS) +#if MBEDTLS_AESNI_HAVE_CODE == 2 static unsigned info[4] = { 0, 0, 0, 0 }; #if defined(_MSC_VER) __cpuid(info, 1); @@ -56,20 +56,20 @@ int mbedtls_aesni_has_support(unsigned int what) __cpuid(1, info[0], info[1], info[2], info[3]); #endif c = info[2]; -#else +#else /* AESNI using asm */ asm ("movl $1, %%eax \n\t" "cpuid \n\t" : "=c" (c) : : "eax", "ebx", "edx"); -#endif +#endif /* MBEDTLS_AESNI_HAVE_CODE */ done = 1; } return (c & what) != 0; } -#if defined(MBEDTLS_HAVE_AESNI_INTRINSICS) +#if MBEDTLS_AESNI_HAVE_CODE == 2 /* * AES-NI AES-ECB block en(de)cryption @@ -388,7 +388,7 @@ static void aesni_setkey_enc_256(unsigned char *rk_bytes, aesni_set_rk_256(rk[12], rk[13], _mm_aeskeygenassist_si128(rk[13], 0x40), &rk[14], &rk[15]); } -#else /* MBEDTLS_HAVE_AESNI_INTRINSICS */ +#else /* MBEDTLS_AESNI_HAVE_CODE == 1 */ #if defined(__has_feature) #if __has_feature(memory_sanitizer) @@ -776,7 +776,7 @@ static void aesni_setkey_enc_256(unsigned char *rk, : "memory", "cc", "0"); } -#endif /* MBEDTLS_HAVE_AESNI_INTRINSICS */ +#endif /* MBEDTLS_AESNI_HAVE_CODE */ /* * Key expansion, wrapper @@ -795,6 +795,6 @@ int mbedtls_aesni_setkey_enc(unsigned char *rk, return 0; } -#endif /* MBEDTLS_HAVE_X86_64 */ +#endif /* MBEDTLS_AESNI_HAVE_CODE */ #endif /* MBEDTLS_AESNI_C */ diff --git a/library/aesni.h b/library/aesni.h index c1c4bdd8f..a81a11725 100644 --- a/library/aesni.h +++ b/library/aesni.h @@ -32,6 +32,9 @@ #define MBEDTLS_AESNI_AES 0x02000000u #define MBEDTLS_AESNI_CLMUL 0x00000002u +/* Can we do AESNI with inline assembly? + * (Only implemented with gas syntax, only for 64-bit.) + */ #if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \ (defined(__amd64__) || defined(__x86_64__)) && \ !defined(MBEDTLS_HAVE_X86_64) @@ -40,19 +43,33 @@ #if defined(MBEDTLS_AESNI_C) -#if defined(MBEDTLS_HAVE_X86_64) -#define MBEDTLS_AESNI_HAVE_CODE // via assembly -#endif - +/* Can we do AESNI with intrinsics? + * (Only implemented with certain compilers, .) + */ +#undef MBEDTLS_AESNI_HAVE_INTRINSICS #if defined(_MSC_VER) -#define MBEDTLS_HAVE_AESNI_INTRINSICS +/* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support + * VS 2013 and up for other reasons anyway, so no need to check the version. */ +#define MBEDTLS_AESNI_HAVE_INTRINSICS #endif -#if defined(__GNUC__) && defined(__AES__) -#define MBEDTLS_HAVE_AESNI_INTRINSICS +/* GCC-like compilers: currently, we only support intrinsics if the requisite + * target flag is enabled when building the library (e.g. `gcc -mpclmul -msse2` + * or `clang -maes -mpclmul`). */ +#if defined(__GNUC__) && defined(__AES__) && defined(__PCLMUL__) +#define MBEDTLS_AESNI_HAVE_INTRINSICS #endif -#if defined(MBEDTLS_HAVE_AESNI_INTRINSICS) -#define MBEDTLS_AESNI_HAVE_CODE // via intrinsics +/* Choose the implementation of AESNI, if one is available. */ +#undef MBEDTLS_AESNI_HAVE_CODE +/* To minimize disruption when releasing the intrinsics-based implementation, + * favor the assembly-based implementation if it's available. We intend to + * revise this in a later release of Mbed TLS 3.x. In the long run, we will + * likely remove the assembly implementation. */ +#if defined(MBEDTLS_HAVE_X86_64) +#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly +#endif +#if defined(MBEDTLS_AESNI_HAVE_INTRINSICS) +#define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics #endif #if defined(MBEDTLS_AESNI_HAVE_CODE)