mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Merge remote-tracking branch 'public/feature17694_strongest_027'
This commit is contained in:
commit
7186e2a943
6
changes/bug17694_strongest
Normal file
6
changes/bug17694_strongest
Normal file
@ -0,0 +1,6 @@
|
||||
o Minor features (security):
|
||||
- Never use the system entropy output directly for anything besides
|
||||
seeding the PRNG. When we want to generate important keys, instead
|
||||
of using system entropy directly, hash it with the PRNG stream.
|
||||
This may help resist certain attacks based on broken OS entropy
|
||||
implementations. Closes part of ticket 17694.
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,4 +1,4 @@
|
||||
/* Added for Tor. */
|
||||
#include "crypto.h"
|
||||
#define randombytes(b, n) \
|
||||
(crypto_strongest_rand((b), (n)))
|
||||
(crypto_strongest_rand((b), (n)), 0)
|
||||
|
Loading…
Reference in New Issue
Block a user