Always hash crypto_strongest_rand() along with some prng

(before using it for anything besides feeding the PRNG)

Part of #17694
This commit is contained in:
Nick Mathewson
2015-12-08 10:54:42 -05:00
parent 943369f927
commit 2259de0de7
7 changed files with 58 additions and 20 deletions
+42 -4
View File
@@ -2280,10 +2280,13 @@ crypto_seed_weak_rng(tor_weak_rng_t *rng)
}
/** Try to get <b>out_len</b> bytes of the strongest entropy we can generate,
* storing it into <b>out</b>.
* storing it into <b>out</b>. Return 0 on success, -1 on failure.
*
* (You should almost never call this directly unless you are seeding a PRNG;
* use crypto_strongest_rand() instead.)
*/
int
crypto_strongest_rand(uint8_t *out, size_t out_len)
static int
crypto_strongest_rand_raw(uint8_t *out, size_t out_len)
{
#ifdef _WIN32
static int provider_set = 0;
@@ -2334,6 +2337,41 @@ crypto_strongest_rand(uint8_t *out, size_t out_len)
#endif
}
/** Try to get <b>out_len</b> bytes of the strongest entropy we can generate,
* storing it into <b>out</b>.
*/
void
crypto_strongest_rand(uint8_t *out, size_t out_len)
{
const unsigned DLEN = SHA512_DIGEST_LENGTH;
uint8_t inp[DLEN*2];
uint8_t tmp[DLEN];
tor_assert(out);
while (out_len) {
crypto_rand((char*) inp+DLEN, DLEN);
if (crypto_strongest_rand_raw(inp, DLEN) < 0) {
log_err(LD_CRYPTO, "Failed to load strong entropy when generating an "
"important key. Exiting.");
tor_assert(0);
}
if (out_len >= DLEN) {
SHA512(inp, sizeof(inp), out);
out += DLEN;
out_len -= DLEN;
} else {
SHA512(inp, sizeof(inp), tmp);
memcpy(out, tmp, out_len);
out += DLEN;
out_len -= DLEN;
break;
}
}
memwipe(tmp, 0, sizeof(tmp));
memwipe(inp, 0, sizeof(inp));
}
/** Seed OpenSSL's random number generator with bytes from the operating
* system. <b>startup</b> should be true iff we have just started Tor and
* have not yet allocated a bunch of fds. Return 0 on success, -1 on failure.
@@ -2351,7 +2389,7 @@ crypto_seed_rng(void)
if (rand_poll_ok == 0)
log_warn(LD_CRYPTO, "RAND_poll() failed.");
load_entropy_ok = !crypto_strongest_rand(buf, sizeof(buf));
load_entropy_ok = !crypto_strongest_rand_raw(buf, sizeof(buf));
if (load_entropy_ok) {
RAND_seed(buf, sizeof(buf));
}
+1 -1
View File
@@ -262,7 +262,7 @@ int crypto_expand_key_material_rfc5869_sha256(
int crypto_seed_rng(void) ATTR_WUR;
MOCK_DECL(void,crypto_rand,(char *to, size_t n));
void crypto_rand_unmocked(char *to, size_t n);
int crypto_strongest_rand(uint8_t *out, size_t out_len);
void crypto_strongest_rand(uint8_t *out, size_t out_len);
int crypto_rand_int(unsigned int max);
int crypto_rand_int_range(unsigned int min, unsigned int max);
uint64_t crypto_rand_uint64_range(uint64_t min, uint64_t max);
+4 -11
View File
@@ -111,18 +111,11 @@ curve25519_public_key_is_ok(const curve25519_public_key_t *key)
int
curve25519_rand_seckey_bytes(uint8_t *out, int extra_strong)
{
uint8_t k_tmp[CURVE25519_SECKEY_LEN];
if (extra_strong)
crypto_strongest_rand(out, CURVE25519_SECKEY_LEN);
else
crypto_rand((char*)out, CURVE25519_SECKEY_LEN);
crypto_rand((char*)out, CURVE25519_SECKEY_LEN);
if (extra_strong && !crypto_strongest_rand(k_tmp, CURVE25519_SECKEY_LEN)) {
/* If they asked for extra-strong entropy and we have some, use it as an
* HMAC key to improve not-so-good entropy rather than using it directly,
* just in case the extra-strong entropy is less amazing than we hoped. */
crypto_hmac_sha256((char*) out,
(const char *)k_tmp, sizeof(k_tmp),
(const char *)out, CURVE25519_SECKEY_LEN);
}
memwipe(k_tmp, 0, sizeof(k_tmp));
return 0;
}
+3 -1
View File
@@ -107,7 +107,9 @@ ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out,
{
int r;
uint8_t seed[32];
if (! extra_strong || crypto_strongest_rand(seed, sizeof(seed)) < 0)
if (extra_strong)
crypto_strongest_rand(seed, sizeof(seed));
else
crypto_rand((char*)seed, sizeof(seed));
r = get_ed_impl()->seckey_expand(seckey_out->seckey, seed);
+1 -2
View File
@@ -148,8 +148,7 @@ ed25519_donna_seckey(unsigned char *sk)
{
ed25519_secret_key seed;
if (crypto_strongest_rand(seed, 32))
return -1;
crypto_strongest_rand(seed, 32);
ed25519_extsk(sk, seed);
+1 -1
View File
@@ -1,4 +1,4 @@
/* Added for Tor. */
#include "crypto.h"
#define randombytes(b, n) \
(crypto_strongest_rand((b), (n)))
(crypto_strongest_rand((b), (n)), 0)