Add RNG support for FreeBSD.

Get entropy from /dev/urandom on FreeBSD < 12, or getrandom() on FreeBSD
12, per
https://www.freebsd.org/cgi/man.cgi?query=getrandom&sektion=2&format=html

Tested manually with `ninja run_tests` on both FreeBSD 11 and 12.

Change-Id: I72ef54d1a83104d1fbe172fd86f6cd32dacc9819
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46188
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/fipsmodule/rand/urandom.c b/crypto/fipsmodule/rand/urandom.c
index 3def3aa..8464e9e 100644
--- a/crypto/fipsmodule/rand/urandom.c
+++ b/crypto/fipsmodule/rand/urandom.c
@@ -62,6 +62,15 @@
 #include <sys/random.h>
 #endif
 
+#if defined(OPENSSL_FREEBSD)
+#define URANDOM_BLOCKS_FOR_ENTROPY
+#if __FreeBSD__ >= 12
+// getrandom is supported in FreeBSD 12 and up.
+#define FREEBSD_GETRANDOM
+#include <sys/random.h>
+#endif
+#endif
+
 #include <openssl/thread.h>
 #include <openssl/mem.h>
 
@@ -176,6 +185,11 @@
   }
 #endif
 
+#if defined(FREEBSD_GETRANDOM)
+  *urandom_fd_bss_get() = kHaveGetrandom;
+  return;
+#endif
+
   // Android FIPS builds must support getrandom.
 #if defined(BORINGSSL_FIPS) && defined(OPENSSL_ANDROID)
   perror("getrandom not found");
@@ -256,11 +270,11 @@
     return;
   }
 
-#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.
+#if defined(BORINGSSL_FIPS) && !defined(URANDOM_BLOCKS_FOR_ENTROPY)
+  // In FIPS mode on platforms where urandom doesn't block at startup, 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.
   for (;;) {
     int entropy_bits;
     if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) {
@@ -277,7 +291,7 @@
 
     usleep(250000);
   }
-#endif  // BORINGSSL_FIPS
+#endif  // BORINGSSL_FIPS && !URANDOM_BLOCKS_FOR_ENTROPY
 }
 
 // fill_with_entropy writes |len| bytes of entropy into |out|. It returns one
@@ -291,11 +305,14 @@
     return 1;
   }
 
-#if defined(USE_NR_getrandom)
+#if defined(USE_NR_getrandom) || defined(FREEBSD_GETRANDOM)
   int getrandom_flags = 0;
   if (!block) {
     getrandom_flags |= GRND_NONBLOCK;
   }
+#endif
+
+#if defined (USE_NR_getrandom)
   if (seed) {
     getrandom_flags |= *extra_getrandom_flags_for_seed_bss_get();
   }
@@ -315,6 +332,8 @@
     if (*urandom_fd_bss_get() == kHaveGetrandom) {
 #if defined(USE_NR_getrandom)
       r = boringssl_getrandom(out, len, getrandom_flags);
+#elif defined(FREEBSD_GETRANDOM)
+      r = getrandom(out, len, getrandom_flags);
 #elif defined(OPENSSL_MACOS)
       if (__builtin_available(macos 10.12, *)) {
         // |getentropy| can only request 256 bytes at a time.
diff --git a/include/openssl/base.h b/include/openssl/base.h
index 79c4444..61a8886 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -166,6 +166,10 @@
 #endif
 #endif
 
+#if defined(__FreeBSD__)
+#define OPENSSL_FREEBSD
+#endif
+
 // BoringSSL requires platform's locking APIs to make internal global state
 // thread-safe, including the PRNG. On some single-threaded embedded platforms,
 // locking APIs may not exist, so this dependency may be disabled with the