Commit b5b77f8b authored by Nick Mathewson's avatar Nick Mathewson 🐘
Browse files

r19004@catbus: nickm | 2008-03-21 15:18:43 -0400

 Use RAND_poll() again: the bug that made us stop using it has been fixed.


svn:r14150
parent 64f38f21
Loading
Loading
Loading
Loading
+7 −0
Changes for ChangeLog: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -24,6 +24,13 @@ Changes in version 0.2.1.1-alpha - 2008-??-??
    - Add a couple of extra warnings to --enable-gcc-warnings for GCC 4.3,
      and stop using a warning that had become unfixably verbose under GCC
      4.3.
    - Start using OpenSSL's RAND_poll() for better (and more portable)
      cross-platform entropy collection again.  We used to use it, then
      stopped using it because of a bug that could crash systems that called
      RAND_poll when they had a lot of fds open.  It looks like the bug got
      fixed in late 2006.  Our new behavior is to call RAND_poll() at
      startup, and to call RAND_poll() when we reseed later only if we
      have a non-buggy OpenSSL version.

  o Code simplifications and refactoring:
    - Refactor code using connection_ap_handshake_attach_circuit() to
+21 −11
Changes for src/common/crypto.c: 21 added lines, 11 removed lines.
Original line number Diff line number Diff line
@@ -1667,19 +1667,29 @@ crypto_dh_free(crypto_dh_env_t *dh)

/* Use RAND_poll if openssl is 0.9.6 release or later.  (The "f" means
   "release".)  */
//#define USE_RAND_POLL (OPENSSL_VERSION_NUMBER >= 0x0090600fl)
#define USE_RAND_POLL 0
/* XXX Somehow setting USE_RAND_POLL on causes stack smashes. We're
 * not sure where. This was the big bug with Tor 0.1.1.9-alpha. */
#define HAVE_RAND_POLL (OPENSSL_VERSION_NUMBER >= 0x0090600fl)

/** Seed OpenSSL's random number generator with bytes from the
 * operating system.  Return 0 on success, -1 on failure.
/* Versions of openssl prior to 0.9.7k and 0.9.8c had a bug where RAND_poll
 * would allocate an fd_set on the stack, open a new file, and try to FD_SET
 * that fd without checking whether it fit in the fd_set.  Thus, if the
 * system has not just been started up, it is unsafe to call */
#define RAND_POLL_IS_SAFE                       \
  ((OPENSSL_VERSION_NUMBER >= 0x009070afl &&    \
    OPENSSL_VERSION_NUMBER <= 0x00907fffl) ||   \
   (OPENSSL_VERSION_NUMBER >= 0x0090803fl))

/* We could actually get away with calling RAND_poll */
#define USE_RAND_POLL (HAVE_RAND_POLL && RAND_POLL_IS_SAFE)

/** 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.
 */
int
crypto_seed_rng(void)
crypto_seed_rng(int startup)
{
  char buf[ADD_ENTROPY];
  int rand_poll_status;
  int rand_poll_status = 0;

  /* local variables */
#ifdef MS_WINDOWS
@@ -1693,15 +1703,15 @@ crypto_seed_rng(void)
  size_t n;
#endif

#if USE_RAND_POLL
#if HAVE_RAND_POLL
  /* OpenSSL 0.9.6 adds a RAND_poll function that knows about more kinds of
   * entropy than we do.  We'll try calling that, *and* calling our own entropy
   * functions.  If one succeeds, we'll accept the RNG as seeded. */
  if (startup || RAND_POLL_IS_SAFE) {
    rand_poll_status = RAND_poll();
    if (rand_poll_status == 0)
      log_warn(LD_CRYPTO, "RAND_poll() failed.");
#else
  rand_poll_status = 0;
  }
#endif

#ifdef MS_WINDOWS
+1 −1
Changes for src/common/crypto.h: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -166,7 +166,7 @@ int crypto_expand_key_material(const char *key_in, size_t in_len,
                               char *key_out, size_t key_out_len);

/* random numbers */
int crypto_seed_rng(void);
int crypto_seed_rng(int startup);
int crypto_rand(char *to, size_t n);
int crypto_rand_int(unsigned int max);
uint64_t crypto_rand_uint64(uint64_t max);
+2 −2
Changes for src/or/main.c: 2 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -900,7 +900,7 @@ run_scheduled_events(time_t now)
  if (time_to_add_entropy < now) {
    if (time_to_add_entropy) {
      /* We already seeded once, so don't die on failure. */
      crypto_seed_rng();
      crypto_seed_rng(0);
    }
/** How often do we add more entropy to OpenSSL's RNG pool? */
#define ENTROPY_INTERVAL (60*60)
@@ -1810,7 +1810,7 @@ tor_init(int argc, char *argv[])
#endif

  crypto_global_init(get_options()->HardwareAccel);
  if (crypto_seed_rng()) {
  if (crypto_seed_rng(1)) {
    log_err(LD_BUG, "Unable to seed random number generator. Exiting.");
    return -1;
  }