summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorbcook <>2018-11-11 06:41:28 +0000
committerbcook <>2018-11-11 06:41:28 +0000
commitc3082ab78ba758ef51c552b6a91bdf1236de0cf8 (patch)
tree6d18ff101148258c403e820ff423d10a65fba89e /src/lib
parent32ccc9aa9f3dd1c0efa02d4b21376521a91e4705 (diff)
downloadopenbsd-c3082ab78ba758ef51c552b6a91bdf1236de0cf8.tar.gz
openbsd-c3082ab78ba758ef51c552b6a91bdf1236de0cf8.tar.bz2
openbsd-c3082ab78ba758ef51c552b6a91bdf1236de0cf8.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@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/Makefile4
-rw-r--r--src/lib/libcrypto/cryptlib.c469
-rw-r--r--src/lib/libcrypto/crypto.h54
-rw-r--r--src/lib/libcrypto/crypto_init.c3
-rw-r--r--src/lib/libcrypto/crypto_lock.c55
-rw-r--r--src/lib/libcrypto/engine/engine.h7
6 files changed, 140 insertions, 452 deletions
diff --git a/src/lib/libcrypto/Makefile b/src/lib/libcrypto/Makefile
index 7f6322ff7f..6e6effc9b4 100644
--- a/src/lib/libcrypto/Makefile
+++ b/src/lib/libcrypto/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.28 2018/10/24 17:57:22 jsing Exp $ 1# $OpenBSD: Makefile,v 1.29 2018/11/11 06:41:28 bcook Exp $
2 2
3LIB= crypto 3LIB= crypto
4LIBREBUILD=y 4LIBREBUILD=y
@@ -37,7 +37,7 @@ SYMBOL_LIST= ${.CURDIR}/Symbols.list
37# crypto/ 37# crypto/
38SRCS+= cryptlib.c malloc-wrapper.c mem_dbg.c cversion.c ex_data.c cpt_err.c 38SRCS+= cryptlib.c malloc-wrapper.c mem_dbg.c cversion.c ex_data.c cpt_err.c
39SRCS+= o_time.c o_str.c o_init.c 39SRCS+= o_time.c o_str.c o_init.c
40SRCS+= mem_clr.c crypto_init.c 40SRCS+= mem_clr.c crypto_init.c crypto_lock.c
41 41
42# aes/ 42# aes/
43SRCS+= aes_misc.c aes_ecb.c aes_cfb.c aes_ofb.c 43SRCS+= aes_misc.c aes_ecb.c aes_cfb.c aes_ofb.c
diff --git a/src/lib/libcrypto/cryptlib.c b/src/lib/libcrypto/cryptlib.c
index f7b783a029..e10b4f0b58 100644
--- a/src/lib/libcrypto/cryptlib.c
+++ b/src/lib/libcrypto/cryptlib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cryptlib.c,v 1.41 2017/04/29 21:48:43 jsing Exp $ */ 1/* $OpenBSD: cryptlib.c,v 1.42 2018/11/11 06:41:28 bcook Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -114,367 +114,129 @@
114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115 */ 115 */
116 116
117#include <limits.h> 117#include <pthread.h>
118#include <stdarg.h> 118#include <stdarg.h>
119#include <stdint.h> 119#include <stdio.h>
120#include <string.h> 120#include <string.h>
121#include <unistd.h>
122 121
123#include <openssl/opensslconf.h> 122#include <openssl/opensslconf.h>
124
125#include <openssl/crypto.h> 123#include <openssl/crypto.h>
126#include <openssl/buffer.h>
127#include <openssl/err.h>
128#include <openssl/safestack.h>
129#include <openssl/sha.h>
130
131DECLARE_STACK_OF(CRYPTO_dynlock)
132
133/* real #defines in crypto.h, keep these upto date */
134static const char* const lock_names[CRYPTO_NUM_LOCKS] = {
135 "<<ERROR>>",
136 "err",
137 "ex_data",
138 "x509",
139 "x509_info",
140 "x509_pkey",
141 "x509_crl",
142 "x509_req",
143 "dsa",
144 "rsa",
145 "evp_pkey",
146 "x509_store",
147 "ssl_ctx",
148 "ssl_cert",
149 "ssl_session",
150 "ssl_sess_cert",
151 "ssl",
152 "ssl_method",
153 "rand",
154 "rand2",
155 "debug_malloc",
156 "BIO",
157 "gethostbyname",
158 "getservbyname",
159 "readdir",
160 "RSA_blinding",
161 "dh",
162 "debug_malloc2",
163 "dso",
164 "dynlock",
165 "engine",
166 "ui",
167 "ecdsa",
168 "ec",
169 "ecdh",
170 "bn",
171 "ec_pre_comp",
172 "store",
173 "comp",
174 "fips",
175 "fips2",
176#if CRYPTO_NUM_LOCKS != 41
177# error "Inconsistency between crypto.h and cryptlib.c"
178#endif
179};
180
181/* This is for applications to allocate new type names in the non-dynamic
182 array of lock names. These are numbered with positive numbers. */
183static STACK_OF(OPENSSL_STRING) *app_locks = NULL;
184
185/* For applications that want a more dynamic way of handling threads, the
186 following stack is used. These are externally numbered with negative
187 numbers. */
188static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
189
190static void (*locking_callback)(int mode, int type,
191 const char *file, int line) = 0;
192static int (*add_lock_callback)(int *pointer, int amount,
193 int type, const char *file, int line) = 0;
194#ifndef OPENSSL_NO_DEPRECATED
195static unsigned long (*id_callback)(void) = 0;
196#endif
197static void (*threadid_callback)(CRYPTO_THREADID *) = 0;
198static struct CRYPTO_dynlock_value *(*dynlock_create_callback)(
199 const char *file, int line) = 0;
200static void (*dynlock_lock_callback)(int mode,
201 struct CRYPTO_dynlock_value *l, const char *file, int line) = 0;
202static void (*dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
203 const char *file, int line) = 0;
204
205int
206CRYPTO_get_new_lockid(char *name)
207{
208 char *str;
209 int i;
210
211 if ((app_locks == NULL) &&
212 ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) {
213 CRYPTOerror(ERR_R_MALLOC_FAILURE);
214 return (0);
215 }
216 if (name == NULL || (str = strdup(name)) == NULL) {
217 CRYPTOerror(ERR_R_MALLOC_FAILURE);
218 return (0);
219 }
220 i = sk_OPENSSL_STRING_push(app_locks, str);
221 if (!i)
222 free(str);
223 else
224 i += CRYPTO_NUM_LOCKS; /* gap of one :-) */
225 return (i);
226}
227 124
228int 125int
229CRYPTO_num_locks(void) 126CRYPTO_num_locks(void)
230{ 127{
231 return CRYPTO_NUM_LOCKS; 128 return 1;
232} 129}
233 130
234int 131unsigned long (*CRYPTO_get_id_callback(void))(void)
235CRYPTO_get_new_dynlockid(void)
236{ 132{
237 int i = 0; 133 return NULL;
238 CRYPTO_dynlock *pointer = NULL;
239
240 if (dynlock_create_callback == NULL) {
241 CRYPTOerror(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
242 return (0);
243 }
244 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
245 if ((dyn_locks == NULL) &&
246 ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) {
247 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
248 CRYPTOerror(ERR_R_MALLOC_FAILURE);
249 return (0);
250 }
251 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
252
253 pointer = malloc(sizeof(CRYPTO_dynlock));
254 if (pointer == NULL) {
255 CRYPTOerror(ERR_R_MALLOC_FAILURE);
256 return (0);
257 }
258 pointer->references = 1;
259 pointer->data = dynlock_create_callback(__FILE__, __LINE__);
260 if (pointer->data == NULL) {
261 free(pointer);
262 CRYPTOerror(ERR_R_MALLOC_FAILURE);
263 return (0);
264 }
265
266 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
267 /* First, try to find an existing empty slot */
268 i = sk_CRYPTO_dynlock_find(dyn_locks, NULL);
269 /* If there was none, push, thereby creating a new one */
270 if (i == -1)
271 /* Since sk_push() returns the number of items on the
272 stack, not the location of the pushed item, we need
273 to transform the returned number into a position,
274 by decreasing it. */
275 i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1;
276 else
277 /* If we found a place with a NULL pointer, put our pointer
278 in it. */
279 (void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer);
280 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
281
282 if (i == -1) {
283 dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
284 free(pointer);
285 } else
286 i += 1; /* to avoid 0 */
287 return -i;
288} 134}
289 135
290void 136void
291CRYPTO_destroy_dynlockid(int i) 137CRYPTO_set_id_callback(unsigned long (*func)(void))
292{
293 CRYPTO_dynlock *pointer = NULL;
294
295 if (i)
296 i = -i - 1;
297 if (dynlock_destroy_callback == NULL)
298 return;
299
300 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
301
302 if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) {
303 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
304 return;
305 }
306 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
307 if (pointer != NULL) {
308 --pointer->references;
309 if (pointer->references <= 0) {
310 (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
311 } else
312 pointer = NULL;
313 }
314 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
315
316 if (pointer) {
317 dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
318 free(pointer);
319 }
320}
321
322struct CRYPTO_dynlock_value *
323CRYPTO_get_dynlock_value(int i)
324{ 138{
325 CRYPTO_dynlock *pointer = NULL; 139 return;
326
327 if (i)
328 i = -i - 1;
329
330 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
331
332 if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
333 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
334 if (pointer)
335 pointer->references++;
336
337 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
338
339 if (pointer)
340 return pointer->data;
341 return NULL;
342} 140}
343 141
344struct CRYPTO_dynlock_value * 142unsigned long
345(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line) 143CRYPTO_thread_id(void)
346{ 144{
347 return (dynlock_create_callback); 145 return (unsigned long)pthread_self();
348} 146}
349 147
350void 148void
351(*CRYPTO_get_dynlock_lock_callback(void))(int mode, 149CRYPTO_set_locking_callback(void (*func)(int mode, int lock_num,
352 struct CRYPTO_dynlock_value *l, const char *file, int line) 150 const char *file, int line))
353{ 151{
354 return (dynlock_lock_callback); 152 return;
355} 153}
356 154
357void 155void
358(*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, 156(*CRYPTO_get_locking_callback(void))(int mode, int lock_num,
359 const char *file, int line) 157 const char *file, int line)
360{ 158{
361 return (dynlock_destroy_callback); 159 return NULL;
362} 160}
363 161
364void 162void
365CRYPTO_set_dynlock_create_callback( 163CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int lock_num,
366 struct CRYPTO_dynlock_value *(*func)(const char *file, int line)) 164 const char *file, int line))
367{ 165{
368 dynlock_create_callback = func; 166 return;
369} 167}
370 168
371void 169const char *
372CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, 170CRYPTO_get_lock_name(int lock_num)
373 struct CRYPTO_dynlock_value *l, const char *file, int line))
374{ 171{
375 dynlock_lock_callback = func; 172 return "";
376} 173}
377 174
378void 175int
379CRYPTO_set_dynlock_destroy_callback( 176CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
380 void (*func)(struct CRYPTO_dynlock_value *l, const char *file, int line))
381{ 177{
382 dynlock_destroy_callback = func; 178 return 1;
383} 179}
384 180
385void 181void
386(*CRYPTO_get_locking_callback(void))(int mode, int type, const char *file, 182CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
387 int line)
388{ 183{
389 return (locking_callback); 184 return;
390} 185}
391 186
392int 187void
393(*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, 188CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
394 const char *file, int line)
395{ 189{
396 return (add_lock_callback); 190 return;
397} 191}
398 192
399void 193void
400CRYPTO_set_locking_callback(void (*func)(int mode, int type, 194CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(
401 const char *file, int line)) 195 *dyn_create_function)(const char *file, int line))
402{ 196{
403 /* Calling this here ensures initialisation before any threads 197 return;
404 * are started.
405 */
406 locking_callback = func;
407} 198}
408 199
409void 200void
410CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, 201CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)(
411 const char *file, int line)) 202 int mode, struct CRYPTO_dynlock_value *l, const char *file, int line))
412{ 203{
413 add_lock_callback = func; 204 return;
414} 205}
415 206
416/* the memset() here and in set_pointer() seem overkill, but for the sake of
417 * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
418 * "equal" THREADID structs to not be memcmp()-identical. */
419void 207void
420CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) 208CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)(
209 struct CRYPTO_dynlock_value *l, const char *file, int line))
421{ 210{
422 memset(id, 0, sizeof(*id)); 211 return;
423 id->val = val;
424} 212}
425 213
426void 214struct CRYPTO_dynlock_value *
427CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) 215(*CRYPTO_get_dynlock_create_callback(void))(
216 const char *file, int line)
428{ 217{
429 memset(id, 0, sizeof(*id)); 218 return NULL;
430 id->ptr = ptr;
431#if ULONG_MAX >= UINTPTR_MAX
432 /*s u 'ptr' can be embedded in 'val' without loss of uniqueness */
433 id->val = (uintptr_t)id->ptr;
434#else
435 {
436 SHA256_CTX ctx;
437 uint8_t results[SHA256_DIGEST_LENGTH];
438
439 SHA256_Init(&ctx);
440 SHA256_Update(&ctx, (char *)(&id->ptr), sizeof(id->ptr));
441 SHA256_Final(results, &ctx);
442 memcpy(&id->val, results, sizeof(id->val));
443 }
444#endif
445} 219}
446 220
447int 221void
448CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) 222(*CRYPTO_get_dynlock_lock_callback(void))(int mode,
223 struct CRYPTO_dynlock_value *l, const char *file, int line)
449{ 224{
450 if (threadid_callback) 225 return NULL;
451 return 0;
452 threadid_callback = func;
453 return 1;
454} 226}
455 227
456void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *) 228void
229(*CRYPTO_get_dynlock_destroy_callback(void))(
230 struct CRYPTO_dynlock_value *l, const char *file, int line)
457{ 231{
458 return threadid_callback; 232 return NULL;
459} 233}
460 234
461void 235void
462CRYPTO_THREADID_current(CRYPTO_THREADID *id) 236CRYPTO_THREADID_current(CRYPTO_THREADID *id)
463{ 237{
464 if (threadid_callback) { 238 memset(id, 0, sizeof(*id));
465 threadid_callback(id); 239 id->val = (unsigned long)pthread_self();
466 return;
467 }
468#ifndef OPENSSL_NO_DEPRECATED
469 /* If the deprecated callback was set, fall back to that */
470 if (id_callback) {
471 CRYPTO_THREADID_set_numeric(id, id_callback());
472 return;
473 }
474#endif
475 /* Else pick a backup */
476 /* For everything else, default to using the address of 'errno' */
477 CRYPTO_THREADID_set_pointer(id, (void*)&errno);
478} 240}
479 241
480int 242int
@@ -495,129 +257,6 @@ CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
495 return id->val; 257 return id->val;
496} 258}
497 259
498#ifndef OPENSSL_NO_DEPRECATED
499unsigned long (*CRYPTO_get_id_callback(void))(void)
500{
501 return (id_callback);
502}
503
504void
505CRYPTO_set_id_callback(unsigned long (*func)(void))
506{
507 id_callback = func;
508}
509
510unsigned long
511CRYPTO_thread_id(void)
512{
513 unsigned long ret = 0;
514
515 if (id_callback == NULL) {
516 ret = (unsigned long)getpid();
517 } else
518 ret = id_callback();
519 return (ret);
520}
521#endif
522
523void
524CRYPTO_lock(int mode, int type, const char *file, int line)
525{
526#ifdef LOCK_DEBUG
527 {
528 CRYPTO_THREADID id;
529 char *rw_text, *operation_text;
530
531 if (mode & CRYPTO_LOCK)
532 operation_text = "lock ";
533 else if (mode & CRYPTO_UNLOCK)
534 operation_text = "unlock";
535 else
536 operation_text = "ERROR ";
537
538 if (mode & CRYPTO_READ)
539 rw_text = "r";
540 else if (mode & CRYPTO_WRITE)
541 rw_text = "w";
542 else
543 rw_text = "ERROR";
544
545 CRYPTO_THREADID_current(&id);
546 fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n",
547 CRYPTO_THREADID_hash(&id), rw_text, operation_text,
548 CRYPTO_get_lock_name(type), file, line);
549 }
550#endif
551 if (type < 0) {
552 if (dynlock_lock_callback != NULL) {
553 struct CRYPTO_dynlock_value *pointer =
554 CRYPTO_get_dynlock_value(type);
555
556 OPENSSL_assert(pointer != NULL);
557
558 dynlock_lock_callback(mode, pointer, file, line);
559
560 CRYPTO_destroy_dynlockid(type);
561 }
562 } else if (locking_callback != NULL)
563 locking_callback(mode, type, file, line);
564}
565
566int
567CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
568 int line)
569{
570 int ret = 0;
571
572 if (add_lock_callback != NULL) {
573#ifdef LOCK_DEBUG
574 int before= *pointer;
575#endif
576
577 ret = add_lock_callback(pointer, amount, type, file, line);
578#ifdef LOCK_DEBUG
579 {
580 CRYPTO_THREADID id;
581 CRYPTO_THREADID_current(&id);
582 fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
583 CRYPTO_THREADID_hash(&id), before, amount, ret,
584 CRYPTO_get_lock_name(type),
585 file, line);
586 }
587#endif
588 } else {
589 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line);
590
591 ret= *pointer + amount;
592#ifdef LOCK_DEBUG
593 {
594 CRYPTO_THREADID id;
595 CRYPTO_THREADID_current(&id);
596 fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
597 CRYPTO_THREADID_hash(&id), *pointer, amount, ret,
598 CRYPTO_get_lock_name(type), file, line);
599 }
600#endif
601 *pointer = ret;
602 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line);
603 }
604 return (ret);
605}
606
607const char *
608CRYPTO_get_lock_name(int type)
609{
610 if (type < 0)
611 return("dynamic");
612 else if (type < CRYPTO_NUM_LOCKS)
613 return (lock_names[type]);
614 else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
615 return("ERROR");
616 else
617 return (sk_OPENSSL_STRING_value(app_locks,
618 type - CRYPTO_NUM_LOCKS));
619}
620
621#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ 260#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
622 defined(__INTEL__) || \ 261 defined(__INTEL__) || \
623 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) 262 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
diff --git a/src/lib/libcrypto/crypto.h b/src/lib/libcrypto/crypto.h
index e614c6ad65..744079b5bd 100644
--- a/src/lib/libcrypto/crypto.h
+++ b/src/lib/libcrypto/crypto.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: crypto.h,v 1.47 2018/08/24 19:16:03 tb Exp $ */ 1/* $OpenBSD: crypto.h,v 1.48 2018/11/11 06:41:28 bcook Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -203,7 +203,6 @@ typedef struct openssl_item_st {
203#define CRYPTO_READ 4 203#define CRYPTO_READ 4
204#define CRYPTO_WRITE 8 204#define CRYPTO_WRITE 8
205 205
206#ifndef OPENSSL_NO_LOCKING
207#ifndef CRYPTO_w_lock 206#ifndef CRYPTO_w_lock
208#define CRYPTO_w_lock(type) \ 207#define CRYPTO_w_lock(type) \
209 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) 208 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
@@ -216,13 +215,6 @@ typedef struct openssl_item_st {
216#define CRYPTO_add(addr,amount,type) \ 215#define CRYPTO_add(addr,amount,type) \
217 CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) 216 CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
218#endif 217#endif
219#else
220#define CRYPTO_w_lock(a)
221#define CRYPTO_w_unlock(a)
222#define CRYPTO_r_lock(a)
223#define CRYPTO_r_unlock(a)
224#define CRYPTO_add(a,b,c) ((*(a))+=(b))
225#endif
226 218
227/* Some applications as well as some parts of OpenSSL need to allocate 219/* Some applications as well as some parts of OpenSSL need to allocate
228 and deallocate locks in a dynamic fashion. The following typedef 220 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);
370 * potential race-conditions. */ 362 * potential race-conditions. */
371void CRYPTO_cleanup_all_ex_data(void); 363void CRYPTO_cleanup_all_ex_data(void);
372 364
373int CRYPTO_get_new_lockid(char *name);
374
375int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */
376void CRYPTO_lock(int mode, int type, const char *file, int line); 365void CRYPTO_lock(int mode, int type, const char *file, int line);
377void CRYPTO_set_locking_callback(void (*func)(int mode, int type, 366int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
378 const char *file, int line)); 367 int line);
379void (*CRYPTO_get_locking_callback(void))(int mode, int type,
380 const char *file, int line);
381void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type,
382 const char *file, int line));
383int (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type,
384 const char *file, int line);
385 368
386/* Don't use this structure directly. */ 369/* Don't use this structure directly. */
387typedef struct crypto_threadid_st { 370typedef struct crypto_threadid_st {
388 void *ptr; 371 void *ptr;
389 unsigned long val; 372 unsigned long val;
390} CRYPTO_THREADID; 373} CRYPTO_THREADID;
391/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
392void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
393void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
394int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
395void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
396void CRYPTO_THREADID_current(CRYPTO_THREADID *id); 374void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
397int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); 375int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
398void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); 376void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
399unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); 377unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
400#ifndef OPENSSL_NO_DEPRECATED 378
379#ifndef LIBRESSL_INTERNAL
380/* These functions are deprecated no-op stubs */
401void CRYPTO_set_id_callback(unsigned long (*func)(void)); 381void CRYPTO_set_id_callback(unsigned long (*func)(void));
402unsigned long (*CRYPTO_get_id_callback(void))(void); 382unsigned long (*CRYPTO_get_id_callback(void))(void);
403unsigned long CRYPTO_thread_id(void); 383unsigned long CRYPTO_thread_id(void);
404#endif
405 384
385int CRYPTO_get_new_lockid(char *name);
406const char *CRYPTO_get_lock_name(int type); 386const char *CRYPTO_get_lock_name(int type);
407int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
408 int line);
409 387
388int CRYPTO_num_locks(void);
389void CRYPTO_set_locking_callback(void (*func)(int mode, int type,
390 const char *file, int line));
391void (*CRYPTO_get_locking_callback(void))(int mode, int type,
392 const char *file, int line);
393void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type,
394 const char *file, int line));
395int (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type,
396 const char *file, int line);
397
398void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
399void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
400int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
401void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
402#endif
403
404#ifndef LIBRESSL_INTERNAL
410int CRYPTO_get_new_dynlockid(void); 405int CRYPTO_get_new_dynlockid(void);
411void CRYPTO_destroy_dynlockid(int i); 406void CRYPTO_destroy_dynlockid(int i);
412struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); 407struct 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
416struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); 411struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line);
417void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); 412void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line);
418void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file, int line); 413void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file, int line);
414#endif
419 415
420/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- 416/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions --
421 * call the latter last if you need different functions */ 417 * call the latter last if you need different functions */
diff --git a/src/lib/libcrypto/crypto_init.c b/src/lib/libcrypto/crypto_init.c
index 08fb55ffd5..3745e2e718 100644
--- a/src/lib/libcrypto/crypto_init.c
+++ b/src/lib/libcrypto/crypto_init.c
@@ -30,6 +30,8 @@ int OpenSSL_no_config(void);
30 30
31static pthread_t crypto_init_thread; 31static pthread_t crypto_init_thread;
32 32
33void crypto_init_locks(void);
34
33static void 35static void
34OPENSSL_init_crypto_internal(void) 36OPENSSL_init_crypto_internal(void)
35{ 37{
@@ -38,6 +40,7 @@ OPENSSL_init_crypto_internal(void)
38 ERR_load_crypto_strings(); 40 ERR_load_crypto_strings();
39 OpenSSL_add_all_ciphers(); 41 OpenSSL_add_all_ciphers();
40 OpenSSL_add_all_digests(); 42 OpenSSL_add_all_digests();
43 crypto_init_locks();
41} 44}
42 45
43int 46int
diff --git a/src/lib/libcrypto/crypto_lock.c b/src/lib/libcrypto/crypto_lock.c
new file mode 100644
index 0000000000..3d615cf485
--- /dev/null
+++ b/src/lib/libcrypto/crypto_lock.c
@@ -0,0 +1,55 @@
1/* $OpenBSD: crypto_lock.c,v 1.1 2018/11/11 06:41:28 bcook Exp $ */
2/*
3 * Copyright (c) 2018 Brent Cook <bcook@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <pthread.h>
19
20#include <openssl/crypto.h>
21
22static pthread_mutex_t locks[CRYPTO_NUM_LOCKS];
23
24void
25crypto_init_locks(void)
26{
27 int i;
28
29 for (i = 0; i < CRYPTO_NUM_LOCKS; i++)
30 pthread_mutex_init(&locks[i], NULL);
31}
32
33void
34CRYPTO_lock(int mode, int type, const char *file, int line)
35{
36 if (type < 0 || type >= CRYPTO_NUM_LOCKS)
37 return;
38
39 if (mode & CRYPTO_LOCK)
40 pthread_mutex_lock(&locks[type]);
41 else
42 pthread_mutex_unlock(&locks[type]);
43}
44
45int
46CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
47 int line)
48{
49 int ret = 0;
50 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line);
51 ret = *pointer + amount;
52 *pointer = ret;
53 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line);
54 return (ret);
55}
diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h
index 30d1bde4ae..0f603feaaf 100644
--- a/src/lib/libcrypto/engine/engine.h
+++ b/src/lib/libcrypto/engine/engine.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: engine.h,v 1.31 2015/07/19 22:34:27 doug Exp $ */ 1/* $OpenBSD: engine.h,v 1.32 2018/11/11 06:41:28 bcook Exp $ */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL 2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -686,11 +686,6 @@ typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
686 if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ 686 if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
687 fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ 687 fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
688 return 0; \ 688 return 0; \
689 CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
690 CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
691 CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
692 CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
693 CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
694 if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ 689 if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
695 return 0; \ 690 return 0; \
696 if(!ERR_set_implementation(fns->err_fns)) return 0; \ 691 if(!ERR_set_implementation(fns->err_fns)) return 0; \