mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
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)
This commit is contained in:
parent
a56bb5d64e
commit
efa1f22483
@ -161,7 +161,67 @@ CRYPTO_memcmp:
|
||||
lsr w0,w0,#31
|
||||
ret
|
||||
.size CRYPTO_memcmp,.-CRYPTO_memcmp
|
||||
|
||||
.globl _armv8_rng_probe
|
||||
.type _armv8_rng_probe,%function
|
||||
_armv8_rng_probe:
|
||||
mrs x0, s3_3_c2_c4_0 // rndr
|
||||
mrs x0, s3_3_c2_c4_1 // rndrrs
|
||||
ret
|
||||
.size _armv8_rng_probe,.-_armv8_rng_probe
|
||||
___
|
||||
|
||||
sub gen_random {
|
||||
my $rdop = shift;
|
||||
my $rand_reg = $rdop eq "rndr" ? "s3_3_c2_c4_0" : "s3_3_c2_c4_1";
|
||||
|
||||
print<<___;
|
||||
// Fill buffer with Randomly Generated Bytes
|
||||
// inputs: char * in x0 - Pointer to buffer
|
||||
// size_t in x1 - Number of bytes to write to buffer
|
||||
// outputs: size_t in x0 - Number of bytes successfully written to buffer
|
||||
.globl OPENSSL_${rdop}_asm
|
||||
.type OPENSSL_${rdop}_asm,%function
|
||||
.align 4
|
||||
OPENSSL_${rdop}_asm:
|
||||
mov x2,xzr
|
||||
mov x3,xzr
|
||||
|
||||
.align 4
|
||||
.Loop_${rdop}:
|
||||
cmp x1,#0
|
||||
b.eq .${rdop}_done
|
||||
mov x3,xzr
|
||||
mrs x3,$rand_reg
|
||||
b.eq .${rdop}_done
|
||||
|
||||
cmp x1,#8
|
||||
b.lt .Loop_single_byte_${rdop}
|
||||
|
||||
str x3,[x0]
|
||||
add x0,x0,#8
|
||||
add x2,x2,#8
|
||||
subs x1,x1,#8
|
||||
b.ge .Loop_${rdop}
|
||||
|
||||
.align 4
|
||||
.Loop_single_byte_${rdop}:
|
||||
strb w3,[x0]
|
||||
lsr x3,x3,#8
|
||||
add x2,x2,#1
|
||||
add x0,x0,#1
|
||||
subs x1,x1,#1
|
||||
b.gt .Loop_single_byte_${rdop}
|
||||
|
||||
.align 4
|
||||
.${rdop}_done:
|
||||
mov x0,x2
|
||||
ret
|
||||
.size OPENSSL_${rdop}_asm,.-OPENSSL_${rdop}_asm
|
||||
___
|
||||
}
|
||||
gen_random("rndr");
|
||||
gen_random("rndrrs");
|
||||
|
||||
print $code;
|
||||
close STDOUT or die "error closing STDOUT: $!";
|
||||
|
@ -83,6 +83,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized;
|
||||
# define ARMV8_PMULL (1<<5)
|
||||
# define ARMV8_SHA512 (1<<6)
|
||||
# define ARMV8_CPUID (1<<7)
|
||||
# define ARMV8_RNG (1<<8)
|
||||
|
||||
/*
|
||||
* MIDR_EL1 system register
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user