#include <internal/cryptlib_int.h>
#include <openssl/err.h>
+#include <openssl/rand.h>
#include <openssl/evp.h>
#include <internal/evp_int.h>
#include <internal/conf.h>
#include <internal/async.h>
+#ifndef OPENSSL_NO_ENGINE
#include <internal/engine.h>
+#endif
#include <openssl/comp.h>
#include <internal/err.h>
#include <stdlib.h>
+#include <assert.h>
+
+static int stopped = 0;
static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
#if !defined(OPENSSL_THREADS)
typedef int OPENSSL_INIT_ONCE;
# define OPENSSL_INIT_ONCE_STATIC_INIT 0
-# define OPENSSL_INIT_ONCE_DYNAMIC_INIT(once) (*(once) = 0)
static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void))
{
static struct thread_local_inits_st *local = NULL;
static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
{
- static struct thread_local_inits_st *tmp;
+ struct thread_local_inits_st *tmp;
tmp = local;
*/
typedef LONG OPENSSL_INIT_ONCE;
# define OPENSSL_INIT_ONCE_STATIC_INIT 0
-# define OPENSSL_INIT_ONCE_DYNAMIC_INIT(once) (*(once) = 0)
# define ONCE_UNINITED 0
# define ONCE_ININIT 1
typedef INIT_ONCE OPENSSL_INIT_ONCE;
# define OPENSSL_INIT_ONCE_STATIC_INIT INIT_ONCE_STATIC_INIT
-# define OPENSSL_INIT_ONCE_DYNAMIC_INIT(once) \
- InitOnceInitialize((PINIT_ONCE)(once))
static BOOL CALLBACK once_cb(PINIT_ONCE once, PVOID initfp, PVOID *unused)
{
typedef pthread_once_t OPENSSL_INIT_ONCE;
# define OPENSSL_INIT_ONCE_STATIC_INIT PTHREAD_ONCE_INIT
-# define OPENSSL_INIT_ONCE_DYNAMIC_INIT(once) (*(once) = PTHREAD_ONCE_INIT)
static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void))
{
#endif
+typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
struct ossl_init_stop_st {
void (*handler)(void);
OPENSSL_INIT_STOP *next;
fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
#endif
ossl_init_setup_thread_stop();
- atexit(OPENSSL_INIT_library_stop);
+#ifndef OPENSSL_SYS_UEFI
+ atexit(OPENSSL_cleanup);
+#endif
OPENSSL_cpuid_setup();
base_inited = 1;
}
config_inited = 1;
}
+#ifndef OPENSSL_NO_ASYNC
static OPENSSL_INIT_ONCE async = OPENSSL_INIT_ONCE_STATIC_INIT;
static int async_inited = 0;
static void ossl_init_async(void)
async_init();
async_inited = 1;
}
+#endif
#ifndef OPENSSL_NO_ENGINE
static int engine_inited = 0;
if (locals == NULL)
return;
+#ifndef OPENSSL_NO_ASYNC
if (locals->async) {
#ifdef OPENSSL_INIT_DEBUG
fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
#endif
ASYNC_cleanup_thread();
}
+#endif
if (locals->err_state) {
#ifdef OPENSSL_INIT_DEBUG
}
OPENSSL_free(locals);
- ossl_init_thread_stop_cleanup();
}
-void OPENSSL_INIT_thread_stop(void)
+void OPENSSL_thread_stop(void)
{
ossl_init_thread_stop(
(struct thread_local_inits_st *)ossl_init_get_thread_local(0));
return 1;
}
-void OPENSSL_INIT_library_stop(void)
+void OPENSSL_cleanup(void)
{
OPENSSL_INIT_STOP *currhandler, *lasthandler;
+ /* If we've not been inited then no need to deinit */
+ if (!base_inited)
+ return;
+
+ /* Might be explicitly called and also by atexit */
+ if (stopped)
+ return;
+ stopped = 1;
+
/*
* Thread stop may not get automatically called by the thread library for
* the very last thread in some situations, so call it directly.
if (zlib_inited) {
#ifdef OPENSSL_INIT_DEBUG
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
"COMP_zlib_cleanup()\n");
#endif
COMP_zlib_cleanup();
- zlib_inited = 0;
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&zlib);
}
+#ifndef OPENSSL_NO_ASYNC
+ if (async_inited) {
+# ifdef OPENSSL_INIT_DEBUG
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+ "async_deinit()\n");
+# endif
+ async_deinit();
+ }
+#endif
+
#ifndef OPENSSL_NO_ENGINE
if (engine_inited) {
# ifdef OPENSSL_INIT_DEBUG
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
"ENGINE_cleanup()\n");
# endif
ENGINE_cleanup();
- engine_inited = 0;
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_openssl);
-# if !defined(OPENSSL_NO_HW) && \
- (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_cryptodev);
-# endif
-# ifndef OPENSSL_NO_RDRAND
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_rdrand);
-# endif
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_dynamic);
-# ifndef OPENSSL_NO_STATIC_ENGINE
-# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_padlock);
-# endif
-# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_capi);
-# endif
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_dasync);
-# endif
}
#endif
- async_inited = 0;
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&async);
-
- config_inited = 0;
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&config);
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&add_all_ciphers);
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&add_all_digests);
-
if (load_crypto_strings_inited) {
#ifdef OPENSSL_INIT_DEBUG
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
"ERR_free_strings()\n");
#endif
ERR_free_strings();
- load_crypto_strings_inited = 0;
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&load_crypto_strings);
}
- if (base_inited) {
+ ossl_init_thread_stop_cleanup();
+
#ifdef OPENSSL_INIT_DEBUG
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
- "CRYPTO_cleanup_all_ex_data()\n");
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
- "EVP_cleanup()\n");
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
- "CONF_modules_free()\n");
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
- "RAND_cleanup()\n");
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
+ "CRYPTO_cleanup_all_ex_data()\n");
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
+ "EVP_cleanup()\n");
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
+ "CONF_modules_free()\n");
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
+ "RAND_cleanup()\n");
#endif
- CRYPTO_cleanup_all_ex_data();
- EVP_cleanup();
- CONF_modules_free();
- RAND_cleanup();
- base_inited = 0;
- OPENSSL_INIT_ONCE_DYNAMIC_INIT(&base);
- }
-}
-
-static const OPENSSL_INIT_SETTINGS *ossl_init_get_setting(
- const OPENSSL_INIT_SETTINGS *settings, int name)
-{
- if (settings == NULL)
- return NULL;
-
- while (settings->name != OPENSSL_INIT_SET_END) {
- if (settings->name == name)
- return settings;
- settings++;
- }
-
- return NULL;
+ CRYPTO_cleanup_all_ex_data();
+ EVP_cleanup();
+ CONF_modules_free();
+ RAND_cleanup();
+ base_inited = 0;
}
/*
* called prior to any threads making calls to any OpenSSL functions,
* i.e. passing a non-null settings value is assumed to be single-threaded.
*/
-void OPENSSL_INIT_crypto_library_start(uint64_t opts,
- const OPENSSL_INIT_SETTINGS *settings)
-{
+int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
+{
+ static int stoperrset = 0;
+
+ if (stopped) {
+ if (!stoperrset) {
+ /*
+ * We only ever set this once to avoid getting into an infinite
+ * loop where the error system keeps trying to init and fails so
+ * sets an error etc
+ */
+ stoperrset = 1;
+ CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
+ }
+ return 0;
+ }
+
ossl_init_once_run(&base, ossl_init_base);
if (opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
if (opts & OPENSSL_INIT_LOAD_CONFIG) {
CRYPTO_w_lock(CRYPTO_LOCK_INIT);
- if (settings != NULL) {
- const OPENSSL_INIT_SETTINGS *curr;
- curr = ossl_init_get_setting(settings,
- OPENSSL_INIT_SET_CONF_FILENAME);
- config_filename = (curr == NULL) ? NULL : curr->value.type_string;
- } else {
- config_filename = NULL;
- }
+ config_filename = (settings == NULL) ? NULL : settings->config_name;
ossl_init_once_run(&config, ossl_init_config);
CRYPTO_w_unlock(CRYPTO_LOCK_INIT);
}
+#ifndef OPENSSL_NO_ASYNC
if (opts & OPENSSL_INIT_ASYNC) {
ossl_init_once_run(&async, ossl_init_async);
}
-
+#endif
#ifndef OPENSSL_NO_ENGINE
if (opts & OPENSSL_INIT_ENGINE_OPENSSL) {
ossl_init_once_run(&engine_openssl, ossl_init_engine_openssl);
if (opts & OPENSSL_INIT_ZLIB) {
ossl_init_once_run(&zlib, ossl_init_zlib);
}
+
+ return 1;
}
-int OPENSSL_INIT_register_stop_handler(void (*handler)(void))
+int OPENSSL_atexit(void (*handler)(void))
{
OPENSSL_INIT_STOP *newhand;