Tor 0.4.9.0-alpha-dev
crypto_init.c
Go to the documentation of this file.
1/* Copyright (c) 2001, Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5/* See LICENSE for licensing information */
6
7/**
8 * \file crypto_init.c
9 *
10 * \brief Initialize and shut down Tor's crypto library and subsystem.
11 **/
12
13#include "orconfig.h"
14
15#define CRYPTO_PRIVATE
16
18
27#include "lib/conf/conftypes.h"
28#include "lib/log/util_bug.h"
29
30#include "lib/subsys/subsys.h"
31
32#include "ext/siphash.h"
33
34/** Boolean: has our crypto library been initialized? (early phase) */
36
37/** Boolean: has our crypto library been initialized? (late phase) */
39
40static int have_seeded_siphash = 0;
41
42/** Set up the siphash key if we haven't already done so. */
43int
45{
46 struct sipkey key;
47 if (have_seeded_siphash)
48 return 0;
49
50 crypto_rand((char*) &key, sizeof(key));
51 siphash_set_global_key(&key);
52 have_seeded_siphash = 1;
53 return 0;
54}
55
56/** Initialize the crypto library. Return 0 on success, -1 on failure.
57 */
58int
60{
62
64
65#ifdef ENABLE_OPENSSL
67#endif
68#ifdef ENABLE_NSS
69 crypto_nss_early_init(0);
70#endif
71
72 if (crypto_seed_rng() < 0)
73 return -1;
75 return -1;
76
78
80 ed25519_init();
81 }
82 return 0;
83}
84
85/** Initialize the crypto library. Return 0 on success, -1 on failure.
86 */
87int
88crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
89{
91 if (crypto_early_init() < 0)
92 return -1;
93
95
96 crypto_dh_init();
97
98#ifdef ENABLE_OPENSSL
99 if (crypto_openssl_late_init(useAccel, accelName, accelDir) < 0)
100 return -1;
101#else
102 (void)useAccel;
103 (void)accelName;
104 (void)accelDir;
105#endif /* defined(ENABLE_OPENSSL) */
106#ifdef ENABLE_NSS
107 if (crypto_nss_late_init() < 0)
108 return -1;
109#endif
110 }
111 return 0;
112}
113
114/** Free crypto resources held by this thread. */
115void
117{
118#ifdef ENABLE_OPENSSL
120#endif
122}
123
124/**
125 * Uninitialize the crypto library. Return 0 on success. Does not detect
126 * failure.
127 */
128int
130{
131 crypto_dh_free_all();
132
133#ifdef ENABLE_OPENSSL
135#endif
136#ifdef ENABLE_NSS
137 crypto_nss_global_cleanup();
138#endif
139
141
144 have_seeded_siphash = 0;
145 siphash_unset_global_key();
146
147 return 0;
148}
149
150/** Run operations that the crypto library requires to be happy again
151 * after forking. */
152void
154{
155#ifdef ENABLE_NSS
156 crypto_nss_prefork();
157#endif
158 /* It is not safe to share a fast_rng object across a fork boundary unless
159 * we actually have zero-on-fork support in map_anon.c. If we have
160 * drop-on-fork support, we will crash; if we have neither, we will yield
161 * a copy of the parent process's rng, which is scary and insecure.
162 */
164}
165
166/** Run operations that the crypto library requires to be happy again
167 * after forking. */
168void
170{
171#ifdef ENABLE_NSS
172 crypto_nss_postfork();
173#endif
174}
175
176/** Return the name of the crypto library we're using. */
177const char *
179{
180#ifdef ENABLE_OPENSSL
181 return "OpenSSL";
182#endif
183#ifdef ENABLE_NSS
184 return "NSS";
185#endif
186}
187
188/** Return the version of the crypto library we are using, as given in the
189 * library. */
190const char *
192{
193#ifdef ENABLE_OPENSSL
194 return crypto_openssl_get_version_str();
195#endif
196#ifdef ENABLE_NSS
197 return crypto_nss_get_version_str();
198#endif
199}
200
201/** Return the version of the crypto library we're using, as given in the
202 * headers. */
203const char *
205{
206#ifdef ENABLE_OPENSSL
207 return crypto_openssl_get_header_version_str();
208#endif
209#ifdef ENABLE_NSS
210 return crypto_nss_get_header_version_str();
211#endif
212}
213
214/** Return true iff Tor is using the NSS library. */
215int
217{
218#ifdef ENABLE_NSS
219 return 1;
220#else
221 return 0;
222#endif
223}
224
225static int
226subsys_crypto_initialize(void)
227{
228 if (crypto_early_init() < 0)
229 return -1;
230 crypto_dh_init();
231 return 0;
232}
233
234static void
235subsys_crypto_shutdown(void)
236{
238}
239
240static void
241subsys_crypto_prefork(void)
242{
244}
245
246static void
247subsys_crypto_postfork(void)
248{
250}
251
252static void
253subsys_crypto_thread_cleanup(void)
254{
256}
257
258/** Magic number for crypto_options_t. */
259#define CRYPTO_OPTIONS_MAGIC 0x68757368
260
261/**
262 * Return 0 if <b>arg</b> is a valid crypto_options_t. Otherwise return -1
263 * and set *<b>msg_out</b> to a freshly allocated error string.
264 **/
265static int
266crypto_options_validate(const void *arg, char **msg_out)
267{
268 const crypto_options_t *opt = arg;
269 tor_assert(opt->magic == CRYPTO_OPTIONS_MAGIC);
270 tor_assert(msg_out);
271
272 if (opt->AccelDir && !opt->AccelName) {
273 *msg_out = tor_strdup("Can't use hardware crypto accelerator dir "
274 "without engine name.");
275 return -1;
276 }
277
278 return 0;
279}
280
281/* Declare the options field table for crypto_options */
282#define CONF_CONTEXT LL_TABLE
284#undef CONF_CONTEXT
285
286/**
287 * Declares the configuration options for this module.
288 **/
290 .size = sizeof(crypto_options_t),
291 .magic = { "crypto_options_t",
293 offsetof(crypto_options_t, magic) },
294 .vars = crypto_options_t_vars,
295 .validate_fn = crypto_options_validate,
296};
297
298/**
299 * Invoked from subsysmgr.c when a new set of options arrives.
300 **/
301static int
303{
304 const crypto_options_t *options = arg;
305 const bool hardware_accel = options->HardwareAccel || options->AccelName;
306
307 // This call already checks for crypto_global_initialized_, so it
308 // will only initialize the subsystem the first time it's called.
309 if (crypto_global_init(hardware_accel,
310 options->AccelName,
311 options->AccelDir)) {
312 log_err(LD_BUG, "Unable to initialize the crypto subsystem. Exiting.");
313 return -1;
314 }
315 return 0;
316}
317
318const struct subsys_fns_t sys_crypto = {
319 .name = "crypto",
321 .supported = true,
322 .level = -60,
323 .initialize = subsys_crypto_initialize,
324 .shutdown = subsys_crypto_shutdown,
325 .prefork = subsys_crypto_prefork,
326 .postfork = subsys_crypto_postfork,
327 .thread_cleanup = subsys_crypto_thread_cleanup,
328
329 .options_format = &crypto_options_fmt,
330 .set_options = crypto_set_options,
331};
Types used to specify configurable options.
void curve25519_init(void)
Header for crypto_curve25519.c.
Headers for crypto_dh.c.
Header for crypto_ed25519.c.
int crypto_global_cleanup(void)
Definition: crypto_init.c:129
static int crypto_options_validate(const void *arg, char **msg_out)
Definition: crypto_init.c:266
void crypto_postfork(void)
Definition: crypto_init.c:169
int crypto_init_siphash_key(void)
Definition: crypto_init.c:44
#define CRYPTO_OPTIONS_MAGIC
Definition: crypto_init.c:259
const char * crypto_get_library_version_string(void)
Definition: crypto_init.c:191
int crypto_early_init(void)
Definition: crypto_init.c:59
void crypto_thread_cleanup(void)
Definition: crypto_init.c:116
int crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
Definition: crypto_init.c:88
static const config_format_t crypto_options_fmt
Definition: crypto_init.c:289
static int crypto_set_options(void *arg)
Definition: crypto_init.c:302
static int crypto_early_initialized_
Definition: crypto_init.c:35
void crypto_prefork(void)
Definition: crypto_init.c:153
const char * crypto_get_header_version_string(void)
Definition: crypto_init.c:204
const char * crypto_get_library_name(void)
Definition: crypto_init.c:178
static int crypto_global_initialized_
Definition: crypto_init.c:38
int tor_is_using_nss(void)
Definition: crypto_init.c:216
Headers for crypto_init.c.
Headers for crypto_nss_mgt.c.
void crypto_openssl_early_init(void)
void crypto_openssl_thread_cleanup(void)
int crypto_openssl_late_init(int useAccel, const char *accelName, const char *accelDir)
void crypto_openssl_global_cleanup(void)
Headers for crypto_openssl_mgt.c.
Declare configuration options for the crypto_ops module.
Header for lib/crypt_ops/crypto_options_st.c.
int crypto_seed_rng(void)
Definition: crypto_rand.c:454
void crypto_rand(char *to, size_t n)
Definition: crypto_rand.c:479
Common functions for using (pseudo-)random number generators.
void destroy_thread_fast_rng(void)
void crypto_rand_fast_init(void)
void crypto_rand_fast_shutdown(void)
Declare subsystem object for the crypto module.
#define LD_BUG
Definition: log.h:86
Definition: siphash.h:6
const char * name
Definition: subsys.h:43
Types used to declare a subsystem.
#define SUBSYS_DECLARE_LOCATION()
Definition: subsys.h:211
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:103