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 <agl@google.com>
This commit is contained in:
Adam Langley 2017-04-11 15:48:13 -07:00
parent 92f888e836
commit bc7daec4d8

View File

@ -29,6 +29,8 @@
#include <unistd.h>
#if defined(OPENSSL_LINUX)
#include <linux/random.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#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|. */