diff options
author | Matt Caswell <matt@openssl.org> | 2016-02-08 16:43:03 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-02-09 15:11:38 +0000 |
commit | 7b9f8f7f03eda2faa1cdd42ed29a0b70e60eaf59 (patch) | |
tree | 30f805756265bd1d016aead84dcf1c909cca8b4b | |
parent | b184e3ef73200cb3b7914a603b43a5b8a074c85f (diff) |
Auto init/deinit libcrypto
This builds on the previous commit to auto initialise/deinitialise
libcrypto.
Reviewed-by: Richard Levitte <levitte@openssl.org>
45 files changed, 422 insertions, 347 deletions
diff --git a/apps/s_client.c b/apps/s_client.c index 8fe16121a9..c122c1a613 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -1504,7 +1504,6 @@ int s_client_main(int argc, char **argv) if (async) { SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC); - ASYNC_init(1, 0, 0); } if (!config_ctx(cctx, ssl_args, ctx, jpake_secret == NULL)) @@ -2420,9 +2419,6 @@ int s_client_main(int argc, char **argv) print_stuff(bio_c_out, con, 1); SSL_free(con); } - if (async) { - ASYNC_cleanup(1); - } #if !defined(OPENSSL_NO_NEXTPROTONEG) OPENSSL_free(next_proto.data); #endif diff --git a/apps/s_server.c b/apps/s_server.c index f07c8f61a9..368558637d 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -1721,7 +1721,6 @@ int s_server_main(int argc, char *argv[]) if (async) { SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC); - ASYNC_init(1, 0, 0); } #ifndef OPENSSL_NO_SRTP @@ -2026,9 +2025,6 @@ int s_server_main(int argc, char *argv[]) bio_s_out = NULL; BIO_free(bio_s_msg); bio_s_msg = NULL; - if (async) { - ASYNC_cleanup(1); - } return (ret); } diff --git a/crypto/async/arch/async_null.c b/crypto/async/arch/async_null.c index d3f686f492..2b1d28eaf3 100644 --- a/crypto/async/arch/async_null.c +++ b/crypto/async/arch/async_null.c @@ -80,11 +80,6 @@ int async_global_init(void) return 0; } -int async_local_init(void) -{ - return 0; -} - void async_local_cleanup(void) { } diff --git a/crypto/async/arch/async_null.h b/crypto/async/arch/async_null.h index 93887aec19..4cd0a8b966 100644 --- a/crypto/async/arch/async_null.h +++ b/crypto/async/arch/async_null.h @@ -66,7 +66,7 @@ typedef struct async_fibre_st { # define async_set_ctx(nctx) 0 -# define async_get_ctx() ((async_ctx *)NULL) +# define async_arch_get_ctx() ((async_ctx *)NULL) # define async_fibre_swapcontext(o,n,r) 0 # define async_fibre_makecontext(c) 0 # define async_fibre_free(f) diff --git a/crypto/async/arch/async_posix.c b/crypto/async/arch/async_posix.c index 1df77cccbe..57cce7b4c4 100644 --- a/crypto/async/arch/async_posix.c +++ b/crypto/async/arch/async_posix.c @@ -72,14 +72,6 @@ int async_global_init(void) return 1; } -int async_local_init(void) -{ - if (!async_set_ctx(NULL) || ! async_set_pool(NULL)) - return 0; - - return 1; -} - void async_local_cleanup(void) { } diff --git a/crypto/async/arch/async_posix.h b/crypto/async/arch/async_posix.h index 85d033f851..7f1bdd1cc5 100644 --- a/crypto/async/arch/async_posix.h +++ b/crypto/async/arch/async_posix.h @@ -78,7 +78,7 @@ typedef struct async_fibre_st { } async_fibre; # define async_set_ctx(nctx) (pthread_setspecific(posixctx , (nctx)) == 0) -# define async_get_ctx() ((async_ctx *)pthread_getspecific(posixctx)) +# define async_arch_get_ctx() ((async_ctx *)pthread_getspecific(posixctx)) # define async_set_pool(p) (pthread_setspecific(posixpool , (p)) == 0) # define async_get_pool() ((async_pool *)pthread_getspecific(posixpool)) diff --git a/crypto/async/arch/async_win.c b/crypto/async/arch/async_win.c index f3de79a73b..3f3a005cc2 100644 --- a/crypto/async/arch/async_win.c +++ b/crypto/async/arch/async_win.c @@ -66,7 +66,6 @@ struct winpool { static DWORD asyncwinpool = 0; static DWORD asyncwinctx = 0; -static DWORD asyncwindispatch = 0; void async_start_func(void); @@ -75,33 +74,22 @@ int async_global_init(void) { asyncwinpool = TlsAlloc(); asyncwinctx = TlsAlloc(); - asyncwindispatch = TlsAlloc(); - if (asyncwinpool == TLS_OUT_OF_INDEXES || asyncwinctx == TLS_OUT_OF_INDEXES - || asyncwindispatch == TLS_OUT_OF_INDEXES) { + if (asyncwinpool == TLS_OUT_OF_INDEXES + || asyncwinctx == TLS_OUT_OF_INDEXES) { if (asyncwinpool != TLS_OUT_OF_INDEXES) { TlsFree(asyncwinpool); } if (asyncwinctx != TLS_OUT_OF_INDEXES) { TlsFree(asyncwinctx); } - if (asyncwindispatch != TLS_OUT_OF_INDEXES) { - TlsFree(asyncwindispatch); - } return 0; } return 1; } -int async_local_init(void) -{ - return (TlsSetValue(asyncwinpool, NULL) != 0) - && (TlsSetValue(asyncwinctx, NULL) != 0) - && (TlsSetValue(asyncwindispatch, NULL) != 0); -} - void async_local_cleanup(void) { - async_ctx *ctx = async_get_ctx(); + async_ctx *ctx = async_arch_get_ctx(); if (ctx != NULL) { async_fibre *fibre = &ctx->dispatcher; if(fibre != NULL && fibre->fibre != NULL && fibre->converted) { @@ -115,32 +103,24 @@ void async_global_cleanup(void) { TlsFree(asyncwinpool); TlsFree(asyncwinctx); - TlsFree(asyncwindispatch); asyncwinpool = 0; asyncwinctx = 0; - asyncwindispatch = 0; } int async_fibre_init_dispatcher(async_fibre *fibre) { LPVOID dispatcher; - dispatcher = (LPVOID)TlsGetValue(asyncwindispatch); - if (dispatcher == NULL) { - fibre->fibre = ConvertThreadToFiber(NULL); - if (fibre->fibre == NULL) { - fibre->converted = 0; - fibre->fibre = GetCurrentFiber(); - if (fibre->fibre == NULL) - return 0; - } else { - fibre->converted = 1; - } - if (TlsSetValue(asyncwindispatch, (LPVOID)fibre->fibre) == 0) + fibre->fibre = ConvertThreadToFiber(NULL); + if (fibre->fibre == NULL) { + fibre->converted = 0; + fibre->fibre = GetCurrentFiber(); + if (fibre->fibre == NULL) return 0; } else { - fibre->fibre = dispatcher; + fibre->converted = 1; } + return 1; } @@ -196,7 +176,7 @@ int async_set_pool(async_pool *pool) return TlsSetValue(asyncwinpool, (LPVOID)pool) != 0; } -async_ctx *async_get_ctx(void) +async_ctx *async_arch_get_ctx(void) { return (async_ctx *)TlsGetValue(asyncwinctx); } diff --git a/crypto/async/arch/async_win.h b/crypto/async/arch/async_win.h index fa345cb1f7..87e30a4f6e 100644 --- a/crypto/async/arch/async_win.h +++ b/crypto/async/arch/async_win.h @@ -73,7 +73,7 @@ typedef struct async_fibre_st { ((c)->fibre = CreateFiber(0, async_start_func_win, 0)) # define async_fibre_free(f) (DeleteFiber((f)->fibre)) -async_ctx *async_get_ctx(void); +async_ctx *async_arch_get_ctx(void); int async_set_ctx(async_ctx *ctx); int async_fibre_init_dispatcher(async_fibre *fibre); diff --git a/crypto/async/async.c b/crypto/async/async.c index 9d68a7c77f..024aaf6122 100644 --- a/crypto/async/async.c +++ b/crypto/async/async.c @@ -62,6 +62,7 @@ #include "async_locl.h" #include <openssl/err.h> +#include <internal/cryptlib_int.h> #include <string.h> #define ASYNC_JOB_RUNNING 0 @@ -94,6 +95,12 @@ err: return NULL; } +static async_ctx *async_get_ctx(void) +{ + OPENSSL_INIT_crypto_library_start(OPENSSL_INIT_ASYNC, NULL); + return async_arch_get_ctx(); +} + static int async_ctx_free(void) { async_ctx *ctx; @@ -191,16 +198,17 @@ static void async_release_job(ASYNC_JOB *job) { void async_start_func(void) { ASYNC_JOB *job; + async_ctx *ctx = async_get_ctx(); while (1) { /* Run the job */ - job = async_get_ctx()->currjob; + job = ctx->currjob; job->ret = job->func(job->funcargs); /* Stop the job */ job->status = ASYNC_JOB_STOPPING; if (!async_fibre_swapcontext(&job->fibrectx, - &async_get_ctx()->dispatcher, 1)) { + &ctx->dispatcher, 1)) { /* * Should not happen. Getting here will close the thread...can't do * much about it @@ -213,36 +221,39 @@ void async_start_func(void) int ASYNC_start_job(ASYNC_JOB **job, int *ret, int (*func)(void *), void *args, size_t size) { - if (async_get_ctx() == NULL && async_ctx_new() == NULL) { + async_ctx *ctx = async_get_ctx(); + if (ctx == NULL) + ctx = async_ctx_new(); + if (ctx == NULL) { return ASYNC_ERR; } if (*job) { - async_get_ctx()->currjob = *job; + ctx->currjob = *job; } for (;;) { - if (async_get_ctx()->currjob != NULL) { - if (async_get_ctx()->currjob->status == ASYNC_JOB_STOPPING) { - *ret = async_get_ctx()->currjob->ret; - async_release_job(async_get_ctx()->currjob); - async_get_ctx()->currjob = NULL; + if (ctx->currjob != NULL) { + if (ctx->currjob->status == ASYNC_JOB_STOPPING) { + *ret = ctx->currjob->ret; + async_release_job(ctx->currjob); + ctx->currjob = NULL; *job = NULL; return ASYNC_FINISH; } - if (async_get_ctx()->currjob->status == ASYNC_JOB_PAUSING) { - *job = async_get_ctx()->currjob; - async_get_ctx()->currjob->status = ASYNC_JOB_PAUSED; - async_get_ctx()->currjob = NULL; + if (ctx->currjob->status == ASYNC_JOB_PAUSING) { + *job = ctx->currjob; + ctx->currjob->status = ASYNC_JOB_PAUSED; + ctx->currjob = NULL; return ASYNC_PAUSE; } - if (async_get_ctx()->currjob->status == ASYNC_JOB_PAUSED) { - async_get_ctx()->currjob = *job; + if (ctx->currjob->status == ASYNC_JOB_PAUSED) { + ctx->currjob = *job; /* Resume previous job */ - if (!async_fibre_swapcontext(&async_get_ctx()->dispatcher, - &async_get_ctx()->currjob->fibrectx, 1)) { + if (!async_fibre_swapcontext(&ctx->dispatcher, + &ctx->currjob->fibrectx, 1)) { ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); goto err; @@ -252,41 +263,41 @@ int ASYNC_start_job(ASYNC_JOB **job, int *ret, int (*func)(void *), /* Should not happen */ ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_INTERNAL_ERROR); - async_release_job(async_get_ctx()->currjob); - async_get_ctx()->currjob = NULL; + async_release_job(ctx->currjob); + ctx->currjob = NULL; *job = NULL; return ASYNC_ERR; } /* Start a new job */ - if ((async_get_ctx()->currjob = async_get_pool_job()) == NULL) { + if ((ctx->currjob = async_get_pool_job()) == NULL) { return ASYNC_NO_JOBS; } if (args != NULL) { - async_get_ctx()->currjob->funcargs = OPENSSL_malloc(size); - if (async_get_ctx()->currjob->funcargs == NULL) { + ctx->currjob->funcargs = OPENSSL_malloc(size); + if (ctx->currjob->funcargs == NULL) { ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_MALLOC_FAILURE); - async_release_job(async_get_ctx()->currjob); - async_get_ctx()->currjob = NULL; + async_release_job(ctx->currjob); + ctx->currjob = NULL; return ASYNC_ERR; } - memcpy(async_get_ctx()->currjob->funcargs, args, size); + memcpy(ctx->currjob->funcargs, args, size); } else { - async_get_ctx()->currjob->funcargs = NULL; + ctx->currjob->funcargs = NULL; } - async_get_ctx()->currjob->func = func; - if (!async_fibre_swapcontext(&async_get_ctx()->dispatcher, - &async_get_ctx()->currjob->fibrectx, 1)) { + ctx->currjob->func = func; + if (!async_fibre_swapcontext(&ctx->dispatcher, + &ctx->currjob->fibrectx, 1)) { ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); goto err; } } err: - async_release_job(async_get_ctx()->currjob); - async_get_ctx()->currjob = NULL; + async_release_job(ctx->currjob); + ctx->currjob = NULL; *job = NULL; return ASYNC_ERR; } @@ -295,10 +306,11 @@ err: int ASYNC_pause_job(void) { ASYNC_JOB *job; + async_ctx *ctx = async_get_ctx(); - if (async_get_ctx() == NULL - || async_get_ctx()->currjob == NULL - || async_get_ctx()->blocked) { + if (ctx == NULL + || ctx->currjob == NULL + || ctx->blocked) { /* * Could be we've deliberately not been started within a job so this is * counted as success. @@ -306,11 +318,11 @@ int ASYNC_pause_job(void) return 1; } - job = async_get_ctx()->currjob; + job = ctx->currjob; job->status = ASYNC_JOB_PAUSING; if (!async_fibre_swapcontext(&job->fibrectx, - &async_get_ctx()->dispatcher, 1)) { + &ctx->dispatcher, 1)) { ASYNCerr(ASYNC_F_ASYNC_PAUSE_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); return 0; } @@ -331,14 +343,11 @@ static void async_empty_pool(async_pool *pool) } while (job); } -int ASYNC_init(int init_thread, size_t max_size, size_t init_size) +int async_init(void) { if (!async_global_init()) return 0; - if (init_thread) - return ASYNC_init_thread(max_size, init_size); - return 1; } @@ -352,10 +361,12 @@ int ASYNC_init_thread(size_t max_size, size_t init_size) return 0; } - if (!async_local_init()) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INIT_FAILED); + OPENSSL_INIT_crypto_library_start(OPENSSL_INIT_ASYNC, NULL); + if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) { + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); return 0; } + pool = OPENSSL_zalloc(sizeof *pool); if (pool == NULL) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); @@ -417,16 +428,6 @@ void ASYNC_cleanup_thread(void) async_free_pool_internal(async_get_pool()); } -void ASYNC_cleanup(int cleanupthread) -{ - /* - * We don't actually have any global cleanup at the moment so just cleanup - * the thread - */ - if (cleanupthread) - ASYNC_cleanup_thread(); -} - ASYNC_JOB *ASYNC_get_current_job(void) { async_ctx *ctx; @@ -464,25 +465,25 @@ void ASYNC_clear_wake(ASYNC_JOB *job) void ASYNC_block_pause(void) { - if (async_get_ctx() == NULL - || async_get_ctx()->currjob == NULL) { + async_ctx *ctx = async_get_ctx(); + if (ctx == NULL || ctx->currjob == NULL) { /* * We're not in a job anyway so ignore this */ return; } - async_get_ctx()->blocked++; + ctx->blocked++; } void ASYNC_unblock_pause(void) { - if (async_get_ctx() == NULL - || async_get_ctx()->currjob == NULL) { + async_ctx *ctx = async_get_ctx(); + if (ctx == NULL || ctx->currjob == NULL) { /* * We're not in a job anyway so ignore this */ return; } - if(async_get_ctx()->blocked > 0) - async_get_ctx()->blocked--; + if(ctx->blocked > 0) + ctx->blocked--; } diff --git a/crypto/async/async_locl.h b/crypto/async/async_locl.h index 0710f9e74c..53a192b329 100644 --- a/crypto/async/async_locl.h +++ b/crypto/async/async_locl.h @@ -59,7 +59,7 @@ # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif -#include <openssl/async.h> +#include <internal/async.h> #include <openssl/crypto.h> typedef struct async_ctx_st async_ctx; @@ -95,7 +95,6 @@ struct async_pool_st { }; int async_global_init(void); -int async_local_init(void); void async_local_cleanup(void); void async_global_cleanup(void); void async_start_func(void); diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c index a2a811d982..899dadfe21 100644 --- a/crypto/comp/c_zlib.c +++ b/crypto/comp/c_zlib.c @@ -58,6 +58,7 @@ #include <openssl/objects.h> #include <openssl/comp.h> #include <openssl/err.h> +#include <internal/cryptlib_int.h> #include "comp_lcl.h" COMP_METHOD *COMP_zlib(void); @@ -290,6 +291,7 @@ COMP_METHOD *COMP_zlib(void) zlib_loaded++; if (zlib_loaded) meth = &zlib_stateful_method; + OPENSSL_INIT_crypto_library_start(OPENSSL_INIT_ZLIB, NULL); } } #endif diff --git a/crypto/conf/conf_sap.c b/crypto/conf/conf_sap.c index fead45134a..bb1dcc502f 100644 --- a/crypto/conf/conf_sap.c +++ b/crypto/conf/conf_sap.c @@ -59,7 +59,7 @@ #include <stdio.h> #include <openssl/crypto.h> #include "internal/cryptlib.h" -#include <openssl/conf.h> +#include <internal/conf.h> #include <openssl/dso.h> #include <openssl/x509.h> #include <openssl/asn1.h> @@ -77,6 +77,16 @@ static int openssl_configured = 0; void OPENSSL_config(const char *config_name) { + const OPENSSL_INIT_SETTINGS settings[2] = { + { OPENSSL_INIT_SET_CONF_FILENAME, .value.type_string = config_name }, + { OPENSSL_INIT_SET_END, .value.type_int = 0 } + }; + OPENSSL_INIT_crypto_library_start(OPENSSL_INIT_LOAD_CONFIG, + (const OPENSSL_INIT_SETTINGS *)&settings); +} + +void openssl_config_internal(const char *config_name) +{ if (openssl_configured) return; @@ -94,7 +104,7 @@ void OPENSSL_config(const char *config_name) openssl_configured = 1; } -void OPENSSL_no_config() +void openssl_no_config_internal(void) { openssl_configured = 1; } diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index bd58d35757..138708b867 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c @@ -113,7 +113,7 @@ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ -#include "internal/cryptlib.h" +#include "internal/cryptlib_int.h" #include <openssl/safestack.h> #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ @@ -234,6 +234,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: + ossl_init_thread_stop( + (struct thread_local_inits_st *)ossl_init_get_thread_local(0)); break; case DLL_PROCESS_DETACH: break; diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c index eb8a8bb218..eb25790ae0 100644 --- a/crypto/engine/eng_cryptodev.c +++ b/crypto/engine/eng_cryptodev.c @@ -27,9 +27,10 @@ */ #include <openssl/objects.h> -#include <openssl/engine.h> +#include <internal/engine.h> #include <openssl/evp.h> #include <openssl/bn.h> +#include <openssl/crypto.h> #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ (defined(OpenBSD) || defined(__FreeBSD__)) @@ -64,7 +65,7 @@ #ifndef HAVE_CRYPTODEV -void ENGINE_load_cryptodev(void) +void engine_load_cryptodev_internal(void) { /* This is a NOP on platforms without /dev/crypto */ return; @@ -136,7 +137,7 @@ static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, #endif static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); -void ENGINE_load_cryptodev(void); +void engine_load_cryptodev_internal(void); static const ENGINE_CMD_DEFN cryptodev_defns[] = { {0, NULL, NULL, 0} @@ -1619,7 +1620,7 @@ cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) return (1); } -void ENGINE_load_cryptodev(void) +void engine_load_cryptodev_internal(void) { ENGINE *engine = ENGINE_new(); int fd; diff --git a/crypto/engine/eng_dyn.c b/crypto/engine/eng_dyn.c index 607317b355..3ca24807c7 100644 --- a/crypto/engine/eng_dyn.c +++ b/crypto/engine/eng_dyn.c @@ -58,6 +58,7 @@ #include "eng_int.h" #include <openssl/dso.h> +#include <openssl/crypto.h> /* * Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE @@ -294,7 +295,7 @@ static ENGINE *engine_dynamic(void) return ret; } -void ENGINE_load_dynamic(void) +void engine_load_dynamic_internal(void) { ENGINE *toadd = engine_dynamic(); if (!toadd) diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h index 804214d9ae..9d58d93ecd 100644 --- a/crypto/engine/eng_int.h +++ b/crypto/engine/eng_int.h @@ -65,8 +65,7 @@ # define HEADER_ENGINE_INT_H # include "internal/cryptlib.h" -/* Take public definitions from engine.h */ -# include <openssl/engine.h> +# include <internal/engine.h> #ifdef __cplusplus extern "C" { |