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: $!";
#include <sys/sysctl.h>
#endif
#include "internal/cryptlib.h"
+#include <unistd.h>
#include "arm_arch.h"
# 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);
# 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)
OPENSSL_armcap_P |= ARMV8_CPUID;
# endif
}
+# ifdef __aarch64__
+ if (getauxval(HWCAP2) & HWCAP2_RNG)
+ OPENSSL_armcap_P |= ARMV8_RNG;
+# endif
# endif
sigfillset(&all_masked);
}
# 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 */