diff options
Diffstat (limited to 'crypto/armcap.c')
-rw-r--r-- | crypto/armcap.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/crypto/armcap.c b/crypto/armcap.c index 356fa152871f..1b3c2722d1e1 100644 --- a/crypto/armcap.c +++ b/crypto/armcap.c @@ -1,9 +1,19 @@ +/* + * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <setjmp.h> #include <signal.h> -#include <crypto.h> +#include <openssl/crypto.h> +#include "internal/cryptlib.h" #include "arm_arch.h" @@ -14,7 +24,7 @@ void OPENSSL_cpuid_setup(void) { } -unsigned long OPENSSL_rdtsc(void) +uint32_t OPENSSL_rdtsc(void) { return 0; } @@ -36,9 +46,12 @@ void _armv8_aes_probe(void); void _armv8_sha1_probe(void); void _armv8_sha256_probe(void); void _armv8_pmull_probe(void); -unsigned long _armv7_tick(void); +# ifdef __aarch64__ +void _armv8_sha512_probe(void); +# endif +uint32_t _armv7_tick(void); -unsigned long OPENSSL_rdtsc(void) +uint32_t OPENSSL_rdtsc(void) { if (OPENSSL_armcap_P & ARMV7_TICK) return _armv7_tick(); @@ -46,19 +59,21 @@ unsigned long OPENSSL_rdtsc(void) return 0; } +# if defined(__GNUC__) && __GNUC__>=2 +void OPENSSL_cpuid_setup(void) __attribute__ ((constructor)); +# endif /* * Use a weak reference to getauxval() so we can use it if it is available but * don't break the build if it is not. */ -# if defined(__GNUC__) && __GNUC__>=2 -void OPENSSL_cpuid_setup(void) __attribute__ ((constructor)); +# if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) extern unsigned long getauxval(unsigned long type) __attribute__ ((weak)); # else static unsigned long (*getauxval) (unsigned long) = NULL; # endif /* - * ARM puts the the feature bits for Crypto Extensions in AT_HWCAP2, whereas + * ARM puts the feature bits for Crypto Extensions in AT_HWCAP2, whereas * AArch64 used AT_HWCAP. */ # if defined(__arm__) || defined (__arm) @@ -82,11 +97,12 @@ static unsigned long (*getauxval) (unsigned long) = NULL; # define HWCAP_CE_PMULL (1 << 4) # define HWCAP_CE_SHA1 (1 << 5) # define HWCAP_CE_SHA256 (1 << 6) +# define HWCAP_CE_SHA512 (1 << 21) # endif void OPENSSL_cpuid_setup(void) { - char *e; + const char *e; struct sigaction ill_oact, ill_act; sigset_t oset; static int trigger = 0; @@ -100,6 +116,24 @@ void OPENSSL_cpuid_setup(void) return; } +# if defined(__APPLE__) && !defined(__aarch64__) + /* + * Capability probing by catching SIGILL appears to be problematic + * on iOS. But since Apple universe is "monocultural", it's actually + * possible to simply set pre-defined processor capability mask. + */ + if (1) { + OPENSSL_armcap_P = ARMV7_NEON; + return; + } + /* + * One could do same even for __aarch64__ iOS builds. It's not done + * exclusively for reasons of keeping code unified across platforms. + * Unified code works because it never triggers SIGILL on Apple + * devices... + */ +# endif + sigfillset(&all_masked); sigdelset(&all_masked, SIGILL); sigdelset(&all_masked, SIGTRAP); @@ -133,6 +167,11 @@ void OPENSSL_cpuid_setup(void) if (hwcap & HWCAP_CE_SHA256) OPENSSL_armcap_P |= ARMV8_SHA256; + +# ifdef __aarch64__ + if (hwcap & HWCAP_CE_SHA512) + OPENSSL_armcap_P |= ARMV8_SHA512; +# endif } } else if (sigsetjmp(ill_jmp, 1) == 0) { _armv7_neon_probe(); @@ -152,6 +191,12 @@ void OPENSSL_cpuid_setup(void) _armv8_sha256_probe(); OPENSSL_armcap_P |= ARMV8_SHA256; } +# if defined(__aarch64__) && !defined(__APPLE__) + if (sigsetjmp(ill_jmp, 1) == 0) { + _armv8_sha512_probe(); + OPENSSL_armcap_P |= ARMV8_SHA512; + } +# endif } if (sigsetjmp(ill_jmp, 1) == 0) { _armv7_tick(); |