diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2016-10-17 11:52:50 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2016-10-17 11:52:50 +0300 |
commit | 9e083fd4683294f41544e6d0d72f6e258ff3a77c (patch) | |
tree | bbacc73b0c4a29a0d7b62d3c5a7bb4583d592ad1 /contrib/pgcrypto/internal.c | |
parent | 5dfc198146b49ce7ecc8a1fc9d5e171fb75f6ba5 (diff) | |
download | postgresql-9e083fd4683294f41544e6d0d72f6e258ff3a77c.tar.gz postgresql-9e083fd4683294f41544e6d0d72f6e258ff3a77c.zip |
Replace PostmasterRandom() with a stronger way of generating randomness.
This adds a new routine, pg_strong_random() for generating random bytes,
for use in both frontend and backend. At the moment, it's only used in
the backend, but the upcoming SCRAM authentication patches need strong
random numbers in libpq as well.
pg_strong_random() is based on, and replaces, the existing implementation
in pgcrypto. It can acquire strong random numbers from a number of sources,
depending on what's available:
- OpenSSL RAND_bytes(), if built with OpenSSL
- On Windows, the native cryptographic functions are used
- /dev/urandom
- /dev/random
Original patch by Magnus Hagander, with further work by Michael Paquier
and me.
Discussion: <CAB7nPqRy3krN8quR9XujMVVHYtXJ0_60nqgVc6oUk8ygyVkZsA@mail.gmail.com>
Diffstat (limited to 'contrib/pgcrypto/internal.c')
-rw-r--r-- | contrib/pgcrypto/internal.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c index 02ff976c25a..ad942f733a2 100644 --- a/contrib/pgcrypto/internal.c +++ b/contrib/pgcrypto/internal.c @@ -626,8 +626,6 @@ static time_t check_time = 0; static void system_reseed(void) { - uint8 buf[1024]; - int n; time_t t; int skip = 1; @@ -642,24 +640,34 @@ system_reseed(void) else if (check_time == 0 || (t - check_time) > SYSTEM_RESEED_CHECK_TIME) { + uint8 buf; + check_time = t; /* roll dice */ - px_get_random_bytes(buf, 1); - skip = buf[0] >= SYSTEM_RESEED_CHANCE; - } - /* clear 1 byte */ - px_memset(buf, 0, sizeof(buf)); - - if (skip) - return; - - n = px_acquire_system_randomness(buf); - if (n > 0) - fortuna_add_entropy(buf, n); + px_get_random_bytes(&buf, 1); + skip = (buf >= SYSTEM_RESEED_CHANCE); - seed_time = t; - px_memset(buf, 0, sizeof(buf)); + /* clear 1 byte */ + px_memset(&buf, 0, sizeof(buf)); + } + if (!skip) + { + /* + * fortuna_add_entropy passes the input to SHA-256, so there's no + * point in giving it more than 256 bits of input to begin with. + */ + uint8 buf[32]; + + if (!pg_strong_random(buf, sizeof(buf))) + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("could not acquire random data"))); + fortuna_add_entropy(buf, sizeof(buf)); + + seed_time = t; + px_memset(buf, 0, sizeof(buf)); + } } int |