fips module header inclusion fine-tunning
[openssl.git] / crypto / armcap.c
index 6c0acda24459bd08e96e921e5e5323954f56a02d..62e166a4dd039fa157adafb0c58a888dc1be8ee8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #include <setjmp.h>
 #include <signal.h>
 #include <openssl/crypto.h>
+#ifdef __APPLE__
+#include <sys/sysctl.h>
+#endif
 #include "internal/cryptlib.h"
 
 #include "arm_arch.h"
 
 unsigned int OPENSSL_armcap_P = 0;
 unsigned int OPENSSL_arm_midr = 0;
+unsigned int OPENSSL_armv8_rsa_neonized = 0;
 
 #if __ARM_MAX_ARCH__<7
 void OPENSSL_cpuid_setup(void)
@@ -70,6 +74,12 @@ void OPENSSL_cpuid_setup(void) __attribute__ ((constructor));
 #   include <sys/auxv.h>
 #   define OSSL_IMPLEMENT_GETAUXVAL
 #  endif
+# elif defined(__ANDROID_API__)
+/* see https://developer.android.google.cn/ndk/guides/cpu-features */
+#  if __ANDROID_API__ >= 18
+#   include <sys/auxv.h>
+#   define OSSL_IMPLEMENT_GETAUXVAL
+#  endif
 # endif
 # if defined(__FreeBSD__)
 #  include <sys/param.h>
@@ -89,6 +99,15 @@ static unsigned long getauxval(unsigned long key)
 #  endif
 # endif
 
+/*
+ * Android: according to https://developer.android.com/ndk/guides/cpu-features,
+ * getauxval is supported starting with API level 18
+ */
+#  if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 18
+#   include <sys/auxv.h>
+#   define OSSL_IMPLEMENT_GETAUXVAL
+#  endif
+
 /*
  * ARM puts the feature bits for Crypto Extensions in AT_HWCAP2, whereas
  * AArch64 used AT_HWCAP.
@@ -129,12 +148,15 @@ void OPENSSL_cpuid_setup(void)
         return;
     trigger = 1;
 
+    OPENSSL_armcap_P = 0;
+
     if ((e = getenv("OPENSSL_armcap"))) {
         OPENSSL_armcap_P = (unsigned int)strtoul(e, NULL, 0);
         return;
     }
 
-# if defined(__APPLE__) && !defined(__aarch64__)
+# if defined(__APPLE__)
+#   if !defined(__aarch64__)
     /*
      * Capability probing by catching SIGILL appears to be problematic
      * on iOS. But since Apple universe is "monocultural", it's actually
@@ -150,9 +172,16 @@ void OPENSSL_cpuid_setup(void)
      * Unified code works because it never triggers SIGILL on Apple
      * devices...
      */
-# endif
+#   else
+    {
+        unsigned int sha512;
+        size_t len = sizeof(sha512);
 
-    OPENSSL_armcap_P = 0;
+        if (sysctlbyname("hw.optional.armv8_2_sha512", &sha512, &len, NULL, 0) == 0 && sha512 == 1)
+            OPENSSL_armcap_P |= ARMV8_SHA512;
+    }
+#   endif
+# endif
 
 # ifdef OSSL_IMPLEMENT_GETAUXVAL
     if (getauxval(HWCAP) & HWCAP_NEON) {
@@ -237,6 +266,12 @@ void OPENSSL_cpuid_setup(void)
 # ifdef __aarch64__
     if (OPENSSL_armcap_P & ARMV8_CPUID)
         OPENSSL_arm_midr = _armv8_cpuid_probe();
+
+    if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) ||
+         MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N1)) &&
+        (OPENSSL_armcap_P & ARMV7_NEON)) {
+            OPENSSL_armv8_rsa_neonized = 1;
+    }
 # endif
 }
 #endif