cryptlib.c revision 296341
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
472int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
473{
474    if (threadid_callback)
475        return 0;
476    threadid_callback = func;
477    return 1;
478}
479
480void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *) {
481    return threadid_callback;
482}
483
484void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
485{
486    if (threadid_callback) {
487        threadid_callback(id);
488        return;
489    }
490#ifndef OPENSSL_NO_DEPRECATED
491    /* If the deprecated callback was set, fall back to that */
492    if (id_callback) {
493        CRYPTO_THREADID_set_numeric(id, id_callback());
494        return;
495    }
496#endif
497    /* Else pick a backup */
498#ifdef OPENSSL_SYS_WIN16
499    CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
500#elif defined(OPENSSL_SYS_WIN32)
501    CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
502#elif defined(OPENSSL_SYS_BEOS)
503    CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
504#else
505    /* For everything else, default to using the address of 'errno' */
506    CRYPTO_THREADID_set_pointer(id, (void *)&errno);
507#endif
508}
509
510int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
511{
512    return memcmp(a, b, sizeof(*a));
513}
514
515void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
516{
517    memcpy(dest, src, sizeof(*src));
518}
519
520unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
521{
522    return id->val;
523}
524
525#ifndef OPENSSL_NO_DEPRECATED
526unsigned long (*CRYPTO_get_id_callback(void)) (void) {
527    return (id_callback);
528}
529
530void CRYPTO_set_id_callback(unsigned long (*func) (void))
531{
532    id_callback = func;
533}
534
535unsigned long CRYPTO_thread_id(void)
536{
537    unsigned long ret = 0;
538
539    if (id_callback == NULL) {
540# ifdef OPENSSL_SYS_WIN16
541        ret = (unsigned long)GetCurrentTask();
542# elif defined(OPENSSL_SYS_WIN32)
543        ret = (unsigned long)GetCurrentThreadId();
544# elif defined(GETPID_IS_MEANINGLESS)
545        ret = 1L;
546# elif defined(OPENSSL_SYS_BEOS)
547        ret = (unsigned long)find_thread(NULL);
548# else
549        ret = (unsigned long)getpid();
550# endif
551    } else
552        ret = id_callback();
553    return (ret);
554}
555#endif
556
557void CRYPTO_lock(int mode, int type, const char *file, int line)
558{
559#ifdef LOCK_DEBUG
560    {
561        CRYPTO_THREADID id;
562        char *rw_text, *operation_text;
563
564        if (mode & CRYPTO_LOCK)
565            operation_text = "lock  ";
566        else if (mode & CRYPTO_UNLOCK)
567            operation_text = "unlock";
568        else
569            operation_text = "ERROR ";
570
571        if (mode & CRYPTO_READ)
572            rw_text = "r";
573        else if (mode & CRYPTO_WRITE)
574            rw_text = "w";
575        else
576            rw_text = "ERROR";
577
578        CRYPTO_THREADID_current(&id);
579        fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n",
580                CRYPTO_THREADID_hash(&id), rw_text, operation_text,
581                CRYPTO_get_lock_name(type), file, line);
582    }
583#endif
584    if (type < 0) {
585        if (dynlock_lock_callback != NULL) {
586            struct CRYPTO_dynlock_value *pointer
587                = CRYPTO_get_dynlock_value(type);
588
589            OPENSSL_assert(pointer != NULL);
590
591            dynlock_lock_callback(mode, pointer, file, line);
592
593            CRYPTO_destroy_dynlockid(type);
594        }
595    } else if (locking_callback != NULL)
596        locking_callback(mode, type, file, line);
597}
598
599int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
600                    int line)
601{
602    int ret = 0;
603
604    if (add_lock_callback != NULL) {
605#ifdef LOCK_DEBUG
606        int before = *pointer;
607#endif
608
609        ret = add_lock_callback(pointer, amount, type, file, line);
610#ifdef LOCK_DEBUG
611        {
612            CRYPTO_THREADID id;
613            CRYPTO_THREADID_current(&id);
614            fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
615                    CRYPTO_THREADID_hash(&id), before, amount, ret,
616                    CRYPTO_get_lock_name(type), file, line);
617        }
618#endif
619    } else {
620        CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
621
622        ret = *pointer + amount;
623#ifdef LOCK_DEBUG
624        {
625            CRYPTO_THREADID id;
626            CRYPTO_THREADID_current(&id);
627            fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
628                    CRYPTO_THREADID_hash(&id),
629                    *pointer, amount, ret,
630                    CRYPTO_get_lock_name(type), file, line);
631        }
632#endif
633        *pointer = ret;
634        CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line);
635    }
636    return (ret);
637}
638
639const char *CRYPTO_get_lock_name(int type)
640{
641    if (type < 0)
642        return ("dynamic");
643    else if (type < CRYPTO_NUM_LOCKS)
644        return (lock_names[type]);
645    else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
646        return ("ERROR");
647    else
648        return (sk_OPENSSL_STRING_value(app_locks, type - CRYPTO_NUM_LOCKS));
649}
650
651#if     defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
652        defined(__INTEL__) || \
653        defined(__x86_64) || defined(__x86_64__) || \
654        defined(_M_AMD64) || defined(_M_X64)
655
656unsigned int OPENSSL_ia32cap_P[2];
657unsigned long *OPENSSL_ia32cap_loc(void)
658{
659    if (sizeof(long) == 4)
660        /*
661         * If 32-bit application pulls address of OPENSSL_ia32cap_P[0]
662         * clear second element to maintain the illusion that vector
663         * is 32-bit.
664         */
665        OPENSSL_ia32cap_P[1] = 0;
666    return (unsigned long *)OPENSSL_ia32cap_P;
667}
668
669# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
670#  define OPENSSL_CPUID_SETUP
671#  if defined(_WIN32)
672typedef unsigned __int64 IA32CAP;
673#  else
674typedef unsigned long long IA32CAP;
675#  endif
676void OPENSSL_cpuid_setup(void)
677{
678    static int trigger = 0;
679    IA32CAP OPENSSL_ia32_cpuid(void);
680    IA32CAP vec;
681    char *env;
682
683    if (trigger)
684        return;
685
686    trigger = 1;
687    if ((env = getenv("OPENSSL_ia32cap"))) {
688        int off = (env[0] == '~') ? 1 : 0;
689#  if defined(_WIN32)
690        if (!sscanf(env + off, "%I64i", &vec))
691            vec = strtoul(env + off, NULL, 0);
692#  else
693        if (!sscanf(env + off, "%lli", (long long *)&vec))
694            vec = strtoul(env + off, NULL, 0);
695#  endif
696        if (off)
697            vec = OPENSSL_ia32_cpuid() & ~vec;
698    } else
699        vec = OPENSSL_ia32_cpuid();
700
701    /*
702     * |(1<<10) sets a reserved bit to signal that variable
703     * was initialized already... This is to avoid interference
704     * with cpuid snippets in ELF .init segment.
705     */
706    OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
707    OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
708}
709# endif
710
711#else
712unsigned long *OPENSSL_ia32cap_loc(void)
713{
714    return NULL;
715}
716#endif
717int OPENSSL_NONPIC_relocated = 0;
718#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
719void OPENSSL_cpuid_setup(void)
720{
721}
722#endif
723
724#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
725# ifdef __CYGWIN__
726/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
727#  include <windows.h>
728/*
729 * this has side-effect of _WIN32 getting defined, which otherwise is
730 * mutually exclusive with __CYGWIN__...
731 */
732# endif
733
734/*
735 * All we really need to do is remove the 'error' state when a thread
736 * detaches
737 */
738
739BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
740{
741    switch (fdwReason) {
742    case DLL_PROCESS_ATTACH:
743        OPENSSL_cpuid_setup();
744# if defined(_WIN32_WINNT)
745        {
746            IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL;
747            IMAGE_NT_HEADERS *nt_headers;
748
749            if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) {
750                nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header
751                                                   + dos_header->e_lfanew);
752                if (nt_headers->Signature == IMAGE_NT_SIGNATURE &&
753                    hinstDLL !=
754                    (HINSTANCE) (nt_headers->OptionalHeader.ImageBase))
755                    OPENSSL_NONPIC_relocated = 1;
756            }
757        }
758# endif
759        break;
760    case DLL_THREAD_ATTACH:
761        break;
762    case DLL_THREAD_DETACH:
763        break;
764    case DLL_PROCESS_DETACH:
765        break;
766    }
767    return (TRUE);
768}
769#endif
770
771#if defined(_WIN32) && !defined(__CYGWIN__)
772# include <tchar.h>
773# include <signal.h>
774# ifdef __WATCOMC__
775#  if defined(_UNICODE) || defined(__UNICODE__)
776#   define _vsntprintf _vsnwprintf
777#  else
778#   define _vsntprintf _vsnprintf
779#  endif
780# endif
781# ifdef _MSC_VER
782#  define alloca _alloca
783# endif
784
785# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
786int OPENSSL_isservice(void)
787{
788    HWINSTA h;
789    DWORD len;
790    WCHAR *name;
791    static union {
792        void *p;
793        int (*f) (void);
794    } _OPENSSL_isservice = {
795        NULL
796    };
797
798    if (_OPENSSL_isservice.p == NULL) {
799        HANDLE h = GetModuleHandle(NULL);
800        if (h != NULL)
801            _OPENSSL_isservice.p = GetProcAddress(h, "_OPENSSL_isservice");
802        if (_OPENSSL_isservice.p == NULL)
803            _OPENSSL_isservice.p = (void *)-1;
804    }
805
806    if (_OPENSSL_isservice.p != (void *)-1)
807        return (*_OPENSSL_isservice.f) ();
808
809    h = GetProcessWindowStation();
810    if (h == NULL)
811        return -1;
812
813    if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
814        GetLastError() != ERROR_INSUFFICIENT_BUFFER)
815        return -1;
816
817    if (len > 512)
818        return -1;              /* paranoia */
819    len++, len &= ~1;           /* paranoia */
820    name = (WCHAR *)alloca(len + sizeof(WCHAR));
821    if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
822        return -1;
823
824    len++, len &= ~1;           /* paranoia */
825    name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
826#  if 1
827    /*
828     * This doesn't cover "interactive" services [working with real
829     * WinSta0's] nor programs started non-interactively by Task Scheduler
830     * [those are working with SAWinSta].
831     */
832    if (wcsstr(name, L"Service-0x"))
833        return 1;
834#  else
835    /* This covers all non-interactive programs such as services. */
836    if (!wcsstr(name, L"WinSta0"))
837        return 1;
838#  endif
839    else
840        return 0;
841}
842# else
843int OPENSSL_isservice(void)
844{
845    return 0;
846}
847# endif
848
849void OPENSSL_showfatal(const char *fmta, ...)
850{
851    va_list ap;
852    TCHAR buf[256];
853    const TCHAR *fmt;
854# ifdef STD_ERROR_HANDLE        /* what a dirty trick! */
855    HANDLE h;
856
857    if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
858        GetFileType(h) != FILE_TYPE_UNKNOWN) {
859        /* must be console application */
860        va_start(ap, fmta);
861        vfprintf(stderr, fmta, ap);
862        va_end(ap);
863        return;
864    }
865# endif
866
867    if (sizeof(TCHAR) == sizeof(char))
868        fmt = (const TCHAR *)fmta;
869    else
870        do {
871            int keepgoing;
872            size_t len_0 = strlen(fmta) + 1, i;
873            WCHAR *fmtw;
874
875            fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
876            if (fmtw == NULL) {
877                fmt = (const TCHAR *)L"no stack?";
878                break;
879            }
880# ifndef OPENSSL_NO_MULTIBYTE
881            if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
882# endif
883                for (i = 0; i < len_0; i++)
884                    fmtw[i] = (WCHAR)fmta[i];
885
886            for (i = 0; i < len_0; i++) {
887                if (fmtw[i] == L'%')
888                    do {
889                        keepgoing = 0;
890                        switch (fmtw[i + 1]) {
891                        case L'0':
892                        case L'1':
893                        case L'2':
894                        case L'3':
895                        case L'4':
896                        case L'5':
897                        case L'6':
898                        case L'7':
899                        case L'8':
900                        case L'9':
901                        case L'.':
902                        case L'*':
903                        case L'-':
904                            i++;
905                            keepgoing = 1;
906                            break;
907                        case L's':
908                            fmtw[i + 1] = L'S';
909                            break;
910                        case L'S':
911                            fmtw[i + 1] = L's';
912                            break;
913                        case L'c':
914                            fmtw[i + 1] = L'C';
915                            break;
916                        case L'C':
917                            fmtw[i + 1] = L'c';
918                            break;
919                        }
920                    } while (keepgoing);
921            }
922            fmt = (const TCHAR *)fmtw;
923        } while (0);
924
925    va_start(ap, fmta);
926    _vsntprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap);
927    buf[sizeof(buf) / sizeof(TCHAR) - 1] = _T('\0');
928    va_end(ap);
929
930# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
931    /* this -------------v--- guards NT-specific calls */
932    if (check_winnt() && OPENSSL_isservice() > 0) {
933        HANDLE h = RegisterEventSource(0, _T("OPENSSL"));
934        const TCHAR *pmsg = buf;
935        ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 0, 0, 1, 0, &pmsg, 0);
936        DeregisterEventSource(h);
937    } else
938# endif
939        MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONSTOP);
940}
941#else
942void OPENSSL_showfatal(const char *fmta, ...)
943{
944    va_list ap;
945
946    va_start(ap, fmta);
947    vfprintf(stderr, fmta, ap);
948    va_end(ap);
949}
950
951int OPENSSL_isservice(void)
952{
953    return 0;
954}
955#endif
956
957void OpenSSLDie(const char *file, int line, const char *assertion)
958{
959    OPENSSL_showfatal
960        ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line,
961         assertion);
962#if !defined(_WIN32) || defined(__CYGWIN__)
963    abort();
964#else
965    /*
966     * Win32 abort() customarily shows a dialog, but we just did that...
967     */
968    raise(SIGABRT);
969    _exit(3);
970#endif
971}
972
973void *OPENSSL_stderr(void)
974{
975    return stderr;
976}
977
978int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
979{
980    size_t i;
981    const unsigned char *a = in_a;
982    const unsigned char *b = in_b;
983    unsigned char x = 0;
984
985    for (i = 0; i < len; i++)
986        x |= a[i] ^ b[i];
987
988    return x;
989}
990