diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 266eb9ef4..c81cd1cc5 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -66,13 +66,6 @@ #error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" #endif -#if defined(__aarch64__) && defined(__GNUC__) -/* We don't do anything with MBEDTLS_AESCE_C on systems without ^ these two */ -#if defined(MBEDTLS_AESCE_C) && !defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_AESCE_C defined, but not all prerequisites" -#endif -#endif - #if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) #error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" #endif diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 89d565971..615885003 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -2076,12 +2076,15 @@ * Module: library/aesce.c * Caller: library/aes.c * - * Requires: MBEDTLS_HAVE_ASM, MBEDTLS_AES_C + * Requires: MBEDTLS_AES_C * * \warning Runtime detection only works on Linux. For non-Linux operating * system, Armv8-A Cryptographic Extensions must be supported by * the CPU when this option is enabled. * + * \note Minimum compiler versions for this feature are Clang 4.0, + * GCC 6.0 or MSVC 2019 version 16.11.2. + * * This module adds support for the AES Armv8-A Cryptographic Extensions on Aarch64 systems. */ #define MBEDTLS_AESCE_C diff --git a/library/aesce.c b/library/aesce.c index fe056dc4c..ff8c2e09c 100644 --- a/library/aesce.c +++ b/library/aesce.c @@ -48,22 +48,34 @@ #if defined(MBEDTLS_HAVE_ARM64) +/* Compiler version checks. */ +#if defined(__clang__) +# if __clang_major__ < 4 +# error "Minimum version of Clang for MBEDTLS_AESCE_C is 4.0." +# endif +#elif defined(__GNUC__) +# if __GNUC__ < 6 +# error "Minimum version of GCC for MBEDTLS_AESCE_C is 6.0." +# endif +#elif defined(_MSC_VER) +/* TODO: We haven't verified MSVC from 1920 to 1928. If someone verified that, + * please update this and document of `MBEDTLS_AESCE_C` in + * `mbedtls_config.h`. */ +# if _MSC_VER < 1929 +# error "Minimum version of MSVC for MBEDTLS_AESCE_C is 2019 version 16.11.2." +# endif +#endif + #if !defined(__ARM_FEATURE_AES) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG) # if defined(__clang__) -# if __clang_major__ < 4 -# error "A more recent Clang is required for MBEDTLS_AESCE_C" -# endif # pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function) # define MBEDTLS_POP_TARGET_PRAGMA # elif defined(__GNUC__) -# if __GNUC__ < 6 -# error "A more recent GCC is required for MBEDTLS_AESCE_C" -# endif # pragma GCC push_options # pragma GCC target ("arch=armv8-a+crypto") # define MBEDTLS_POP_TARGET_PRAGMA -# else -# error "Only GCC and Clang supported for MBEDTLS_AESCE_C" +# elif defined(_MSC_VER) +# error "Required feature(__ARM_FEATURE_AES) is not enabled." # endif #endif /* !__ARM_FEATURE_AES || MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */ @@ -295,12 +307,24 @@ static inline poly64_t vget_low_p64(poly64x2_t __a) * Older compilers miss some intrinsic functions for `poly*_t`. We use * uint8x16_t and uint8x16x3_t as input/output parameters. */ +#if defined(__GNUC__) && !defined(__clang__) +/* GCC reports incompatible type error without cast. GCC think poly64_t and + * poly64x1_t are different, that is different with MSVC and Clang. */ +#define MBEDTLS_VMULL_P64(a, b) vmull_p64((poly64_t) a, (poly64_t) b) +#else +/* MSVC reports `error C2440: 'type cast'` with cast. Clang does not report + * error with/without cast. And I think poly64_t and poly64x1_t are same, no + * cast for clang also. */ +#define MBEDTLS_VMULL_P64(a, b) vmull_p64(a, b) +#endif static inline uint8x16_t pmull_low(uint8x16_t a, uint8x16_t b) { + return vreinterpretq_u8_p128( - vmull_p64( - (poly64_t) vget_low_p64(vreinterpretq_p64_u8(a)), - (poly64_t) vget_low_p64(vreinterpretq_p64_u8(b)))); + MBEDTLS_VMULL_P64( + vget_low_p64(vreinterpretq_p64_u8(a)), + vget_low_p64(vreinterpretq_p64_u8(b)) + )); } static inline uint8x16_t pmull_high(uint8x16_t a, uint8x16_t b) @@ -362,9 +386,14 @@ static inline uint8x16x3_t poly_mult_128(uint8x16_t a, uint8x16_t b) static inline uint8x16_t poly_mult_reduce(uint8x16x3_t input) { uint8x16_t const ZERO = vdupq_n_u8(0); - /* use 'asm' as an optimisation barrier to prevent loading MODULO from memory */ + uint64x2_t r = vreinterpretq_u64_u8(vdupq_n_u8(0x87)); +#if defined(__GNUC__) + /* use 'asm' as an optimisation barrier to prevent loading MODULO from + * memory. It is for GNUC compatible compilers. + */ asm ("" : "+w" (r)); +#endif uint8x16_t const MODULO = vreinterpretq_u8_u64(vshrq_n_u64(r, 64 - 8)); uint8x16_t h, m, l; /* input high/middle/low 128b */ uint8x16_t c, d, e, f, g, n, o; diff --git a/library/aesce.h b/library/aesce.h index 12ddc74b3..7048d77c5 100644 --- a/library/aesce.h +++ b/library/aesce.h @@ -30,11 +30,11 @@ #include "mbedtls/aes.h" - -#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \ - defined(__aarch64__) && !defined(MBEDTLS_HAVE_ARM64) +#if !defined(MBEDTLS_HAVE_ARM64) +#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) #define MBEDTLS_HAVE_ARM64 #endif +#endif #if defined(MBEDTLS_HAVE_ARM64)