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
58 const char *msg, *lib, *func;
59 while ((err = ERR_get_error()) != 0) {
60 msg = (
const char*)ERR_reason_error_string(err);
61 lib = (
const char*)ERR_lib_error_string(err);
62 func = (
const char*)ERR_func_error_string(err);
63 if (!msg) msg =
"(null)";
64 if (!lib) lib =
"(null)";
65 if (!func) func =
"(null)";
66 if (BUG(!doing)) doing =
"(null)";
68 doing, msg, lib, func);
78 const char *end_of_version = NULL;
82 raw_version += strlen(
"OpenSSL ");
83 end_of_version = strchr(raw_version,
' ');
87 return tor_strndup(raw_version,
88 end_of_version-raw_version);
90 return tor_strdup(raw_version);
93static char *crypto_openssl_version_str = NULL;
96crypto_openssl_get_version_str(
void)
98 const int query = OPENSSL_VERSION;
100 if (crypto_openssl_version_str == NULL) {
101 const char *raw_version = OpenSSL_version(query);
104 return crypto_openssl_version_str;
107static char *crypto_openssl_header_version_str = NULL;
111crypto_openssl_get_header_version_str(
void)
113 if (crypto_openssl_header_version_str == NULL) {
114 crypto_openssl_header_version_str =
117 return crypto_openssl_header_version_str;
121#ifndef OPENSSL_THREADS
122#error "OpenSSL has been built without thread support. Tor requires an \
123 OpenSSL library with thread support enabled."
139 tor_free(crypto_openssl_version_str);
140 tor_free(crypto_openssl_header_version_str);
147 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS |
148 OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
149 OPENSSL_INIT_ADD_ALL_CIPHERS |
150 OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
154 unsigned long version_num = tor_OpenSSL_version_num();
155 const char *version_str = crypto_openssl_get_version_str();
156 if (version_num == OPENSSL_VERSION_NUMBER &&
157 !strcmp(version_str, OPENSSL_VERSION_TEXT)) {
158 log_info(
LD_CRYPTO,
"OpenSSL version matches version from headers "
159 "(%lx: %s).", version_num, version_str);
160 }
else if ((version_num & 0xffff0000) ==
161 (OPENSSL_VERSION_NUMBER & 0xffff0000)) {
163 "We compiled with OpenSSL %lx: %s and we "
164 "are running with OpenSSL %lx: %s. "
165 "These two versions should be binary compatible.",
166 (
unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT,
167 version_num, version_str);
169 log_warn(
LD_CRYPTO,
"OpenSSL version from headers does not match the "
170 "version we're running with. If you get weird crashes, that "
171 "might be why. (Compiled with %lx: %s; running with %lx: %s).",
172 (
unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT,
173 version_num, version_str);
179#ifndef DISABLE_ENGINES
185 ENGINE *e = ENGINE_by_id(
"dynamic");
187 if (!ENGINE_ctrl_cmd_string(e,
"ID", engine, 0) ||
188 !ENGINE_ctrl_cmd_string(e,
"DIR_LOAD",
"2", 0) ||
189 !ENGINE_ctrl_cmd_string(e,
"DIR_ADD", path, 0) ||
190 !ENGINE_ctrl_cmd_string(e,
"LOAD", NULL, 0)) {
199#ifndef DISABLE_ENGINES
205 const char *
name, *id;
206 name = ENGINE_get_name(e);
207 id = ENGINE_get_id(e);
208 log_notice(
LD_CRYPTO,
"Default OpenSSL engine for %s is %s [%s]",
211 log_info(
LD_CRYPTO,
"Using default implementation for %s", fn);
225 const char *accelDir)
227#ifdef DISABLE_ENGINES
230 log_warn(
LD_CRYPTO,
"No OpenSSL hardware acceleration support enabled.");
231 if (accelName && accelName[0] ==
'!') {
232 log_warn(
LD_CRYPTO,
"Unable to load required dynamic OpenSSL engine "
233 "\"%s\".", accelName+1);
240 log_info(
LD_CRYPTO,
"Initializing OpenSSL engine support.");
241 ENGINE_load_builtin_engines();
242 ENGINE_register_all_complete();
245 const bool required = accelName[0] ==
'!';
249 log_info(
LD_CRYPTO,
"Trying to load dynamic OpenSSL engine \"%s\""
250 " via path \"%s\".", accelName, accelDir);
253 log_info(
LD_CRYPTO,
"Initializing dynamic OpenSSL engine \"%s\""
254 " acceleration support.", accelName);
255 e = ENGINE_by_id(accelName);
258 log_warn(
LD_CRYPTO,
"Unable to load %sdynamic OpenSSL engine \"%s\".",
259 required?
"required ":
"",
264 log_info(
LD_CRYPTO,
"Loaded dynamic OpenSSL engine \"%s\".",
269 log_info(
LD_CRYPTO,
"Loaded OpenSSL hardware acceleration engine,"
270 " setting default ciphers.");
271 ENGINE_set_default(e, ENGINE_METHOD_ALL);
278 log_engine(
"RAND", ENGINE_get_default_RAND());
279 log_engine(
"RAND (which we will not use)", ENGINE_get_default_RAND());
280 log_engine(
"SHA1", ENGINE_get_digest_engine(NID_sha1));
281 log_engine(
"3DES-CBC", ENGINE_get_cipher_engine(NID_des_ede3_cbc));
282 log_engine(
"AES-128-ECB", ENGINE_get_cipher_engine(NID_aes_128_ecb));
283 log_engine(
"AES-128-CBC", ENGINE_get_cipher_engine(NID_aes_128_cbc));
284#ifdef NID_aes_128_ctr
285 log_engine(
"AES-128-CTR", ENGINE_get_cipher_engine(NID_aes_128_ctr));
287#ifdef NID_aes_128_gcm
288 log_engine(
"AES-128-GCM", ENGINE_get_cipher_engine(NID_aes_128_gcm));
290 log_engine(
"AES-256-CBC", ENGINE_get_cipher_engine(NID_aes_256_cbc));
291#ifdef NID_aes_256_gcm
292 log_engine(
"AES-256-GCM", ENGINE_get_cipher_engine(NID_aes_256_gcm));
302 const char *accelDir)
304 if (tor_OpenSSL_version_num() < OPENSSL_V_SERIES(3,0,0)) {
305 log_warn(
LD_CRYPTO,
"Running with OpenSSL version \"%s\", "
306 "which is no longer maintained by the OpenSSL project. "
307 "We recommend that you upgrade to OpenSSL 3.0 or later. "
308 "OpenSSL >=3.5 would be ideal.",
309 OPENSSL_VERSION_TEXT);
316 log_info(
LD_CRYPTO,
"NOT using OpenSSL engine support.");
324 evaluate_evp_for_aes(-1);
325 evaluate_ctr_for_aes();
340 CONF_modules_unload(1);
Header for compat_mutex.c.
void crypto_openssl_early_init(void)
static ENGINE * try_load_engine(const char *path, const char *engine)
void crypto_openssl_thread_cleanup(void)
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 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.