}
+// Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.
+// The entropy pool starts out empty and needs to fill up before the PRNG
+// can be used securely. Once the pool is filled, it never dries up again;
+// its contents is stirred and reused when necessary.
+//
+// OpenSSL normally fills the pool automatically but not when someone starts
+// generating random numbers before the pool is full: in that case OpenSSL
+// keeps lowering the entropy estimate to thwart attackers trying to guess
+// the initial state of the PRNG.
+//
+// When that happens, we will have to wait until enough entropy is available.
+// That should normally never take longer than a few milliseconds.
+//
+// OpenSSL draws from /dev/random and /dev/urandom. While /dev/random may
+// block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't
+// block under normal circumstances.
+//
+// The only time when /dev/urandom may conceivably block is right after boot,
+// when the whole system is still low on entropy. That's not something we can
+// do anything about.
+inline void CheckEntropy() {
+ for (;;) {
+ int status = RAND_status();
+ assert(status >= 0); // Cannot fail.
+ if (status != 0)
+ break;
+ if (RAND_poll() == 0) // Give up, RAND_poll() not supported.
+ break;
+ }
+}
+
+
bool EntropySource(unsigned char* buffer, size_t length) {
+ // Ensure that OpenSSL's PRNG is properly seeded.
+ CheckEntropy();
// RAND_bytes() can return 0 to indicate that the entropy data is not truly
// random. That's okay, it's still better than V8's stock source of entropy,
// which is /dev/urandom on UNIX platforms and the current time on Windows.
work_req_);
int r;
+ // Ensure that OpenSSL's PRNG is properly seeded.
+ CheckEntropy();
+
if (pseudoRandom == true) {
r = RAND_pseudo_bytes(reinterpret_cast<unsigned char*>(req->data_),
req->size_);