From 3a8bf57bd3008b2f5338bbd8ba1db5e9e2622c92 Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Wed, 14 Sep 2016 16:10:34 -0400 Subject: [PATCH] Add getrandom to k5_get_os_entropy() using syscall ticket: 8499 (cherry picked from commit a9a48392c088b53d8dd86b8008b4059ab78a3679) --- src/lib/crypto/krb/prng.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c index 9ad24c1..22948a4 100644 --- a/src/lib/crypto/krb/prng.c +++ b/src/lib/crypto/krb/prng.c @@ -58,6 +58,9 @@ k5_get_os_entropy(unsigned char *buf, size_t len, int strong) #ifdef HAVE_SYS_STAT_H #include #endif +#ifdef __linux__ +#include +#endif /* __linux__ */ /* Open device, ensure that it is not a regular file, and read entropy. Return * true on success, false on failure. */ @@ -96,6 +99,33 @@ krb5_boolean k5_get_os_entropy(unsigned char *buf, size_t len, int strong) { const char *device; +#if defined(__linux__) && defined(SYS_getrandom) + int r; + + while (len > 0) { + /* + * Pull from the /dev/urandom pool, but it to have been seeded. This + * ensures strong randomness while only blocking during first system + * boot. + * + * glibc does not currently provide a binding for getrandom: + * https://sourceware.org/bugzilla/show_bug.cgi?id=17252 + */ + errno = 0; + r = syscall(SYS_getrandom, buf, len, 0); + if (r <= 0) { + if (errno == EINTR) + continue; + + /* ENOSYS or other unrecoverable failure */ + break; + } + len -= r; + buf += r; + } + if (len == 0) + return TRUE; +#endif /* defined(__linux__) && defined(SYS_getrandom) */ device = strong ? "/dev/random" : "/dev/urandom"; return read_entropy_from_device(device, buf, len); -- 2.9.3