cryptlib.c revision 325337
1/* crypto/cryptlib.c */
2/* ====================================================================
3 * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in
14 *    the documentation and/or other materials provided with the
15 *    distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 *    software must display the following acknowledgment:
19 *    "This product includes software developed by the OpenSSL Project
20 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 *    endorse or promote products derived from this software without
24 *    prior written permission. For written permission, please contact
25 *    openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 *    nor may "OpenSSL" appear in their names without prior written
29 *    permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 *    acknowledgment:
33 *    "This product includes software developed by the OpenSSL Project
34 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com).  This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
56 * All rights reserved.
57 *
58 * This package is an SSL implementation written
59 * by Eric Young (eay@cryptsoft.com).
60 * The implementation was written so as to conform with Netscapes SSL.
61 *
62 * This library is free for commercial and non-commercial use as long as
63 * the following conditions are aheared to.  The following conditions
64 * apply to all code found in this distribution, be it the RC4, RSA,
65 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
66 * included with this distribution is covered by the same copyright terms
67 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
68 *
69 * Copyright remains Eric Young's, and as such any Copyright notices in
70 * the code are not to be removed.
71 * If this package is used in a product, Eric Young should be given attribution
72 * as the author of the parts of the library used.
73 * This can be in the form of a textual message at program startup or
74 * in documentation (online or textual) provided with the package.
75 *
76 * Redistribution and use in source and binary forms, with or without
77 * modification, are permitted provided that the following conditions
78 * are met:
79 * 1. Redistributions of source code must retain the copyright
80 *    notice, this list of conditions and the following disclaimer.
81 * 2. Redistributions in binary form must reproduce the above copyright
82 *    notice, this list of conditions and the following disclaimer in the
83 *    documentation and/or other materials provided with the distribution.
84 * 3. All advertising materials mentioning features or use of this software
85 *    must display the following acknowledgement:
86 *    "This product includes cryptographic software written by
87 *     Eric Young (eay@cryptsoft.com)"
88 *    The word 'cryptographic' can be left out if the rouines from the library
89 *    being used are not cryptographic related :-).
90 * 4. If you include any Windows specific code (or a derivative thereof) from
91 *    the apps directory (application code) you must include an acknowledgement:
92 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
93 *
94 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
95 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
96 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
97 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
98 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
99 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
100 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
101 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
102 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
103 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
104 * SUCH DAMAGE.
105 *
106 * The licence and distribution terms for any publically available version or
107 * derivative of this code cannot be changed.  i.e. this code cannot simply be
108 * copied and put under another distribution licence
109 * [including the GNU Public Licence.]
110 */
111/* ====================================================================
112 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113 * ECDH support in OpenSSL originally developed by
114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115 */
116
117#include "cryptlib.h"
118#include <openssl/safestack.h>
119
120#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
121static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */
122#endif
123
124DECLARE_STACK_OF(CRYPTO_dynlock)
125
126/* real #defines in crypto.h, keep these upto date */
127static const char *const lock_names[CRYPTO_NUM_LOCKS] = {
128    "<<ERROR>>",
129    "err",
130    "ex_data",
131    "x509",
132    "x509_info",
133    "x509_pkey",
134    "x509_crl",
135    "x509_req",
136    "dsa",
137    "rsa",
138    "evp_pkey",
139    "x509_store",
140    "ssl_ctx",
141    "ssl_cert",
142    "ssl_session",
143    "ssl_sess_cert",
144    "ssl",
145    "ssl_method",
146    "rand",
147    "rand2",
148    "debug_malloc",
149    "BIO",
150    "gethostbyname",
151    "getservbyname",
152    "readdir",
153    "RSA_blinding",
154    "dh",
155    "debug_malloc2",
156    "dso",
157    "dynlock",
158    "engine",
159    "ui",
160    "ecdsa",
161    "ec",
162    "ecdh",
163    "bn",
164    "ec_pre_comp",
165    "store",
166    "comp",
167    "fips",
168    "fips2",
169#if CRYPTO_NUM_LOCKS != 41
170# error "Inconsistency between crypto.h and cryptlib.c"
171#endif
172};
173
174/*
175 * This is for applications to allocate new type names in the non-dynamic
176 * array of lock names.  These are numbered with positive numbers.
177 */
178static STACK_OF(OPENSSL_STRING) *app_locks = NULL;
179
180/*
181 * For applications that want a more dynamic way of handling threads, the
182 * following stack is used.  These are externally numbered with negative
183 * numbers.
184 */
185static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
186
187static void (MS_FAR *locking_callback) (int mode, int type,
188                                        const char *file, int line) = 0;
189static int (MS_FAR *add_lock_callback) (int *pointer, int amount,
190                                        int type, const char *file,
191                                        int line) = 0;
192#ifndef OPENSSL_NO_DEPRECATED
193static unsigned long (MS_FAR *id_callback) (void) = 0;
194#endif
195static void (MS_FAR *threadid_callback) (CRYPTO_THREADID *) = 0;
196static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
197 (const char *file, int line) = 0;
198static void (MS_FAR *dynlock_lock_callback) (int mode,
199                                             struct CRYPTO_dynlock_value *l,
200                                             const char *file, int line) = 0;
201static void (MS_FAR *dynlock_destroy_callback) (struct CRYPTO_dynlock_value
202                                                *l, const char *file,
203                                                int line) = 0;
204
205int CRYPTO_get_new_lockid(char *name)
206{
207    char *str;
208    int i;
209
210#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
211    /*
212     * A hack to make Visual C++ 5.0 work correctly when linking as a DLL
213     * using /MT. Without this, the application cannot use any floating point
214     * printf's. It also seems to be needed for Visual C 1.5 (win16)
215     */
216    SSLeay_MSVC5_hack = (double)name[0] * (double)name[1];
217#endif
218
219    if ((app_locks == NULL)
220        && ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) {
221        CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE);
222        return (0);
223    }
224    if ((str = BUF_strdup(name)) == NULL) {
225        CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE);
226        return (0);
227    }
228    i = sk_OPENSSL_STRING_push(app_locks, str);
229    if (!i)
230        OPENSSL_free(str);
231    else
232        i += CRYPTO_NUM_LOCKS;  /* gap of one :-) */
233    return (i);
234}
235
236int CRYPTO_num_locks(void)
237{
238    return CRYPTO_NUM_LOCKS;
239}
240
241int CRYPTO_get_new_dynlockid(void)
242{
243    int i = 0;
244    CRYPTO_dynlock *pointer = NULL;
245
246    if (dynlock_create_callback == NULL) {
247        CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,
248                  CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
249        return (0);
250    }
251    CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
252    if ((dyn_locks == NULL)
253        && ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) {
254        CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
255        CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE);
256        return (0);
257    }
258    CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
259
260    pointer = (CRYPTO_dynlock *) OPENSSL_malloc(sizeof(CRYPTO_dynlock));
261    if (pointer == NULL) {
262        CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE);
263        return (0);
264    }
265    pointer->references = 1;
266    pointer->data = dynlock_create_callback(__FILE__, __LINE__);
267    if (pointer->data == NULL) {
268        OPENSSL_free(pointer);
269        CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE);
270        return (0);
271    }
272
273    CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
274    /* First, try to find an existing empty slot */
275    i = sk_CRYPTO_dynlock_find(dyn_locks, NULL);
276    /* If there was none, push, thereby creating a new one */
277    if (i == -1)
278        /*
279         * Since sk_push() returns the number of items on the stack, not the
280         * location of the pushed item, we need to transform the returned
281         * number into a position, by decreasing it.
282         */
283        i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1;
284    else
285        /*
286         * If we found a place with a NULL pointer, put our pointer in it.
287         */
288        (void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer);
289    CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
290
291    if (i == -1) {
292        dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
293        OPENSSL_free(pointer);
294    } else
295        i += 1;                 /* to avoid 0 */
296    return -i;
297}
298
299void CRYPTO_destroy_dynlockid(int i)
300{
301    CRYPTO_dynlock *pointer = NULL;
302    if (i)
303        i = -i - 1;
304    if (dynlock_destroy_callback == NULL)
305        return;
306
307    CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
308
309    if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) {
310        CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
311        return;
312    }
313    pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
314    if (pointer != NULL) {
315        --pointer->references;
316#ifdef REF_CHECK
317        if (pointer->references < 0) {
318            fprintf(stderr,
319                    "CRYPTO_destroy_dynlockid, bad reference count\n");
320            abort();
321        } else
322#endif
323        if (pointer->references <= 0) {
324            (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
325        } else
326            pointer = NULL;
327    }
328    CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
329
330    if (pointer) {
331        dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
332        OPENSSL_free(pointer);
333    }
334}
335
336struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
337{
338    CRYPTO_dynlock *pointer = NULL;
339    if (i)
340        i = -i - 1;
341
342    CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
343
344    if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
345        pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
346    if (pointer)
347        pointer->references++;
348
349    CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
350
351    if (pointer)
352        return pointer->data;
353    return NULL;
354}
355
356struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
357 (const char *file, int line) {
358    return (dynlock_create_callback);
359}
360
361void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode,
362                                                struct CRYPTO_dynlock_value
363                                                *l, const char *file,
364                                                int line) {
365    return (dynlock_lock_callback);
366}
367
368void (*CRYPTO_get_dynlock_destroy_callback(void))
369 (struct CRYPTO_dynlock_value *l, const char *file, int line) {
370    return (dynlock_destroy_callback);
371}
372
373void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
374                                         (const char *file, int line))
375{
376    dynlock_create_callback = func;
377}
378
379void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode,
380                                                    struct
381                                                    CRYPTO_dynlock_value *l,
382                                                    const char *file,
383                                                    int line))
384{
385    dynlock_lock_callback = func;
386}
387
388void CRYPTO_set_dynlock_destroy_callback(void (*func)
389                                          (struct CRYPTO_dynlock_value *l,
390                                           const char *file, int line))
391{
392    dynlock_destroy_callback = func;
393}
394
395void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
396                                           const char *file, int line) {
397    return (locking_callback);
398}
399
400int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type,
401                                           const char *file, int line) {
402    return (add_lock_callback);
403}
404
405void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
406                                               const char *file, int line))
407{
408    /*
409     * Calling this here ensures initialisation before any threads are
410     * started.
411     */
412    OPENSSL_init();
413    locking_callback = func;
414}
415
416void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
417                                               const char *file, int line))
418{
419    add_lock_callback = func;
420}
421
422/*
423 * the memset() here and in set_pointer() seem overkill, but for the sake of
424 * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause
425 * two "equal" THREADID structs to not be memcmp()-identical.
426 */
427void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
428{
429    memset(id, 0, sizeof(*id));
430    id->val = val;
431}
432
433static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
434
435void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
436{
437    unsigned char *dest = (void *)&id->val;
438    unsigned int accum = 0;
439    unsigned char dnum = sizeof(id->val);
440
441    memset(id, 0, sizeof(*id));
442    id->ptr = ptr;
443    if (sizeof(id->val) >= sizeof(id->ptr)) {
444        /*
445         * 'ptr' can be embedded in 'val' without loss of uniqueness
446         */
447        id->val = (unsigned long)id->ptr;
448        return;
449    }
450    /*
451     * hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
452     * linear function over the bytes in 'ptr', the co-efficients of which
453     * are a sequence of low-primes (hash_coeffs is an 8-element cycle) - the
454     * starting prime for the sequence varies for each byte of 'val' (unique
455     * polynomials unless pointers are >64-bit). For added spice, the totals
456     * accumulate rather than restarting from zero, and the index of the
457     * 'val' byte is added each time (position dependence). If I was a
458     * black-belt, I'd scan big-endian pointers in reverse to give low-order
459     * bits more play, but this isn't crypto and I'd prefer nobody mistake it
460     * as such. Plus I'm lazy.
461     */
462    while (dnum--) {
463        const unsigned char *src = (void *)&id->ptr;
464        unsigned char snum = sizeof(id->ptr);
465        while (snum--)
466            accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
467        accum += dnum;
468        *(dest++) = accum & 255;
469    }
470}
471
472#ifdef OPENSSL_FIPS
473extern int FIPS_crypto_threadid_set_callback(void (*func) (CRYPTO_THREADID *));
474#endif
475
476int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
477{
478    if (threadid_callback)
479        return 0;
480    threadid_callback = func;
481#ifdef OPENSSL_FIPS
482    FIPS_crypto_threadid_set_callback(func);
483#endif
484    return 1;
485}
486
487void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *) {
488    return threadid_callback;
489}
490
491void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
492{
493    if (threadid_callback) {
494        threadid_callback(id);
495        return;
496    }
497#ifndef OPENSSL_NO_DEPRECATED
498    /* If the deprecated callback was set, fall back to that */
499    if (id_callback) {
500        CRYPTO_THREADID_set_numeric(id, id_callback());
501        return;
502    }
503#endif
504    /* Else pick a backup */
505#ifdef OPENSSL_SYS_WIN16
506    CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
507#elif defined(OPENSSL_SYS_WIN32)
508    CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
509#elif defined(OPENSSL_SYS_BEOS)
510    CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
511#else
512    /* For everything else, default to using the address of 'errno' */
513    CRYPTO_THREADID_set_pointer(id, (void *)&errno);
514#endif
515}
516
517int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
518{
519    return memcmp(a, b, sizeof(*a));
520}
521
522void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
523{
524    memcpy(dest, src, sizeof(*src));
525}
526
527unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
528{
529    return id->val;
530}
531
532#ifndef OPENSSL_NO_DEPRECATED
533unsigned long (*CRYPTO_get_id_callback(void)) (void) {
534    return (id_callback);
535}
536
537void CRYPTO_set_id_callback(unsigned long (*func) (void))
538{
539    id_callback = func;
540}
541
542unsigned long CRYPTO_thread_id(void)
543{
544    unsigned long ret = 0;
545
546    if (id_callback == NULL) {
547# ifdef OPENSSL_SYS_WIN16
548        ret = (unsigned long)GetCurrentTask();
549# elif defined(OPENSSL_SYS_WIN32)
550        ret = (unsigned long)GetCurrentThreadId();
551# elif defined(GETPID_IS_MEANINGLESS)
552        ret = 1L;
553# elif defined(OPENSSL_SYS_BEOS)
554        ret = (unsigned long)find_thread(NULL);
555# else
556        ret = (unsigned long)getpid();
557# endif
558    } else
559        ret = id_callback();
560    return (ret);
561}
562#endif
563
564void CRYPTO_lock(int mode, int type, const char *file, int line)
565{
566#ifdef LOCK_DEBUG
567    {
568        CRYPTO_THREADID id;
569        char *rw_text, *operation_text;
570
571        if (mode & CRYPTO_LOCK)
572            operation_text = "lock  ";
573        else if (mode & CRYPTO_UNLOCK)
574            operation_text = "unlock";
575        else
576            operation_text = "ERROR ";
577
578        if (mode & CRYPTO_READ)
579            rw_text = "r";
580        else if (mode & CRYPTO_WRITE)
581            rw_text = "w";
582        else
583            rw_text = "ERROR";
584
585        CRYPTO_THREADID_current(&id);
586        fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n",
587                CRYPTO_THREADID_hash(&id), rw_text, operation_text,
588                CRYPTO_get_lock_name(type), file, line);
589    }
590#endif
591    if (type < 0) {
592        if (dynlock_lock_callback != NULL) {
593            struct CRYPTO_dynlock_value *pointer
594                = CRYPTO_get_dynlock_value(type);
595
596            OPENSSL_assert(pointer != NULL);
597
598            dynlock_lock_callback(mode, pointer, file, line);
599
600            CRYPTO_destroy_dynlockid(type);
601        }
602    } else if (locking_callback != NULL)
603        locking_callback(mode, type, file, line);
604}
605
606int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
607                    int line)
608{
609    int ret = 0;
610
611    if (add_lock_callback != NULL) {
612#ifdef LOCK_DEBUG
613        int before = *pointer;
614#endif
615
616        ret = add_lock_callback(pointer, amount, type, file, line);
617#ifdef LOCK_DEBUG
618        {
619            CRYPTO_THREADID id;
620            CRYPTO_THREADID_current(&id);
621            fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
622                    CRYPTO_THREADID_hash(&id), before, amount, ret,
623                    CRYPTO_get_lock_name(type), file, line);
624        }
625#endif
626    } else {
627        CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
628
629        ret = *pointer + amount;
630#ifdef LOCK_DEBUG
631        {
632            CRYPTO_THREADID id;
633            CRYPTO_THREADID_current(&id);
634            fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
635                    CRYPTO_THREADID_hash(&id),
636                    *pointer, amount, ret,
637                    CRYPTO_get_lock_name(type), file, line);
638        }
639#endif
640        *pointer = ret;
641        CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line);
642    }
643    return (ret);
644}
645
646const char *CRYPTO_get_lock_name(int type)
647{
648    if (type < 0)
649        return ("dynamic");
650    else if (type < CRYPTO_NUM_LOCKS)
651        return (lock_names[type]);
652    else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
653        return ("ERROR");
654    else
655        return (sk_OPENSSL_STRING_value(app_locks, type - CRYPTO_NUM_LOCKS));
656}
657
658#if     defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
659        defined(__INTEL__) || \
660        defined(__x86_64) || defined(__x86_64__) || \
661        defined(_M_AMD64) || defined(_M_X64)
662
663extern unsigned int OPENSSL_ia32cap_P[4];
664unsigned long *OPENSSL_ia32cap_loc(void)
665{
666    if (sizeof(long) == 4)
667        /*
668         * If 32-bit application pulls address of OPENSSL_ia32cap_P[0]
669         * clear second element to maintain the illusion that vector
670         * is 32-bit.
671         */
672        OPENSSL_ia32cap_P[1] = 0;
673
674    OPENSSL_ia32cap_P[2] = 0;
675
676    return (unsigned long *)OPENSSL_ia32cap_P;
677}
678
679# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
680#  define OPENSSL_CPUID_SETUP
681#  if defined(_WIN32)
682typedef unsigned __int64 IA32CAP;
683#  else
684typedef unsigned long long IA32CAP;
685#  endif
686void OPENSSL_cpuid_setup(void)
687{
688    static int trigger = 0;
689    IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
690    IA32CAP vec;
691    char *env;
692
693    if (trigger)
694        return;
695
696    trigger = 1;
697    if ((env = getenv("OPENSSL_ia32cap"))) {
698        int off = (env[0] == '~') ? 1 : 0;
699#  if defined(_WIN32)
700        if (!sscanf(env + off, "%I64i", &vec))
701            vec = strtoul(env + off, NULL, 0);
702#  else
703        if (!sscanf(env + off, "%lli", (long long *)&vec))
704            vec = strtoul(env + off, NULL, 0);
705#  endif
706        if (off)
707            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
708        else if (env[0] == ':')
709            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
710
711        OPENSSL_ia32cap_P[2] = 0;
712        if ((env = strchr(env, ':'))) {
713            unsigned int vecx;
714            env++;
715            off = (env[0] == '~') ? 1 : 0;
716            vecx = strtoul(env + off, NULL, 0);
717            if (off)
718                OPENSSL_ia32cap_P[2] &= ~vecx;
719            else
720                OPENSSL_ia32cap_P[2] = vecx;
721        }
722    } else
723        vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
724
725    /*
726     * |(1<<10) sets a reserved bit to signal that variable
727     * was initialized already... This is to avoid interference
728     * with cpuid snippets in ELF .init segment.
729     */
730    OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
731    OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
732}
733# else
734unsigned int OPENSSL_ia32cap_P[4];
735# endif
736
737#else
738unsigned long *OPENSSL_ia32cap_loc(void)
739{
740    return NULL;
741}
742#endif
743int OPENSSL_NONPIC_relocated = 0;
744#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
745void OPENSSL_cpuid_setup(void)
746{
747}
748#endif
749
750#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
751# ifdef __CYGWIN__
752/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
753#  include <windows.h>
754/*
755 * this has side-effect of _WIN32 getting defined, which otherwise is
756 * mutually exclusive with __CYGWIN__...
757 */
758# endif
759
760/*
761 * All we really need to do is remove the 'error' state when a thread
762 * detaches
763 */
764
765BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
766{
767    switch (fdwReason) {
768    case DLL_PROCESS_ATTACH:
769        OPENSSL_cpuid_setup();
770# if defined(_WIN32_WINNT)
771        {
772            IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL;
773            IMAGE_NT_HEADERS *nt_headers;
774
775            if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) {
776                nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header
777                                                   + dos_header->e_lfanew);
778                if (nt_headers->Signature == IMAGE_NT_SIGNATURE &&
779                    hinstDLL !=
780                    (HINSTANCE) (nt_headers->OptionalHeader.ImageBase))
781                    OPENSSL_NONPIC_relocated = 1;
782            }
783        }
784# endif
785        break;
786    case DLL_THREAD_ATTACH:
787        break;
788    case DLL_THREAD_DETACH:
789        break;
790    case DLL_PROCESS_DETACH:
791        break;
792    }
793    return (TRUE);
794}
795#endif
796
797#if defined(_WIN32) && !defined(__CYGWIN__)
798# include <tchar.h>
799# include <signal.h>
800# ifdef __WATCOMC__
801#  if defined(_UNICODE) || defined(__UNICODE__)
802#   define _vsntprintf _vsnwprintf
803#  else
804#   define _vsntprintf _vsnprintf
805#  endif
806# endif
807# ifdef _MSC_VER
808#  define alloca _alloca
809# endif
810
811# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
812int OPENSSL_isservice(void)
813{
814    HWINSTA h;
815    DWORD len;
816    WCHAR *name;
817    static union {
818        void *p;
819        int (*f) (void);
820    } _OPENSSL_isservice = {
821        NULL
822    };
823
824    if (_OPENSSL_isservice.p == NULL) {
825        HANDLE h = GetModuleHandle(NULL);
826        if (h != NULL)
827            _OPENSSL_isservice.p = GetProcAddress(h, "_OPENSSL_isservice");
828        if (_OPENSSL_isservice.p == NULL)
829            _OPENSSL_isservice.p = (void *)-1;
830    }
831
832    if (_OPENSSL_isservice.p != (void *)-1)
833        return (*_OPENSSL_isservice.f) ();
834
835    h = GetProcessWindowStation();
836    if (h == NULL)
837        return -1;
838
839    if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
840        GetLastError() != ERROR_INSUFFICIENT_BUFFER)
841        return -1;
842
843    if (len > 512)
844        return -1;              /* paranoia */
845    len++, len &= ~1;           /* paranoia */
846    name = (WCHAR *)alloca(len + sizeof(WCHAR));
847    if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
848        return -1;
849
850    len++, len &= ~1;           /* paranoia */
851    name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
852#  if 1
853    /*
854     * This doesn't cover "interactive" services [working with real
855     * WinSta0's] nor programs started non-interactively by Task Scheduler
856     * [those are working with SAWinSta].
857     */
858    if (wcsstr(name, L"Service-0x"))
859        return 1;
860#  else
861    /* This covers all non-interactive programs such as services. */
862    if (!wcsstr(name, L"WinSta0"))
863        return 1;
864#  endif
865    else
866        return 0;
867}
868# else
869int OPENSSL_isservice(void)
870{
871    return 0;
872}
873# endif
874
875void OPENSSL_showfatal(const char *fmta, ...)
876{
877    va_list ap;
878    TCHAR buf[256];
879    const TCHAR *fmt;
880# ifdef STD_ERROR_HANDLE        /* what a dirty trick! */
881    HANDLE h;
882
883    if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
884        GetFileType(h) != FILE_TYPE_UNKNOWN) {
885        /* must be console application */
886        int len;
887        DWORD out;
888
889        va_start(ap, fmta);
890        len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
891        WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
892        va_end(ap);
893        return;
894    }
895# endif
896
897    if (sizeof(TCHAR) == sizeof(char))
898        fmt = (const TCHAR *)fmta;
899    else
900        do {
901            int keepgoing;
902            size_t len_0 = strlen(fmta) + 1, i;
903            WCHAR *fmtw;
904
905            fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
906            if (fmtw == NULL) {
907                fmt = (const TCHAR *)L"no stack?";
908                break;
909            }
910# ifndef OPENSSL_NO_MULTIBYTE
911            if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
912# endif
913                for (i = 0; i < len_0; i++)
914                    fmtw[i] = (WCHAR)fmta[i];
915
916            for (i = 0; i < len_0; i++) {
917                if (fmtw[i] == L'%')
918                    do {
919                        keepgoing = 0;
920                        switch (fmtw[i + 1]) {
921                        case L'0':
922                        case L'1':
923                        case L'2':
924                        case L'3':
925                        case L'4':
926                        case L'5':
927                        case L'6':
928                        case L'7':
929                        case L'8':
930                        case L'9':
931                        case L'.':
932                        case L'*':
933                        case L'-':
934                            i++;
935                            keepgoing = 1;
936                            break;
937                        case L's':
938                            fmtw[i + 1] = L'S';
939                            break;
940                        case L'S':
941                            fmtw[i + 1] = L's';
942                            break;
943                        case L'c':
944                            fmtw[i + 1] = L'C';
945                            break;
946                        case L'C':
947                            fmtw[i + 1] = L'c';
948                            break;
949                        }
950                    } while (keepgoing);
951            }
952            fmt = (const TCHAR *)fmtw;
953        } while (0);
954
955    va_start(ap, fmta);
956    _vsntprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap);
957    buf[sizeof(buf) / sizeof(TCHAR) - 1] = _T('\0');
958    va_end(ap);
959
960# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
961    /* this -------------v--- guards NT-specific calls */
962    if (check_winnt() && OPENSSL_isservice() > 0) {
963        HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));
964
965        if (hEventLog != NULL) {
966            const TCHAR *pmsg = buf;
967
968            if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
969                             1, 0, &pmsg, NULL)) {
970#if defined(DEBUG)
971                /*
972                 * We are in a situation where we tried to report a critical
973                 * error and this failed for some reason. As a last resort,
974                 * in debug builds, send output to the debugger or any other
975                 * tool like DebugView which can monitor the output.
976                 */
977                OutputDebugString(pmsg);
978#endif
979            }
980
981            (void)DeregisterEventSource(hEventLog);
982        }
983    } else
984# endif
985        MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
986}
987#else
988void OPENSSL_showfatal(const char *fmta, ...)
989{
990    va_list ap;
991
992    va_start(ap, fmta);
993    vfprintf(stderr, fmta, ap);
994    va_end(ap);
995}
996
997int OPENSSL_isservice(void)
998{
999    return 0;
1000}
1001#endif
1002
1003void OpenSSLDie(const char *file, int line, const char *assertion)
1004{
1005    OPENSSL_showfatal
1006        ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line,
1007         assertion);
1008#if !defined(_WIN32) || defined(__CYGWIN__)
1009    abort();
1010#else
1011    /*
1012     * Win32 abort() customarily shows a dialog, but we just did that...
1013     */
1014# if !defined(_WIN32_WCE)
1015    raise(SIGABRT);
1016# endif
1017    _exit(3);
1018#endif
1019}
1020
1021void *OPENSSL_stderr(void)
1022{
1023    return stderr;
1024}
1025
1026int CRYPTO_memcmp(const volatile void *in_a, const volatile void *in_b, size_t len)
1027{
1028    size_t i;
1029    const volatile unsigned char *a = in_a;
1030    const volatile unsigned char *b = in_b;
1031    unsigned char x = 0;
1032
1033    for (i = 0; i < len; i++)
1034        x |= a[i] ^ b[i];
1035
1036    return x;
1037}
1038