crypto_init.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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-2018, 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. #include "lib/crypt_ops/crypto_init.h"
  13. #include "lib/crypt_ops/crypto_curve25519.h"
  14. #include "lib/crypt_ops/crypto_dh.h"
  15. #include "lib/crypt_ops/crypto_ed25519.h"
  16. #include "lib/crypt_ops/crypto_openssl_mgt.h"
  17. #include "lib/crypt_ops/crypto_rand.h"
  18. #include "siphash.h"
  19. /** Boolean: has OpenSSL's crypto been initialized? */
  20. static int crypto_early_initialized_ = 0;
  21. /** Boolean: has OpenSSL's crypto been initialized? */
  22. static int crypto_global_initialized_ = 0;
  23. static int have_seeded_siphash = 0;
  24. /** Set up the siphash key if we haven't already done so. */
  25. int
  26. crypto_init_siphash_key(void)
  27. {
  28. struct sipkey key;
  29. if (have_seeded_siphash)
  30. return 0;
  31. crypto_rand((char*) &key, sizeof(key));
  32. siphash_set_global_key(&key);
  33. have_seeded_siphash = 1;
  34. return 0;
  35. }
  36. /** Initialize the crypto library. Return 0 on success, -1 on failure.
  37. */
  38. int
  39. crypto_early_init(void)
  40. {
  41. if (!crypto_early_initialized_) {
  42. crypto_early_initialized_ = 1;
  43. #ifdef ENABLE_OPENSSL
  44. crypto_openssl_early_init();
  45. #endif
  46. if (crypto_seed_rng() < 0)
  47. return -1;
  48. if (crypto_init_siphash_key() < 0)
  49. return -1;
  50. curve25519_init();
  51. ed25519_init();
  52. }
  53. return 0;
  54. }
  55. /** Initialize the crypto library. Return 0 on success, -1 on failure.
  56. */
  57. int
  58. crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
  59. {
  60. if (!crypto_global_initialized_) {
  61. if (crypto_early_init() < 0)
  62. return -1;
  63. crypto_global_initialized_ = 1;
  64. #ifdef ENABLE_OPENSSL
  65. return crypto_openssl_late_init(useAccel, accelName, accelDir);
  66. #endif
  67. }
  68. return 0;
  69. }
  70. /** Free crypto resources held by this thread. */
  71. void
  72. crypto_thread_cleanup(void)
  73. {
  74. #ifndef NEW_THREAD_API
  75. ERR_remove_thread_state(NULL);
  76. #endif
  77. }
  78. /**
  79. * Uninitialize the crypto library. Return 0 on success. Does not detect
  80. * failure.
  81. */
  82. int
  83. crypto_global_cleanup(void)
  84. {
  85. crypto_dh_free_all();
  86. #ifdef ENABLE_OPENSSL
  87. crypto_openssl_global_cleanup();
  88. #endif
  89. crypto_early_initialized_ = 0;
  90. crypto_global_initialized_ = 0;
  91. have_seeded_siphash = 0;
  92. siphash_unset_global_key();
  93. return 0;
  94. }