diff options
author | Martin Peck <coder@peertech.org> | 2009-05-23 16:42:44 -0700 |
---|---|---|
committer | Martin Peck <coder@peertech.org> | 2009-05-23 16:42:44 -0700 |
commit | 7703b887f5db0d8d62e9eb87305bb8e2113276f1 (patch) | |
tree | 4cf6f080b0f3ac0f70ff2f4e6e35097c41fcecd0 | |
parent | 75f963e9517ba8702fe1ed1d470e28b0462fb3d2 (diff) | |
download | tor-7703b887f5db0d8d62e9eb87305bb8e2113276f1.tar.gz tor-7703b887f5db0d8d62e9eb87305bb8e2113276f1.zip |
Add support for dynamic OpenSSL hardware crypto acceleration engines.
-rw-r--r-- | src/common/crypto.c | 59 | ||||
-rw-r--r-- | src/common/crypto.h | 4 | ||||
-rw-r--r-- | src/common/tortls.c | 1 | ||||
-rw-r--r-- | src/or/config.c | 19 | ||||
-rw-r--r-- | src/or/main.c | 4 | ||||
-rw-r--r-- | src/or/or.h | 2 | ||||
-rw-r--r-- | src/or/router.c | 4 | ||||
-rw-r--r-- | src/or/test.c | 2 | ||||
-rw-r--r-- | src/tools/tor-checkkey.c | 2 | ||||
-rw-r--r-- | src/tools/tor-gencert.c | 2 |
10 files changed, 77 insertions, 22 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c index bc7eb0c6ca..7b5743f64a 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -27,6 +27,7 @@ #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/evp.h> +#include <openssl/engine.h> #include <openssl/rand.h> #include <openssl/opensslv.h> #include <openssl/bn.h> @@ -166,36 +167,70 @@ log_engine(const char *fn, ENGINE *e) } } +/** Try to load an engine in a shared library via fully qualified path. + */ +static ENGINE * +try_load_engine(const char *path, const char *engine) +{ + ENGINE *e = ENGINE_by_id("dynamic"); + if (e) { + if (!ENGINE_ctrl_cmd_string(e, "ID", engine, 0) || + !ENGINE_ctrl_cmd_string(e, "DIR_LOAD", "2", 0) || + !ENGINE_ctrl_cmd_string(e, "DIR_ADD", path, 0) || + !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) { + ENGINE_free(e); + e = NULL; + } + } + return e; +} + /** Initialize the crypto library. Return 0 on success, -1 on failure. */ int -crypto_global_init(int useAccel) +crypto_global_init(int useAccel, const char *accelName, const char *accelDir) { if (!_crypto_global_initialized) { ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); _crypto_global_initialized = 1; setup_openssl_threading(); - /* XXX the below is a bug, since we can't know if we're supposed - * to be using hardware acceleration or not. we should arrange - * for this function to be called before init_keys. But make it - * not complain loudly, at least until we make acceleration work. */ - if (useAccel < 0) { - log_info(LD_CRYPTO, "Initializing OpenSSL via tor_tls_init()."); - } if (useAccel > 0) { + ENGINE *e = NULL; log_info(LD_CRYPTO, "Initializing OpenSSL engine support."); ENGINE_load_builtin_engines(); - if (!ENGINE_register_all_complete()) - return -1; - - /* XXXX make sure this isn't leaking. */ + ENGINE_register_all_complete(); + if (accelName) { + if (accelDir) { + log_info(LD_CRYPTO, "Trying to load dynamic OpenSSL engine \"%s\"" + " via path \"%s\".", accelName, accelDir); + e = try_load_engine(accelName, accelDir); + } else { + log_info(LD_CRYPTO, "Initializing dynamic OpenSSL engine \"%s\"" + " acceleration support.", accelName); + e = ENGINE_by_id(accelName); + } + if (!e) { + log_warn(LD_CRYPTO, "Unable to load dynamic OpenSSL engine \"%s\".", + accelName); + } else { + log_info(LD_CRYPTO, "Loaded dynamic OpenSSL engine \"%s\".", + accelName); + } + } + if (e) { + log_info(LD_CRYPTO, "Loaded OpenSSL hardware acceleration engine," + " setting default ciphers."); + ENGINE_set_default(e, ENGINE_METHOD_ALL); + } log_engine("RSA", ENGINE_get_default_RSA()); log_engine("DH", ENGINE_get_default_DH()); log_engine("RAND", ENGINE_get_default_RAND()); log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1)); log_engine("3DES", ENGINE_get_cipher_engine(NID_des_ede3_ecb)); log_engine("AES", ENGINE_get_cipher_engine(NID_aes_128_ecb)); + } else { + log_info(LD_CRYPTO, "NOT using OpenSSL engine support."); } return crypto_seed_rng(1); } diff --git a/src/common/crypto.h b/src/common/crypto.h index dd353ef030..fa6735d788 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -55,7 +55,9 @@ typedef struct crypto_digest_env_t crypto_digest_env_t; typedef struct crypto_dh_env_t crypto_dh_env_t; /* global state */ -int crypto_global_init(int hardwareAccel); +int crypto_global_init(int hardwareAccel, + const char *accelName, + const char *accelPath); void crypto_thread_cleanup(void); int crypto_global_cleanup(void); diff --git a/src/common/tortls.c b/src/common/tortls.c index 581b35848a..106a9d40ee 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -308,7 +308,6 @@ tor_tls_init(void) if (!tls_library_is_initialized) { SSL_library_init(); SSL_load_error_strings(); - crypto_global_init(-1); tls_library_is_initialized = 1; } } diff --git a/src/or/config.c b/src/or/config.c index a4461a6fe7..0d176670e4 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -222,6 +222,8 @@ static config_var_t _option_vars[] = { #endif OBSOLETE("Group"), V(HardwareAccel, BOOL, "0"), + V(AccelName, STRING, NULL), + V(AccelDir, FILENAME, NULL), V(HashedControlPassword, LINELIST, NULL), V(HidServDirectoryV2, BOOL, "1"), VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL), @@ -444,6 +446,10 @@ static config_var_description_t options_description[] = { * FetchUselessDescriptors */ { "HardwareAccel", "If set, Tor tries to use hardware crypto accelerators " "when it can." }, + { "AccelName", "If set, try to use hardware crypto accelerator with this " + "specific ID." }, + { "AccelDir", "If set, look in this directory for the dynamic hardware " + "engine in addition to OpenSSL default path." }, /* HashedControlPassword */ { "HTTPProxy", "Force Tor to make all HTTP directory requests through this " "host:port (or host:80 if port is not set)." }, @@ -3602,6 +3608,11 @@ options_validate(or_options_t *old_options, or_options_t *options, "testing Tor network!"); } + if (options->AccelName && !options->HardwareAccel) + options->HardwareAccel = 1; + if (options->AccelDir && !options->AccelName) + REJECT("Can't use hardware crypto accelerator dir without engine name."); + return 0; #undef REJECT #undef COMPLAIN @@ -3659,9 +3670,11 @@ options_transition_allowed(or_options_t *old, or_options_t *new_val, return -1; } - if (old->HardwareAccel != new_val->HardwareAccel) { - *msg = tor_strdup("While Tor is running, changing HardwareAccel is " - "not allowed."); + if ((old->HardwareAccel != new_val->HardwareAccel) + || (old->AccelName != new_val->AccelName) + || (old->AccelDir != new_val->AccelDir)) { + *msg = tor_strdup("While Tor is running, changing OpenSSL hardware " + "acceleration engine is not allowed."); return -1; } diff --git a/src/or/main.c b/src/or/main.c index b151b1f666..456d9fab16 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1818,7 +1818,9 @@ tor_init(int argc, char *argv[]) "and you probably shouldn't."); #endif - if (crypto_global_init(get_options()->HardwareAccel)) { + if (crypto_global_init(get_options()->HardwareAccel, + get_options()->AccelName, + get_options()->AccelDir)) { log_err(LD_BUG, "Unable to initialize OpenSSL. Exiting."); return -1; } diff --git a/src/or/or.h b/src/or/or.h index d5b36c85a6..77582309e9 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2422,6 +2422,8 @@ typedef struct { * log whether it was DNS-leaking or not? */ int HardwareAccel; /**< Boolean: Should we enable OpenSSL hardware * acceleration where available? */ + char *AccelName; /**< Optional hardware acceleration engine name. */ + char *AccelDir; /**< Optional hardware acceleration engine search dir. */ int UseEntryGuards; /**< Boolean: Do we try to enter from a smallish number * of fixed nodes? */ int NumEntryGuards; /**< How many entry guards do we try to establish? */ diff --git a/src/or/router.c b/src/or/router.c index da922b7508..7a567be30d 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -442,7 +442,9 @@ init_keys(void) key_lock = tor_mutex_new(); /* There are a couple of paths that put us here before */ - if (crypto_global_init(get_options()->HardwareAccel)) { + if (crypto_global_init(get_options()->HardwareAccel, + get_options()->AccelName, + get_options()->AccelDir)) { log_err(LD_BUG, "Unable to initialize OpenSSL. Exiting."); return -1; } diff --git a/src/or/test.c b/src/or/test.c index 6ce0aaeb47..ef61e62ee1 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -4793,7 +4793,7 @@ main(int c, char**v) } options->command = CMD_RUN_UNITTESTS; - crypto_global_init(0); + crypto_global_init(0, NULL, NULL); rep_hist_init(); network_init(); setup_directory(); diff --git a/src/tools/tor-checkkey.c b/src/tools/tor-checkkey.c index b29b52d8db..6416dbfbb3 100644 --- a/src/tools/tor-checkkey.c +++ b/src/tools/tor-checkkey.c @@ -29,7 +29,7 @@ int main(int c, char **v) return 1; } - if (crypto_global_init(0)) { + if (crypto_global_init(0, NULL, NULL)) { fprintf(stderr, "Couldn't initialize crypto library.\n"); return 1; } diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c index 4971668c9f..d2ea4eb109 100644 --- a/src/tools/tor-gencert.c +++ b/src/tools/tor-gencert.c @@ -496,7 +496,7 @@ main(int argc, char **argv) init_logging(); /* Don't bother using acceleration. */ - if (crypto_global_init(0)) { + if (crypto_global_init(0, NULL, NULL)) { fprintf(stderr, "Couldn't initialize crypto library.\n"); return 1; } |