AESNI: Overhaul implementation selection
Have clearly separated code to: * determine whether the assembly-based implementation is available; * determine whether the intrinsics-based implementation is available; * select one of the available implementations if any. Now MBEDTLS_AESNI_HAVE_CODE can be the single interface for aes.c and aesni.c to determine which AESNI is built. Change the implementation selection: now, if both implementations are available, always prefer assembly. Before, the intrinsics were used if available. This preference is to minimize disruption, and will likely be revised in a later minor release. Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
parent
0de8f853f0
commit
9c682e724a
3 changed files with 37 additions and 20 deletions
|
@ -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.
|
* i.e. an offset of 1 means 4 bytes and so on.
|
||||||
*/
|
*/
|
||||||
#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
|
#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
|
#define MAY_NEED_TO_ALIGN
|
||||||
#endif
|
#endif
|
||||||
static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
|
static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
|
||||||
|
@ -528,7 +528,7 @@ static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
|
||||||
}
|
}
|
||||||
#endif
|
#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)) {
|
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
|
||||||
align_16_bytes = 1;
|
align_16_bytes = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#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)
|
#if !defined(_WIN32)
|
||||||
#include <cpuid.h>
|
#include <cpuid.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,7 +48,7 @@ int mbedtls_aesni_has_support(unsigned int what)
|
||||||
static unsigned int c = 0;
|
static unsigned int c = 0;
|
||||||
|
|
||||||
if (!done) {
|
if (!done) {
|
||||||
#if defined(MBEDTLS_HAVE_AESNI_INTRINSICS)
|
#if MBEDTLS_AESNI_HAVE_CODE == 2
|
||||||
static unsigned info[4] = { 0, 0, 0, 0 };
|
static unsigned info[4] = { 0, 0, 0, 0 };
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
__cpuid(info, 1);
|
__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]);
|
__cpuid(1, info[0], info[1], info[2], info[3]);
|
||||||
#endif
|
#endif
|
||||||
c = info[2];
|
c = info[2];
|
||||||
#else
|
#else /* AESNI using asm */
|
||||||
asm ("movl $1, %%eax \n\t"
|
asm ("movl $1, %%eax \n\t"
|
||||||
"cpuid \n\t"
|
"cpuid \n\t"
|
||||||
: "=c" (c)
|
: "=c" (c)
|
||||||
:
|
:
|
||||||
: "eax", "ebx", "edx");
|
: "eax", "ebx", "edx");
|
||||||
#endif
|
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (c & what) != 0;
|
return (c & what) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_HAVE_AESNI_INTRINSICS)
|
#if MBEDTLS_AESNI_HAVE_CODE == 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AES-NI AES-ECB block en(de)cryption
|
* 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]);
|
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 defined(__has_feature)
|
||||||
#if __has_feature(memory_sanitizer)
|
#if __has_feature(memory_sanitizer)
|
||||||
|
@ -776,7 +776,7 @@ static void aesni_setkey_enc_256(unsigned char *rk,
|
||||||
: "memory", "cc", "0");
|
: "memory", "cc", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MBEDTLS_HAVE_AESNI_INTRINSICS */
|
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Key expansion, wrapper
|
* Key expansion, wrapper
|
||||||
|
@ -795,6 +795,6 @@ int mbedtls_aesni_setkey_enc(unsigned char *rk,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MBEDTLS_HAVE_X86_64 */
|
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||||
|
|
||||||
#endif /* MBEDTLS_AESNI_C */
|
#endif /* MBEDTLS_AESNI_C */
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
#define MBEDTLS_AESNI_AES 0x02000000u
|
#define MBEDTLS_AESNI_AES 0x02000000u
|
||||||
#define MBEDTLS_AESNI_CLMUL 0x00000002u
|
#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__) && \
|
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
|
||||||
(defined(__amd64__) || defined(__x86_64__)) && \
|
(defined(__amd64__) || defined(__x86_64__)) && \
|
||||||
!defined(MBEDTLS_HAVE_X86_64)
|
!defined(MBEDTLS_HAVE_X86_64)
|
||||||
|
@ -40,19 +43,33 @@
|
||||||
|
|
||||||
#if defined(MBEDTLS_AESNI_C)
|
#if defined(MBEDTLS_AESNI_C)
|
||||||
|
|
||||||
#if defined(MBEDTLS_HAVE_X86_64)
|
/* Can we do AESNI with intrinsics?
|
||||||
#define MBEDTLS_AESNI_HAVE_CODE // via assembly
|
* (Only implemented with certain compilers, .)
|
||||||
#endif
|
*/
|
||||||
|
#undef MBEDTLS_AESNI_HAVE_INTRINSICS
|
||||||
#if defined(_MSC_VER)
|
#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
|
#endif
|
||||||
#if defined(__GNUC__) && defined(__AES__)
|
/* GCC-like compilers: currently, we only support intrinsics if the requisite
|
||||||
#define MBEDTLS_HAVE_AESNI_INTRINSICS
|
* 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
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_HAVE_AESNI_INTRINSICS)
|
/* Choose the implementation of AESNI, if one is available. */
|
||||||
#define MBEDTLS_AESNI_HAVE_CODE // via intrinsics
|
#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
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||||
|
|
Loading…
Reference in a new issue