diff options
author | Nick Mathewson <nickm@torproject.org> | 2015-12-10 09:02:10 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2015-12-10 09:02:10 -0500 |
commit | 7186e2a94361e29188ba43837e244683ce7fbf04 (patch) | |
tree | 7a2812d5dd3d609b575b0667c8974a385a0137f9 /src | |
parent | 7e7188cb00d02a52baee1a26b548cd5eebd85ce7 (diff) | |
parent | 3843c6615c7f62606973fef9068bbb7be58ff243 (diff) | |
download | tor-7186e2a94361e29188ba43837e244683ce7fbf04.tar.gz tor-7186e2a94361e29188ba43837e244683ce7fbf04.zip |
Merge remote-tracking branch 'public/feature17694_strongest_027'
Diffstat (limited to 'src')
-rw-r--r-- | src/common/crypto.c | 44 | ||||
-rw-r--r-- | src/common/crypto.h | 2 | ||||
-rw-r--r-- | src/common/crypto_curve25519.c | 17 | ||||
-rw-r--r-- | src/common/crypto_ed25519.c | 4 | ||||
-rw-r--r-- | src/ext/ed25519/donna/ed25519_tor.c | 3 | ||||
-rw-r--r-- | src/ext/ed25519/ref10/randombytes.h | 2 |
6 files changed, 53 insertions, 19 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c index 5569ec78b6..816423aa85 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -2481,7 +2481,7 @@ crypto_strongest_rand_fallback(uint8_t *out, size_t out_len) * request size of 256 bytes is imposed. */ int -crypto_strongest_rand(uint8_t *out, size_t out_len) +crypto_strongest_rand_raw(uint8_t *out, size_t out_len) { static const size_t sanity_min_size = 16; static const int max_attempts = 3; @@ -2523,6 +2523,43 @@ crypto_strongest_rand(uint8_t *out, size_t out_len) return -1; } +/** 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; + /* We're going to hash DLEN bytes from the system RNG together with some + * bytes from the openssl PRNG, in order to yield DLEN bytes. + */ + uint8_t inp[DLEN*2]; + uint8_t tmp[DLEN]; + tor_assert(out); + while (out_len) { + crypto_rand((char*) inp, DLEN); + if (crypto_strongest_rand_raw(inp+DLEN, DLEN) < 0) { + log_err(LD_CRYPTO, "Failed to load strong entropy when generating an " + "important key. Exiting."); + /* Die with an assertion so we get a stack trace. */ + 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. Return 0 on success, -1 on failure. */ @@ -2539,7 +2576,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)); } @@ -2580,6 +2617,9 @@ crypto_rand_unmocked(char *to, size_t n) tor_assert(n < INT_MAX); tor_assert(to); r = RAND_bytes((unsigned char*)to, (int)n); + /* We consider a PRNG failure non-survivable. Let's assert so that we get a + * stack trace about where it happened. + */ tor_assert(r >= 0); } diff --git a/src/common/crypto.h b/src/common/crypto.h index 9b922ff818..0fba958f8d 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -273,7 +273,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); diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c index 00302a2ff0..2002483265 100644 --- a/src/common/crypto_curve25519.c +++ b/src/common/crypto_curve25519.c @@ -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]; - - 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)); + if (extra_strong) + crypto_strongest_rand(out, CURVE25519_SECKEY_LEN); + else + crypto_rand((char*)out, CURVE25519_SECKEY_LEN); + return 0; } diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c index 1749efc34c..41ec486f0a 100644 --- a/src/common/crypto_ed25519.c +++ b/src/common/crypto_ed25519.c @@ -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); diff --git a/src/ext/ed25519/donna/ed25519_tor.c b/src/ext/ed25519/donna/ed25519_tor.c index 12493f7d14..ac726ba045 100644 --- a/src/ext/ed25519/donna/ed25519_tor.c +++ b/src/ext/ed25519/donna/ed25519_tor.c @@ -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); diff --git a/src/ext/ed25519/ref10/randombytes.h b/src/ext/ed25519/ref10/randombytes.h index fc709fcefc..8bf31631f0 100644 --- a/src/ext/ed25519/ref10/randombytes.h +++ b/src/ext/ed25519/ref10/randombytes.h @@ -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) |