Merge branch 'hardware_accel_improvements'

This commit is contained in:
Nick Mathewson 2009-05-31 13:36:50 -04:00
commit e84ddead34
12 changed files with 95 additions and 25 deletions

View File

@ -1,5 +1,9 @@
Changes in version 0.2.2.1-alpha - 2009-??-??
o Minor features
o Major features:
- Add support for dynamic OpenSSL hardware crypto acceleration engines
via new AccelName and AccelDir options.
o Minor features:
- New --digests command-line switch to output the digests of the
source files Tor was built with.
- The "torify" script now uses torsocks where available.

View File

@ -350,8 +350,19 @@ On startup, setuid to this user and setgid to their primary group.
.LP
.TP
\fBHardwareAccel \fR\fB0\fR|\fB1\fP
If non-zero, try to use crypto hardware acceleration when
available. This is untested and probably buggy. (Default: 0)
If non-zero, try to use built-in (static) crypto hardware acceleration when
available. (Default: 0)
.LP
.TP
\fBAccelName \fR\fINAME\fP
When using OpenSSL hardware crypto acceleration attempt to load the dynamic
engine of this name. This must be used for any dynamic hardware engine. Names
can be verified with the openssl engine command.
.LP
.TP
\fBAccelDir \fR\fIDIR\fP
Specify this option if using dynamic hardware acceleration and the engine
implementation library resides somewhere other than the OpenSSL default.
.LP
.TP
\fBAvoidDiskWrites \fR\fB0\fR|\fB1\fP

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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)." },
@ -3611,6 +3617,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
@ -3668,9 +3679,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)
|| !opt_streq(old->AccelName, new_val->AccelName)
|| !opt_streq(old->AccelDir, new_val->AccelDir)) {
*msg = tor_strdup("While Tor is running, changing OpenSSL hardware "
"acceleration engine is not allowed.");
return -1;
}

View File

@ -1810,7 +1810,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;
}

View File

@ -2416,6 +2416,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? */

View File

@ -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;
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
}