From baf5b59c8aad82395688f0a96efcfba4e16b8fc2 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Thu, 26 May 2016 09:26:09 +0100 Subject: [PATCH] rand/noise.c (noise_devrandom): Use new Linux system call `getrandom'. The new system call has pretty much the right semantics. If it's available, then try to use it. Annoyingly, the syscall isn't supported in the libc, so we have to do it the hard way. On the plus side, this means that the code will work if built on a system with the syscall defined, and run on one with the right kernel, without introducing a dependency on the libc. If it fails because the kernel entropy pool isn't initialized, then there's no point in messing with the devices because they won't be any better. If it fails because the call isn't there, then it proceeds with other options. --- configure.ac | 1 + rand/noise.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/configure.ac b/configure.ac index 246a74a4..631f7838 100644 --- a/configure.ac +++ b/configure.ac @@ -221,6 +221,7 @@ AC_SUBST([limits]) dnl Functions used for noise-gathering. AC_CHECK_FUNCS([setgroups]) +AC_CHECK_HEADERS([linux/random.h]) AC_CACHE_CHECK([whether the freewheel noise generator will work], [catacomb_cv_freewheel], [AC_TRY_LINK( diff --git a/rand/noise.c b/rand/noise.c index 6458f92d..b59fd8ad 100644 --- a/rand/noise.c +++ b/rand/noise.c @@ -29,6 +29,7 @@ #include "config.h" +#include #include #include #include @@ -46,6 +47,11 @@ # include #endif +#if defined(HAVE_LINUX_RANDOM_H) +# include +# include +#endif + #include #include #include @@ -167,6 +173,22 @@ int noise_devrandom(rand_pool *r) struct timeval tv = { 0, 0 }; #endif +#if defined(HAVE_LINUX_RANDOM_H) && \ + defined(GRND_NONBLOCK) && \ + defined(SYS_getrandom) + /* --- Use the new shinies if available --- */ + + while (n < sizeof(buf)) { + if ((len = syscall(SYS_getrandom, buf + n, sizeof(buf) - n, + GRND_NONBLOCK)) <= 0) { + if (errno == ENOSYS) break; + else goto done; + } + n += len; + } + if (n == sizeof(buf)) goto win; +#endif + #ifdef __linux__ /* --- Don't take from `/dev/urandom' if `/dev/random' would block --- */ -- 2.11.0