diff options
author | Orr Toledano <otoledan@amazon.com> | 2021-05-19 18:54:20 +0000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-12-16 12:38:09 +0100 |
commit | efa1f22483ee43d84e1aee01b08c0bda04060c1c (patch) | |
tree | 219f223e67a048aa8187c1e222086ba7eab93152 /crypto/armcap.c | |
parent | a56bb5d64e7599140117f935eeeb34ba94c83aea (diff) |
Add Arm Assembly (aarch64) support for RNG
Include aarch64 asm instructions for random number generation using the
RNDR and RNDRRS instructions. Provide detection functions for RNDR and
RNDRRS getauxval.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15361)
Diffstat (limited to 'crypto/armcap.c')
-rw-r--r-- | crypto/armcap.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/crypto/armcap.c b/crypto/armcap.c index 5b45a9d0f4..117c57efe4 100644 --- a/crypto/armcap.c +++ b/crypto/armcap.c @@ -17,6 +17,7 @@ #include <sys/sysctl.h> #endif #include "internal/cryptlib.h" +#include <unistd.h> #include "arm_arch.h" @@ -54,6 +55,37 @@ void _armv8_pmull_probe(void); # ifdef __aarch64__ void _armv8_sha512_probe(void); unsigned int _armv8_cpuid_probe(void); +void _armv8_rng_probe(void); + +size_t OPENSSL_rndr_asm(unsigned char *buf, size_t len); +size_t OPENSSL_rndrrs_asm(unsigned char *buf, size_t len); + +size_t OPENSSL_rndr_bytes(unsigned char *buf, size_t len); +size_t OPENSSL_rndrrs_bytes(unsigned char *buf, size_t len); + +static size_t OPENSSL_rndr_wrapper(size_t (*func)(unsigned char *, size_t), unsigned char *buf, size_t len) +{ + size_t buffer_size; + int i; + + for (i = 0; i < 8; i++) { + buffer_size = func(buf, len); + if (buffer_size == len) + break; + usleep(5000); /* 5000 microseconds (5 milliseconds) */ + } + return buffer_size; +} + +size_t OPENSSL_rndr_bytes(unsigned char *buf, size_t len) +{ + return OPENSSL_rndr_wrapper(OPENSSL_rndr_asm, buf, len); +} + +size_t OPENSSL_rndrrs_bytes(unsigned char *buf, size_t len) +{ + return OPENSSL_rndr_wrapper(OPENSSL_rndrrs_asm, buf, len); +} # endif uint32_t _armv7_tick(void); @@ -138,6 +170,9 @@ static unsigned long getauxval(unsigned long key) # define HWCAP_CE_SHA256 (1 << 6) # define HWCAP_CPUID (1 << 11) # define HWCAP_CE_SHA512 (1 << 21) + /* AT_HWCAP2 */ +# define HWCAP2 26 +# define HWCAP2_RNG (1 << 16) # endif void OPENSSL_cpuid_setup(void) @@ -212,6 +247,10 @@ void OPENSSL_cpuid_setup(void) OPENSSL_armcap_P |= ARMV8_CPUID; # endif } +# ifdef __aarch64__ + if (getauxval(HWCAP2) & HWCAP2_RNG) + OPENSSL_armcap_P |= ARMV8_RNG; +# endif # endif sigfillset(&all_masked); @@ -255,6 +294,12 @@ void OPENSSL_cpuid_setup(void) } # endif } +# ifdef __aarch64__ + if (sigsetjmp(ill_jmp, 1) == 0) { + _armv8_rng_probe(); + OPENSSL_armcap_P |= ARMV8_RNG; + } +# endif # endif /* Things that getauxval didn't tell us */ |