[tor-commits] [tor/master] Merge remote-tracking branch 'public/feature17694_strongest_027'

nickm at torproject.org nickm at torproject.org
Thu Dec 10 14:02:16 UTC 2015


commit 7186e2a94361e29188ba43837e244683ce7fbf04
Merge: 7e7188c 3843c66
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Dec 10 09:02:10 2015 -0500

    Merge remote-tracking branch 'public/feature17694_strongest_027'

 changes/bug17694_strongest          |    6 +++++
 src/common/crypto.c                 |   44 +++++++++++++++++++++++++++++++++--
 src/common/crypto.h                 |    2 +-
 src/common/crypto_curve25519.c      |   17 ++++----------
 src/common/crypto_ed25519.c         |    4 +++-
 src/ext/ed25519/donna/ed25519_tor.c |    3 +--
 src/ext/ed25519/ref10/randombytes.h |    2 +-
 7 files changed, 59 insertions(+), 19 deletions(-)

diff --cc src/common/crypto.c
index 5569ec7,1897946..816423a
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@@ -2477,54 -2338,45 +2477,91 @@@ crypto_strongest_rand_fallback(uint8_t 
  }
  
  /** Try to get <b>out_len</b> bytes of the strongest entropy we can generate,
 + * storing it into <b>out</b>. Return 0 on success, -1 on failure.  A maximum
 + * 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;
 +  tor_assert(out_len <= MAX_STRONGEST_RAND_SIZE);
 +
 +  /* For buffers >= 16 bytes (128 bits), we sanity check the output by
 +   * zero filling the buffer and ensuring that it actually was at least
 +   * partially modified.
 +   *
 +   * Checking that any individual byte is non-zero seems like it would
 +   * fail too often (p = out_len * 1/256) for comfort, but this is an
 +   * "adjust according to taste" sort of check.
 +   */
 +  memwipe(out, 0, out_len);
 +  for (int i = 0; i < max_attempts; i++) {
 +    /* Try to use the syscall/OS favored mechanism to get strong entropy. */
 +    if (crypto_strongest_rand_syscall(out, out_len) != 0) {
 +      /* Try to use the less-favored mechanism to get strong entropy. */
 +      if (crypto_strongest_rand_fallback(out, out_len) != 0) {
 +        /* Welp, we tried.  Hopefully the calling code terminates the process
 +         * since we're basically boned without good entropy.
 +         */
 +        log_warn(LD_CRYPTO,
 +                 "Cannot get strong entropy: no entropy source found.");
 +        return -1;
 +      }
 +    }
 +
 +    if ((out_len < sanity_min_size) || !tor_mem_is_zero((char*)out, out_len))
 +      return 0;
 +  }
 +
 +  /* We tried max_attempts times to fill a buffer >= 128 bits long,
 +   * and each time it returned all '0's.  Either the system entropy
 +   * source is busted, or the user should go out and buy a ticket to
 +   * every lottery on the planet.
 +   */
 +  log_warn(LD_CRYPTO, "Strong OS entropy returned all zero buffer.");
 +  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.  <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.
 + * system.  Return 0 on success, -1 on failure.
   */
  int
  crypto_seed_rng(void)



More information about the tor-commits mailing list