1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay (at) cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57 #ifndef OPENSSL_HEADER_THREAD_H 58 #define OPENSSL_HEADER_THREAD_H 59 60 #include <openssl/base.h> 61 62 #if defined(__cplusplus) 63 extern "C" { 64 #endif 65 66 67 /* Functions to support multithreading. 68 * 69 * OpenSSL can safely be used in multi-threaded applications provided that at 70 * least two callback functions are set with |CRYPTO_set_locking_callback| and 71 * |CRYPTO_THREADID_set_callback|. 72 * 73 * The locking callback performs mutual exclusion. Rather than using a single 74 * lock for all, shared data-structures, OpenSSL requires that the locking 75 * callback support a fixed (at run-time) number of different locks, given by 76 * |CRYPTO_num_locks|. 77 * 78 * The thread ID callback is called to record the currently executing thread's 79 * identifier in a |CRYPTO_THREADID| structure. If this callback is not 80 * provided then the address of |errno| is used as the thread identifier. This 81 * is sufficient only if the system has a thread-local |errno| value. */ 82 83 84 /* CRYPTO_num_locks returns the number of static locks that the callback 85 * function passed to |CRYPTO_set_locking_callback| must be able to handle. */ 86 OPENSSL_EXPORT int CRYPTO_num_locks(void); 87 88 /* CRYPTO_set_locking_callback sets a callback function that implements locking 89 * on behalf of OpenSSL. The callback is called whenever OpenSSL needs to lock 90 * or unlock a lock, and locks are specified as a number between zero and 91 * |CRYPTO_num_locks()-1|. 92 * 93 * The mode argument to the callback is a bitwise-OR of either CRYPTO_LOCK or 94 * CRYPTO_UNLOCK, to denote the action, and CRYPTO_READ or CRYPTO_WRITE, to 95 * indicate the type of lock. The |file| and |line| arguments give the location 96 * in the OpenSSL source where the locking action originated. */ 97 OPENSSL_EXPORT void CRYPTO_set_locking_callback( 98 void (*func)(int mode, int lock_num, const char *file, int line)); 99 100 /* CRYPTO_set_add_lock_callback sets an optional callback which is used when 101 * OpenSSL needs to add a fixed amount to an integer. For example, this is used 102 * when maintaining reference counts. Normally the reference counts are 103 * maintained by performing the addition under a lock but, if this callback 104 * has been set, the application is free to implement the operation using 105 * faster methods (i.e. atomic operations). 106 * 107 * The callback is given a pointer to the integer to be altered (|num|), the 108 * amount to add to the integer (|amount|, which may be negative), the number 109 * of the lock which would have been taken to protect the operation and the 110 * position in the OpenSSL code where the operation originated. */ 111 OPENSSL_EXPORT void CRYPTO_set_add_lock_callback(int (*func)( 112 int *num, int amount, int lock_num, const char *file, int line)); 113 114 /* CRYPTO_get_lock_name returns the name of the lock given by |lock_num|. This 115 * can be used in a locking callback for debugging purposes. */ 116 OPENSSL_EXPORT const char *CRYPTO_get_lock_name(int lock_num); 117 118 119 /* CRYPTO_THREADID identifies a thread in a multithreaded program. This 120 * structure should not be used directly. Rather applications should use 121 * |CRYPTO_THREADID_set_numeric| and |CRYPTO_THREADID_set_pointer|. */ 122 typedef struct crypto_threadid_st { 123 void *ptr; 124 unsigned long val; 125 } CRYPTO_THREADID; 126 127 /* CRYPTO_THREADID_set_callback sets a callback function that stores an 128 * identifier of the currently executing thread into |threadid|. The 129 * CRYPTO_THREADID structure should not be accessed directly. Rather one of 130 * |CRYPTO_THREADID_set_numeric| or |CRYPTO_THREADID_set_pointer| should be 131 * used depending on whether thread IDs are numbers or pointers on the host 132 * system. */ 133 OPENSSL_EXPORT int CRYPTO_THREADID_set_callback( 134 void (*threadid_func)(CRYPTO_THREADID *threadid)); 135 136 OPENSSL_EXPORT void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, 137 unsigned long val); 138 OPENSSL_EXPORT void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); 139 140 141 /* Private functions: */ 142 143 /* CRYPTO_get_locking_callback returns the callback, if any, that was most 144 * recently set using |CRYPTO_set_locking_callback|. */ 145 void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num, 146 const char *file, int line); 147 148 /* CRYPTO_get_add_lock_callback returns the callback, if any, that was most 149 * recently set using |CRYPTO_set_add_lock_callback|. */ 150 int (*CRYPTO_get_add_lock_callback(void))(int *num, int amount, int lock_num, 151 const char *file, int line); 152 153 /* CRYPTO_lock locks or unlocks the lock specified by |lock_num| (one of 154 * |CRYPTO_LOCK_*|). Don't call this directly, rather use one of the 155 * CRYPTO_[rw]_(un)lock macros. */ 156 OPENSSL_EXPORT void CRYPTO_lock(int mode, int lock_num, const char *file, 157 int line); 158 159 /* CRYPTO_add_lock adds |amount| to |*pointer|, protected by the lock specified 160 * by |lock_num|. It returns the new value of |*pointer|. Don't call this 161 * function directly, rather use the |CRYPTO_add_lock| macro. 162 * 163 * TODO(fork): rename to CRYPTO_add_locked. */ 164 OPENSSL_EXPORT int CRYPTO_add_lock(int *pointer, int amount, int lock_num, 165 const char *file, int line); 166 167 168 /* CRYPTO_THREADID_current stores the current thread identifier in |id|. */ 169 OPENSSL_EXPORT void CRYPTO_THREADID_current(CRYPTO_THREADID *id); 170 171 /* CRYPTO_THREADID_cmp returns < 0, 0 or > 0 if |a| is less than, equal to or 172 * greater than |b|, respectively. */ 173 int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); 174 175 /* CRYPTO_THREADID_cpy sets |*dest| equal to |*src|. */ 176 void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); 177 178 /* CRYPTO_THREADID_hash returns a hash of the numeric value of |id|. */ 179 uint32_t CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); 180 181 /* These are the locks used by OpenSSL. These values should match up with the 182 * table in thread.c. */ 183 #define CRYPTO_LOCK_ERR 1 184 #define CRYPTO_LOCK_EX_DATA 2 185 #define CRYPTO_LOCK_X509 3 186 #define CRYPTO_LOCK_X509_INFO 4 187 #define CRYPTO_LOCK_X509_PKEY 5 188 #define CRYPTO_LOCK_X509_CRL 6 189 #define CRYPTO_LOCK_X509_REQ 7 190 #define CRYPTO_LOCK_DSA 8 191 #define CRYPTO_LOCK_RSA 9 192 #define CRYPTO_LOCK_EVP_PKEY 10 193 #define CRYPTO_LOCK_X509_STORE 11 194 #define CRYPTO_LOCK_SSL_CTX 12 195 #define CRYPTO_LOCK_SSL_CERT 13 196 #define CRYPTO_LOCK_SSL_SESSION 14 197 #define CRYPTO_LOCK_SSL_SESS_CERT 15 198 #define CRYPTO_LOCK_SSL 16 199 #define CRYPTO_LOCK_SSL_METHOD 17 200 #define CRYPTO_LOCK_RAND 18 201 #define CRYPTO_LOCK_RAND2 19 202 #define CRYPTO_LOCK_MALLOC 20 203 #define CRYPTO_LOCK_BIO 21 204 #define CRYPTO_LOCK_GETHOSTBYNAME 22 205 #define CRYPTO_LOCK_GETSERVBYNAME 23 206 #define CRYPTO_LOCK_READDIR 24 207 #define CRYPTO_LOCK_RSA_BLINDING 25 208 #define CRYPTO_LOCK_DH 26 209 #define CRYPTO_LOCK_MALLOC2 27 210 #define CRYPTO_LOCK_DSO 28 211 #define CRYPTO_LOCK_DYNLOCK 29 212 #define CRYPTO_LOCK_ENGINE 30 213 #define CRYPTO_LOCK_UI 31 214 #define CRYPTO_LOCK_ECDSA 32 215 #define CRYPTO_LOCK_EC 33 216 #define CRYPTO_LOCK_ECDH 34 217 #define CRYPTO_LOCK_BN 35 218 #define CRYPTO_LOCK_EC_PRE_COMP 36 219 #define CRYPTO_LOCK_STORE 37 220 #define CRYPTO_LOCK_COMP 38 221 #define CRYPTO_LOCK_FIPS 39 222 #define CRYPTO_LOCK_FIPS2 40 223 #define CRYPTO_LOCK_OBJ 40 224 #define CRYPTO_NUM_LOCKS 42 225 226 #define CRYPTO_LOCK 1 227 #define CRYPTO_UNLOCK 2 228 #define CRYPTO_READ 4 229 #define CRYPTO_WRITE 8 230 231 #define CRYPTO_w_lock(lock_num) \ 232 CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, lock_num, __FILE__, __LINE__) 233 #define CRYPTO_w_unlock(lock_num) \ 234 CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, lock_num, __FILE__, __LINE__) 235 #define CRYPTO_r_lock(lock_num) \ 236 CRYPTO_lock(CRYPTO_LOCK | CRYPTO_READ, lock_num, __FILE__, __LINE__) 237 #define CRYPTO_r_unlock(lock_num) \ 238 CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_READ, lock_num, __FILE__, __LINE__) 239 #define CRYPTO_add(addr, amount, lock_num) \ 240 CRYPTO_add_lock(addr, amount, lock_num, __FILE__, __LINE__) 241 242 243 /* Private functions. 244 * 245 * Some old code calls these functions and so no-op implementations are 246 * provided. 247 * 248 * TODO(fork): cleanup callers and remove. */ 249 250 OPENSSL_EXPORT void CRYPTO_set_id_callback(unsigned long (*func)(void)); 251 252 typedef struct { 253 int references; 254 struct CRYPTO_dynlock_value *data; 255 } CRYPTO_dynlock; 256 257 OPENSSL_EXPORT void CRYPTO_set_dynlock_create_callback( 258 struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, 259 int line)); 260 261 OPENSSL_EXPORT void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)( 262 int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)); 263 264 OPENSSL_EXPORT void CRYPTO_set_dynlock_destroy_callback( 265 void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, 266 const char *file, int line)); 267 268 269 #if defined(__cplusplus) 270 } /* extern C */ 271 #endif 272 273 #endif /* OPENSSL_HEADER_THREAD_H */ 274