diff options
author | bcook <> | 2018-11-11 06:41:28 +0000 |
---|---|---|
committer | bcook <> | 2018-11-11 06:41:28 +0000 |
commit | c3082ab78ba758ef51c552b6a91bdf1236de0cf8 (patch) | |
tree | 6d18ff101148258c403e820ff423d10a65fba89e /src/lib | |
parent | 32ccc9aa9f3dd1c0efa02d4b21376521a91e4705 (diff) | |
download | openbsd-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/Makefile | 4 | ||||
-rw-r--r-- | src/lib/libcrypto/cryptlib.c | 469 | ||||
-rw-r--r-- | src/lib/libcrypto/crypto.h | 54 | ||||
-rw-r--r-- | src/lib/libcrypto/crypto_init.c | 3 | ||||
-rw-r--r-- | src/lib/libcrypto/crypto_lock.c | 55 | ||||
-rw-r--r-- | src/lib/libcrypto/engine/engine.h | 7 |
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 | ||
3 | LIB= crypto | 3 | LIB= crypto |
4 | LIBREBUILD=y | 4 | LIBREBUILD=y |
@@ -37,7 +37,7 @@ SYMBOL_LIST= ${.CURDIR}/Symbols.list | |||
37 | # crypto/ | 37 | # crypto/ |
38 | SRCS+= cryptlib.c malloc-wrapper.c mem_dbg.c cversion.c ex_data.c cpt_err.c | 38 | SRCS+= cryptlib.c malloc-wrapper.c mem_dbg.c cversion.c ex_data.c cpt_err.c |
39 | SRCS+= o_time.c o_str.c o_init.c | 39 | SRCS+= o_time.c o_str.c o_init.c |
40 | SRCS+= mem_clr.c crypto_init.c | 40 | SRCS+= mem_clr.c crypto_init.c crypto_lock.c |
41 | 41 | ||
42 | # aes/ | 42 | # aes/ |
43 | SRCS+= aes_misc.c aes_ecb.c aes_cfb.c aes_ofb.c | 43 | SRCS+= 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 | |||
131 | DECLARE_STACK_OF(CRYPTO_dynlock) | ||
132 | |||
133 | /* real #defines in crypto.h, keep these upto date */ | ||
134 | static 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. */ | ||
183 | static 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. */ | ||
188 | static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL; | ||
189 | |||
190 | static void (*locking_callback)(int mode, int type, | ||
191 | const char *file, int line) = 0; | ||
192 | static int (*add_lock_callback)(int *pointer, int amount, | ||
193 | int type, const char *file, int line) = 0; | ||
194 | #ifndef OPENSSL_NO_DEPRECATED | ||
195 | static unsigned long (*id_callback)(void) = 0; | ||
196 | #endif | ||
197 | static void (*threadid_callback)(CRYPTO_THREADID *) = 0; | ||
198 | static struct CRYPTO_dynlock_value *(*dynlock_create_callback)( | ||
199 | const char *file, int line) = 0; | ||
200 | static void (*dynlock_lock_callback)(int mode, | ||
201 | struct CRYPTO_dynlock_value *l, const char *file, int line) = 0; | ||
202 | static void (*dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, | ||
203 | const char *file, int line) = 0; | ||
204 | |||
205 | int | ||
206 | CRYPTO_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 | ||
228 | int | 125 | int |
229 | CRYPTO_num_locks(void) | 126 | CRYPTO_num_locks(void) |
230 | { | 127 | { |
231 | return CRYPTO_NUM_LOCKS; | 128 | return 1; |
232 | } | 129 | } |
233 | 130 | ||
234 | int | 131 | unsigned long (*CRYPTO_get_id_callback(void))(void) |
235 | CRYPTO_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 | ||
290 | void | 136 | void |
291 | CRYPTO_destroy_dynlockid(int i) | 137 | CRYPTO_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 | |||
322 | struct CRYPTO_dynlock_value * | ||
323 | CRYPTO_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 | ||
344 | struct CRYPTO_dynlock_value * | 142 | unsigned long |
345 | (*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line) | 143 | CRYPTO_thread_id(void) |
346 | { | 144 | { |
347 | return (dynlock_create_callback); | 145 | return (unsigned long)pthread_self(); |
348 | } | 146 | } |
349 | 147 | ||
350 | void | 148 | void |
351 | (*CRYPTO_get_dynlock_lock_callback(void))(int mode, | 149 | CRYPTO_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 | ||
357 | void | 155 | void |
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 | ||
364 | void | 162 | void |
365 | CRYPTO_set_dynlock_create_callback( | 163 | CRYPTO_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 | ||
371 | void | 169 | const char * |
372 | CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, | 170 | CRYPTO_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 | ||
378 | void | 175 | int |
379 | CRYPTO_set_dynlock_destroy_callback( | 176 | CRYPTO_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 | ||
385 | void | 181 | void |
386 | (*CRYPTO_get_locking_callback(void))(int mode, int type, const char *file, | 182 | CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) |
387 | int line) | ||
388 | { | 183 | { |
389 | return (locking_callback); | 184 | return; |
390 | } | 185 | } |
391 | 186 | ||
392 | int | 187 | void |
393 | (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, | 188 | CRYPTO_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 | ||
399 | void | 193 | void |
400 | CRYPTO_set_locking_callback(void (*func)(int mode, int type, | 194 | CRYPTO_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 | ||
409 | void | 200 | void |
410 | CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, | 201 | CRYPTO_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. */ | ||
419 | void | 207 | void |
420 | CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) | 208 | CRYPTO_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 | ||
426 | void | 214 | struct CRYPTO_dynlock_value * |
427 | CRYPTO_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 | ||
447 | int | 221 | void |
448 | CRYPTO_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 | ||
456 | void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *) | 228 | void |
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 | ||
461 | void | 235 | void |
462 | CRYPTO_THREADID_current(CRYPTO_THREADID *id) | 236 | CRYPTO_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 | ||
480 | int | 242 | int |
@@ -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 | ||
499 | unsigned long (*CRYPTO_get_id_callback(void))(void) | ||
500 | { | ||
501 | return (id_callback); | ||
502 | } | ||
503 | |||
504 | void | ||
505 | CRYPTO_set_id_callback(unsigned long (*func)(void)) | ||
506 | { | ||
507 | id_callback = func; | ||
508 | } | ||
509 | |||
510 | unsigned long | ||
511 | CRYPTO_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 | |||
523 | void | ||
524 | CRYPTO_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 | |||
566 | int | ||
567 | CRYPTO_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 | |||
607 | const char * | ||
608 | CRYPTO_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. */ |
371 | void CRYPTO_cleanup_all_ex_data(void); | 363 | void CRYPTO_cleanup_all_ex_data(void); |
372 | 364 | ||
373 | int CRYPTO_get_new_lockid(char *name); | ||
374 | |||
375 | int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */ | ||
376 | void CRYPTO_lock(int mode, int type, const char *file, int line); | 365 | void CRYPTO_lock(int mode, int type, const char *file, int line); |
377 | void CRYPTO_set_locking_callback(void (*func)(int mode, int type, | 366 | int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, |
378 | const char *file, int line)); | 367 | int line); |
379 | void (*CRYPTO_get_locking_callback(void))(int mode, int type, | ||
380 | const char *file, int line); | ||
381 | void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, | ||
382 | const char *file, int line)); | ||
383 | int (*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. */ |
387 | typedef struct crypto_threadid_st { | 370 | typedef 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 */ | ||
392 | void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); | ||
393 | void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); | ||
394 | int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *)); | ||
395 | void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *); | ||
396 | void CRYPTO_THREADID_current(CRYPTO_THREADID *id); | 374 | void CRYPTO_THREADID_current(CRYPTO_THREADID *id); |
397 | int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); | 375 | int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); |
398 | void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); | 376 | void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); |
399 | unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); | 377 | unsigned 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 */ | ||
401 | void CRYPTO_set_id_callback(unsigned long (*func)(void)); | 381 | void CRYPTO_set_id_callback(unsigned long (*func)(void)); |
402 | unsigned long (*CRYPTO_get_id_callback(void))(void); | 382 | unsigned long (*CRYPTO_get_id_callback(void))(void); |
403 | unsigned long CRYPTO_thread_id(void); | 383 | unsigned long CRYPTO_thread_id(void); |
404 | #endif | ||
405 | 384 | ||
385 | int CRYPTO_get_new_lockid(char *name); | ||
406 | const char *CRYPTO_get_lock_name(int type); | 386 | const char *CRYPTO_get_lock_name(int type); |
407 | int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, | ||
408 | int line); | ||
409 | 387 | ||
388 | int CRYPTO_num_locks(void); | ||
389 | void CRYPTO_set_locking_callback(void (*func)(int mode, int type, | ||
390 | const char *file, int line)); | ||
391 | void (*CRYPTO_get_locking_callback(void))(int mode, int type, | ||
392 | const char *file, int line); | ||
393 | void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, | ||
394 | const char *file, int line)); | ||
395 | int (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, | ||
396 | const char *file, int line); | ||
397 | |||
398 | void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); | ||
399 | void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); | ||
400 | int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *)); | ||
401 | void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *); | ||
402 | #endif | ||
403 | |||
404 | #ifndef LIBRESSL_INTERNAL | ||
410 | int CRYPTO_get_new_dynlockid(void); | 405 | int CRYPTO_get_new_dynlockid(void); |
411 | void CRYPTO_destroy_dynlockid(int i); | 406 | void CRYPTO_destroy_dynlockid(int i); |
412 | struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); | 407 | 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 | |||
416 | struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); | 411 | struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); |
417 | void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); | 412 | void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); |
418 | void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file, int line); | 413 | void (*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 | ||
31 | static pthread_t crypto_init_thread; | 31 | static pthread_t crypto_init_thread; |
32 | 32 | ||
33 | void crypto_init_locks(void); | ||
34 | |||
33 | static void | 35 | static void |
34 | OPENSSL_init_crypto_internal(void) | 36 | OPENSSL_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 | ||
43 | int | 46 | int |
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 | |||
22 | static pthread_mutex_t locks[CRYPTO_NUM_LOCKS]; | ||
23 | |||
24 | void | ||
25 | crypto_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 | |||
33 | void | ||
34 | CRYPTO_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 | |||
45 | int | ||
46 | CRYPTO_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; \ |