8000 Add Arm Assembly (aarch64) support for RNG · openssl/openssl@45c74de · GitHub
[go: up one dir, main page]

Skip to content

Commit 45c74de

Browse files
otoledant8m
authored andcommitted
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 #15361) (cherry picked from commit efa1f22)
1 parent ee51843 commit 45c74de

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

crypto/arm64cpuid.pl

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,67 @@
161161
lsr w0,w0,#31
162162
ret
163163
.size CRYPTO_memcmp,.-CRYPTO_memcmp
164+
165+
.globl _armv8_rng_probe
166+
.type _armv8_rng_probe,%function
167+
_armv8_rng_probe:
168+
mrs x0, s3_3_c2_c4_0 // rndr
169+
mrs x0, s3_3_c2_c4_1 // rndrrs
170+
ret
171+
.size _armv8_rng_probe,.-_armv8_rng_probe
172+
___
173+
174+
sub gen_random {
175+
my $rdop = shift;
176+
my $rand_reg = $rdop eq "rndr" ? "s3_3_c2_c4_0" : "s3_3_c2_c4_1";
177+
178+
print<<___;
179+
// Fill buffer with Randomly Generated Bytes
180+
// inputs: char * in x0 - Pointer to buffer
181+
// size_t in x1 - Number of bytes to write to buffer
182+
// outputs: size_t in x0 - Number of bytes successfully written to buffer
183+
.globl OPENSSL_${rdop}_asm
184+
.type OPENSSL_${rdop}_asm,%function
185+
.align 4
186+
OPENSSL_${rdop}_asm:
187+
mov x2,xzr
188+
mov x3,xzr
189+
190+
.align 4
191+
.Loop_${rdop}:
192+
cmp x1,#0
193+
b.eq .${rdop}_done
194+
mov x3,xzr
195+
mrs x3,$rand_reg
196+
b.eq .${rdop}_done
197+
198+
cmp x1,#8
199+
b.lt .Loop_single_byte_${rdop}
200+
201+
str x3,[x0]
202+
add x0,x0,#8
203+
add x2,x2,#8
204+
subs x1,x1,#8
205+
b.ge .Loop_${rdop}
206+
207+
.align 4
208+
.Loop_single_byte_${rdop}:
209+
strb w3,[x0]
210+
lsr x3,x3,#8
211+
add x2,x2,#1
212+
add x0,x0,#1
213+
subs x1,x1,#1
214+
b.gt .Loop_single_byte_${rdop}
215+
216+
.align 4
217+
.${rdop}_done:
218+
mov x0,x2
219+
ret
220+
.size OPENSSL_${rdop}_asm,.-OPENSSL_${rdop}_asm
164221
___
222+
}
223+
gen_random("rndr");
224+
gen_random("rndrrs");
165225

166226
print $code;
167227
close STDOUT or die "error closing STDOUT: $!";

crypto/arm_arch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized;
8383
# define ARMV8_PMULL (1<<5)
8484
# define ARMV8_SHA512 (1<<6)
8585
# define ARMV8_CPUID (1<<7)
86+
# define ARMV8_RNG (1<<8)
8687

8788
/*
8889
* MIDR_EL1 system register

crypto/armcap.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <sys/sysctl.h>
1818
#endif
1919
#include "internal/cryptlib.h"
20+
#include <unistd.h>
2021

2122
#include "arm_arch.h"
2223

@@ -54,6 +55,37 @@ void _armv8_pmull_probe(void);
5455
# ifdef __aarch64__
5556
void _armv8_sha512_probe(void);
5657
unsigned int _armv8_cpuid_probe(void);
58+
void _armv8_rng_probe(void);
59+
60+
size_t OPENSSL_rndr_asm(unsigned char *buf, size_t len);
61+
size_t OPENSSL_rndrrs_asm(unsigned char *buf, size_t len);
62+
63+
size_t OPENSSL_rndr_bytes(unsigned char *buf, size_t len);
64+
size_t OPENSSL_rndrrs_bytes(unsigned char *buf, size_t len);
65+
66+
static size_t OPENSSL_rndr_wrapper(size_t (*func)(unsigned char *, size_t), unsigned char *buf, size_t len)
67+
{
68+
size_t buffer_size;
69+
int i;
70+
71+
for (i = 0; i < 8; i++) {
72+
buffer_size = func(buf, len);
73+
if (buffer_size == len)
74+
break;
75+
usleep(5000); /* 5000 microseconds (5 milliseconds) */
76+
}
77+
return buffer_size;
78+
}
79+
80+
size_t OPENSSL_rndr_bytes(unsigned char *buf, size_t len)
81+
{
82+
return OPENSSL_rndr_wrapper(OPENSSL_rndr_asm, buf, len);
83+
}
84+
85+
size_t OPENSSL_rndrrs_bytes(unsigned char *buf, size_t len)
86+
{
87+
return OPENSSL_rndr_wrapper(OPENSSL_rndrrs_asm, buf, len);
88+
}
5789
# endif
5890
uint32_t _armv7_tick(void);
5991

@@ -138,6 +170,9 @@ static unsigned long getauxval(unsigned long key)
138170
# define HWCAP_CE_SHA256 (1 << 6)
139171
# define HWCAP_CPUID (1 << 11)
140172
# define HWCAP_CE_SHA512 (1 << 21)
173+
/* AT_HWCAP2 */
174+
# define HWCAP2 26
175+
# define HWCAP2_RNG (1 << 16)
141176
# endif
142177

143178
void OPENSSL_cpuid_setup(void)
@@ -212,6 +247,10 @@ void OPENSSL_cpuid_setup(void)
212247
OPENSSL_armcap_P |= ARMV8_CPUID;
213248
# endif
214249
}
250+
# ifdef __aarch64__
251+
if (getauxval(HWCAP2) & HWCAP2_RNG)
252+
OPENSSL_armcap_P |= ARMV8_RNG;
253+
# endif
215254
# endif
216255

217256
sigfillset(&all_masked);
@@ -255,6 +294,12 @@ void OPENSSL_cpuid_setup(void)
255294
}
256295
# endif
257296
}
297+
# ifdef __aarch64__
298+
if (sigsetjmp(ill_jmp, 1) == 0) {
299+
_armv8_rng_probe();
300+
OPENSSL_armcap_P |= ARMV8_RNG;
301+
}
302+
# endif
258303
# endif
259304

260305
/*

0 commit comments

Comments
 (0)
0