summaryrefslogtreecommitdiff
path: root/src/lib/crypt_ops/crypto_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/crypt_ops/crypto_init.c')
-rw-r--r--src/lib/crypt_ops/crypto_init.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/lib/crypt_ops/crypto_init.c b/src/lib/crypt_ops/crypto_init.c
new file mode 100644
index 0000000000..c731662d49
--- /dev/null
+++ b/src/lib/crypt_ops/crypto_init.c
@@ -0,0 +1,193 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file crypto_init.c
+ *
+ * \brief Initialize and shut down Tor's crypto library and subsystem.
+ **/
+
+#include "orconfig.h"
+
+#include "lib/crypt_ops/crypto_init.h"
+
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_dh.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_openssl_mgt.h"
+#include "lib/crypt_ops/crypto_nss_mgt.h"
+#include "lib/crypt_ops/crypto_rand.h"
+
+#include "siphash.h"
+
+/** Boolean: has our crypto library been initialized? (early phase) */
+static int crypto_early_initialized_ = 0;
+
+/** Boolean: has our crypto library been initialized? (late phase) */
+static int crypto_global_initialized_ = 0;
+
+static int have_seeded_siphash = 0;
+
+/** Set up the siphash key if we haven't already done so. */
+int
+crypto_init_siphash_key(void)
+{
+ struct sipkey key;
+ if (have_seeded_siphash)
+ return 0;
+
+ crypto_rand((char*) &key, sizeof(key));
+ siphash_set_global_key(&key);
+ have_seeded_siphash = 1;
+ return 0;
+}
+
+/** Initialize the crypto library. Return 0 on success, -1 on failure.
+ */
+int
+crypto_early_init(void)
+{
+ if (!crypto_early_initialized_) {
+
+ crypto_early_initialized_ = 1;
+
+#ifdef ENABLE_OPENSSL
+ crypto_openssl_early_init();
+#endif
+#ifdef ENABLE_NSS
+ crypto_nss_early_init(0);
+#endif
+
+ if (crypto_seed_rng() < 0)
+ return -1;
+ if (crypto_init_siphash_key() < 0)
+ return -1;
+
+ curve25519_init();
+ ed25519_init();
+ }
+ return 0;
+}
+
+/** Initialize the crypto library. Return 0 on success, -1 on failure.
+ */
+int
+crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
+{
+ if (!crypto_global_initialized_) {
+ if (crypto_early_init() < 0)
+ return -1;
+
+ crypto_global_initialized_ = 1;
+
+ crypto_dh_init();
+
+#ifdef ENABLE_OPENSSL
+ if (crypto_openssl_late_init(useAccel, accelName, accelDir) < 0)
+ return -1;
+#else
+ (void)useAccel;
+ (void)accelName;
+ (void)accelDir;
+#endif
+#ifdef ENABLE_NSS
+ if (crypto_nss_late_init() < 0)
+ return -1;
+#endif
+ }
+ return 0;
+}
+
+/** Free crypto resources held by this thread. */
+void
+crypto_thread_cleanup(void)
+{
+#ifdef ENABLE_OPENSSL
+ crypto_openssl_thread_cleanup();
+#endif
+}
+
+/**
+ * Uninitialize the crypto library. Return 0 on success. Does not detect
+ * failure.
+ */
+int
+crypto_global_cleanup(void)
+{
+ crypto_dh_free_all();
+
+#ifdef ENABLE_OPENSSL
+ crypto_openssl_global_cleanup();
+#endif
+#ifdef ENABLE_NSS
+ crypto_nss_global_cleanup();
+#endif
+
+ crypto_early_initialized_ = 0;
+ crypto_global_initialized_ = 0;
+ have_seeded_siphash = 0;
+ siphash_unset_global_key();
+
+ return 0;
+}
+
+/** Run operations that the crypto library requires to be happy again
+ * after forking. */
+void
+crypto_prefork(void)
+{
+#ifdef ENABLE_NSS
+ crypto_nss_prefork();
+#endif
+}
+
+/** Run operations that the crypto library requires to be happy again
+ * after forking. */
+void
+crypto_postfork(void)
+{
+#ifdef ENABLE_NSS
+ crypto_nss_postfork();
+#endif
+}
+
+/** Return the name of the crypto library we're using. */
+const char *
+crypto_get_library_name(void)
+{
+#ifdef ENABLE_OPENSSL
+ return "OpenSSL";
+#endif
+#ifdef ENABLE_NSS
+ return "NSS";
+#endif
+}
+
+/** Return the version of the crypto library we are using, as given in the
+ * library. */
+const char *
+crypto_get_library_version_string(void)
+{
+#ifdef ENABLE_OPENSSL
+ return crypto_openssl_get_version_str();
+#endif
+#ifdef ENABLE_NSS
+ return crypto_nss_get_version_str();
+#endif
+}
+
+/** Return the version of the crypto library we're using, as given in the
+ * headers. */
+const char *
+crypto_get_header_version_string(void)
+{
+#ifdef ENABLE_OPENSSL
+ return crypto_openssl_get_header_version_str();
+#endif
+#ifdef ENABLE_NSS
+ return crypto_nss_get_header_version_str();
+#endif
+}