aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobbie Harwood <rharwood@redhat.com>2016-09-14 16:10:34 -0400
committerGreg Hudson <ghudson@mit.edu>2016-09-22 13:40:30 -0400
commita9a48392c088b53d8dd86b8008b4059ab78a3679 (patch)
treef805c77ec23de2187f7999ab77f9308b72f64abc
parent5e54525fbe40d56f44368e216c92938403cad96d (diff)
downloadkrb5-a9a48392c088b53d8dd86b8008b4059ab78a3679.zip
krb5-a9a48392c088b53d8dd86b8008b4059ab78a3679.tar.gz
krb5-a9a48392c088b53d8dd86b8008b4059ab78a3679.tar.bz2
Add getrandom to k5_get_os_entropy() using syscall
ticket: 8499
-rw-r--r--src/lib/crypto/krb/prng.c30
1 files changed, 30 insertions, 0 deletions
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 <sys/stat.h>
#endif
+#ifdef __linux__
+#include <sys/syscall.h>
+#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);