[tor-commits] [tor/master] Split crypto_global_init() into pre/post config

nickm at torproject.org nickm at torproject.org
Sat Feb 15 21:04:28 UTC 2014


commit d3fb846d8c98c13d349762682e714e8312f20270
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Feb 12 11:56:29 2014 -0500

    Split crypto_global_init() into pre/post config
    
    It's increasingly apparent that we want to make sure we initialize our
    PRNG nice and early, or else OpenSSL will do it for us.  (OpenSSL
    doesn't do _too_ bad a job, but it's nice to do it ourselves.)
    
    We'll also need this for making sure we initialize the siphash key
    before we do any hashes.
---
 src/common/crypto.c |   54 +++++++++++++++++++++++++++++++++++++++++----------
 src/common/crypto.h |    1 +
 src/or/main.c       |    7 +++++++
 3 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/src/common/crypto.c b/src/common/crypto.c
index 9bdb1f4..13095ad 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -132,6 +132,9 @@ crypto_get_rsa_padding(int padding)
 }
 
 /** Boolean: has OpenSSL's crypto been initialized? */
+static int crypto_early_initialized_ = 0;
+
+/** Boolean: has OpenSSL's crypto been initialized? */
 static int crypto_global_initialized_ = 0;
 
 /** Log all pending crypto errors at level <b>severity</b>.  Use
@@ -242,15 +245,31 @@ crypto_openssl_get_header_version_str(void)
   return crypto_openssl_header_version_str;
 }
 
-/** Initialize the crypto library.  Return 0 on success, -1 on failure.
+/** Make sure that openssl is using its default PRNG. Return 1 if we had to
+ * adjust it; 0 otherwise. */
+static int
+crypto_force_rand_ssleay(void)
+{
+  if (RAND_get_rand_method() != RAND_SSLeay()) {
+    log_notice(LD_CRYPTO, "It appears that one of our engines has provided "
+               "a replacement the OpenSSL RNG. Resetting it to the default "
+               "implementation.");
+    RAND_set_rand_method(RAND_SSLeay());
+    return 1;
+  }
+  return 0;
+}
+
+/** Initialize the parts of the crypto library that don't depend on
+ * settings or options.  Return 0 on success, -1 on failure.
  */
 int
-crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
+crypto_early_init(void)
 {
-  if (!crypto_global_initialized_) {
+  if (!crypto_early_initialized_) {
     ERR_load_crypto_strings();
     OpenSSL_add_all_algorithms();
-    crypto_global_initialized_ = 1;
+
     setup_openssl_threading();
 
     if (SSLeay() == OPENSSL_VERSION_NUMBER &&
@@ -272,6 +291,24 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
                  crypto_openssl_get_version_str());
     }
 
+    crypto_force_rand_ssleay();
+
+    if (crypto_seed_rng(1) < 0)
+      return -1;
+  }
+  return 0;
+}
+
+/** Initialize the crypto library.  Return 0 on success, -1 on failure.
+ */
+int
+crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
+{
+  if (!crypto_global_initialized_) {
+    crypto_early_init();
+
+    crypto_global_initialized_ = 1;
+
     if (useAccel > 0) {
 #ifdef DISABLE_ENGINES
       (void)accelName;
@@ -335,17 +372,14 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
       log_info(LD_CRYPTO, "NOT using OpenSSL engine support.");
     }
 
-    if (RAND_get_rand_method() != RAND_SSLeay()) {
-      log_notice(LD_CRYPTO, "It appears that one of our engines has provided "
-                 "a replacement the OpenSSL RNG. Resetting it to the default "
-                 "implementation.");
-      RAND_set_rand_method(RAND_SSLeay());
+    if (crypto_force_rand_ssleay()) {
+      if (crypto_seed_rng(1) < 0)
+        return -1;
     }
 
     evaluate_evp_for_aes(-1);
     evaluate_ctr_for_aes();
 
-    return crypto_seed_rng(1);
   }
   return 0;
 }
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 6ce3697..79a8a1b 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -110,6 +110,7 @@ typedef struct crypto_dh_t crypto_dh_t;
 /* global state */
 const char * crypto_openssl_get_version_str(void);
 const char * crypto_openssl_get_header_version_str(void);
+int crypto_early_init(void);
 int crypto_global_init(int hardwareAccel,
                        const char *accelName,
                        const char *accelPath);
diff --git a/src/or/main.c b/src/or/main.c
index a970e35..526f000 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -2329,6 +2329,13 @@ tor_init(int argc, char *argv[])
   /* Have the log set up with our application name. */
   tor_snprintf(progname, sizeof(progname), "Tor %s", get_version());
   log_set_application_name(progname);
+
+  /* Set up the crypto nice and early */
+  if (crypto_early_init() < 0) {
+    log_err(LD_GENERAL, "Unable to initialize the crypto subsystem!");
+    return 1;
+  }
+
   /* Initialize the history structures. */
   rep_hist_init();
   /* Initialize the service cache. */





More information about the tor-commits mailing list