15 #if !defined(_GNU_SOURCE)
16 #define _GNU_SOURCE // needed for syscall() on Linux.
23 #if defined(OPENSSL_URANDOM)
32 #if defined(OPENSSL_LINUX)
33 #if defined(BORINGSSL_FIPS)
34 #include <linux/random.h>
35 #include <sys/ioctl.h>
37 #include <sys/syscall.h>
39 #if defined(OPENSSL_ANDROID)
40 #include <sys/system_properties.h>
43 #if !defined(OPENSSL_ANDROID)
44 #define OPENSSL_HAS_GETAUXVAL
51 #if defined(__GLIBC_PREREQ)
52 #if !__GLIBC_PREREQ(2, 16)
53 #undef OPENSSL_HAS_GETAUXVAL
56 #if defined(OPENSSL_HAS_GETAUXVAL)
59 #endif // OPENSSL_LINUX
61 #if defined(OPENSSL_MACOS)
62 #include <sys/random.h>
65 #if defined(OPENSSL_FREEBSD)
66 #define URANDOM_BLOCKS_FOR_ENTROPY
69 #define FREEBSD_GETRANDOM
70 #include <sys/random.h>
78 #include "../delocate.h"
79 #include "../../internal.h"
82 #if defined(USE_NR_getrandom)
84 #if defined(OPENSSL_MSAN)
85 void __msan_unpoison(
void *,
size_t);
88 static ssize_t boringssl_getrandom(
void *
buf,
size_t buf_len,
unsigned flags) {
92 }
while (
ret == -1 && errno == EINTR);
94 #if defined(OPENSSL_MSAN)
100 #endif // OPENSSL_MSAN
105 #endif // USE_NR_getrandom
114 #if defined(USE_NR_getrandom)
129 static void maybe_set_extra_getrandom_flags(
void) {
130 #if defined(BORINGSSL_FIPS) && defined(OPENSSL_ANDROID)
131 char value[PROP_VALUE_MAX + 1];
132 int length = __system_property_get(
"ro.boringcrypto.hwrand",
value);
133 if (length < 0 || length > PROP_VALUE_MAX) {
139 *extra_getrandom_flags_for_seed_bss_get() = GRND_RANDOM;
144 #endif // USE_NR_getrandom
152 #if defined(USE_NR_getrandom)
156 boringssl_getrandom(&
dummy,
sizeof(
dummy), GRND_NONBLOCK);
157 if (getrandom_ret == 1) {
158 *getrandom_ready_bss_get() = 1;
160 }
else if (getrandom_ret == -1 && errno == EAGAIN) {
163 }
else if (getrandom_ret == -1 && errno == ENOSYS) {
172 if (have_getrandom) {
174 maybe_set_extra_getrandom_flags();
177 #endif // USE_NR_getrandom
179 #if defined(OPENSSL_MACOS)
182 if (__builtin_available(macos 10.12, *)) {
188 #if defined(FREEBSD_GETRANDOM)
194 #if defined(BORINGSSL_FIPS) && defined(OPENSSL_ANDROID)
195 perror(
"getrandom not found");
201 fd =
open(
"/dev/urandom", O_RDONLY);
202 }
while (fd == -1 && errno == EINTR);
205 perror(
"failed to open /dev/urandom");
209 int flags = fcntl(fd, F_GETFD);
212 if (errno != ENOSYS) {
213 perror(
"failed to get flags from urandom fd");
218 if (fcntl(fd, F_SETFD,
flags) == -1) {
219 perror(
"failed to set FD_CLOEXEC on urandom fd");
223 *urandom_fd_bss_get() = fd;
229 int fd = *urandom_fd_bss_get();
234 #if defined(USE_NR_getrandom)
235 if (*getrandom_ready_bss_get()) {
242 boringssl_getrandom(&
dummy,
sizeof(
dummy), GRND_NONBLOCK);
243 if (getrandom_ret == -1 && errno == EAGAIN) {
246 const char *current_process =
"<unknown>";
247 #if defined(OPENSSL_HAS_GETAUXVAL)
248 const unsigned long getauxval_ret = getauxval(AT_EXECFN);
249 if (getauxval_ret != 0) {
250 current_process = (
const char *)getauxval_ret;
256 "%s: getrandom indicates that the entropy pool has not been "
257 "initialized. Rather than continue with poor entropy, this process "
258 "will block until entropy is available.\n",
262 boringssl_getrandom(&
dummy,
sizeof(
dummy), 0 );
265 if (getrandom_ret != 1) {
269 #endif // USE_NR_getrandom
273 #if defined(BORINGSSL_FIPS) && !defined(URANDOM_BLOCKS_FOR_ENTROPY)
280 if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) {
282 "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this "
283 "case when in FIPS mode.\n");
287 static const int kBitsNeeded = 256;
288 if (entropy_bits >= kBitsNeeded) {
294 #endif // BORINGSSL_FIPS && !URANDOM_BLOCKS_FOR_ENTROPY
308 #if defined(USE_NR_getrandom) || defined(FREEBSD_GETRANDOM)
309 int getrandom_flags = 0;
311 getrandom_flags |= GRND_NONBLOCK;
315 #if defined (USE_NR_getrandom)
317 getrandom_flags |= *extra_getrandom_flags_for_seed_bss_get();
333 #if defined(USE_NR_getrandom)
334 r = boringssl_getrandom(
out,
len, getrandom_flags);
335 #elif defined(FREEBSD_GETRANDOM)
336 r = getrandom(
out,
len, getrandom_flags);
337 #elif defined(OPENSSL_MACOS)
338 if (__builtin_available(macos 10.12, *)) {
341 if (getentropy(
out,
todo) != 0) {
347 fprintf(
stderr,
"urandom fd corrupt.\n");
350 #else // USE_NR_getrandom
351 fprintf(
stderr,
"urandom fd corrupt.\n");
357 }
while (
r == -1 && errno == EINTR);
377 perror(
"entropy fill failed");
384 perror(
"entropy fill failed");
392 }
else if (errno == EAGAIN) {
396 perror(
"opportunistic entropy fill failed");
401 #endif // OPENSSL_URANDOM