Allow ARM capabilities to be set at compile time.
Some ARM environments don't support |getauxval| or signals and need to configure the capabilities of the chip at compile time. This change adds defines that allow them to do so. Change-Id: I4e6987f69dd13444029bc7ac7ed4dbf8fb1faa76 Reviewed-on: https://boringssl-review.googlesource.com/6280 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
c2ae53db6d
commit
6a7cfbe06a
24
BUILDING.md
24
BUILDING.md
@ -91,6 +91,30 @@ binaries.
|
||||
don't have steps for assembling the assembly language source files, so they
|
||||
currently cannot be used to build BoringSSL.
|
||||
|
||||
## Embedded ARM
|
||||
|
||||
ARM, unlike Intel, does not have an instruction that allows applications to
|
||||
discover the capabilities of the processor. Instead, the capability information
|
||||
has to be provided by the operating system somehow.
|
||||
|
||||
BoringSSL will try to use `getauxval` to discover the capabilities and, failing
|
||||
that, will probe for NEON support by executing a NEON instruction and handling
|
||||
any illegal-instruction signal. But some environments don't support that sort
|
||||
of thing and, for them, it's possible to configure the CPU capabilities
|
||||
at compile time.
|
||||
|
||||
If you define `OPENSSL_STATIC_ARMCAP` then you can define any of the following
|
||||
to enabling the corresponding ARM feature.
|
||||
|
||||
* `OPENSSL_STATIC_ARMCAP_NEON` or `__ARM_NEON__` (note that the latter is set by compilers when NEON support is enabled).
|
||||
* `OPENSSL_STATIC_ARMCAP_AES`
|
||||
* `OPENSSL_STATIC_ARMCAP_SHA1`
|
||||
* `OPENSSL_STATIC_ARMCAP_SHA256`
|
||||
* `OPENSSL_STATIC_ARMCAP_PMULL`
|
||||
|
||||
Note that if a feature is enabled in this way, but not actually supported at
|
||||
run-time, BoringSSL will likely crash.
|
||||
|
||||
# Running tests
|
||||
|
||||
There are two sets of tests: the C/C++ tests and the blackbox tests. For former
|
||||
|
@ -51,6 +51,8 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
@ -1059,10 +1061,9 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
||||
#else
|
||||
|
||||
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
#include <openssl/arm_arch.h>
|
||||
|
||||
static int hwaes_capable(void) {
|
||||
return (OPENSSL_armcap_P & ARMV8_AES) != 0;
|
||||
return CRYPTO_is_ARMv8_AES_capable();
|
||||
}
|
||||
|
||||
int aes_v8_set_encrypt_key(const uint8_t *user_key, const int bits,
|
||||
|
@ -121,7 +121,7 @@ static char bsaes_capable(void) {
|
||||
|
||||
#define HWAES
|
||||
static int hwaes_capable(void) {
|
||||
return (OPENSSL_armcap_P & ARMV8_AES) != 0;
|
||||
return CRYPTO_is_ARMv8_AES_capable();
|
||||
}
|
||||
|
||||
int aes_v8_set_encrypt_key(const uint8_t *user_key, const int bits,
|
||||
@ -1756,7 +1756,7 @@ int EVP_has_aes_hardware(void) {
|
||||
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
|
||||
return aesni_capable() && crypto_gcm_clmul_enabled();
|
||||
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
return hwaes_capable() && (OPENSSL_armcap_P & ARMV8_PMULL);
|
||||
return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -14,15 +14,14 @@
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
|
||||
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \
|
||||
!defined(OPENSSL_STATIC_ARMCAP)
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(OPENSSL_TRUSTY)
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/arm_arch.h>
|
||||
|
||||
@ -33,6 +32,8 @@
|
||||
|
||||
unsigned long getauxval(unsigned long type) __attribute__((weak));
|
||||
|
||||
extern uint32_t OPENSSL_armcap_P;
|
||||
|
||||
char CRYPTO_is_NEON_capable(void) {
|
||||
return (OPENSSL_armcap_P & ARMV7_NEON) != 0;
|
||||
}
|
||||
@ -62,7 +63,15 @@ void CRYPTO_set_NEON_functional(char neon_functional) {
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM) && !defined(OPENSSL_TRUSTY)
|
||||
int CRYPTO_is_ARMv8_AES_capable(void) {
|
||||
return (OPENSSL_armcap_P & ARMV8_AES) != 0;
|
||||
}
|
||||
|
||||
int CRYPTO_is_ARMv8_PMULL_capable(void) {
|
||||
return (OPENSSL_armcap_P & ARMV8_PMULL) != 0;
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM)
|
||||
|
||||
static sigjmp_buf sigill_jmp;
|
||||
|
||||
@ -120,7 +129,7 @@ static int probe_for_NEON(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !OPENSSL_NO_ASM && OPENSSL_ARM && !OPENSSL_TRUSTY */
|
||||
#endif /* !OPENSSL_NO_ASM && OPENSSL_ARM */
|
||||
|
||||
void OPENSSL_cpuid_setup(void) {
|
||||
if (getauxval == NULL) {
|
||||
@ -186,4 +195,5 @@ void OPENSSL_cpuid_setup(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) */
|
||||
#endif /* (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) &&
|
||||
!defined(OPENSSL_STATIC_ARMCAP) */
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && \
|
||||
#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_STATIC_ARMCAP) && \
|
||||
(defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
|
||||
defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
|
||||
/* x86, x86_64 and the ARMs need to record the result of a cpuid call for the
|
||||
@ -57,7 +57,27 @@ uint32_t OPENSSL_ia32cap_P[4] = {0};
|
||||
|
||||
#include <openssl/arm_arch.h>
|
||||
|
||||
#if defined(__ARM_NEON__)
|
||||
#if defined(OPENSSL_STATIC_ARMCAP)
|
||||
|
||||
uint32_t OPENSSL_armcap_P =
|
||||
#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
|
||||
ARMV7_NEON | ARMV7_NEON_FUNCTIONAL |
|
||||
#endif
|
||||
#if defined(OPENSSL_STATIC_ARMCAP_AES)
|
||||
ARMV8_AES |
|
||||
#endif
|
||||
#if defined(OPENSSL_STATIC_ARMCAP_SHA1)
|
||||
ARMV8_SHA1 |
|
||||
#endif
|
||||
#if defined(OPENSSL_STATIC_ARMCAP_SHA256)
|
||||
ARMV8_SHA256 |
|
||||
#endif
|
||||
#if defined(OPENSSL_STATIC_ARMCAP_PMULL)
|
||||
ARMV8_PMULL |
|
||||
#endif
|
||||
0;
|
||||
|
||||
#elif defined(__ARM_NEON__)
|
||||
uint32_t OPENSSL_armcap_P = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
|
||||
#else
|
||||
uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL;
|
||||
|
@ -355,7 +355,7 @@ void gcm_ghash_4bit_x86(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in
|
||||
#define GCM_FUNCREF_4BIT
|
||||
|
||||
static int pmull_capable(void) {
|
||||
return (OPENSSL_armcap_P & ARMV8_PMULL) != 0;
|
||||
return CRYPTO_is_ARMv8_PMULL_capable();
|
||||
}
|
||||
|
||||
void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]);
|
||||
|
@ -102,15 +102,6 @@
|
||||
* will be included. */
|
||||
#define __ARM_MAX_ARCH__ 8
|
||||
|
||||
#if !__ASSEMBLER__
|
||||
|
||||
/* OPENSSL_armcap_P contains flags describing the capabilities of the CPU and
|
||||
* is easy for assembly code to acesss. For C code, see the functions in
|
||||
* |cpu.h|. */
|
||||
extern uint32_t OPENSSL_armcap_P;
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
/* ARMV7_NEON is true when a NEON unit is present in the current CPU. */
|
||||
#define ARMV7_NEON (1 << 0)
|
||||
|
||||
|
@ -94,6 +94,9 @@ extern uint32_t OPENSSL_ia32cap_P[4];
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
|
||||
#if !defined(OPENSSL_STATIC_ARMCAP)
|
||||
|
||||
/* CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. Note
|
||||
* that |OPENSSL_armcap_P| also exists and contains the same information in a
|
||||
* form that's easier for assembly to use. */
|
||||
@ -116,6 +119,46 @@ OPENSSL_EXPORT char CRYPTO_is_NEON_functional(void);
|
||||
* compiled with |-mfpu=neon| or if |CRYPTO_set_NEON_capable| has been called
|
||||
* with a non-zero argument. */
|
||||
OPENSSL_EXPORT void CRYPTO_set_NEON_functional(char neon_functional);
|
||||
|
||||
/* CRYPTO_is_ARMv8_AES_capable returns true if the current CPU supports the
|
||||
* ARMv8 AES instruction. */
|
||||
int CRYPTO_is_ARMv8_AES_capable(void);
|
||||
|
||||
/* CRYPTO_is_ARMv8_PMULL_capable returns true if the current CPU supports the
|
||||
* ARMv8 PMULL instruction. */
|
||||
int CRYPTO_is_ARMv8_PMULL_capable(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline int CRYPTO_is_NEON_capable(void) {
|
||||
#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int CRYPTO_is_NEON_functional(void) {
|
||||
return CRYPTO_is_NEON_capable();
|
||||
}
|
||||
|
||||
static inline int CRYPTO_is_ARMv8_AES_capable(void) {
|
||||
#if defined(OPENSSL_STATIC_ARMCAP_AES)
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int CRYPTO_is_ARMv8_PMULL_capable(void) {
|
||||
#if defined(OPENSSL_STATIC_ARMCAP_PMULL)
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_STATIC_ARMCAP */
|
||||
#endif /* OPENSSL_ARM */
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user