diff options
| author | Jung-uk Kim <jkim@FreeBSD.org> | 2019-05-28 20:08:17 +0000 | 
|---|---|---|
| committer | Jung-uk Kim <jkim@FreeBSD.org> | 2019-05-28 20:08:17 +0000 | 
| commit | 375b8e6770f750fb915859470f6f1fe43f35cc48 (patch) | |
| tree | 5db6744924edfc112439ad2366f52f246baa21d1 /crypto/rand/rand_unix.c | |
| parent | 851f7386fd78b9787f4f6669ad271886a2a003f1 (diff) | |
Notes
Diffstat (limited to 'crypto/rand/rand_unix.c')
| -rw-r--r-- | crypto/rand/rand_unix.c | 29 | 
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; | 
