aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/rand/rand_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/rand/rand_unix.c')
-rw-r--r--crypto/rand/rand_unix.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
index 9cbc9ade77fa..4710dbb2d101 100644
--- a/crypto/rand/rand_unix.c
+++ b/crypto/rand/rand_unix.c
@@ -19,7 +19,7 @@
#include <stdio.h>
#include "internal/dso.h"
#if defined(__linux)
-# include <sys/syscall.h>
+# include <asm/unistd.h>
#endif
#if defined(__FreeBSD__)
# include <sys/types.h>
@@ -324,8 +324,8 @@ static ssize_t syscall_random(void *buf, size_t buflen)
# endif
/* Linux supports this since version 3.17 */
-# if defined(__linux) && defined(SYS_getrandom)
- return syscall(SYS_getrandom, buf, buflen, 0);
+# if defined(__linux) && defined(__NR_getrandom)
+ return syscall(__NR_getrandom, buf, buflen, 0);
# elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
return sysctl_random(buf, buflen);
# else
@@ -510,6 +510,29 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
{
size_t i;
+#ifdef DEVRANDOM_WAIT
+ static int wait_done = 0;
+
+ /*
+ * On some implementations reading from /dev/urandom is possible
+ * before it is initialized. Therefore we wait for /dev/random
+ * to be readable to make sure /dev/urandom is initialized.
+ */
+ if (!wait_done && bytes_needed > 0) {
+ int f = open(DEVRANDOM_WAIT, O_RDONLY);
+
+ if (f >= 0) {
+ fd_set fds;
+
+ FD_ZERO(&fds);
+ FD_SET(f, &fds);
+ while (select(f+1, &fds, NULL, NULL, NULL) < 0
+ && errno == EINTR);
+ close(f);
+ }
+ wait_done = 1;
+ }
+#endif
for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths); i++) {
ssize_t bytes = 0;