[openssl] master update
tomas at openssl.org
tomas at openssl.org
Thu Dec 16 11:38:48 UTC 2021
The branch master has been updated
via e8b597f33143410fb50bdeba8722c249524bc0b9 (commit)
via 1f8ce0c9faee59ac51a5db7a8ec42c38866be090 (commit)
via eb28fda79748c303d88a8af48de5187100f2c64c (commit)
via efa1f22483ee43d84e1aee01b08c0bda04060c1c (commit)
from a56bb5d64e7599140117f935eeeb34ba94c83aea (commit)
- Log -----------------------------------------------------------------
commit e8b597f33143410fb50bdeba8722c249524bc0b9
Author: Orr Toledano <otoledan at amazon.com>
Date: Thu May 20 22:13:30 2021 +0000
Documentation for RNDR and RNDRRS
Reviewed-by: Paul Dale <pauli at openssl.org>
Reviewed-by: Tomas Mraz <tomas at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15361)
commit 1f8ce0c9faee59ac51a5db7a8ec42c38866be090
Author: Orr Toledano <otoledan at amazon.com>
Date: Thu May 6 18:46:27 2021 +0000
Add tests for RNDR and combine tests with RDRAND
Add test cases for RNDR and RNDRRS. Combine tests for RDRAND and RNDR to
share common logic.
Reviewed-by: Paul Dale <pauli at openssl.org>
Reviewed-by: Tomas Mraz <tomas at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15361)
commit eb28fda79748c303d88a8af48de5187100f2c64c
Author: Orr Toledano <otoledan at amazon.com>
Date: Thu May 6 21:32:49 2021 +0000
Add support for RNDRRS Provider
Create new provider for RNDRRS. Modify support for rand_cpu to default to
RDRAND/RDSEED on x86 and RNDRRS on aarch64.
Reviewed-by: Paul Dale <pauli at openssl.org>
Reviewed-by: Tomas Mraz <tomas at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15361)
commit efa1f22483ee43d84e1aee01b08c0bda04060c1c
Author: Orr Toledano <otoledan at amazon.com>
Date: Wed May 19 18:54:20 2021 +0000
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 at openssl.org>
Reviewed-by: Tomas Mraz <tomas at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15361)
-----------------------------------------------------------------------
Summary of changes:
CHANGES.md | 5 ++
INSTALL.md | 3 +-
crypto/arm64cpuid.pl | 60 +++++++++++++++++++
crypto/arm_arch.h | 1 +
crypto/armcap.c | 45 +++++++++++++++
crypto/info.c | 4 ++
providers/implementations/rands/seeding/build.info | 7 ++-
.../implementations/rands/seeding/rand_cpu_arm64.c | 67 ++++++++++++++++++++++
test/build.info | 8 +--
test/{rdrand_sanitytest.c => rdcpu_sanitytest.c} | 48 ++++++++++++----
...test_rdrand_sanity.t => 06-test_rdcpu_sanity.t} | 4 +-
11 files changed, 234 insertions(+), 18 deletions(-)
create mode 100644 providers/implementations/rands/seeding/rand_cpu_arm64.c
rename test/{rdrand_sanitytest.c => rdcpu_sanitytest.c} (80%)
rename test/recipes/{06-test_rdrand_sanity.t => 06-test_rdcpu_sanity.t} (87%)
diff --git a/CHANGES.md b/CHANGES.md
index 16e2c341bd..7ddc41a0e7 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -24,6 +24,11 @@ OpenSSL 3.1
### Changes between 3.0 and 3.1 [xx XXX xxxx]
+ * RNDR and RNDRRS support in provider functions to provide
+ random number generation for Arm CPUs (aarch64).
+
+ *Orr Toledano*
+
* s_client and s_server apps now explicitly say when the TLS version
does not include the renegotiation mechanism. This avoids confusion
between that scenario versus when the TLS version includes secure
diff --git a/INSTALL.md b/INSTALL.md
index 70eb8da1ed..40ca7090b5 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -446,7 +446,8 @@ This source is ignored by the FIPS provider.
### rdcpu
-Use the `RDSEED` or `RDRAND` command if provided by the CPU.
+Use the `RDSEED` or `RDRAND` command on x86 or `RNDRRS` command on aarch64
+if provided by the CPU.
### librandom
diff --git a/crypto/arm64cpuid.pl b/crypto/arm64cpuid.pl
index 11f0e50279..a86fa6073a 100755
--- a/crypto/arm64cpuid.pl
+++ b/crypto/arm64cpuid.pl
@@ -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: $!";
diff --git a/crypto/arm_arch.h b/crypto/arm_arch.h
index aa380acce0..ca48045670 100644
--- a/crypto/arm_arch.h
+++ b/crypto/arm_arch.h
@@ -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
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 */
diff --git a/crypto/info.c b/crypto/info.c
index a106e8c885..f3bef56b13 100644
--- a/crypto/info.c
+++ b/crypto/info.c
@@ -135,7 +135,11 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings)
add_seeds_string("stdsc");
#endif
#ifdef OPENSSL_RAND_SEED_RDCPU
+# ifdef __aarch64__
+ add_seeds_string("rndr ( rndrrs rndr )");
+# else
add_seeds_string("rdrand ( rdseed rdrand )");
+# endif
#endif
#ifdef OPENSSL_RAND_SEED_LIBRANDOM
add_seeds_string("C-library-random");
diff --git a/providers/implementations/rands/seeding/build.info b/providers/implementations/rands/seeding/build.info
index 2788146ad4..9c5eefee2d 100644
--- a/providers/implementations/rands/seeding/build.info
+++ b/providers/implementations/rands/seeding/build.info
@@ -1,10 +1,15 @@
-$COMMON=rand_unix.c rand_win.c rand_tsc.c rand_cpu_x86.c
+$COMMON=rand_unix.c rand_win.c rand_tsc.c
IF[{- $config{target} =~ /vxworks/i -}]
$COMMON=$COMMON rand_vxworks.c
ENDIF
IF[{- $config{target} =~ /vms/i -}]
$COMMON=$COMMON rand_vms.c
ENDIF
+IF[{- !$disabled{asm} && $config{target} =~ '.*aarch64' -}]
+ $COMMON=$COMMON rand_cpu_arm64.c
+ELSE
+ $COMMON=$COMMON rand_cpu_x86.c
+ENDIF
SOURCE[../../../libdefault.a]=$COMMON
diff --git a/providers/implementations/rands/seeding/rand_cpu_arm64.c b/providers/implementations/rands/seeding/rand_cpu_arm64.c
new file mode 100644
index 0000000000..a8530e02b5
--- /dev/null
+++ b/providers/implementations/rands/seeding/rand_cpu_arm64.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/cryptlib.h"
+#include <openssl/opensslconf.h>
+#include "crypto/rand_pool.h"
+#include "prov/seeding.h"
+
+
+#ifdef OPENSSL_RAND_SEED_RDCPU
+#include "crypto/arm_arch.h"
+
+size_t OPENSSL_rndrrs_bytes(unsigned char *buf, size_t len);
+
+static size_t get_hardware_random_value(unsigned char *buf, size_t len);
+
+/*
+ * Acquire entropy using Arm-specific cpu instructions
+ *
+ * Uses the RNDRRS instruction. RNDR is never needed since
+ * RNDRRS will always be available if RNDR is an available
+ * instruction.
+ *
+ * Returns the total entropy count, if it exceeds the requested
+ * entropy count. Otherwise, returns an entropy count of 0.
+ */
+size_t ossl_prov_acquire_entropy_from_cpu(RAND_POOL *pool)
+{
+ size_t bytes_needed;
+ unsigned char *buffer;
+
+ bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
+ if (bytes_needed > 0) {
+ buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
+
+ if (buffer != NULL) {
+ if (get_hardware_random_value(buffer, bytes_needed) == bytes_needed)
+ ossl_rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
+ else
+ ossl_rand_pool_add_end(pool, 0, 0);
+ }
+ }
+
+ return ossl_rand_pool_entropy_available(pool);
+}
+
+static size_t get_hardware_random_value(unsigned char *buf, size_t len)
+{
+ /* Always use RNDRRS or nothing */
+ if (OPENSSL_armcap_P & ARMV8_RNG) {
+ if (OPENSSL_rndrrs_bytes(buf, len) != len)
+ return 0;
+ } else {
+ return 0;
+ }
+ return len;
+}
+
+#else
+NON_EMPTY_TRANSLATION_UNIT
+#endif /* OPENSSL_RAND_SEED_RDCPU */
diff --git a/test/build.info b/test/build.info
index bc8d400232..ec4bd8d5db 100644
--- a/test/build.info
+++ b/test/build.info
@@ -584,7 +584,7 @@ IF[{- !$disabled{tests} -}]
IF[1]
PROGRAMS{noinst}=asn1_internal_test modes_internal_test x509_internal_test \
tls13encryptiontest wpackettest ctype_internal_test \
- rdrand_sanitytest property_test ideatest rsa_mp_test \
+ rdcpu_sanitytest property_test ideatest rsa_mp_test \
rsa_sp800_56b_test bn_internal_test ecdsatest rsa_test \
rc2test rc4test rc5test hmactest ffc_internal_test \
asn1_dsa_internal_test dsatest dsa_no_digest_size_test \
@@ -737,9 +737,9 @@ IF[{- !$disabled{tests} -}]
INCLUDE[rc4test]=../include ../apps/include
DEPEND[rc4test]=../libcrypto.a libtestutil.a
- SOURCE[rdrand_sanitytest]=rdrand_sanitytest.c
- INCLUDE[rdrand_sanitytest]=../include ../apps/include
- DEPEND[rdrand_sanitytest]=../libcrypto.a libtestutil.a
+ SOURCE[rdcpu_sanitytest]=rdcpu_sanitytest.c
+ INCLUDE[rdcpu_sanitytest]=../include ../apps/include ../crypto
+ DEPEND[rdcpu_sanitytest]=../libcrypto.a libtestutil.a
SOURCE[rsa_sp800_56b_test]=rsa_sp800_56b_test.c
INCLUDE[rsa_sp800_56b_test]=.. ../include ../crypto/rsa ../apps/include
diff --git a/test/rdrand_sanitytest.c b/test/rdcpu_sanitytest.c
similarity index 80%
rename from test/rdrand_sanitytest.c
rename to test/rdcpu_sanitytest.c
index dcc9d2800a..df1858ae9b 100644
--- a/test/rdrand_sanitytest.c
+++ b/test/rdcpu_sanitytest.c
@@ -16,10 +16,24 @@
#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)
-
+# define IS_X_86 1
size_t OPENSSL_ia32_rdrand_bytes(unsigned char *buf, size_t len);
size_t OPENSSL_ia32_rdseed_bytes(unsigned char *buf, size_t len);
+#else
+# define IS_X_86 0
+#endif
+
+#if defined(__aarch64__)
+# define IS_AARCH_64 1
+# include "arm_arch.h"
+
+size_t OPENSSL_rndr_bytes(unsigned char *buf, size_t len);
+size_t OPENSSL_rndrrs_bytes(unsigned char *buf, size_t len);
+#else
+# define IS_AARCH_64 0
+#endif
+#if (IS_X_86 || IS_AARCH_64)
static int sanity_check_bytes(size_t (*rng)(unsigned char *, size_t),
int rounds, int min_failures, int max_retries, int max_zero_words)
{
@@ -76,7 +90,9 @@ static int sanity_check_bytes(size_t (*rng)(unsigned char *, size_t),
end:
return testresult;
}
+#endif
+#if IS_X_86
static int sanity_check_rdrand_bytes(void)
{
return sanity_check_bytes(OPENSSL_ia32_rdrand_bytes, 1000, 0, 10, 10);
@@ -92,11 +108,24 @@ static int sanity_check_rdseed_bytes(void)
*/
return sanity_check_bytes(OPENSSL_ia32_rdseed_bytes, 1000, 1, 10000, 10);
}
+#elif IS_AARCH_64
+static int sanity_check_rndr_bytes(void)
+{
+ return sanity_check_bytes(OPENSSL_rndr_bytes, 1000, 0, 10, 10);
+}
+
+static int sanity_check_rndrrs_bytes(void)
+{
+ return sanity_check_bytes(OPENSSL_rndrrs_bytes, 1000, 0, 10000, 10);
+}
+#endif
int setup_tests(void)
{
+#if (IS_X_86 || IS_AARCH_64)
OPENSSL_cpuid_setup();
+# if IS_X_86
int have_rdseed = (OPENSSL_ia32cap_P[2] & (1 << 18)) != 0;
int have_rdrand = (OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0;
@@ -107,16 +136,15 @@ int setup_tests(void)
if (have_rdseed) {
ADD_TEST(sanity_check_rdseed_bytes);
}
+# elif IS_AARCH_64
+ int have_rndr_rndrrs = (OPENSSL_armcap_P & (1 << 8)) != 0;
- return 1;
-}
-
-
-#else
+ if (have_rndr_rndrrs) {
+ ADD_TEST(sanity_check_rndr_bytes);
+ ADD_TEST(sanity_check_rndrrs_bytes);
+ }
+# endif
+#endif
-int setup_tests(void)
-{
return 1;
}
-
-#endif
diff --git a/test/recipes/06-test_rdrand_sanity.t b/test/recipes/06-test_rdcpu_sanity.t
similarity index 87%
rename from test/recipes/06-test_rdrand_sanity.t
rename to test/recipes/06-test_rdcpu_sanity.t
index a20e09e778..9907abc7c0 100644
--- a/test/recipes/06-test_rdrand_sanity.t
+++ b/test/recipes/06-test_rdcpu_sanity.t
@@ -13,10 +13,10 @@ use OpenSSL::Test; # get 'plan'
use OpenSSL::Test::Simple;
use OpenSSL::Test::Utils;
-setup("test_rdrand_sanity");
+setup("test_rdcpu_sanity");
# We also need static builds to be enabled even on linux
plan skip_all => "This test is unsupported if static builds are not enabled"
if disabled("static");
-simple_test("test_rdrand_sanity", "rdrand_sanitytest");
+simple_test("test_rdcpu_sanity", "rdcpu_sanitytest");
More information about the openssl-commits
mailing list