diff options
author | Daniel Kahn Gillmor <dkg@fifthhorseman.net> | 2018-09-05 10:34:04 -0400 |
---|---|---|
committer | Daniel Kahn Gillmor <dkg@fifthhorseman.net> | 2018-09-05 10:34:04 -0400 |
commit | 842ff5f60cfaf6ce3b236a44dadeddf241dbd2c3 (patch) | |
tree | 56c66de1c66625fd1ecf15cbfe576bfed3273c6e | |
parent | 86e5e06a97ae13b8bbf6923ecc76e02b9c429b46 (diff) | |
download | libgcrypt-dkg/fix-T3894.tar.gz |
random: use getrandom() on Linux where availabledkg/fix-T3894
* random/rndlinux.c (_gcry_rndlinux_gather_random): use the
getrandom() syscall on Linux if it exists, regardless of what kind of
entropy was requested.
--
This change avoids the serious usability problem of unnecessary
blocking on /dev/random when the kernel's PRNG is already seeded,
without introducing the risk of pulling from an uninitialized PRNG.
It only has an effect on Linux systems with a functioning getrandom()
syscall. If that syscall is unavailable or fails, it should fall
through to the pre-existing behavior.
GnuPG-bug-id: 3894
Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
-rw-r--r-- | random/rndlinux.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/random/rndlinux.c b/random/rndlinux.c index 1bb7c761..509b0b19 100644 --- a/random/rndlinux.c +++ b/random/rndlinux.c @@ -220,17 +220,16 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t, struct timeval tv; int rc; - /* If we have a modern Linux kernel and we want to read from the - * the non-blocking /dev/urandom, we first try to use the new + /* If we have a modern Linux kernel, we first try to use the new * getrandom syscall. That call guarantees that the kernel's * RNG has been properly seeded before returning any data. This * is different from /dev/urandom which may, due to its * non-blocking semantics, return data even if the kernel has - * not been properly seeded. Unfortunately we need to use a + * not been properly seeded. And it differs from /dev/random by never + * blocking once the kernel is seeded. Unfortunately we need to use a * syscall and not a new device and thus we are not able to use * select(2) to have a timeout. */ #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) - if (fd == fd_urandom) { long ret; size_t nbytes; @@ -247,7 +246,7 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t, } while (ret == -1 && errno == EINTR); if (ret == -1 && errno == ENOSYS) - ; /* The syscall is not supported - fallback to /dev/urandom. */ + ; /* The syscall is not supported - fallback to pulling from fd. */ else { /* The syscall is supported. Some sanity checks. */ if (ret == -1) |