195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com). 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL. 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to. The following conditions 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA, 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed. 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used. 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package. 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in the 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * documentation and/or other materials provided with the distribution. 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * must display the following acknowledgement: 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes cryptographic software written by 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Eric Young (eay@cryptsoft.com)" 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The word 'cryptographic' can be left out if the rouines from the library 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * being used are not cryptographic related :-). 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the apps directory (application code) you must include an acknowledgement: 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE. 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.] */ 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/thread.h> 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <errno.h> 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 61b7725cf3ecfcb5f31834a8fb30f2522fc5c76f8cYoshisato Yanagisawa#if defined(OPENSSL_WINDOWS) 62b7725cf3ecfcb5f31834a8fb30f2522fc5c76f8cYoshisato Yanagisawa#include <Windows.h> 63b7725cf3ecfcb5f31834a8fb30f2522fc5c76f8cYoshisato Yanagisawa#endif 64b7725cf3ecfcb5f31834a8fb30f2522fc5c76f8cYoshisato Yanagisawa 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/type_check.h> 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* lock_names contains the names of all the locks defined in thread.h. */ 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic const char *const lock_names[] = { 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "<<ERROR>>", "err", "ex_data", "x509", 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "x509_info", "x509_pkey", "x509_crl", "x509_req", 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "dsa", "rsa", "evp_pkey", "x509_store", 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "ssl_ctx", "ssl_cert", "ssl_session", "ssl_sess_cert", 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "ssl", "ssl_method", "rand", "rand2", 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "debug_malloc", "BIO", "gethostbyname", "getservbyname", 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "readdir", "RSA_blinding", "dh", "debug_malloc2", 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "dso", "dynlock", "engine", "ui", 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "ecdsa", "ec", "ecdh", "bn", 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "ec_pre_comp", "store", "comp", "fips", 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "fips2", "obj", 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyOPENSSL_COMPILE_ASSERT(CRYPTO_NUM_LOCKS == 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sizeof(lock_names) / sizeof(lock_names[0]), 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_NUM_LOCKS_inconsistent); 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void (*locking_callback)(int mode, int lock_num, const char *file, 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int line) = 0; 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int (*add_lock_callback)(int *pointer, int amount, int lock_num, 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const char *file, int line) = 0; 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void (*threadid_callback)(CRYPTO_THREADID *) = 0; 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint CRYPTO_num_locks(void) { return CRYPTO_NUM_LOCKS; } 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_set_locking_callback(void (*func)(int mode, int lock_num, 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const char *file, int line)) { 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley locking_callback = func; 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int lock_num, 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const char *file, int line)) { 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley add_lock_callback = func; 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst char *CRYPTO_get_lock_name(int lock_num) { 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (lock_num >= 0 && lock_num < CRYPTO_NUM_LOCKS) { 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return lock_names[lock_num]; 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return "ERROR"; 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) { 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (threadid_callback) { 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley threadid_callback = func; 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) { 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(id, 0, sizeof(*id)); 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley id->val = val; 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) { 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(id, 0, sizeof(*id)); 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley id->ptr = ptr; 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid (*CRYPTO_get_locking_callback(void))(int mode, int lock_num, 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const char *file, int line) { 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return locking_callback; 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int lock_num, 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const char *file, int line) { 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return add_lock_callback; 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_lock(int mode, int lock_num, const char *file, int line) { 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (locking_callback != NULL) { 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley locking_callback(mode, lock_num, file, line); 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint CRYPTO_add_lock(int *pointer, int amount, int lock_num, const char *file, 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int line) { 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret = 0; 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (add_lock_callback != NULL) { 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = add_lock_callback(pointer, amount, lock_num, file, line); 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, lock_num, file, line); 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = *pointer + amount; 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pointer = ret; 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, lock_num, file, line); 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_THREADID_current(CRYPTO_THREADID *id) { 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (threadid_callback) { 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley threadid_callback(id); 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return; 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 170ded93581f1674f81faa0dba4b15a842756066ab2Adam Langley#if defined(OPENSSL_WINDOWS) 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId()); 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#else 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* For everything else, default to using the address of 'errno' */ 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_THREADID_set_pointer(id, (void *)&errno); 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b) { 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return memcmp(a, b, sizeof(*a)); 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src) { 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(dest, src, sizeof(*src)); 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyuint32_t CRYPTO_THREADID_hash(const CRYPTO_THREADID *id) { 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return OPENSSL_hash32(id, sizeof(CRYPTO_THREADID)); 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_set_id_callback(unsigned long (*func)(void)) {} 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *( 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *dyn_create_function)(const char *file, int line)) {} 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)( 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)) {} 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)( 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley struct CRYPTO_dynlock_value *l, const char *file, int line)) {} 200