From bc7daec4d833ed399571cf847221bb3065fbc9ab Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Tue, 11 Apr 2017 15:48:13 -0700 Subject: [PATCH] In FIPS mode, block at start up until the kernel has sufficient entropy. We already do this in the case that getrandom is supported. This change adds a polling loop for the case where we are using /dev/urandom. This makes FIPS imply Linux, which I think is fine for the time being. Change-Id: I9bf5c0f51a908621655cbcc47fc86b0366168b97 Reviewed-on: https://boringssl-review.googlesource.com/14925 Reviewed-by: Adam Langley --- crypto/rand/urandom.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/crypto/rand/urandom.c b/crypto/rand/urandom.c index dc31a51f..f3aab448 100644 --- a/crypto/rand/urandom.c +++ b/crypto/rand/urandom.c @@ -29,6 +29,8 @@ #include #if defined(OPENSSL_LINUX) +#include +#include #include #endif @@ -136,6 +138,38 @@ static void init_once(void) { abort(); } +#if defined(BORINGSSL_FIPS) + /* In FIPS mode we ensure that the kernel has sufficient entropy before + * continuing. This is automatically handled by getrandom, which requires + * that the entropy pool has been initialised, but for urandom we have to + * poll. */ + int first_iteration = 1; + for (;;) { + int entropy_bits; + if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) { + fprintf(stderr, + "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this " + "case when in FIPS mode.\n"); + abort(); + } + + static const int kBitsNeeded = 256; + if (entropy_bits >= kBitsNeeded) { + break; + } + + if (first_iteration) { + fprintf(stderr, + "The kernel entropy pool contains too few bits: have %d, want " + "%d. This process is built in FIPS mode and will block until " + "sufficient entropy is available.\n", entropy_bits, kBitsNeeded); + } + first_iteration = 0; + + usleep(250000); + } +#endif + int flags = fcntl(fd, F_GETFD); if (flags == -1) { /* Native Client doesn't implement |fcntl|. */