diff --git a/configure.ac b/configure.ac index 5335fcbf..11a8b678 100644 --- a/configure.ac +++ b/configure.ac @@ -554,7 +554,7 @@ AC_SUBST(CFLAGS_AESNI) AC_SUBST(CFLAGS_PCLMUL) AC_SUBST(CFLAGS_RDRAND) -AC_CHECK_HEADERS([sys/mman.h sys/random.h intrin.h]) +AC_CHECK_HEADERS([sys/mman.h sys/random.h intrin.h sys/auxv.h]) AC_MSG_CHECKING([if _xgetbv() is available]) AC_LINK_IFELSE( @@ -818,6 +818,7 @@ unsigned char buf; ]) AC_CHECK_FUNCS([posix_memalign getpid nanosleep]) AC_CHECK_FUNCS([memset_s explicit_bzero explicit_memset]) +AC_CHECK_FUNCS([getauxval]) AC_SUBST([LIBTOOL_EXTRA_FLAGS]) diff --git a/dist-build/emscripten-symbols.def b/dist-build/emscripten-symbols.def index b8870183..8e3abf0b 100644 --- a/dist-build/emscripten-symbols.def +++ b/dist-build/emscripten-symbols.def @@ -606,6 +606,7 @@ _sodium_runtime_has_avx 0 0 _sodium_runtime_has_avx2 0 0 _sodium_runtime_has_avx512f 0 0 _sodium_runtime_has_neon 0 0 +_sodium_runtime_has_armcrypto_aes 0 0 _sodium_runtime_has_pclmul 0 0 _sodium_runtime_has_rdrand 0 0 _sodium_runtime_has_sse2 0 0 diff --git a/src/libsodium/include/sodium/runtime.h b/src/libsodium/include/sodium/runtime.h index 7f15d58e..929fb5ff 100644 --- a/src/libsodium/include/sodium/runtime.h +++ b/src/libsodium/include/sodium/runtime.h @@ -11,6 +11,9 @@ extern "C" { SODIUM_EXPORT_WEAK int sodium_runtime_has_neon(void); +SODIUM_EXPORT_WEAK +int sodium_runtime_has_armcrypto_aes(void); + SODIUM_EXPORT_WEAK int sodium_runtime_has_sse2(void); diff --git a/src/libsodium/sodium/runtime.c b/src/libsodium/sodium/runtime.c index 9dfe54f8..73ced4d1 100644 --- a/src/libsodium/sodium/runtime.c +++ b/src/libsodium/sodium/runtime.c @@ -3,6 +3,14 @@ #ifdef HAVE_ANDROID_GETCPUFEATURES # include #endif +#ifdef __APPLE__ +# include +# include +# include +#endif +#ifdef HAVE_SYS_AUXV_H +# include +#endif #include "private/common.h" #include "runtime.h" @@ -10,6 +18,7 @@ typedef struct CPUFeatures_ { int initialized; int has_neon; + int has_armcrypto_aes; int has_sse2; int has_sse3; int has_ssse3; @@ -48,25 +57,50 @@ static CPUFeatures _cpu_features; static int _sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features) { + cpu_features->has_neon = 0; + cpu_features->has_armcrypto_aes = 0; + #ifndef __arm__ - cpu_features->has_neon = 0; - return -1; -#else -# ifdef __APPLE__ -# ifdef __ARM_NEON__ + return -1; /* LCOV_EXCL_LINE */ +#endif + +#if defined(__ARM_NEON) || defined(__aarch64__) cpu_features->has_neon = 1; -# else - cpu_features->has_neon = 0; -# endif -# elif defined(HAVE_ANDROID_GETCPUFEATURES) && \ - defined(ANDROID_CPU_ARM_FEATURE_NEON) +#elif defined(HAVE_ANDROID_GETCPUFEATURES) && defined(ANDROID_CPU_ARM_FEATURE_NEON) cpu_features->has_neon = (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0x0; -# else - cpu_features->has_neon = 0; -# endif - return 0; +#elif defined(HAVE_GETAUXVAL) && defined(AT_HWCAP) && defined(__aarch64__) + cpu_features->has_neon = (getauxval(AT_HWCAP) & (1L << 1)) != 0; #endif + + if (cpu_features->has_neon == 0) { + return 0; + } + +#if __ARM_FEATURE_CRYPTO + cpu_features->has_armcrypto_aes = 1; +#elif defined(__APPLE__) && defined(CPU_TYPE_ARM64) && defined(CPU_SUBTYPE_ARM64E) + { + cpu_type_t cpu_type; + cpu_subtype_t cpu_subtype; + size_t cpu_type_len = sizeof cpu_type; + size_t cpu_subtype_len = sizeof cpu_subtype; + + if (sysctlbyname("hw.cputype", &cpu_type, &cpu_type_len, + NULL, 0) == 0 && cpu_type == CPU_TYPE_ARM64 && + sysctlbyname("hw.cpusubtype", &cpu_subtype, &cpu_subtype_len, + NULL, 0) == 0 && cpu_type == CPU_SUBTYPE_ARM64E) { + cpu_features->has_armcrypto_aes = 1; + } + } +#elif defined(HAVE_ANDROID_GETCPUFEATURES) && defined(ANDROID_CPU_ARM_FEATURE_AES) + cpu_features->has_armcrypto_aes = + (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_AES) != 0x0; +#elif defined(HAVE_GETAUXVAL) && defined(AT_HWCAP) && defined(__aarch64__) + cpu_features->has_armcrypto_aes = (getauxval(AT_HWCAP) & (1L << 3)) != 0; +#endif + + return 0; } static void @@ -248,6 +282,12 @@ sodium_runtime_has_neon(void) return _cpu_features.has_neon; } +int +sodium_runtime_has_armcrypto_aes(void) +{ + return _cpu_features.has_armcrypto_aes; +} + int sodium_runtime_has_sse2(void) { diff --git a/test/default/sodium_core.c b/test/default/sodium_core.c index a3985b0e..7f930bb8 100644 --- a/test/default/sodium_core.c +++ b/test/default/sodium_core.c @@ -19,6 +19,7 @@ main(void) assert(sodium_init() == 1); (void) sodium_runtime_has_neon(); + (void) sodium_runtime_has_armcrypto_aes(); (void) sodium_runtime_has_sse2(); (void) sodium_runtime_has_sse3(); (void) sodium_runtime_has_ssse3(); diff --git a/test/symbols/all-symbols.txt b/test/symbols/all-symbols.txt index f3a5e97b..67b04686 100644 --- a/test/symbols/all-symbols.txt +++ b/test/symbols/all-symbols.txt @@ -680,6 +680,7 @@ sodium_munlock sodium_munshield sodium_pad sodium_runtime_has_aesni +sodium_runtime_has_armcrypto_aes sodium_runtime_has_avx sodium_runtime_has_avx2 sodium_runtime_has_avx512f