Tor  0.4.7.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 
40 static int have_seeded_siphash = 0;
41 
42 /** Set up the siphash key if we haven't already done so. */
43 int
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  */
58 int
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;
74  if (crypto_init_siphash_key() < 0)
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  */
87 int
88 crypto_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. */
115 void
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  */
128 int
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. */
152 void
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. */
168 void
170 {
171 #ifdef ENABLE_NSS
172  crypto_nss_postfork();
173 #endif
174 }
175 
176 /** Return the name of the crypto library we're using. */
177 const 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. */
190 const 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. */
203 const 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. */
215 int
217 {
218 #ifdef ENABLE_NSS
219  return 1;
220 #else
221  return 0;
222 #endif
223 }
224 
225 static int
226 subsys_crypto_initialize(void)
227 {
228  if (crypto_early_init() < 0)
229  return -1;
230  crypto_dh_init();
231  return 0;
232 }
233 
234 static void
235 subsys_crypto_shutdown(void)
236 {
238 }
239 
240 static void
241 subsys_crypto_prefork(void)
242 {
243  crypto_prefork();
244 }
245 
246 static void
247 subsys_crypto_postfork(void)
248 {
249  crypto_postfork();
250 }
251 
252 static void
253 subsys_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  **/
265 static int
266 crypto_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  **/
301 static 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 
318 const 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.
const char * crypto_get_library_name(void)
Definition: crypto_init.c:178
int crypto_global_cleanup(void)
Definition: crypto_init.c:129
const char * crypto_get_library_version_string(void)
Definition: crypto_init.c:191
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
int crypto_early_init(void)
Definition: crypto_init.c:59
const char * crypto_get_header_version_string(void)
Definition: crypto_init.c:204
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
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:452
void crypto_rand(char *to, size_t n)
Definition: crypto_rand.c:477
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:102