Browse Source

Load hardware acceleration options when/where available. Can anybody test this?

svn:r4467
Nick Mathewson 19 years ago
parent
commit
2aff87caae
8 changed files with 56 additions and 10 deletions
  1. 2 1
      doc/TODO
  2. 4 0
      doc/tor.1.in
  3. 38 4
      src/common/crypto.c
  4. 1 1
      src/common/crypto.h
  5. 2 3
      src/common/tortls.c
  6. 6 0
      src/or/config.c
  7. 1 1
      src/or/main.c
  8. 2 0
      src/or/or.h

+ 2 - 1
doc/TODO

@@ -107,7 +107,8 @@ N - Handle rendezvousing with unverified nodes.
     prefix.
   - cpu fixes:
     - see if we should make use of truncate to retry
-    - hardware accelerator support
+    o hardware accelerator support (configure engines.)
+    - hardware accelerator support (use instead of aes.c when reasonable)
 r   - kill dns workers more slowly
   - continue decentralizing the directory
     - Specify and design all of the below before implementing any.

+ 4 - 0
doc/tor.1.in

@@ -154,6 +154,10 @@ minutes for clients, 15 minutes for servers)
 .TP
 \fBUser \fR\fIUID\fP
 On startup, setuid to this user.
+.TP
+\fBHardwareAccel \fR\fI0|1\fP
+If non-zero, try to use crypto hardware acceleration when
+available. (Default: 1. )
 
 .SH CLIENT OPTIONS
 .PP

+ 38 - 4
src/common/crypto.c

@@ -22,6 +22,7 @@ const char crypto_c_id[] = "$Id$";
 
 #include <string.h>
 
+#include <openssl/engine.h>
 #include <openssl/err.h>
 #include <openssl/rsa.h>
 #include <openssl/pem.h>
@@ -159,14 +160,46 @@ crypto_log_errors(int severity, const char *doing)
   }
 }
 
+static void
+log_engine(const char *fn, ENGINE *e)
+{
+  if (e) {
+    const char *name, *id;
+    name = ENGINE_get_name(e);
+    id = ENGINE_get_id(e);
+    log(LOG_NOTICE, "Using OpenSSL engine %s [%s] for %s",
+        name?name:"?", id?id:"?", fn);
+  } else {
+    log(LOG_INFO, "Using default implementation for %s", fn);
+  }
+}
+
 /** Initialize the crypto library.  Return 0 on success, -1 on failure.
  */
-int crypto_global_init()
+int
+crypto_global_init(int useAccel)
 {
   if (!_crypto_global_initialized) {
-      ERR_load_crypto_strings();
-      _crypto_global_initialized = 1;
-      setup_openssl_threading();
+    ERR_load_crypto_strings();
+    OpenSSL_add_all_algorithms();
+    _crypto_global_initialized = 1;
+    setup_openssl_threading();
+    if (useAccel) {
+      if (useAccel < 0)
+        log_fn(LOG_WARN, "Initializing OpenSSL via tor_tls_init().");
+      log_fn(LOG_INFO, "Initializing OpenSSL engine support.");
+      ENGINE_load_builtin_engines();
+      if (!ENGINE_register_all_complete())
+        return -1;
+
+      /* XXXX make sure this isn't leaking. */
+      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));
+    }
   }
   return 0;
 }
@@ -176,6 +209,7 @@ int crypto_global_init()
 int crypto_global_cleanup()
 {
   ERR_free_strings();
+  ENGINE_cleanup();
 #ifdef TOR_IS_MULTITHREADED
   if (_n_openssl_mutexes) {
     int n = _n_openssl_mutexes;

+ 1 - 1
src/common/crypto.h

@@ -48,7 +48,7 @@ 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(void);
+int crypto_global_init(int hardwareAccel);
 int crypto_global_cleanup(void);
 
 /* environment setup */

+ 2 - 3
src/common/tortls.c

@@ -148,12 +148,11 @@ tor_tls_get_error(tor_tls *tls, int r, int extra,
 /** Initialize OpenSSL, unless it has already been initialized.
  */
 static void
-tor_tls_init(void) {
+tor_tls_init() {
   if (!tls_library_is_initialized) {
     SSL_library_init();
     SSL_load_error_strings();
-    crypto_global_init();
-    OpenSSL_add_all_algorithms();
+    crypto_global_init(-1);
     tls_library_is_initialized = 1;
   }
 }

+ 6 - 0
src/or/config.c

@@ -135,6 +135,7 @@ static config_var_t config_vars[] = {
   VAR("HttpProxyAuthenticator",STRING, HttpProxyAuthenticator,NULL),
   VAR("HttpsProxy",          STRING,   HttpsProxy,           NULL),
   VAR("HttpsProxyAuthenticator",STRING,HttpsProxyAuthenticator,NULL),
+  VAR("HardwareAccel",       BOOL,     HardwareAccel,        "1"),
   VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines,    NULL),
   VAR("HiddenServiceDir",    LINELIST_S, RendConfigLines,    NULL),
   VAR("HiddenServicePort",   LINELIST_S, RendConfigLines,    NULL),
@@ -1662,6 +1663,11 @@ options_transition_allowed(or_options_t *old, or_options_t *new_val)
     return -1;
   }
 
+  if (old->HardwareAccel != new_val->HardwareAccel) {
+    log_fn(LOG_WARN,"During reload, changing HardwareAccel is not allowed. Failing.");
+    return -1;
+  }
+
   return 0;
 }
 

+ 1 - 1
src/or/main.c

@@ -1320,7 +1320,7 @@ tor_init(int argc, char *argv[])
     log_fn(LOG_WARN,"You are running Tor as root. You don't need to, and you probably shouldn't.");
 #endif
 
-  crypto_global_init();
+  crypto_global_init(get_options()->HardwareAccel);
   if (crypto_seed_rng()) {
     log_fn(LOG_ERR, "Unable to seed random number generator. Exiting.");
     return -1;

+ 2 - 0
src/or/or.h

@@ -1137,6 +1137,8 @@ typedef struct {
                            * long do we wait before exiting? */
   int SafeLogging; /**< Boolean: are we allowed to log sensitive strings
                     * such as addresses (0), or do we scrub them first (1)? */
+  int HardwareAccel; /**< Boolean: Should we enable OpenSSL hardware
+                      * acceleration where available? */
 } or_options_t;
 
 #define MAX_SOCKS_REPLY_LEN 1024