crypto_init.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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-2019, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file crypto_init.c
  8. *
  9. * \brief Initialize and shut down Tor's crypto library and subsystem.
  10. **/
  11. #include "orconfig.h"
  12. #define CRYPTO_PRIVATE
  13. #include "lib/crypt_ops/crypto_init.h"
  14. #include "lib/crypt_ops/crypto_curve25519.h"
  15. #include "lib/crypt_ops/crypto_dh.h"
  16. #include "lib/crypt_ops/crypto_ed25519.h"
  17. #include "lib/crypt_ops/crypto_openssl_mgt.h"
  18. #include "lib/crypt_ops/crypto_nss_mgt.h"
  19. #include "lib/crypt_ops/crypto_rand.h"
  20. #include "lib/crypt_ops/crypto_sys.h"
  21. #include "lib/subsys/subsys.h"
  22. #include "ext/siphash.h"
  23. /** Boolean: has our crypto library been initialized? (early phase) */
  24. static int crypto_early_initialized_ = 0;
  25. /** Boolean: has our crypto library been initialized? (late phase) */
  26. static int crypto_global_initialized_ = 0;
  27. static int have_seeded_siphash = 0;
  28. /** Set up the siphash key if we haven't already done so. */
  29. int
  30. crypto_init_siphash_key(void)
  31. {
  32. struct sipkey key;
  33. if (have_seeded_siphash)
  34. return 0;
  35. crypto_rand((char*) &key, sizeof(key));
  36. siphash_set_global_key(&key);
  37. have_seeded_siphash = 1;
  38. return 0;
  39. }
  40. /** Initialize the crypto library. Return 0 on success, -1 on failure.
  41. */
  42. int
  43. crypto_early_init(void)
  44. {
  45. if (!crypto_early_initialized_) {
  46. crypto_early_initialized_ = 1;
  47. #ifdef ENABLE_OPENSSL
  48. crypto_openssl_early_init();
  49. #endif
  50. #ifdef ENABLE_NSS
  51. crypto_nss_early_init(0);
  52. #endif
  53. if (crypto_seed_rng() < 0)
  54. return -1;
  55. if (crypto_init_siphash_key() < 0)
  56. return -1;
  57. crypto_rand_fast_init();
  58. curve25519_init();
  59. ed25519_init();
  60. }
  61. return 0;
  62. }
  63. /** Initialize the crypto library. Return 0 on success, -1 on failure.
  64. */
  65. int
  66. crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
  67. {
  68. if (!crypto_global_initialized_) {
  69. if (crypto_early_init() < 0)
  70. return -1;
  71. crypto_global_initialized_ = 1;
  72. crypto_dh_init();
  73. #ifdef ENABLE_OPENSSL
  74. if (crypto_openssl_late_init(useAccel, accelName, accelDir) < 0)
  75. return -1;
  76. #else
  77. (void)useAccel;
  78. (void)accelName;
  79. (void)accelDir;
  80. #endif /* defined(ENABLE_OPENSSL) */
  81. #ifdef ENABLE_NSS
  82. if (crypto_nss_late_init() < 0)
  83. return -1;
  84. #endif
  85. }
  86. return 0;
  87. }
  88. /** Free crypto resources held by this thread. */
  89. void
  90. crypto_thread_cleanup(void)
  91. {
  92. #ifdef ENABLE_OPENSSL
  93. crypto_openssl_thread_cleanup();
  94. #endif
  95. destroy_thread_fast_rng();
  96. }
  97. /**
  98. * Uninitialize the crypto library. Return 0 on success. Does not detect
  99. * failure.
  100. */
  101. int
  102. crypto_global_cleanup(void)
  103. {
  104. crypto_dh_free_all();
  105. #ifdef ENABLE_OPENSSL
  106. crypto_openssl_global_cleanup();
  107. #endif
  108. #ifdef ENABLE_NSS
  109. crypto_nss_global_cleanup();
  110. #endif
  111. crypto_rand_fast_shutdown();
  112. crypto_early_initialized_ = 0;
  113. crypto_global_initialized_ = 0;
  114. have_seeded_siphash = 0;
  115. siphash_unset_global_key();
  116. return 0;
  117. }
  118. /** Run operations that the crypto library requires to be happy again
  119. * after forking. */
  120. void
  121. crypto_prefork(void)
  122. {
  123. #ifdef ENABLE_NSS
  124. crypto_nss_prefork();
  125. #endif
  126. /* It is not safe to share a fast_rng object across a fork boundary unless
  127. * we actually have zero-on-fork support in map_anon.c. If we have
  128. * drop-on-fork support, we will crash; if we have neither, we will yield
  129. * a copy of the parent process's rng, which is scary and insecure.
  130. */
  131. destroy_thread_fast_rng();
  132. }
  133. /** Run operations that the crypto library requires to be happy again
  134. * after forking. */
  135. void
  136. crypto_postfork(void)
  137. {
  138. #ifdef ENABLE_NSS
  139. crypto_nss_postfork();
  140. #endif
  141. }
  142. /** Return the name of the crypto library we're using. */
  143. const char *
  144. crypto_get_library_name(void)
  145. {
  146. #ifdef ENABLE_OPENSSL
  147. return "OpenSSL";
  148. #endif
  149. #ifdef ENABLE_NSS
  150. return "NSS";
  151. #endif
  152. }
  153. /** Return the version of the crypto library we are using, as given in the
  154. * library. */
  155. const char *
  156. crypto_get_library_version_string(void)
  157. {
  158. #ifdef ENABLE_OPENSSL
  159. return crypto_openssl_get_version_str();
  160. #endif
  161. #ifdef ENABLE_NSS
  162. return crypto_nss_get_version_str();
  163. #endif
  164. }
  165. /** Return the version of the crypto library we're using, as given in the
  166. * headers. */
  167. const char *
  168. crypto_get_header_version_string(void)
  169. {
  170. #ifdef ENABLE_OPENSSL
  171. return crypto_openssl_get_header_version_str();
  172. #endif
  173. #ifdef ENABLE_NSS
  174. return crypto_nss_get_header_version_str();
  175. #endif
  176. }
  177. /** Return true iff Tor is using the NSS library. */
  178. int
  179. tor_is_using_nss(void)
  180. {
  181. #ifdef ENABLE_NSS
  182. return 1;
  183. #else
  184. return 0;
  185. #endif
  186. }
  187. static int
  188. subsys_crypto_initialize(void)
  189. {
  190. if (crypto_early_init() < 0)
  191. return -1;
  192. crypto_dh_init();
  193. return 0;
  194. }
  195. static void
  196. subsys_crypto_shutdown(void)
  197. {
  198. crypto_global_cleanup();
  199. }
  200. static void
  201. subsys_crypto_prefork(void)
  202. {
  203. crypto_prefork();
  204. }
  205. static void
  206. subsys_crypto_postfork(void)
  207. {
  208. crypto_postfork();
  209. }
  210. static void
  211. subsys_crypto_thread_cleanup(void)
  212. {
  213. crypto_thread_cleanup();
  214. }
  215. const struct subsys_fns_t sys_crypto = {
  216. .name = "crypto",
  217. .supported = true,
  218. .level = -60,
  219. .initialize = subsys_crypto_initialize,
  220. .shutdown = subsys_crypto_shutdown,
  221. .prefork = subsys_crypto_prefork,
  222. .postfork = subsys_crypto_postfork,
  223. .thread_cleanup = subsys_crypto_thread_cleanup,
  224. };