From eb28fda79748c303d88a8af48de5187100f2c64c Mon Sep 17 00:00:00 2001 From: Orr Toledano Date: Thu, 6 May 2021 21:32:49 +0000 Subject: [PATCH] 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 Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/15361) --- crypto/info.c | 4 ++ .../implementations/rands/seeding/build.info | 7 +- .../rands/seeding/rand_cpu_arm64.c | 67 +++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 providers/implementations/rands/seeding/rand_cpu_arm64.c diff --git a/crypto/info.c b/crypto/info.c index a106e8c8859..f3bef56b136 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 2788146ad42..9c5eefee2d0 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 00000000000..a8530e02b57 --- /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 +#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 */ -- 2.47.2