Tor 0.4.9.2-alpha-dev
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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#include "ext/polyval/polyval.h"
30
31#include "lib/subsys/subsys.h"
32
33#include "ext/siphash.h"
34
35/** Boolean: has our crypto library been initialized? (early phase) */
37
38/** Boolean: has our crypto library been initialized? (late phase) */
40
41static int have_seeded_siphash = 0;
42
43/** Set up the siphash key if we haven't already done so. */
44int
46{
47 struct sipkey key;
48 if (have_seeded_siphash)
49 return 0;
50
51 crypto_rand((char*) &key, sizeof(key));
52 siphash_set_global_key(&key);
53 have_seeded_siphash = 1;
54 return 0;
55}
56
57/** Initialize the crypto library. Return 0 on success, -1 on failure.
58 */
59int
61{
63
65
66#ifdef ENABLE_OPENSSL
68#endif
69#ifdef ENABLE_NSS
70 crypto_nss_early_init(0);
71#endif
72
74
75 if (crypto_seed_rng() < 0)
76 return -1;
78 return -1;
79
81
83 ed25519_init();
84 }
85 return 0;
86}
87
88/** Initialize the crypto library. Return 0 on success, -1 on failure.
89 */
90int
91crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
92{
94 if (crypto_early_init() < 0)
95 return -1;
96
98
99 crypto_dh_init();
100
101#ifdef ENABLE_OPENSSL
102 if (crypto_openssl_late_init(useAccel, accelName, accelDir) < 0)
103 return -1;
104#else
105 (void)useAccel;
106 (void)accelName;
107 (void)accelDir;
108#endif /* defined(ENABLE_OPENSSL) */
109#ifdef ENABLE_NSS
110 if (crypto_nss_late_init() < 0)
111 return -1;
112#endif
113 }
114 return 0;
115}
116
117/** Free crypto resources held by this thread. */
118void
120{
121#ifdef ENABLE_OPENSSL
123#endif
125}
126
127/**
128 * Uninitialize the crypto library. Return 0 on success. Does not detect
129 * failure.
130 */
131int
133{
134 crypto_dh_free_all();
135
136#ifdef ENABLE_OPENSSL
138#endif
139#ifdef ENABLE_NSS
140 crypto_nss_global_cleanup();
141#endif
142
144
147 have_seeded_siphash = 0;
148 siphash_unset_global_key();
149
150 return 0;
151}
152
153/** Run operations that the crypto library requires to be happy again
154 * after forking. */
155void
157{
158#ifdef ENABLE_NSS
159 crypto_nss_prefork();
160#endif
161 /* It is not safe to share a fast_rng object across a fork boundary unless
162 * we actually have zero-on-fork support in map_anon.c. If we have
163 * drop-on-fork support, we will crash; if we have neither, we will yield
164 * a copy of the parent process's rng, which is scary and insecure.
165 */
167}
168
169/** Run operations that the crypto library requires to be happy again
170 * after forking. */
171void
173{
174#ifdef ENABLE_NSS
175 crypto_nss_postfork();
176#endif
177}
178
179/** Return the name of the crypto library we're using. */
180const char *
182{
183#ifdef ENABLE_OPENSSL
184 return "OpenSSL";
185#endif
186#ifdef ENABLE_NSS
187 return "NSS";
188#endif
189}
190
191/** Return the version of the crypto library we are using, as given in the
192 * library. */
193const char *
195{
196#ifdef ENABLE_OPENSSL
197 return crypto_openssl_get_version_str();
198#endif
199#ifdef ENABLE_NSS
200 return crypto_nss_get_version_str();
201#endif
202}
203
204/** Return the version of the crypto library we're using, as given in the
205 * headers. */
206const char *
208{
209#ifdef ENABLE_OPENSSL
210 return crypto_openssl_get_header_version_str();
211#endif
212#ifdef ENABLE_NSS
213 return crypto_nss_get_header_version_str();
214#endif
215}
216
217/** Return true iff Tor is using the NSS library. */
218int
220{
221#ifdef ENABLE_NSS
222 return 1;
223#else
224 return 0;
225#endif
226}
227
228static int
229subsys_crypto_initialize(void)
230{
231 if (crypto_early_init() < 0)
232 return -1;
233 crypto_dh_init();
234 return 0;
235}
236
237static void
238subsys_crypto_shutdown(void)
239{
241}
242
243static void
244subsys_crypto_prefork(void)
245{
247}
248
249static void
250subsys_crypto_postfork(void)
251{
253}
254
255static void
256subsys_crypto_thread_cleanup(void)
257{
259}
260
261/** Magic number for crypto_options_t. */
262#define CRYPTO_OPTIONS_MAGIC 0x68757368
263
264/**
265 * Return 0 if <b>arg</b> is a valid crypto_options_t. Otherwise return -1
266 * and set *<b>msg_out</b> to a freshly allocated error string.
267 **/
268static int
269crypto_options_validate(const void *arg, char **msg_out)
270{
271 const crypto_options_t *opt = arg;
272 tor_assert(opt->magic == CRYPTO_OPTIONS_MAGIC);
273 tor_assert(msg_out);
274
275 if (opt->AccelDir && !opt->AccelName) {
276 *msg_out = tor_strdup("Can't use hardware crypto accelerator dir "
277 "without engine name.");
278 return -1;
279 }
280
281 return 0;
282}
283
284/* Declare the options field table for crypto_options */
285#define CONF_CONTEXT LL_TABLE
287#undef CONF_CONTEXT
288
289/**
290 * Declares the configuration options for this module.
291 **/
293 .size = sizeof(crypto_options_t),
294 .magic = { "crypto_options_t",
296 offsetof(crypto_options_t, magic) },
297 .vars = crypto_options_t_vars,
298 .validate_fn = crypto_options_validate,
299};
300
301/**
302 * Invoked from subsysmgr.c when a new set of options arrives.
303 **/
304static int
306{
307 const crypto_options_t *options = arg;
308 const bool hardware_accel = options->HardwareAccel || options->AccelName;
309
310 // This call already checks for crypto_global_initialized_, so it
311 // will only initialize the subsystem the first time it's called.
312 if (crypto_global_init(hardware_accel,
313 options->AccelName,
314 options->AccelDir)) {
315 log_err(LD_BUG, "Unable to initialize the crypto subsystem. Exiting.");
316 return -1;
317 }
318 return 0;
319}
320
321const struct subsys_fns_t sys_crypto = {
322 .name = "crypto",
324 .supported = true,
325 .level = -60,
326 .initialize = subsys_crypto_initialize,
327 .shutdown = subsys_crypto_shutdown,
328 .prefork = subsys_crypto_prefork,
329 .postfork = subsys_crypto_postfork,
330 .thread_cleanup = subsys_crypto_thread_cleanup,
331
332 .options_format = &crypto_options_fmt,
333 .set_options = crypto_set_options,
334};
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:132
static int crypto_options_validate(const void *arg, char **msg_out)
Definition: crypto_init.c:269
void crypto_postfork(void)
Definition: crypto_init.c:172
int crypto_init_siphash_key(void)
Definition: crypto_init.c:45
#define CRYPTO_OPTIONS_MAGIC
Definition: crypto_init.c:262
const char * crypto_get_library_version_string(void)
Definition: crypto_init.c:194
int crypto_early_init(void)
Definition: crypto_init.c:60
void crypto_thread_cleanup(void)
Definition: crypto_init.c:119
int crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
Definition: crypto_init.c:91
static const config_format_t crypto_options_fmt
Definition: crypto_init.c:292
static int crypto_set_options(void *arg)
Definition: crypto_init.c:305
static int crypto_early_initialized_
Definition: crypto_init.c:36
void crypto_prefork(void)
Definition: crypto_init.c:156
const char * crypto_get_header_version_string(void)
Definition: crypto_init.c:207
const char * crypto_get_library_name(void)
Definition: crypto_init.c:181
static int crypto_global_initialized_
Definition: crypto_init.c:39
int tor_is_using_nss(void)
Definition: crypto_init.c:219
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
Implementation for polyval universal hash function.
void polyval_detect_implementation(void)
Definition: polyval.c:444
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