diff options
author | bcook <bcook@openbsd.org> | 2018-11-11 06:41:28 +0000 |
---|---|---|
committer | bcook <bcook@openbsd.org> | 2018-11-11 06:41:28 +0000 |
commit | 3938ed1ebd7560655156b4463ed629b56b149c35 (patch) | |
tree | 0017d2ce22455fa146c3cc54b66e3d7908a3776e | |
parent | when encapsulating mpls, map the mpls qos value to an ip tos. (diff) | |
download | wireguard-openbsd-3938ed1ebd7560655156b4463ed629b56b149c35.tar.xz wireguard-openbsd-3938ed1ebd7560655156b4463ed629b56b149c35.zip |
Add automatic threading initialization for libcrypto.
This implements automatic thread support initialization in libcrypto.
This does not remove any functions from the ABI, but does turn them into
no-ops. Stub implementations of pthread_mutex_(init|lock|unlock) are
provided for ramdisks.
This does not implement the new OpenSSL 1.1 thread API internally,
keeping the original CRYTPO_lock / CRYPTO_add_lock functions for library
locking. For -portable, crypto_lock.c can be reimplemented with
OS-specific primitives as needed.
ok beck@, tb@, looks sane guenther@
-rw-r--r-- | distrib/special/libstubs/Makefile | 4 | ||||
-rw-r--r-- | distrib/special/libstubs/pthread_mutex.c | 40 | ||||
-rw-r--r-- | lib/libcrypto/Makefile | 4 | ||||
-rw-r--r-- | lib/libcrypto/cryptlib.c | 469 | ||||
-rw-r--r-- | lib/libcrypto/crypto.h | 54 | ||||
-rw-r--r-- | lib/libcrypto/crypto_init.c | 3 | ||||
-rw-r--r-- | lib/libcrypto/crypto_lock.c | 55 | ||||
-rw-r--r-- | lib/libcrypto/engine/engine.h | 7 | ||||
-rw-r--r-- | regress/lib/libssl/ssl/ssltest.c | 56 | ||||
-rw-r--r-- | usr.bin/openssl/openssl.c | 54 |
10 files changed, 183 insertions, 563 deletions
diff --git a/distrib/special/libstubs/Makefile b/distrib/special/libstubs/Makefile index 06f83aae313..19b8f4b5901 100644 --- a/distrib/special/libstubs/Makefile +++ b/distrib/special/libstubs/Makefile @@ -1,9 +1,9 @@ -# $OpenBSD: Makefile,v 1.19 2018/03/08 16:07:36 beck Exp $ +# $OpenBSD: Makefile,v 1.20 2018/11/11 06:41:28 bcook Exp $ .include <bsd.own.mk> LIB= stubs SRCS= db.c setlocale.c sha1.c sha2.c getgrent.c getpwent.c \ - ethers.c pthread_once.c \ + ethers.c pthread_mutex.c pthread_once.c \ mbrtowc_sb.c sscanf.c vfprintf.c vfscanf.c SRCS+= asr.c \ asr_utils.c \ diff --git a/distrib/special/libstubs/pthread_mutex.c b/distrib/special/libstubs/pthread_mutex.c new file mode 100644 index 00000000000..b4693dc9911 --- /dev/null +++ b/distrib/special/libstubs/pthread_mutex.c @@ -0,0 +1,40 @@ +/* $OpenBSD: pthread_mutex.c,v 1.1 2018/11/11 06:41:28 bcook Exp $ */ +/* + * Copyright (c) 2018 Brent Cook <bcook@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <pthread.h> + +int +pthread_mutex_init(pthread_mutex_t *mutex, + const pthread_mutexattr_t *attr) +{ + return (0); +} +DEF_STRONG(pthread_mutex_init); + +int +pthread_mutex_lock(pthread_mutex_t *mutex) +{ + return (0); +} +DEF_STRONG(pthread_mutex_lock); + +int +pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + return (0); +} +DEF_STRONG(pthread_mutex_unlock); diff --git a/lib/libcrypto/Makefile b/lib/libcrypto/Makefile index 7f6322ff7f6..6e6effc9b43 100644 --- a/lib/libcrypto/Makefile +++ b/lib/libcrypto/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.28 2018/10/24 17:57:22 jsing Exp $ +# $OpenBSD: Makefile,v 1.29 2018/11/11 06:41:28 bcook Exp $ LIB= crypto LIBREBUILD=y @@ -37,7 +37,7 @@ SYMBOL_LIST= ${.CURDIR}/Symbols.list # crypto/ SRCS+= cryptlib.c malloc-wrapper.c mem_dbg.c cversion.c ex_data.c cpt_err.c SRCS+= o_time.c o_str.c o_init.c -SRCS+= mem_clr.c crypto_init.c +SRCS+= mem_clr.c crypto_init.c crypto_lock.c # aes/ SRCS+= aes_misc.c aes_ecb.c aes_cfb.c aes_ofb.c diff --git a/lib/libcrypto/cryptlib.c b/lib/libcrypto/cryptlib.c index f7b783a029b..e10b4f0b580 100644 --- a/lib/libcrypto/cryptlib.c +++ b/lib/libcrypto/cryptlib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cryptlib.c,v 1.41 2017/04/29 21:48:43 jsing Exp $ */ +/* $OpenBSD: cryptlib.c,v 1.42 2018/11/11 06:41:28 bcook Exp $ */ /* ==================================================================== * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * @@ -114,367 +114,129 @@ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ -#include <limits.h> +#include <pthread.h> #include <stdarg.h> -#include <stdint.h> +#include <stdio.h> #include <string.h> -#include <unistd.h> #include <openssl/opensslconf.h> - #include <openssl/crypto.h> -#include <openssl/buffer.h> -#include <openssl/err.h> -#include <openssl/safestack.h> -#include <openssl/sha.h> - -DECLARE_STACK_OF(CRYPTO_dynlock) - -/* real #defines in crypto.h, keep these upto date */ -static const char* const lock_names[CRYPTO_NUM_LOCKS] = { - "<<ERROR>>", - "err", - "ex_data", - "x509", - "x509_info", - "x509_pkey", - "x509_crl", - "x509_req", - "dsa", - "rsa", - "evp_pkey", - "x509_store", - "ssl_ctx", - "ssl_cert", - "ssl_session", - "ssl_sess_cert", - "ssl", - "ssl_method", - "rand", - "rand2", - "debug_malloc", - "BIO", - "gethostbyname", - "getservbyname", - "readdir", - "RSA_blinding", - "dh", - "debug_malloc2", - "dso", - "dynlock", - "engine", - "ui", - "ecdsa", - "ec", - "ecdh", - "bn", - "ec_pre_comp", - "store", - "comp", - "fips", - "fips2", -#if CRYPTO_NUM_LOCKS != 41 -# error "Inconsistency between crypto.h and cryptlib.c" -#endif -}; - -/* This is for applications to allocate new type names in the non-dynamic - array of lock names. These are numbered with positive numbers. */ -static STACK_OF(OPENSSL_STRING) *app_locks = NULL; - -/* For applications that want a more dynamic way of handling threads, the - following stack is used. These are externally numbered with negative - numbers. */ -static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL; - -static void (*locking_callback)(int mode, int type, - const char *file, int line) = 0; -static int (*add_lock_callback)(int *pointer, int amount, - int type, const char *file, int line) = 0; -#ifndef OPENSSL_NO_DEPRECATED -static unsigned long (*id_callback)(void) = 0; -#endif -static void (*threadid_callback)(CRYPTO_THREADID *) = 0; -static struct CRYPTO_dynlock_value *(*dynlock_create_callback)( - const char *file, int line) = 0; -static void (*dynlock_lock_callback)(int mode, - struct CRYPTO_dynlock_value *l, const char *file, int line) = 0; -static void (*dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, - const char *file, int line) = 0; - -int -CRYPTO_get_new_lockid(char *name) -{ - char *str; - int i; - - if ((app_locks == NULL) && - ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) { - CRYPTOerror(ERR_R_MALLOC_FAILURE); - return (0); - } - if (name == NULL || (str = strdup(name)) == NULL) { - CRYPTOerror(ERR_R_MALLOC_FAILURE); - return (0); - } - i = sk_OPENSSL_STRING_push(app_locks, str); - if (!i) - free(str); - else - i += CRYPTO_NUM_LOCKS; /* gap of one :-) */ - return (i); -} int CRYPTO_num_locks(void) { - return CRYPTO_NUM_LOCKS; + return 1; } -int -CRYPTO_get_new_dynlockid(void) +unsigned long (*CRYPTO_get_id_callback(void))(void) { - int i = 0; - CRYPTO_dynlock *pointer = NULL; - - if (dynlock_create_callback == NULL) { - CRYPTOerror(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); - return (0); - } - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - if ((dyn_locks == NULL) && - ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) { - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - CRYPTOerror(ERR_R_MALLOC_FAILURE); - return (0); - } - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - pointer = malloc(sizeof(CRYPTO_dynlock)); - if (pointer == NULL) { - CRYPTOerror(ERR_R_MALLOC_FAILURE); - return (0); - } - pointer->references = 1; - pointer->data = dynlock_create_callback(__FILE__, __LINE__); - if (pointer->data == NULL) { - free(pointer); - CRYPTOerror(ERR_R_MALLOC_FAILURE); - return (0); - } - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - /* First, try to find an existing empty slot */ - i = sk_CRYPTO_dynlock_find(dyn_locks, NULL); - /* If there was none, push, thereby creating a new one */ - if (i == -1) - /* Since sk_push() returns the number of items on the - stack, not the location of the pushed item, we need - to transform the returned number into a position, - by decreasing it. */ - i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1; - else - /* If we found a place with a NULL pointer, put our pointer - in it. */ - (void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer); - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (i == -1) { - dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); - free(pointer); - } else - i += 1; /* to avoid 0 */ - return -i; + return NULL; } void -CRYPTO_destroy_dynlockid(int i) -{ - CRYPTO_dynlock *pointer = NULL; - - if (i) - i = -i - 1; - if (dynlock_destroy_callback == NULL) - return; - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - - if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) { - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - return; - } - pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); - if (pointer != NULL) { - --pointer->references; - if (pointer->references <= 0) { - (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); - } else - pointer = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (pointer) { - dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); - free(pointer); - } -} - -struct CRYPTO_dynlock_value * -CRYPTO_get_dynlock_value(int i) +CRYPTO_set_id_callback(unsigned long (*func)(void)) { - CRYPTO_dynlock *pointer = NULL; - - if (i) - i = -i - 1; - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - - if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) - pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); - if (pointer) - pointer->references++; - - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (pointer) - return pointer->data; - return NULL; + return; } -struct CRYPTO_dynlock_value * -(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line) +unsigned long +CRYPTO_thread_id(void) { - return (dynlock_create_callback); + return (unsigned long)pthread_self(); } void -(*CRYPTO_get_dynlock_lock_callback(void))(int mode, - struct CRYPTO_dynlock_value *l, const char *file, int line) +CRYPTO_set_locking_callback(void (*func)(int mode, int lock_num, + const char *file, int line)) { - return (dynlock_lock_callback); + return; } void -(*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, - const char *file, int line) +(*CRYPTO_get_locking_callback(void))(int mode, int lock_num, + const char *file, int line) { - return (dynlock_destroy_callback); + return NULL; } void -CRYPTO_set_dynlock_create_callback( - struct CRYPTO_dynlock_value *(*func)(const char *file, int line)) +CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int lock_num, + const char *file, int line)) { - dynlock_create_callback = func; + return; } -void -CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, - struct CRYPTO_dynlock_value *l, const char *file, int line)) +const char * +CRYPTO_get_lock_name(int lock_num) { - dynlock_lock_callback = func; + return ""; } -void -CRYPTO_set_dynlock_destroy_callback( - void (*func)(struct CRYPTO_dynlock_value *l, const char *file, int line)) +int +CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) { - dynlock_destroy_callback = func; + return 1; } void -(*CRYPTO_get_locking_callback(void))(int mode, int type, const char *file, - int line) +CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) { - return (locking_callback); + return; } -int -(*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, - const char *file, int line) +void +CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) { - return (add_lock_callback); + return; } void -CRYPTO_set_locking_callback(void (*func)(int mode, int type, - const char *file, int line)) +CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *( + *dyn_create_function)(const char *file, int line)) { - /* Calling this here ensures initialisation before any threads - * are started. - */ - locking_callback = func; + return; } void -CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, - const char *file, int line)) +CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)( + int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)) { - add_lock_callback = func; + return; } -/* the memset() here and in set_pointer() seem overkill, but for the sake of - * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two - * "equal" THREADID structs to not be memcmp()-identical. */ void -CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) +CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)( + struct CRYPTO_dynlock_value *l, const char *file, int line)) { - memset(id, 0, sizeof(*id)); - id->val = val; + return; } -void -CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) +struct CRYPTO_dynlock_value * +(*CRYPTO_get_dynlock_create_callback(void))( + const char *file, int line) { - memset(id, 0, sizeof(*id)); - id->ptr = ptr; -#if ULONG_MAX >= UINTPTR_MAX - /*s u 'ptr' can be embedded in 'val' without loss of uniqueness */ - id->val = (uintptr_t)id->ptr; -#else - { - SHA256_CTX ctx; - uint8_t results[SHA256_DIGEST_LENGTH]; - - SHA256_Init(&ctx); - SHA256_Update(&ctx, (char *)(&id->ptr), sizeof(id->ptr)); - SHA256_Final(results, &ctx); - memcpy(&id->val, results, sizeof(id->val)); - } -#endif + return NULL; } -int -CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) +void +(*CRYPTO_get_dynlock_lock_callback(void))(int mode, + struct CRYPTO_dynlock_value *l, const char *file, int line) { - if (threadid_callback) - return 0; - threadid_callback = func; - return 1; + return NULL; } -void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *) +void +(*CRYPTO_get_dynlock_destroy_callback(void))( + struct CRYPTO_dynlock_value *l, const char *file, int line) { - return threadid_callback; + return NULL; } void CRYPTO_THREADID_current(CRYPTO_THREADID *id) { - if (threadid_callback) { - threadid_callback(id); - return; - } -#ifndef OPENSSL_NO_DEPRECATED - /* If the deprecated callback was set, fall back to that */ - if (id_callback) { - CRYPTO_THREADID_set_numeric(id, id_callback()); - return; - } -#endif - /* Else pick a backup */ - /* For everything else, default to using the address of 'errno' */ - CRYPTO_THREADID_set_pointer(id, (void*)&errno); + memset(id, 0, sizeof(*id)); + id->val = (unsigned long)pthread_self(); } int @@ -495,129 +257,6 @@ CRYPTO_THREADID_hash(const CRYPTO_THREADID *id) return id->val; } -#ifndef OPENSSL_NO_DEPRECATED -unsigned long (*CRYPTO_get_id_callback(void))(void) -{ - return (id_callback); -} - -void -CRYPTO_set_id_callback(unsigned long (*func)(void)) -{ - id_callback = func; -} - -unsigned long -CRYPTO_thread_id(void) -{ - unsigned long ret = 0; - - if (id_callback == NULL) { - ret = (unsigned long)getpid(); - } else - ret = id_callback(); - return (ret); -} -#endif - -void -CRYPTO_lock(int mode, int type, const char *file, int line) -{ -#ifdef LOCK_DEBUG - { - CRYPTO_THREADID id; - char *rw_text, *operation_text; - - if (mode & CRYPTO_LOCK) - operation_text = "lock "; - else if (mode & CRYPTO_UNLOCK) - operation_text = "unlock"; - else - operation_text = "ERROR "; - - if (mode & CRYPTO_READ) - rw_text = "r"; - else if (mode & CRYPTO_WRITE) - rw_text = "w"; - else - rw_text = "ERROR"; - - CRYPTO_THREADID_current(&id); - fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n", - CRYPTO_THREADID_hash(&id), rw_text, operation_text, - CRYPTO_get_lock_name(type), file, line); - } -#endif - if (type < 0) { - if (dynlock_lock_callback != NULL) { - struct CRYPTO_dynlock_value *pointer = - CRYPTO_get_dynlock_value(type); - - OPENSSL_assert(pointer != NULL); - - dynlock_lock_callback(mode, pointer, file, line); - - CRYPTO_destroy_dynlockid(type); - } - } else if (locking_callback != NULL) - locking_callback(mode, type, file, line); -} - -int -CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, - int line) -{ - int ret = 0; - - if (add_lock_callback != NULL) { -#ifdef LOCK_DEBUG - int before= *pointer; -#endif - - ret = add_lock_callback(pointer, amount, type, file, line); -#ifdef LOCK_DEBUG - { - CRYPTO_THREADID id; - CRYPTO_THREADID_current(&id); - fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", - CRYPTO_THREADID_hash(&id), before, amount, ret, - CRYPTO_get_lock_name(type), - file, line); - } -#endif - } else { - CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line); - - ret= *pointer + amount; -#ifdef LOCK_DEBUG - { - CRYPTO_THREADID id; - CRYPTO_THREADID_current(&id); - fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", - CRYPTO_THREADID_hash(&id), *pointer, amount, ret, - CRYPTO_get_lock_name(type), file, line); - } -#endif - *pointer = ret; - CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line); - } - return (ret); -} - -const char * -CRYPTO_get_lock_name(int type) -{ - if (type < 0) - return("dynamic"); - else if (type < CRYPTO_NUM_LOCKS) - return (lock_names[type]); - else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks)) - return("ERROR"); - else - return (sk_OPENSSL_STRING_value(app_locks, - type - CRYPTO_NUM_LOCKS)); -} - #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__INTEL__) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) diff --git a/lib/libcrypto/crypto.h b/lib/libcrypto/crypto.h index e614c6ad659..744079b5bd0 100644 --- a/lib/libcrypto/crypto.h +++ b/lib/libcrypto/crypto.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.h,v 1.47 2018/08/24 19:16:03 tb Exp $ */ +/* $OpenBSD: crypto.h,v 1.48 2018/11/11 06:41:28 bcook Exp $ */ /* ==================================================================== * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * @@ -203,7 +203,6 @@ typedef struct openssl_item_st { #define CRYPTO_READ 4 #define CRYPTO_WRITE 8 -#ifndef OPENSSL_NO_LOCKING #ifndef CRYPTO_w_lock #define CRYPTO_w_lock(type) \ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) @@ -216,13 +215,6 @@ typedef struct openssl_item_st { #define CRYPTO_add(addr,amount,type) \ CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) #endif -#else -#define CRYPTO_w_lock(a) -#define CRYPTO_w_unlock(a) -#define CRYPTO_r_lock(a) -#define CRYPTO_r_unlock(a) -#define CRYPTO_add(a,b,c) ((*(a))+=(b)) -#endif /* Some applications as well as some parts of OpenSSL need to allocate and deallocate locks in a dynamic fashion. The following typedef @@ -370,43 +362,46 @@ void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); * potential race-conditions. */ void CRYPTO_cleanup_all_ex_data(void); -int CRYPTO_get_new_lockid(char *name); - -int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */ void CRYPTO_lock(int mode, int type, const char *file, int line); -void CRYPTO_set_locking_callback(void (*func)(int mode, int type, - const char *file, int line)); -void (*CRYPTO_get_locking_callback(void))(int mode, int type, - const char *file, int line); -void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, - const char *file, int line)); -int (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, - const char *file, int line); +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line); /* Don't use this structure directly. */ typedef struct crypto_threadid_st { void *ptr; unsigned long val; } CRYPTO_THREADID; -/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ -void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); -void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); -int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *)); -void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *); void CRYPTO_THREADID_current(CRYPTO_THREADID *id); int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); -#ifndef OPENSSL_NO_DEPRECATED + +#ifndef LIBRESSL_INTERNAL +/* These functions are deprecated no-op stubs */ void CRYPTO_set_id_callback(unsigned long (*func)(void)); unsigned long (*CRYPTO_get_id_callback(void))(void); unsigned long CRYPTO_thread_id(void); -#endif +int CRYPTO_get_new_lockid(char *name); const char *CRYPTO_get_lock_name(int type); -int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, - int line); +int CRYPTO_num_locks(void); +void CRYPTO_set_locking_callback(void (*func)(int mode, int type, + const char *file, int line)); +void (*CRYPTO_get_locking_callback(void))(int mode, int type, + const char *file, int line); +void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, + const char *file, int line)); +int (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, + const char *file, int line); + +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); +int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *)); +void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *); +#endif + +#ifndef LIBRESSL_INTERNAL int CRYPTO_get_new_dynlockid(void); void CRYPTO_destroy_dynlockid(int i); struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); @@ -416,6 +411,7 @@ void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)(struct CRY struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file, int line); +#endif /* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- * call the latter last if you need different functions */ diff --git a/lib/libcrypto/crypto_init.c b/lib/libcrypto/crypto_init.c index 08fb55ffd52..3745e2e7186 100644 --- a/lib/libcrypto/crypto_init.c +++ b/lib/libcrypto/crypto_init.c @@ -30,6 +30,8 @@ int OpenSSL_no_config(void); static pthread_t crypto_init_thread; +void crypto_init_locks(void); + static void OPENSSL_init_crypto_internal(void) { @@ -38,6 +40,7 @@ OPENSSL_init_crypto_internal(void) ERR_load_crypto_strings(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); + crypto_init_locks(); } int diff --git a/lib/libcrypto/crypto_lock.c b/lib/libcrypto/crypto_lock.c new file mode 100644 index 00000000000..3d615cf485b --- /dev/null +++ b/lib/libcrypto/crypto_lock.c @@ -0,0 +1,55 @@ +/* $OpenBSD: crypto_lock.c,v 1.1 2018/11/11 06:41:28 bcook Exp $ */ +/* + * Copyright (c) 2018 Brent Cook <bcook@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <pthread.h> + +#include <openssl/crypto.h> + +static pthread_mutex_t locks[CRYPTO_NUM_LOCKS]; + +void +crypto_init_locks(void) +{ + int i; + + for (i = 0; i < CRYPTO_NUM_LOCKS; i++) + pthread_mutex_init(&locks[i], NULL); +} + +void +CRYPTO_lock(int mode, int type, const char *file, int line) +{ + if (type < 0 || type >= CRYPTO_NUM_LOCKS) + return; + + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(&locks[type]); + else + pthread_mutex_unlock(&locks[type]); +} + +int +CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line) +{ + int ret = 0; + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line); + ret = *pointer + amount; + *pointer = ret; + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line); + return (ret); +} diff --git a/lib/libcrypto/engine/engine.h b/lib/libcrypto/engine/engine.h index 30d1bde4ae2..0f603feaaf8 100644 --- a/lib/libcrypto/engine/engine.h +++ b/lib/libcrypto/engine/engine.h @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.h,v 1.31 2015/07/19 22:34:27 doug Exp $ */ +/* $OpenBSD: engine.h,v 1.32 2018/11/11 06:41:28 bcook Exp $ */ /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL * project 2000. */ @@ -686,11 +686,6 @@ typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id, if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ return 0; \ - CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \ - CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \ - CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \ - CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \ - CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \ if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ return 0; \ if(!ERR_set_implementation(fns->err_fns)) return 0; \ diff --git a/regress/lib/libssl/ssl/ssltest.c b/regress/lib/libssl/ssl/ssltest.c index 7137d0c4076..4460b1bc37e 100644 --- a/regress/lib/libssl/ssl/ssltest.c +++ b/regress/lib/libssl/ssl/ssltest.c @@ -403,60 +403,6 @@ print_details(SSL *c_ssl, const char *prefix) BIO_printf(bio_stdout, "\n"); } -static void -lock_dbg_cb(int mode, int type, const char *file, int line) -{ - static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ - const char *errstr = NULL; - int rw; - - rw = mode & (CRYPTO_READ|CRYPTO_WRITE); - if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) { - errstr = "invalid mode"; - goto err; - } - - if (type < 0 || type >= CRYPTO_NUM_LOCKS) { - errstr = "type out of bounds"; - goto err; - } - - if (mode & CRYPTO_LOCK) { - if (modes[type]) { - errstr = "already locked"; - /* must not happen in a single-threaded program - * (would deadlock) */ - goto err; - } - - modes[type] = rw; - } else if (mode & CRYPTO_UNLOCK) { - if (!modes[type]) { - errstr = "not locked"; - goto err; - } - - if (modes[type] != rw) { - errstr = (rw == CRYPTO_READ) ? - "CRYPTO_r_unlock on write lock" : - "CRYPTO_w_unlock on read lock"; - } - - modes[type] = 0; - } else { - errstr = "invalid mode"; - goto err; - } - -err: - if (errstr) { - /* we cannot use bio_err here */ - fprintf(stderr, - "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", - errstr, mode, type, file, line); - } -} - int main(int argc, char *argv[]) { @@ -495,8 +441,6 @@ main(int argc, char *argv[]) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE|BIO_FP_TEXT); - CRYPTO_set_locking_callback(lock_dbg_cb); - bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE|BIO_FP_TEXT); argc--; diff --git a/usr.bin/openssl/openssl.c b/usr.bin/openssl/openssl.c index b3e85d63baa..255e34ec33d 100644 --- a/usr.bin/openssl/openssl.c +++ b/usr.bin/openssl/openssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openssl.c,v 1.26 2018/02/07 05:47:55 jsing Exp $ */ +/* $OpenBSD: openssl.c,v 1.27 2018/11/11 06:41:28 bcook Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -344,56 +344,6 @@ CONF *config = NULL; BIO *bio_err = NULL; static void -lock_dbg_cb(int mode, int type, const char *file, int line) -{ - static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ - const char *errstr = NULL; - int rw; - - rw = mode & (CRYPTO_READ | CRYPTO_WRITE); - if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) { - errstr = "invalid mode"; - goto err; - } - if (type < 0 || type >= CRYPTO_NUM_LOCKS) { - errstr = "type out of bounds"; - goto err; - } - if (mode & CRYPTO_LOCK) { - if (modes[type]) { - errstr = "already locked"; - /* - * must not happen in a single-threaded program - * (would deadlock) - */ - goto err; - } - modes[type] = rw; - } else if (mode & CRYPTO_UNLOCK) { - if (!modes[type]) { - errstr = "not locked"; - goto err; - } - if (modes[type] != rw) { - errstr = (rw == CRYPTO_READ) ? - "CRYPTO_r_unlock on write lock" : - "CRYPTO_w_unlock on read lock"; - } - modes[type] = 0; - } else { - errstr = "invalid mode"; - goto err; - } - - err: - if (errstr) { - /* we cannot use bio_err here */ - fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", - errstr, mode, type, file, line); - } -} - -static void openssl_startup(void) { signal(SIGPIPE, SIG_IGN); @@ -451,8 +401,6 @@ main(int argc, char **argv) exit(1); } - CRYPTO_set_locking_callback(lock_dbg_cb); - openssl_startup(); /* Lets load up our environment a little */ |