|
@@ -38,7 +38,6 @@ DISABLE_GCC_WARNING(redundant-decls)
|
|
|
|
|
|
#include <openssl/err.h>
|
|
|
#include <openssl/evp.h>
|
|
|
-#include <openssl/engine.h>
|
|
|
#include <openssl/bn.h>
|
|
|
#include <openssl/dh.h>
|
|
|
#include <openssl/conf.h>
|
|
@@ -74,211 +73,6 @@ ENABLE_GCC_WARNING(redundant-decls)
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
-/** 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;
|
|
|
-
|
|
|
-#ifndef DISABLE_ENGINES
|
|
|
-/** Log any OpenSSL engines we're using at NOTICE. */
|
|
|
-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_notice(LD_CRYPTO, "Default OpenSSL engine for %s is %s [%s]",
|
|
|
- fn, name?name:"?", id?id:"?");
|
|
|
- } else {
|
|
|
- log_info(LD_CRYPTO, "Using default implementation for %s", fn);
|
|
|
- }
|
|
|
-}
|
|
|
-#endif /* !defined(DISABLE_ENGINES) */
|
|
|
-
|
|
|
-#ifndef DISABLE_ENGINES
|
|
|
-/** 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;
|
|
|
-}
|
|
|
-#endif /* !defined(DISABLE_ENGINES) */
|
|
|
-
|
|
|
-static int have_seeded_siphash = 0;
|
|
|
-
|
|
|
-/** Set up the siphash key if we haven't already done so. */
|
|
|
-int
|
|
|
-crypto_init_siphash_key(void)
|
|
|
-{
|
|
|
- struct sipkey key;
|
|
|
- if (have_seeded_siphash)
|
|
|
- return 0;
|
|
|
-
|
|
|
- crypto_rand((char*) &key, sizeof(key));
|
|
|
- siphash_set_global_key(&key);
|
|
|
- have_seeded_siphash = 1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/** Initialize the crypto library. Return 0 on success, -1 on failure.
|
|
|
- */
|
|
|
-int
|
|
|
-crypto_early_init(void)
|
|
|
-{
|
|
|
- if (!crypto_early_initialized_) {
|
|
|
-
|
|
|
- crypto_early_initialized_ = 1;
|
|
|
-
|
|
|
-#ifdef OPENSSL_1_1_API
|
|
|
- OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS |
|
|
|
- OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
|
|
|
- OPENSSL_INIT_ADD_ALL_CIPHERS |
|
|
|
- OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
|
|
|
-#else
|
|
|
- ERR_load_crypto_strings();
|
|
|
- OpenSSL_add_all_algorithms();
|
|
|
-#endif
|
|
|
-
|
|
|
- setup_openssl_threading();
|
|
|
-
|
|
|
- unsigned long version_num = OpenSSL_version_num();
|
|
|
- const char *version_str = OpenSSL_version(OPENSSL_VERSION);
|
|
|
- if (version_num == OPENSSL_VERSION_NUMBER &&
|
|
|
- !strcmp(version_str, OPENSSL_VERSION_TEXT)) {
|
|
|
- log_info(LD_CRYPTO, "OpenSSL version matches version from headers "
|
|
|
- "(%lx: %s).", version_num, version_str);
|
|
|
- } else {
|
|
|
- log_warn(LD_CRYPTO, "OpenSSL version from headers does not match the "
|
|
|
- "version we're running with. If you get weird crashes, that "
|
|
|
- "might be why. (Compiled with %lx: %s; running with %lx: %s).",
|
|
|
- (unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT,
|
|
|
- version_num, version_str);
|
|
|
- }
|
|
|
-
|
|
|
- crypto_force_rand_ssleay();
|
|
|
-
|
|
|
- if (crypto_seed_rng() < 0)
|
|
|
- return -1;
|
|
|
- if (crypto_init_siphash_key() < 0)
|
|
|
- return -1;
|
|
|
-
|
|
|
- curve25519_init();
|
|
|
- ed25519_init();
|
|
|
- }
|
|
|
- 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_) {
|
|
|
- if (crypto_early_init() < 0)
|
|
|
- return -1;
|
|
|
-
|
|
|
- crypto_global_initialized_ = 1;
|
|
|
-
|
|
|
- if (useAccel > 0) {
|
|
|
-#ifdef DISABLE_ENGINES
|
|
|
- (void)accelName;
|
|
|
- (void)accelDir;
|
|
|
- log_warn(LD_CRYPTO, "No OpenSSL hardware acceleration support enabled.");
|
|
|
-#else
|
|
|
- ENGINE *e = NULL;
|
|
|
-
|
|
|
- log_info(LD_CRYPTO, "Initializing OpenSSL engine support.");
|
|
|
- ENGINE_load_builtin_engines();
|
|
|
- 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, if available, the intersection of the set of algorithms
|
|
|
- used by Tor and the set of algorithms available in the engine */
|
|
|
- log_engine("RSA", ENGINE_get_default_RSA());
|
|
|
- log_engine("DH", ENGINE_get_default_DH());
|
|
|
-#ifdef OPENSSL_1_1_API
|
|
|
- log_engine("EC", ENGINE_get_default_EC());
|
|
|
-#else
|
|
|
- log_engine("ECDH", ENGINE_get_default_ECDH());
|
|
|
- log_engine("ECDSA", ENGINE_get_default_ECDSA());
|
|
|
-#endif /* defined(OPENSSL_1_1_API) */
|
|
|
- log_engine("RAND", ENGINE_get_default_RAND());
|
|
|
- log_engine("RAND (which we will not use)", ENGINE_get_default_RAND());
|
|
|
- log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1));
|
|
|
- log_engine("3DES-CBC", ENGINE_get_cipher_engine(NID_des_ede3_cbc));
|
|
|
- log_engine("AES-128-ECB", ENGINE_get_cipher_engine(NID_aes_128_ecb));
|
|
|
- log_engine("AES-128-CBC", ENGINE_get_cipher_engine(NID_aes_128_cbc));
|
|
|
-#ifdef NID_aes_128_ctr
|
|
|
- log_engine("AES-128-CTR", ENGINE_get_cipher_engine(NID_aes_128_ctr));
|
|
|
-#endif
|
|
|
-#ifdef NID_aes_128_gcm
|
|
|
- log_engine("AES-128-GCM", ENGINE_get_cipher_engine(NID_aes_128_gcm));
|
|
|
-#endif
|
|
|
- log_engine("AES-256-CBC", ENGINE_get_cipher_engine(NID_aes_256_cbc));
|
|
|
-#ifdef NID_aes_256_gcm
|
|
|
- log_engine("AES-256-GCM", ENGINE_get_cipher_engine(NID_aes_256_gcm));
|
|
|
-#endif
|
|
|
-
|
|
|
-#endif /* defined(DISABLE_ENGINES) */
|
|
|
- } else {
|
|
|
- log_info(LD_CRYPTO, "NOT using OpenSSL engine support.");
|
|
|
- }
|
|
|
-
|
|
|
- if (crypto_force_rand_ssleay()) {
|
|
|
- if (crypto_seed_rng() < 0)
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- evaluate_evp_for_aes(-1);
|
|
|
- evaluate_ctr_for_aes();
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/** Free crypto resources held by this thread. */
|
|
|
-void
|
|
|
-crypto_thread_cleanup(void)
|
|
|
-{
|
|
|
-#ifndef NEW_THREAD_API
|
|
|
- ERR_remove_thread_state(NULL);
|
|
|
-#endif
|
|
|
-}
|
|
|
-
|
|
|
/** Allocate and return a new symmetric cipher using the provided key and iv.
|
|
|
* The key is <b>bits</b> bits long; the IV is CIPHER_IV_LEN bytes. Both
|
|
|
* must be provided. Key length must be 128, 192, or 256 */
|
|
@@ -465,45 +259,3 @@ crypto_cipher_decrypt_with_iv(const char *key,
|
|
|
crypto_cipher_free(cipher);
|
|
|
return (int)(fromlen - CIPHER_IV_LEN);
|
|
|
}
|
|
|
-
|
|
|
-/** @{ */
|
|
|
-/** Uninitialize the crypto library. Return 0 on success. Does not detect
|
|
|
- * failure.
|
|
|
- */
|
|
|
-int
|
|
|
-crypto_global_cleanup(void)
|
|
|
-{
|
|
|
-#ifndef OPENSSL_1_1_API
|
|
|
- EVP_cleanup();
|
|
|
-#endif
|
|
|
-#ifndef NEW_THREAD_API
|
|
|
- ERR_remove_thread_state(NULL);
|
|
|
-#endif
|
|
|
-#ifndef OPENSSL_1_1_API
|
|
|
- ERR_free_strings();
|
|
|
-#endif
|
|
|
-
|
|
|
- crypto_dh_free_all();
|
|
|
-
|
|
|
-#ifndef DISABLE_ENGINES
|
|
|
-#ifndef OPENSSL_1_1_API
|
|
|
- ENGINE_cleanup();
|
|
|
-#endif
|
|
|
-#endif
|
|
|
-
|
|
|
- CONF_modules_unload(1);
|
|
|
-#ifndef OPENSSL_1_1_API
|
|
|
- CRYPTO_cleanup_all_ex_data();
|
|
|
-#endif
|
|
|
-
|
|
|
- crypto_openssl_free_all();
|
|
|
-
|
|
|
- crypto_early_initialized_ = 0;
|
|
|
- crypto_global_initialized_ = 0;
|
|
|
- have_seeded_siphash = 0;
|
|
|
- siphash_unset_global_key();
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/** @} */
|