LCOV - code coverage report
Current view: top level - third_party/openssl/crypto - cryptlib.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 41 182 22.5 %
Date: 2015-10-10 Functions: 11 36 30.6 %

          Line data    Source code
       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)
     121             : static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */
     122             : #endif
     123             : 
     124             : DECLARE_STACK_OF(CRYPTO_dynlock)
     125             : 
     126             : /* real #defines in crypto.h, keep these upto date */
     127             : static 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             :  */
     178             : static 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             :  */
     185             : static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
     186             : 
     187             : static void (MS_FAR *locking_callback) (int mode, int type,
     188             :                                         const char *file, int line) = 0;
     189             : static 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
     193             : static unsigned long (MS_FAR *id_callback) (void) = 0;
     194             : #endif
     195             : static void (MS_FAR *threadid_callback) (CRYPTO_THREADID *) = 0;
     196             : static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
     197             :  (const char *file, int line) = 0;
     198             : static void (MS_FAR *dynlock_lock_callback) (int mode,
     199             :                                              struct CRYPTO_dynlock_value *l,
     200             :                                              const char *file, int line) = 0;
     201             : static void (MS_FAR *dynlock_destroy_callback) (struct CRYPTO_dynlock_value
     202             :                                                 *l, const char *file,
     203             :                                                 int line) = 0;
     204             : 
     205           0 : int 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           0 :     if ((app_locks == NULL)
     220           0 :         && ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) {
     221           0 :         CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE);
     222           0 :         return (0);
     223             :     }
     224           0 :     if ((str = BUF_strdup(name)) == NULL) {
     225           0 :         CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE);
     226           0 :         return (0);
     227             :     }
     228           0 :     i = sk_OPENSSL_STRING_push(app_locks, str);
     229           0 :     if (!i)
     230           0 :         OPENSSL_free(str);
     231             :     else
     232           0 :         i += CRYPTO_NUM_LOCKS;  /* gap of one :-) */
     233           0 :     return (i);
     234             : }
     235             : 
     236        5203 : int CRYPTO_num_locks(void)
     237             : {
     238        5203 :     return CRYPTO_NUM_LOCKS;
     239             : }
     240             : 
     241           0 : int CRYPTO_get_new_dynlockid(void)
     242             : {
     243             :     int i = 0;
     244             :     CRYPTO_dynlock *pointer = NULL;
     245             : 
     246           0 :     if (dynlock_create_callback == NULL) {
     247           0 :         CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,
     248             :                   CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
     249           0 :         return (0);
     250             :     }
     251           0 :     CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
     252           0 :     if ((dyn_locks == NULL)
     253           0 :         && ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) {
     254           0 :         CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
     255           0 :         CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE);
     256           0 :         return (0);
     257             :     }
     258           0 :     CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
     259             : 
     260           0 :     pointer = (CRYPTO_dynlock *) OPENSSL_malloc(sizeof(CRYPTO_dynlock));
     261           0 :     if (pointer == NULL) {
     262           0 :         CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE);
     263           0 :         return (0);
     264             :     }
     265           0 :     pointer->references = 1;
     266           0 :     pointer->data = dynlock_create_callback(__FILE__, __LINE__);
     267           0 :     if (pointer->data == NULL) {
     268           0 :         OPENSSL_free(pointer);
     269           0 :         CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE);
     270           0 :         return (0);
     271             :     }
     272             : 
     273           0 :     CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
     274             :     /* First, try to find an existing empty slot */
     275           0 :     i = sk_CRYPTO_dynlock_find(dyn_locks, NULL);
     276             :     /* If there was none, push, thereby creating a new one */
     277           0 :     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           0 :         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           0 :         (void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer);
     289           0 :     CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
     290             : 
     291           0 :     if (i == -1) {
     292           0 :         dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
     293           0 :         OPENSSL_free(pointer);
     294             :     } else
     295           0 :         i += 1;                 /* to avoid 0 */
     296           0 :     return -i;
     297             : }
     298             : 
     299           0 : void CRYPTO_destroy_dynlockid(int i)
     300             : {
     301             :     CRYPTO_dynlock *pointer = NULL;
     302           0 :     if (i)
     303           0 :         i = -i - 1;
     304           0 :     if (dynlock_destroy_callback == NULL)
     305             :         return;
     306             : 
     307           0 :     CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
     308             : 
     309           0 :     if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) {
     310           0 :         CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
     311           0 :         return;
     312             :     }
     313           0 :     pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
     314           0 :     if (pointer != NULL) {
     315           0 :         --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           0 :         if (pointer->references <= 0) {
     324           0 :             (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
     325             :         } else
     326             :             pointer = NULL;
     327             :     }
     328           0 :     CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
     329             : 
     330           0 :     if (pointer) {
     331           0 :         dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
     332           0 :         OPENSSL_free(pointer);
     333             :     }
     334             : }
     335             : 
     336           0 : struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
     337             : {
     338             :     CRYPTO_dynlock *pointer = NULL;
     339           0 :     if (i)
     340           0 :         i = -i - 1;
     341             : 
     342           0 :     CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
     343             : 
     344           0 :     if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
     345           0 :         pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
     346           0 :     if (pointer)
     347           0 :         pointer->references++;
     348             : 
     349           0 :     CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
     350             : 
     351           0 :     if (pointer)
     352           0 :         return pointer->data;
     353             :     return NULL;
     354             : }
     355             : 
     356           0 : struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
     357             :  (const char *file, int line) {
     358           0 :     return (dynlock_create_callback);
     359             : }
     360             : 
     361           0 : void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode,
     362             :                                                 struct CRYPTO_dynlock_value
     363             :                                                 *l, const char *file,
     364             :                                                 int line) {
     365           0 :     return (dynlock_lock_callback);
     366             : }
     367             : 
     368           0 : void (*CRYPTO_get_dynlock_destroy_callback(void))
     369             :  (struct CRYPTO_dynlock_value *l, const char *file, int line) {
     370           0 :     return (dynlock_destroy_callback);
     371             : }
     372             : 
     373           0 : void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
     374             :                                          (const char *file, int line))
     375             : {
     376           0 :     dynlock_create_callback = func;
     377           0 : }
     378             : 
     379           0 : void 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           0 :     dynlock_lock_callback = func;
     386           0 : }
     387             : 
     388           0 : void CRYPTO_set_dynlock_destroy_callback(void (*func)
     389             :                                           (struct CRYPTO_dynlock_value *l,
     390             :                                            const char *file, int line))
     391             : {
     392           0 :     dynlock_destroy_callback = func;
     393           0 : }
     394             : 
     395           0 : void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
     396             :                                            const char *file, int line) {
     397           0 :     return (locking_callback);
     398             : }
     399             : 
     400           0 : int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type,
     401             :                                            const char *file, int line) {
     402           0 :     return (add_lock_callback);
     403             : }
     404             : 
     405         121 : void 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         121 :     OPENSSL_init();
     413         121 :     locking_callback = func;
     414         121 : }
     415             : 
     416           0 : void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
     417             :                                                const char *file, int line))
     418             : {
     419           0 :     add_lock_callback = func;
     420           0 : }
     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             :  */
     427           0 : void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
     428             : {
     429             :     memset(id, 0, sizeof(*id));
     430       36272 :     id->val = val;
     431           0 : }
     432             : 
     433             : static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
     434             : 
     435           0 : void 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         252 :     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         252 :         id->val = (unsigned long)id->ptr;
     448           0 :         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           0 : int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
     473             : {
     474           0 :     if (threadid_callback)
     475             :         return 0;
     476           0 :     threadid_callback = func;
     477           0 :     return 1;
     478             : }
     479             : 
     480           0 : void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *) {
     481           0 :     return threadid_callback;
     482             : }
     483             : 
     484       36523 : void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
     485             : {
     486       36523 :     if (threadid_callback) {
     487           0 :         threadid_callback(id);
     488           0 :         return;
     489             :     }
     490             : #ifndef OPENSSL_NO_DEPRECATED
     491             :     /* If the deprecated callback was set, fall back to that */
     492       36523 :     if (id_callback) {
     493       36271 :         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         252 :     CRYPTO_THREADID_set_pointer(id, (void *)&errno);
     507             : #endif
     508             : }
     509             : 
     510       28972 : int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
     511             : {
     512       28972 :     return memcmp(a, b, sizeof(*a));
     513             : }
     514             : 
     515       22168 : void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
     516             : {
     517             :     memcpy(dest, src, sizeof(*src));
     518       22168 : }
     519             : 
     520       21881 : unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
     521             : {
     522       21881 :     return id->val;
     523             : }
     524             : 
     525             : #ifndef OPENSSL_NO_DEPRECATED
     526           0 : unsigned long (*CRYPTO_get_id_callback(void)) (void) {
     527           0 :     return (id_callback);
     528             : }
     529             : 
     530         121 : void CRYPTO_set_id_callback(unsigned long (*func) (void))
     531             : {
     532         121 :     id_callback = func;
     533         121 : }
     534             : 
     535           0 : unsigned long CRYPTO_thread_id(void)
     536             : {
     537             :     unsigned long ret = 0;
     538             : 
     539           0 :     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           0 :         ret = (unsigned long)getpid();
     550             : # endif
     551             :     } else
     552           0 :         ret = id_callback();
     553           0 :     return (ret);
     554             : }
     555             : #endif
     556             : 
     557     7300098 : void 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     7300098 :     if (type < 0) {
     585           0 :         if (dynlock_lock_callback != NULL) {
     586           0 :             struct CRYPTO_dynlock_value *pointer
     587             :                 = CRYPTO_get_dynlock_value(type);
     588             : 
     589           0 :             OPENSSL_assert(pointer != NULL);
     590             : 
     591           0 :             dynlock_lock_callback(mode, pointer, file, line);
     592             : 
     593           0 :             CRYPTO_destroy_dynlockid(type);
     594             :         }
     595     7300098 :     } else if (locking_callback != NULL)
     596      531675 :         locking_callback(mode, type, file, line);
     597     7300208 : }
     598             : 
     599      116626 : int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
     600             :                     int line)
     601             : {
     602             :     int ret = 0;
     603             : 
     604      116626 :     if (add_lock_callback != NULL) {
     605             : #ifdef LOCK_DEBUG
     606             :         int before = *pointer;
     607             : #endif
     608             : 
     609           0 :         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      116626 :         CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
     621             : 
     622      116633 :         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      116633 :         *pointer = ret;
     634      116633 :         CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line);
     635             :     }
     636      116631 :     return (ret);
     637             : }
     638             : 
     639           0 : const char *CRYPTO_get_lock_name(int type)
     640             : {
     641           0 :     if (type < 0)
     642             :         return ("dynamic");
     643           0 :     else if (type < CRYPTO_NUM_LOCKS)
     644           0 :         return (lock_names[type]);
     645           0 :     else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
     646             :         return ("ERROR");
     647             :     else
     648           0 :         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             : 
     656             : extern unsigned int OPENSSL_ia32cap_P[4];
     657           0 : unsigned 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             : 
     667           0 :     OPENSSL_ia32cap_P[2] = 0;
     668             : 
     669           0 :     return (unsigned long *)OPENSSL_ia32cap_P;
     670             : }
     671             : 
     672             : # if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
     673             : #  define OPENSSL_CPUID_SETUP
     674             : #  if defined(_WIN32)
     675             : typedef unsigned __int64 IA32CAP;
     676             : #  else
     677             : typedef unsigned long long IA32CAP;
     678             : #  endif
     679             : void OPENSSL_cpuid_setup(void)
     680             : {
     681             :     static int trigger = 0;
     682             :     IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
     683             :     IA32CAP vec;
     684             :     char *env;
     685             : 
     686             :     if (trigger)
     687             :         return;
     688             : 
     689             :     trigger = 1;
     690             :     if ((env = getenv("OPENSSL_ia32cap"))) {
     691             :         int off = (env[0] == '~') ? 1 : 0;
     692             : #  if defined(_WIN32)
     693             :         if (!sscanf(env + off, "%I64i", &vec))
     694             :             vec = strtoul(env + off, NULL, 0);
     695             : #  else
     696             :         if (!sscanf(env + off, "%lli", (long long *)&vec))
     697             :             vec = strtoul(env + off, NULL, 0);
     698             : #  endif
     699             :         if (off)
     700             :             vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
     701             :         else if (env[0] == ':')
     702             :             vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
     703             : 
     704             :         OPENSSL_ia32cap_P[2] = 0;
     705             :         if ((env = strchr(env, ':'))) {
     706             :             unsigned int vecx;
     707             :             env++;
     708             :             off = (env[0] == '~') ? 1 : 0;
     709             :             vecx = strtoul(env + off, NULL, 0);
     710             :             if (off)
     711             :                 OPENSSL_ia32cap_P[2] &= ~vecx;
     712             :             else
     713             :                 OPENSSL_ia32cap_P[2] = vecx;
     714             :         }
     715             :     } else
     716             :         vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
     717             : 
     718             :     /*
     719             :      * |(1<<10) sets a reserved bit to signal that variable
     720             :      * was initialized already... This is to avoid interference
     721             :      * with cpuid snippets in ELF .init segment.
     722             :      */
     723             :     OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
     724             :     OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
     725             : }
     726             : # else
     727             : unsigned int OPENSSL_ia32cap_P[4];
     728             : # endif
     729             : 
     730             : #else
     731             : unsigned long *OPENSSL_ia32cap_loc(void)
     732             : {
     733             :     return NULL;
     734             : }
     735             : #endif
     736             : int OPENSSL_NONPIC_relocated = 0;
     737             : #if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
     738         121 : void OPENSSL_cpuid_setup(void)
     739             : {
     740         121 : }
     741             : #endif
     742             : 
     743             : #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
     744             : # ifdef __CYGWIN__
     745             : /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
     746             : #  include <windows.h>
     747             : /*
     748             :  * this has side-effect of _WIN32 getting defined, which otherwise is
     749             :  * mutually exclusive with __CYGWIN__...
     750             :  */
     751             : # endif
     752             : 
     753             : /*
     754             :  * All we really need to do is remove the 'error' state when a thread
     755             :  * detaches
     756             :  */
     757             : 
     758             : BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     759             : {
     760             :     switch (fdwReason) {
     761             :     case DLL_PROCESS_ATTACH:
     762             :         OPENSSL_cpuid_setup();
     763             : # if defined(_WIN32_WINNT)
     764             :         {
     765             :             IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL;
     766             :             IMAGE_NT_HEADERS *nt_headers;
     767             : 
     768             :             if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) {
     769             :                 nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header
     770             :                                                    + dos_header->e_lfanew);
     771             :                 if (nt_headers->Signature == IMAGE_NT_SIGNATURE &&
     772             :                     hinstDLL !=
     773             :                     (HINSTANCE) (nt_headers->OptionalHeader.ImageBase))
     774             :                     OPENSSL_NONPIC_relocated = 1;
     775             :             }
     776             :         }
     777             : # endif
     778             :         break;
     779             :     case DLL_THREAD_ATTACH:
     780             :         break;
     781             :     case DLL_THREAD_DETACH:
     782             :         break;
     783             :     case DLL_PROCESS_DETACH:
     784             :         break;
     785             :     }
     786             :     return (TRUE);
     787             : }
     788             : #endif
     789             : 
     790             : #if defined(_WIN32) && !defined(__CYGWIN__)
     791             : # include <tchar.h>
     792             : # include <signal.h>
     793             : # ifdef __WATCOMC__
     794             : #  if defined(_UNICODE) || defined(__UNICODE__)
     795             : #   define _vsntprintf _vsnwprintf
     796             : #  else
     797             : #   define _vsntprintf _vsnprintf
     798             : #  endif
     799             : # endif
     800             : # ifdef _MSC_VER
     801             : #  define alloca _alloca
     802             : # endif
     803             : 
     804             : # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
     805             : int OPENSSL_isservice(void)
     806             : {
     807             :     HWINSTA h;
     808             :     DWORD len;
     809             :     WCHAR *name;
     810             :     static union {
     811             :         void *p;
     812             :         int (*f) (void);
     813             :     } _OPENSSL_isservice = {
     814             :         NULL
     815             :     };
     816             : 
     817             :     if (_OPENSSL_isservice.p == NULL) {
     818             :         HANDLE h = GetModuleHandle(NULL);
     819             :         if (h != NULL)
     820             :             _OPENSSL_isservice.p = GetProcAddress(h, "_OPENSSL_isservice");
     821             :         if (_OPENSSL_isservice.p == NULL)
     822             :             _OPENSSL_isservice.p = (void *)-1;
     823             :     }
     824             : 
     825             :     if (_OPENSSL_isservice.p != (void *)-1)
     826             :         return (*_OPENSSL_isservice.f) ();
     827             : 
     828             :     h = GetProcessWindowStation();
     829             :     if (h == NULL)
     830             :         return -1;
     831             : 
     832             :     if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
     833             :         GetLastError() != ERROR_INSUFFICIENT_BUFFER)
     834             :         return -1;
     835             : 
     836             :     if (len > 512)
     837             :         return -1;              /* paranoia */
     838             :     len++, len &= ~1;           /* paranoia */
     839             :     name = (WCHAR *)alloca(len + sizeof(WCHAR));
     840             :     if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
     841             :         return -1;
     842             : 
     843             :     len++, len &= ~1;           /* paranoia */
     844             :     name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
     845             : #  if 1
     846             :     /*
     847             :      * This doesn't cover "interactive" services [working with real
     848             :      * WinSta0's] nor programs started non-interactively by Task Scheduler
     849             :      * [those are working with SAWinSta].
     850             :      */
     851             :     if (wcsstr(name, L"Service-0x"))
     852             :         return 1;
     853             : #  else
     854             :     /* This covers all non-interactive programs such as services. */
     855             :     if (!wcsstr(name, L"WinSta0"))
     856             :         return 1;
     857             : #  endif
     858             :     else
     859             :         return 0;
     860             : }
     861             : # else
     862             : int OPENSSL_isservice(void)
     863             : {
     864             :     return 0;
     865             : }
     866             : # endif
     867             : 
     868             : void OPENSSL_showfatal(const char *fmta, ...)
     869             : {
     870             :     va_list ap;
     871             :     TCHAR buf[256];
     872             :     const TCHAR *fmt;
     873             : # ifdef STD_ERROR_HANDLE        /* what a dirty trick! */
     874             :     HANDLE h;
     875             : 
     876             :     if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
     877             :         GetFileType(h) != FILE_TYPE_UNKNOWN) {
     878             :         /* must be console application */
     879             :         int len;
     880             :         DWORD out;
     881             : 
     882             :         va_start(ap, fmta);
     883             :         len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
     884             :         WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
     885             :         va_end(ap);
     886             :         return;
     887             :     }
     888             : # endif
     889             : 
     890             :     if (sizeof(TCHAR) == sizeof(char))
     891             :         fmt = (const TCHAR *)fmta;
     892             :     else
     893             :         do {
     894             :             int keepgoing;
     895             :             size_t len_0 = strlen(fmta) + 1, i;
     896             :             WCHAR *fmtw;
     897             : 
     898             :             fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
     899             :             if (fmtw == NULL) {
     900             :                 fmt = (const TCHAR *)L"no stack?";
     901             :                 break;
     902             :             }
     903             : # ifndef OPENSSL_NO_MULTIBYTE
     904             :             if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
     905             : # endif
     906             :                 for (i = 0; i < len_0; i++)
     907             :                     fmtw[i] = (WCHAR)fmta[i];
     908             : 
     909             :             for (i = 0; i < len_0; i++) {
     910             :                 if (fmtw[i] == L'%')
     911             :                     do {
     912             :                         keepgoing = 0;
     913             :                         switch (fmtw[i + 1]) {
     914             :                         case L'0':
     915             :                         case L'1':
     916             :                         case L'2':
     917             :                         case L'3':
     918             :                         case L'4':
     919             :                         case L'5':
     920             :                         case L'6':
     921             :                         case L'7':
     922             :                         case L'8':
     923             :                         case L'9':
     924             :                         case L'.':
     925             :                         case L'*':
     926             :                         case L'-':
     927             :                             i++;
     928             :                             keepgoing = 1;
     929             :                             break;
     930             :                         case L's':
     931             :                             fmtw[i + 1] = L'S';
     932             :                             break;
     933             :                         case L'S':
     934             :                             fmtw[i + 1] = L's';
     935             :                             break;
     936             :                         case L'c':
     937             :                             fmtw[i + 1] = L'C';
     938             :                             break;
     939             :                         case L'C':
     940             :                             fmtw[i + 1] = L'c';
     941             :                             break;
     942             :                         }
     943             :                     } while (keepgoing);
     944             :             }
     945             :             fmt = (const TCHAR *)fmtw;
     946             :         } while (0);
     947             : 
     948             :     va_start(ap, fmta);
     949             :     _vsntprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap);
     950             :     buf[sizeof(buf) / sizeof(TCHAR) - 1] = _T('\0');
     951             :     va_end(ap);
     952             : 
     953             : # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
     954             :     /* this -------------v--- guards NT-specific calls */
     955             :     if (check_winnt() && OPENSSL_isservice() > 0) {
     956             :         HANDLE h = RegisterEventSource(0, _T("OPENSSL"));
     957             :         const TCHAR *pmsg = buf;
     958             :         ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 0, 0, 1, 0, &pmsg, 0);
     959             :         DeregisterEventSource(h);
     960             :     } else
     961             : # endif
     962             :         MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONSTOP);
     963             : }
     964             : #else
     965           0 : void OPENSSL_showfatal(const char *fmta, ...)
     966             : {
     967             :     va_list ap;
     968             : 
     969           0 :     va_start(ap, fmta);
     970           0 :     vfprintf(stderr, fmta, ap);
     971           0 :     va_end(ap);
     972           0 : }
     973             : 
     974           0 : int OPENSSL_isservice(void)
     975             : {
     976           0 :     return 0;
     977             : }
     978             : #endif
     979             : 
     980           0 : void OpenSSLDie(const char *file, int line, const char *assertion)
     981             : {
     982             :     OPENSSL_showfatal
     983           0 :         ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line,
     984             :          assertion);
     985             : #if !defined(_WIN32) || defined(__CYGWIN__)
     986           0 :     abort();
     987             : #else
     988             :     /*
     989             :      * Win32 abort() customarily shows a dialog, but we just did that...
     990             :      */
     991             : # if !defined(_WIN32_WCE)
     992             :     raise(SIGABRT);
     993             : # endif
     994             :     _exit(3);
     995             : #endif
     996             : }
     997             : 
     998           0 : void *OPENSSL_stderr(void)
     999             : {
    1000           0 :     return stderr;
    1001             : }
    1002             : 
    1003        6713 : int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
    1004             : {
    1005             :     size_t i;
    1006             :     const unsigned char *a = in_a;
    1007             :     const unsigned char *b = in_b;
    1008             :     unsigned char x = 0;
    1009             : 
    1010      111193 :     for (i = 0; i < len; i++)
    1011      104480 :         x |= a[i] ^ b[i];
    1012             : 
    1013        6713 :     return x;
    1014             : }

Generated by: LCOV version 1.10