diff --git a/src/port/pg_strong_random.c b/src/port/pg_strong_random.c new file mode 100644 index bc7a8aa..a2ab8c1 --- a/src/port/pg_strong_random.c +++ b/src/port/pg_strong_random.c @@ -103,6 +103,37 @@ pg_strong_random(void *buf, size_t len) * When built with OpenSSL, use OpenSSL's RAND_bytes function. */ #if defined(USE_OPENSSL_RANDOM) + /* + * Check that OpenSSL's CSPRNG has been sufficiently seeded, and if not + * add more seed data using RAND_poll(). With some older versions of + * OpenSSL, it may be necessary to call RAND_poll() a number of times. + */ +#define NUM_RAND_POLL_RETRIES 8 + + if (RAND_status() == 0) + { + int i; + + for (i = 0; i < NUM_RAND_POLL_RETRIES; i++) + { + if (RAND_poll() == 0) + { + /* + * RAND_poll() failed to generate any seed data, which means + * that RAND_bytes() will probably fail. For now, just fall + * through and let that happen. XXX: maybe we could seed it + * some other way. + */ + break; + } + + if (RAND_status() == 1) + { + /* The CSPRNG is now sufficiently seeded */ + break; + } + } + } if (RAND_bytes(buf, len) == 1) return true; return false;