13#include "lib/crypt_ops/compat_openssl.h"
24DISABLE_GCC_WARNING(
"-Wredundant-decls")
26#include <openssl/err.h>
27#include <openssl/rsa.h>
28#include <openssl/pem.h>
29#include <openssl/evp.h>
30#include <openssl/engine.h>
31#include <openssl/rand.h>
32#include <openssl/bn.h>
33#include <openssl/dh.h>
34#include <openssl/conf.h>
35#include <openssl/hmac.h>
36#include <openssl/crypto.h>
37#include <openssl/ssl.h>
39ENABLE_GCC_WARNING(
"-Wredundant-decls")
43#ifdef OPENSSL_NO_ENGINE
45#define DISABLE_ENGINES
59STATIC void tor_set_openssl_thread_id(CRYPTO_THREADID *threadid);
69 const char *msg, *lib, *func;
70 while ((err = ERR_get_error()) != 0) {
71 msg = (
const char*)ERR_reason_error_string(err);
72 lib = (
const char*)ERR_lib_error_string(err);
73 func = (
const char*)ERR_func_error_string(err);
74 if (!msg) msg =
"(null)";
75 if (!lib) lib =
"(null)";
76 if (!func) func =
"(null)";
77 if (BUG(!doing)) doing =
"(null)";
79 doing, msg, lib, func);
89 const char *end_of_version = NULL;
93 raw_version += strlen(
"OpenSSL ");
94 end_of_version = strchr(raw_version,
' ');
98 return tor_strndup(raw_version,
99 end_of_version-raw_version);
101 return tor_strdup(raw_version);
104static char *crypto_openssl_version_str = NULL;
107crypto_openssl_get_version_str(
void)
109#ifdef OPENSSL_VERSION
110 const int query = OPENSSL_VERSION;
113 const int query = SSLEAY_VERSION;
116 if (crypto_openssl_version_str == NULL) {
117 const char *raw_version = OpenSSL_version(query);
120 return crypto_openssl_version_str;
123#undef QUERY_OPENSSL_VERSION
125static char *crypto_openssl_header_version_str = NULL;
129crypto_openssl_get_header_version_str(
void)
131 if (crypto_openssl_header_version_str == NULL) {
132 crypto_openssl_header_version_str =
135 return crypto_openssl_header_version_str;
139#ifndef OPENSSL_THREADS
140#error "OpenSSL has been built without thread support. Tor requires an \
141 OpenSSL library with thread support enabled."
145#ifndef NEW_THREAD_API
157 if (mode & CRYPTO_LOCK)
164tor_set_openssl_thread_id(CRYPTO_THREADID *threadid)
175#ifndef NEW_THREAD_API
177 int n = CRYPTO_num_locks();
180 for (i=0; i < n; ++i)
183 CRYPTO_THREADID_set_callback(tor_set_openssl_thread_id);
192 tor_free(crypto_openssl_version_str);
193 tor_free(crypto_openssl_header_version_str);
199#ifndef NEW_THREAD_API
218#ifdef OPENSSL_1_1_API
219 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS |
220 OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
221 OPENSSL_INIT_ADD_ALL_CIPHERS |
222 OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
224 ERR_load_crypto_strings();
225 OpenSSL_add_all_algorithms();
230 unsigned long version_num = tor_OpenSSL_version_num();
231 const char *version_str = crypto_openssl_get_version_str();
232 if (version_num == OPENSSL_VERSION_NUMBER &&
233 !strcmp(version_str, OPENSSL_VERSION_TEXT)) {
234 log_info(
LD_CRYPTO,
"OpenSSL version matches version from headers "
235 "(%lx: %s).", version_num, version_str);
236 }
else if ((version_num & 0xffff0000) ==
237 (OPENSSL_VERSION_NUMBER & 0xffff0000)) {
239 "We compiled with OpenSSL %lx: %s and we "
240 "are running with OpenSSL %lx: %s. "
241 "These two versions should be binary compatible.",
242 (
unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT,
243 version_num, version_str);
245 log_warn(
LD_CRYPTO,
"OpenSSL version from headers does not match the "
246 "version we're running with. If you get weird crashes, that "
247 "might be why. (Compiled with %lx: %s; running with %lx: %s).",
248 (
unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT,
249 version_num, version_str);
255#ifndef DISABLE_ENGINES
261 ENGINE *e = ENGINE_by_id(
"dynamic");
263 if (!ENGINE_ctrl_cmd_string(e,
"ID", engine, 0) ||
264 !ENGINE_ctrl_cmd_string(e,
"DIR_LOAD",
"2", 0) ||
265 !ENGINE_ctrl_cmd_string(e,
"DIR_ADD", path, 0) ||
266 !ENGINE_ctrl_cmd_string(e,
"LOAD", NULL, 0)) {
275#ifndef DISABLE_ENGINES
281 const char *
name, *id;
282 name = ENGINE_get_name(e);
283 id = ENGINE_get_id(e);
284 log_notice(
LD_CRYPTO,
"Default OpenSSL engine for %s is %s [%s]",
287 log_info(
LD_CRYPTO,
"Using default implementation for %s", fn);
301 const char *accelDir)
303#ifdef DISABLE_ENGINES
306 log_warn(
LD_CRYPTO,
"No OpenSSL hardware acceleration support enabled.");
307 if (accelName && accelName[0] ==
'!') {
308 log_warn(
LD_CRYPTO,
"Unable to load required dynamic OpenSSL engine "
309 "\"%s\".", accelName+1);
316 log_info(
LD_CRYPTO,
"Initializing OpenSSL engine support.");
317 ENGINE_load_builtin_engines();
318 ENGINE_register_all_complete();
321 const bool required = accelName[0] ==
'!';
325 log_info(
LD_CRYPTO,
"Trying to load dynamic OpenSSL engine \"%s\""
326 " via path \"%s\".", accelName, accelDir);
329 log_info(
LD_CRYPTO,
"Initializing dynamic OpenSSL engine \"%s\""
330 " acceleration support.", accelName);
331 e = ENGINE_by_id(accelName);
334 log_warn(
LD_CRYPTO,
"Unable to load %sdynamic OpenSSL engine \"%s\".",
335 required?
"required ":
"",
340 log_info(
LD_CRYPTO,
"Loaded dynamic OpenSSL engine \"%s\".",
345 log_info(
LD_CRYPTO,
"Loaded OpenSSL hardware acceleration engine,"
346 " setting default ciphers.");
347 ENGINE_set_default(e, ENGINE_METHOD_ALL);
353#ifdef OPENSSL_1_1_API
356 log_engine(
"ECDH", ENGINE_get_default_ECDH());
357 log_engine(
"ECDSA", ENGINE_get_default_ECDSA());
359 log_engine(
"RAND", ENGINE_get_default_RAND());
360 log_engine(
"RAND (which we will not use)", ENGINE_get_default_RAND());
361 log_engine(
"SHA1", ENGINE_get_digest_engine(NID_sha1));
362 log_engine(
"3DES-CBC", ENGINE_get_cipher_engine(NID_des_ede3_cbc));
363 log_engine(
"AES-128-ECB", ENGINE_get_cipher_engine(NID_aes_128_ecb));
364 log_engine(
"AES-128-CBC", ENGINE_get_cipher_engine(NID_aes_128_cbc));
365#ifdef NID_aes_128_ctr
366 log_engine(
"AES-128-CTR", ENGINE_get_cipher_engine(NID_aes_128_ctr));
368#ifdef NID_aes_128_gcm
369 log_engine(
"AES-128-GCM", ENGINE_get_cipher_engine(NID_aes_128_gcm));
371 log_engine(
"AES-256-CBC", ENGINE_get_cipher_engine(NID_aes_256_cbc));
372#ifdef NID_aes_256_gcm
373 log_engine(
"AES-256-GCM", ENGINE_get_cipher_engine(NID_aes_256_gcm));
383 const char *accelDir)
389 log_info(
LD_CRYPTO,
"NOT using OpenSSL engine support.");
397 evaluate_evp_for_aes(-1);
398 evaluate_ctr_for_aes();
407#ifndef NEW_THREAD_API
408 ERR_remove_thread_state(NULL);
416#ifndef OPENSSL_1_1_API
419#ifndef NEW_THREAD_API
420 ERR_remove_thread_state(NULL);
422#ifndef OPENSSL_1_1_API
426#ifndef DISABLE_ENGINES
427#ifndef OPENSSL_1_1_API
432 CONF_modules_unload(1);
433#ifndef OPENSSL_1_1_API
434 CRYPTO_cleanup_all_ex_data();
tor_mutex_t * tor_mutex_new(void)
Header for compat_mutex.c.
void tor_mutex_release(tor_mutex_t *m)
void tor_mutex_acquire(tor_mutex_t *m)
#define tor_mutex_free(m)
unsigned long tor_get_thread_id(void)
static tor_mutex_t ** openssl_mutexes_
void crypto_openssl_early_init(void)
static ENGINE * try_load_engine(const char *path, const char *engine)
void crypto_openssl_thread_cleanup(void)
static int n_openssl_mutexes_
int crypto_openssl_late_init(int useAccel, const char *accelName, const char *accelDir)
static int crypto_openssl_init_engines(const char *accelName, const char *accelDir)
static void log_engine(const char *fn, ENGINE *e)
static int setup_openssl_threading(void)
void crypto_openssl_global_cleanup(void)
STATIC char * parse_openssl_version_str(const char *raw_version)
STATIC void openssl_locking_cb_(int mode, int n, const char *file, int line)
static void crypto_openssl_free_all(void)
void crypto_openssl_log_errors(int severity, const char *doing)
Headers for crypto_openssl_mgt.c.
int crypto_seed_rng(void)
int crypto_force_rand_ssleay(void)
Common functions for using (pseudo-)random number generators.
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
Macros to implement mocking and selective exposure for the test code.
Macros to manage assertions, fatal and non-fatal.
int strcmpstart(const char *s1, const char *s2)
Header for util_string.c.