diff options
author | Adam Langley <agl@google.com> | 2015-01-10 02:44:37 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2015-01-15 02:38:11 +0300 |
commit | 3e6526575ac2349a44a04a0bbc7acb917fab5a0b (patch) | |
tree | 51f4fbc4677ec256a8ff1f747df201f13ed50157 /crypto/cpu-arm.c | |
parent | bc44c089fbd87de0924130453058131ce30cd483 (diff) |
aarch64 support.
This is an initial cut at aarch64 support. I have only qemu to test it
however—hopefully hardware will be coming soon.
This also affects 32-bit ARM in that aarch64 chips can run 32-bit code
and we would like to be able to take advantage of the crypto operations
even in 32-bit mode. AES and GHASH should Just Work in this case: the
-armx.pl files can be built for either 32- or 64-bit mode based on the
flavour argument given to the Perl script.
SHA-1 and SHA-256 don't work like this however because they've never
support for multiple implementations, thus BoringSSL built for 32-bit
won't use the SHA instructions on an aarch64 chip.
No dedicated ChaCha20 or Poly1305 support yet.
Change-Id: Ib275bc4894a365c8ec7c42f4e91af6dba3bd686c
Reviewed-on: https://boringssl-review.googlesource.com/2801
Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'crypto/cpu-arm.c')
-rw-r--r-- | crypto/cpu-arm.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/crypto/cpu-arm.c b/crypto/cpu-arm.c index dac7e1e5..6f6e04a9 100644 --- a/crypto/cpu-arm.c +++ b/crypto/cpu-arm.c @@ -56,18 +56,14 @@ #include <openssl/cpu.h> -#if defined(OPENSSL_ARM) +#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) -#include <stdio.h> #include <inttypes.h> +#include <stdio.h> +#include <sys/auxv.h> #include "arm_arch.h" -#if defined(__ARM_NEON__) -uint32_t OPENSSL_armcap_P = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL; -#else -uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL; -#endif char CRYPTO_is_NEON_capable(void) { return (OPENSSL_armcap_P & ARMV7_NEON) != 0; @@ -94,4 +90,53 @@ void CRYPTO_set_NEON_functional(char neon_functional) { } } -#endif /* defined(OPENSSL_ARM) */ +void OPENSSL_cpuid_setup(void) { + unsigned long hwcap = getauxval(AT_HWCAP); + +#if defined(OPENSSL_ARM) + static const unsigned long kNEON = 1 << 12; + if ((hwcap & kNEON) == 0) { + return; + } + + /* In 32-bit mode, the ARMv8 feature bits are in a different aux vector + * value. */ + hwcap = getauxval(AT_HWCAP2); + + /* See /usr/include/asm/hwcap.h on an ARM installation for the source of + * these values. */ + static const unsigned long kAES = 1 << 0; + static const unsigned long kPMULL = 1 << 1; + static const unsigned long kSHA1 = 1 << 2; + static const unsigned long kSHA256 = 1 << 3; +#elif defined(OPENSSL_AARCH64) + /* See /usr/include/asm/hwcap.h on an aarch64 installation for the source of + * these values. */ + static const unsigned long kNEON = 1 << 1; + static const unsigned long kAES = 1 << 3; + static const unsigned long kPMULL = 1 << 4; + static const unsigned long kSHA1 = 1 << 5; + static const unsigned long kSHA256 = 1 << 6; + + if ((hwcap & kNEON) == 0) { + return; + } +#endif + + OPENSSL_armcap_P |= ARMV7_NEON | ARMV7_NEON_FUNCTIONAL; + + if (hwcap & kAES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap & kPMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap & kSHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap & kSHA256) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } +} + +#endif /* defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) */ |