Move to preferring getentropy() for system provided entropy

This changes the order of things so that by default your
system is expected to provide us with a getentropy() in
<unistd.h> for integrators that are not explicitly
supported.

We preserve the getrandom/urandom dance for Linux and Android
for now.

Linux has had getentropy() in libc's since 2017
macOS, and all the BSD's have had it for any versions we
care about.

iOS hides it from us - so we use CommonCrypto CCRandomGenerateBytes

Update-Note: Non-macOS Apple platforms now use CCRandomGenerateBytes
instead of /dev/urandom. Linux behavior remains unchanged. Platforms
which were not explicitly supported with a different codepath will also
switch from /dev/urandom to getentropy. If your platform specifically
requires /dev/urandom, let us know.know

Bug: 287
Change-Id: I0c2b8c594c473e4395379f50b0c4e6713c0a4c02
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/61325
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
This commit is contained in:
Bob Beck 2023-07-04 07:48:12 +00:00 committed by Boringssl LUCI CQ
parent 99ce1e01fc
commit 53f09ad241
5 changed files with 92 additions and 28 deletions

View File

@ -200,6 +200,8 @@ add_library(
rand_extra/deterministic.c
rand_extra/forkunsafe.c
rand_extra/fuchsia.c
rand_extra/getentropy.c
rand_extra/ios.c
rand_extra/passive.c
rand_extra/rand_extra.c
rand_extra/windows.c

View File

@ -34,8 +34,15 @@ extern "C" {
// Trusty's PRNG file is, for now, maintained outside the tree.
#elif defined(OPENSSL_WINDOWS)
#define OPENSSL_RAND_WINDOWS
#else
#elif defined(OPENSSL_LINUX)
#define OPENSSL_RAND_URANDOM
#elif defined(OPENSSL_APPLE) && !defined(OPENSSL_MACOS)
// Unlike macOS, iOS and similar hide away getentropy().
#define OPENSSL_RAND_IOS
#else
// By default if you are integrating BoringSSL we expect you to
// provide getentropy from the <unistd.h> header file.
#define OPENSSL_RAND_GETENTROPY
#endif
// RAND_bytes_with_additional_data samples from the RNG after mixing 32 bytes

View File

@ -58,22 +58,6 @@
#endif
#endif // OPENSSL_LINUX
#if defined(OPENSSL_MACOS)
// getentropy exists in any supported version of MacOS (Sierra and later)
#include <sys/random.h>
#endif
#if defined(OPENSSL_OPENBSD)
// getentropy exists in any supported version of OpenBSD
#include <unistd.h>
#endif
#if defined(OPENSSL_FREEBSD) && __FreeBSD__ >= 12
// getrandom is supported in FreeBSD 12 and up.
#define FREEBSD_GETRANDOM
#include <sys/random.h>
#endif
#include <openssl/thread.h>
#include <openssl/mem.h>
@ -179,11 +163,6 @@ static void init_once(void) {
}
#endif // USE_NR_getrandom
#if defined(OPENSSL_MACOS) || defined(OPENSSL_OPENBSD) || defined(FREEBSD_GETRANDOM)
*urandom_fd_bss_get() = kHaveGetrandom;
return;
#endif
// FIPS builds must support getrandom.
//
// Historically, only Android FIPS builds required getrandom, while Linux FIPS
@ -295,12 +274,6 @@ static int fill_with_entropy(uint8_t *out, size_t len, int block, int seed) {
if (*urandom_fd_bss_get() == kHaveGetrandom) {
#if defined(USE_NR_getrandom)
r = boringssl_getrandom(out, len, getrandom_flags);
#elif defined(FREEBSD_GETRANDOM)
r = getrandom(out, len, getrandom_flags);
#elif defined(OPENSSL_MACOS) || defined(OPENSSL_OPENBSD)
// |getentropy| can only request 256 bytes at a time.
size_t todo = len <= 256 ? len : 256;
r = getentropy(out, todo) != 0 ? -1 : (ssize_t)todo;
#else // USE_NR_getrandom
fprintf(stderr, "urandom fd corrupt.\n");
abort();

View File

@ -0,0 +1,48 @@
/* Copyright (c) 2023, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/rand.h>
#include "../fipsmodule/rand/internal.h"
#if defined(OPENSSL_RAND_GETENTROPY)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#if defined(OPENSSL_MACOS)
#include <sys/random.h>
#endif
// CRYPTO_sysrand puts |requested| random bytes into |out|.
void CRYPTO_sysrand(uint8_t *out, size_t requested) {
while (requested > 0) {
// |getentropy| can only request 256 bytes at a time.
size_t todo = requested <= 256 ? requested : 256;
if (getentropy(out, todo) != 0) {
perror("getentropy() failed");
abort();
}
out += todo;
requested -= todo;
}
}
void CRYPTO_sysrand_for_seed(uint8_t *out, size_t requested) {
CRYPTO_sysrand(out, requested);
}
#endif // OPENSSL_RAND_GETENTROPY

34
crypto/rand_extra/ios.c Normal file
View File

@ -0,0 +1,34 @@
/* Copyright (c) 2023, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/rand.h>
#include "../fipsmodule/rand/internal.h"
#if defined(OPENSSL_RAND_IOS)
#include <stdlib.h>
#include <CommonCrypto/CommonRandom.h>
void CRYPTO_sysrand(uint8_t *out, size_t requested) {
if (CCRandomGenerateBytes(out, requested) == kCCSuccess) {
abort();
}
}
void CRYPTO_sysrand_for_seed(uint8_t *out, size_t requested) {
CRYPTO_sysrand(out, requested);
}
#endif // OPENSSL_RAND_IOS