aboutsummaryrefslogtreecommitdiff
path: root/src/common/crypto.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-02-12 11:56:29 -0500
committerNick Mathewson <nickm@torproject.org>2014-02-12 12:04:07 -0500
commitd3fb846d8c98c13d349762682e714e8312f20270 (patch)
tree68d2ca881730b581d0f94faf9c548c672a9c7f0f /src/common/crypto.c
parent0e97c8e23e2572c14dd0f4f4fbfca77ee8a48be2 (diff)
downloadtor-d3fb846d8c98c13d349762682e714e8312f20270.tar
tor-d3fb846d8c98c13d349762682e714e8312f20270.tar.gz
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.
Diffstat (limited to 'src/common/crypto.c')
-rw-r--r--src/common/crypto.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 9bdb1f41f..13095ad79 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;
}