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         {
 129         "<<ERROR>>",
 130         "err",
 131         "ex_data",
 132         "x509",
 133         "x509_info",
 134         "x509_pkey",
 135         "x509_crl",
 136         "x509_req",
 137         "dsa",
 138         "rsa",
 139         "evp_pkey",
 140         "x509_store",
 141         "ssl_ctx",
 142         "ssl_cert",
 143         "ssl_session",
 144         "ssl_sess_cert",
 145         "ssl",
 146         "ssl_method",
 147         "rand",
 148         "rand2",
 149         "debug_malloc",
 150         "BIO",
 151         "gethostbyname",
 152         "getservbyname",
 153         "readdir",
 154         "RSA_blinding",
 155         "dh",
 156         "debug_malloc2",
 157         "dso",
 158         "dynlock",
 159         "engine",
 160         "ui",
 161         "ecdsa",
 162         "ec",
 163         "ecdh",
 164         "bn",
 165         "ec_pre_comp",
 166         "store",
 167         "comp",
 168         "fips",
 169         "fips2",
 170 #if CRYPTO_NUM_LOCKS != 41
 171 # error "Inconsistency between crypto.h and cryptlib.c"
 172 #endif
 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 static STACK_OF(OPENSSL_STRING) *app_locks=NULL;
 178 
 179 /* For applications that want a more dynamic way of handling threads, the
 180    following stack is used.  These are externally numbered with negative
 181    numbers.  */
 182 static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
 183 
 184 
 185 static void (MS_FAR *locking_callback)(int mode,int type,
 186         const char *file,int line)=0;
 187 static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
 188         int type,const char *file,int line)=0;
 189 #ifndef OPENSSL_NO_DEPRECATED
 190 static unsigned long (MS_FAR *id_callback)(void)=0;
 191 #endif
 192 static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0;
 193 static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
 194         (const char *file,int line)=0;
 195 static void (MS_FAR *dynlock_lock_callback)(int mode,
 196         struct CRYPTO_dynlock_value *l, const char *file,int line)=0;
 197 static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
 198         const char *file,int line)=0;
 199 
 200 int CRYPTO_get_new_lockid(char *name)
 201         {
 202         char *str;
 203         int i;
 204 
 205 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
 206         /* A hack to make Visual C++ 5.0 work correctly when linking as
 207          * a DLL using /MT. Without this, the application cannot use
 208          * any floating point printf's.
 209          * It also seems to be needed for Visual C 1.5 (win16) */
 210         SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
 211 #endif
 212 
 213         if ((app_locks == NULL) && ((app_locks=sk_OPENSSL_STRING_new_null()) == NULL))
 214                 {
 215                 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
 216                 return(0);
 217                 }
 218         if ((str=BUF_strdup(name)) == NULL)
 219                 {
 220                 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
 221                 return(0);
 222                 }
 223         i=sk_OPENSSL_STRING_push(app_locks,str);
 224         if (!i)
 225                 OPENSSL_free(str);
 226         else
 227                 i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
 228         return(i);
 229         }
 230 
 231 int CRYPTO_num_locks(void)
 232         {
 233         return CRYPTO_NUM_LOCKS;
 234         }
 235 
 236 int CRYPTO_get_new_dynlockid(void)
 237         {
 238         int i = 0;
 239         CRYPTO_dynlock *pointer = NULL;
 240 
 241         if (dynlock_create_callback == NULL)
 242                 {
 243                 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
 244                 return(0);
 245                 }
 246         CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
 247         if ((dyn_locks == NULL)
 248                 && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
 249                 {
 250                 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
 251                 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
 252                 return(0);
 253                 }
 254         CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
 255 
 256         pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
 257         if (pointer == NULL)
 258                 {
 259                 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
 260                 return(0);
 261                 }
 262         pointer->references = 1;
 263         pointer->data = dynlock_create_callback(__FILE__,__LINE__);
 264         if (pointer->data == NULL)
 265                 {
 266                 OPENSSL_free(pointer);
 267                 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
 268                 return(0);
 269                 }
 270 
 271         CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
 272         /* First, try to find an existing empty slot */
 273         i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
 274         /* If there was none, push, thereby creating a new one */
 275         if (i == -1)
 276                 /* Since sk_push() returns the number of items on the
 277                    stack, not the location of the pushed item, we need
 278                    to transform the returned number into a position,
 279                    by decreasing it.  */
 280                 i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
 281         else
 282                 /* If we found a place with a NULL pointer, put our pointer
 283                    in it.  */
 284                 (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
 285         CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
 286 
 287         if (i == -1)
 288                 {
 289                 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
 290                 OPENSSL_free(pointer);
 291                 }
 292         else
 293                 i += 1; /* to avoid 0 */
 294         return -i;
 295         }
 296 
 297 void CRYPTO_destroy_dynlockid(int i)
 298         {
 299         CRYPTO_dynlock *pointer = NULL;
 300         if (i)
 301                 i = -i-1;
 302         if (dynlock_destroy_callback == NULL)
 303                 return;
 304 
 305         CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
 306 
 307         if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
 308                 {
 309                 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
 310                 return;
 311                 }
 312         pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
 313         if (pointer != NULL)
 314                 {
 315                 --pointer->references;
 316 #ifdef REF_CHECK
 317                 if (pointer->references < 0)
 318                         {
 319                         fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
 320                         abort();
 321                         }
 322                 else
 323 #endif
 324                         if (pointer->references <= 0)
 325                                 {
 326                                 (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
 327                                 }
 328                         else
 329                                 pointer = NULL;
 330                 }
 331         CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
 332 
 333         if (pointer)
 334                 {
 335                 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
 336                 OPENSSL_free(pointer);
 337                 }
 338         }
 339 
 340 struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
 341         {
 342         CRYPTO_dynlock *pointer = NULL;
 343         if (i)
 344                 i = -i-1;
 345 
 346         CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
 347 
 348         if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
 349                 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
 350         if (pointer)
 351                 pointer->references++;
 352 
 353         CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
 354 
 355         if (pointer)
 356                 return pointer->data;
 357         return NULL;
 358         }
 359 
 360 struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
 361         (const char *file,int line)
 362         {
 363         return(dynlock_create_callback);
 364         }
 365 
 366 void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
 367         struct CRYPTO_dynlock_value *l, const char *file,int line)
 368         {
 369         return(dynlock_lock_callback);
 370         }
 371 
 372 void (*CRYPTO_get_dynlock_destroy_callback(void))
 373         (struct CRYPTO_dynlock_value *l, const char *file,int line)
 374         {
 375         return(dynlock_destroy_callback);
 376         }
 377 
 378 void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
 379         (const char *file, int line))
 380         {
 381         dynlock_create_callback=func;
 382         }
 383 
 384 void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
 385         struct CRYPTO_dynlock_value *l, const char *file, int line))
 386         {
 387         dynlock_lock_callback=func;
 388         }
 389 
 390 void CRYPTO_set_dynlock_destroy_callback(void (*func)
 391         (struct CRYPTO_dynlock_value *l, const char *file, int line))
 392         {
 393         dynlock_destroy_callback=func;
 394         }
 395 
 396 
 397 void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
 398                 int line)
 399         {
 400         return(locking_callback);
 401         }
 402 
 403 int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
 404                                           const char *file,int line)
 405         {
 406         return(add_lock_callback);
 407         }
 408 
 409 void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
 410                                               const char *file,int line))
 411         {
 412         /* Calling this here ensures initialisation before any threads
 413          * are started.
 414          */
 415         OPENSSL_init();
 416         locking_callback=func;
 417         }
 418 
 419 void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
 420                                               const char *file,int line))
 421         {
 422         add_lock_callback=func;
 423         }
 424 
 425 /* the memset() here and in set_pointer() seem overkill, but for the sake of
 426  * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
 427  * "equal" THREADID structs to not be memcmp()-identical. */
 428 void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
 429         {
 430         memset(id, 0, sizeof(*id));
 431         id->val = val;
 432         }
 433 
 434 static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
 435 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         id->ptr = ptr;
 443         if (sizeof(id->val) >= sizeof(id->ptr))
 444                 {
 445                 /* 'ptr' can be embedded in 'val' without loss of uniqueness */
 446                 id->val = (unsigned long)id->ptr;
 447                 return;
 448                 }
 449         /* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
 450          * linear function over the bytes in 'ptr', the co-efficients of which
 451          * are a sequence of low-primes (hash_coeffs is an 8-element cycle) -
 452          * the starting prime for the sequence varies for each byte of 'val'
 453          * (unique polynomials unless pointers are >64-bit). For added spice,
 454          * the totals accumulate rather than restarting from zero, and the index
 455          * of the 'val' byte is added each time (position dependence). If I was
 456          * a black-belt, I'd scan big-endian pointers in reverse to give
 457          * low-order bits more play, but this isn't crypto and I'd prefer nobody
 458          * mistake it as such. Plus I'm lazy. */
 459         while (dnum--)
 460                 {
 461                 const unsigned char *src = (void *)&id->ptr;
 462                 unsigned char snum = sizeof(id->ptr);
 463                 while (snum--)
 464                         accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
 465                 accum += dnum;
 466                 *(dest++) = accum & 255;
 467                 }
 468         }
 469 
 470 int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
 471         {
 472         if (threadid_callback)
 473                 return 0;
 474         threadid_callback = func;
 475         return 1;
 476         }
 477 
 478 void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
 479         {
 480         return threadid_callback;
 481         }
 482 
 483 void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
 484         {
 485         if (threadid_callback)
 486                 {
 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                 {
 494                 CRYPTO_THREADID_set_numeric(id, id_callback());
 495                 return;
 496                 }
 497 #endif
 498         /* Else pick a backup */
 499 #ifdef OPENSSL_SYS_WIN16
 500         CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
 501 #elif defined(OPENSSL_SYS_WIN32)
 502         CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
 503 #elif defined(OPENSSL_SYS_BEOS)
 504         CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
 505 #else
 506         /* For everything else, default to using the address of 'errno' */
 507         CRYPTO_THREADID_set_pointer(id, (void*)&errno);
 508 #endif
 509         }
 510 
 511 int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
 512         {
 513         return memcmp(a, b, sizeof(*a));
 514         }
 515 
 516 void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
 517         {
 518         memcpy(dest, src, sizeof(*src));
 519         }
 520 
 521 unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
 522         {
 523         return id->val;
 524         }
 525 
 526 #ifndef OPENSSL_NO_DEPRECATED
 527 unsigned long (*CRYPTO_get_id_callback(void))(void)
 528         {
 529         return(id_callback);
 530         }
 531 
 532 void CRYPTO_set_id_callback(unsigned long (*func)(void))
 533         {
 534         id_callback=func;
 535         }
 536 
 537 unsigned long CRYPTO_thread_id(void)
 538         {
 539         unsigned long ret=0;
 540 
 541         if (id_callback == NULL)
 542                 {
 543 #ifdef OPENSSL_SYS_WIN16
 544                 ret=(unsigned long)GetCurrentTask();
 545 #elif defined(OPENSSL_SYS_WIN32)
 546                 ret=(unsigned long)GetCurrentThreadId();
 547 #elif defined(GETPID_IS_MEANINGLESS)
 548                 ret=1L;
 549 #elif defined(OPENSSL_SYS_BEOS)
 550                 ret=(unsigned long)find_thread(NULL);
 551 #else
 552                 ret=(unsigned long)getpid();
 553 #endif
 554                 }
 555         else
 556                 ret=id_callback();
 557         return(ret);
 558         }
 559 #endif
 560 
 561 void CRYPTO_lock(int mode, int type, const char *file, int line)
 562         {
 563 #ifdef LOCK_DEBUG
 564                 {
 565                 CRYPTO_THREADID id;
 566                 char *rw_text,*operation_text;
 567 
 568                 if (mode & CRYPTO_LOCK)
 569                         operation_text="lock  ";
 570                 else if (mode & CRYPTO_UNLOCK)
 571                         operation_text="unlock";
 572                 else
 573                         operation_text="ERROR ";
 574 
 575                 if (mode & CRYPTO_READ)
 576                         rw_text="r";
 577                 else if (mode & CRYPTO_WRITE)
 578                         rw_text="w";
 579                 else
 580                         rw_text="ERROR";
 581 
 582                 CRYPTO_THREADID_current(&id);
 583                 fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
 584                         CRYPTO_THREADID_hash(&id), rw_text, operation_text,
 585                         CRYPTO_get_lock_name(type), file, line);
 586                 }
 587 #endif
 588         if (type < 0)
 589                 {
 590                 if (dynlock_lock_callback != NULL)
 591                         {
 592                         struct CRYPTO_dynlock_value *pointer
 593                                 = CRYPTO_get_dynlock_value(type);
 594 
 595                         OPENSSL_assert(pointer != NULL);
 596 
 597                         dynlock_lock_callback(mode, pointer, file, line);
 598 
 599                         CRYPTO_destroy_dynlockid(type);
 600                         }
 601                 }
 602         else
 603                 if (locking_callback != NULL)
 604                         locking_callback(mode,type,file,line);
 605         }
 606 
 607 int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
 608              int line)
 609         {
 610         int ret = 0;
 611 
 612         if (add_lock_callback != NULL)
 613                 {
 614 #ifdef LOCK_DEBUG
 615                 int before= *pointer;
 616 #endif
 617 
 618                 ret=add_lock_callback(pointer,amount,type,file,line);
 619 #ifdef LOCK_DEBUG
 620                 {
 621                 CRYPTO_THREADID id;
 622                 CRYPTO_THREADID_current(&id);
 623                 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
 624                         CRYPTO_THREADID_hash(&id), before,amount,ret,
 625                         CRYPTO_get_lock_name(type),
 626                         file,line);
 627                 }
 628 #endif
 629                 }
 630         else
 631                 {
 632                 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);
 633 
 634                 ret= *pointer+amount;
 635 #ifdef LOCK_DEBUG
 636                 {
 637                 CRYPTO_THREADID id;
 638                 CRYPTO_THREADID_current(&id);
 639                 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
 640                         CRYPTO_THREADID_hash(&id),
 641                         *pointer,amount,ret,
 642                         CRYPTO_get_lock_name(type),
 643                         file,line);
 644                 }
 645 #endif
 646                 *pointer=ret;
 647                 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
 648                 }
 649         return(ret);
 650         }
 651 
 652 const char *CRYPTO_get_lock_name(int type)
 653         {
 654         if (type < 0)
 655                 return("dynamic");
 656         else if (type < CRYPTO_NUM_LOCKS)
 657                 return(lock_names[type]);
 658         else if (type-CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
 659                 return("ERROR");
 660         else
 661                 return(sk_OPENSSL_STRING_value(app_locks,type-CRYPTO_NUM_LOCKS));
 662         }
 663 
 664 #if     defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
 665         defined(__INTEL__) || \
 666         defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
 667 
 668 unsigned int  OPENSSL_ia32cap_P[2];
 669 unsigned long *OPENSSL_ia32cap_loc(void)
 670 {   if (sizeof(long)==4)
 671         /*
 672          * If 32-bit application pulls address of OPENSSL_ia32cap_P[0]
 673          * clear second element to maintain the illusion that vector
 674          * is 32-bit.
 675          */
 676         OPENSSL_ia32cap_P[1]=0;
 677     return (unsigned long *)OPENSSL_ia32cap_P;
 678 }
 679 
 680 #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
 681 #define OPENSSL_CPUID_SETUP
 682 #if defined(_WIN32)
 683 typedef unsigned __int64 IA32CAP;
 684 #else
 685 typedef unsigned long long IA32CAP;
 686 #endif
 687 void OPENSSL_cpuid_setup(void)
 688 { static int trigger=0;
 689   IA32CAP OPENSSL_ia32_cpuid(void);
 690   IA32CAP vec;
 691   char *env;
 692 
 693     if (trigger)        return;
 694 
 695     trigger=1;
 696     if ((env=getenv("OPENSSL_ia32cap"))) {
 697         int off = (env[0]=='~')?1:0;
 698 #if defined(_WIN32)
 699         if (!sscanf(env+off,"%I64i",&vec)) vec = strtoul(env+off,NULL,0);
 700 #else
 701         if (!sscanf(env+off,"%lli",(long long *)&vec)) vec = strtoul(env+off,NULL,0);
 702 #endif
 703         if (off) vec = OPENSSL_ia32_cpuid()&~vec;
 704     }
 705     else
 706         vec = OPENSSL_ia32_cpuid();
 707 
 708     /*
 709      * |(1<<10) sets a reserved bit to signal that variable
 710      * was initialized already... This is to avoid interference
 711      * with cpuid snippets in ELF .init segment.
 712      */
 713     OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10);
 714     OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32);
 715 }
 716 #endif
 717 
 718 #else
 719 unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; }
 720 #endif
 721 int OPENSSL_NONPIC_relocated = 0;
 722 #if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
 723 void OPENSSL_cpuid_setup(void) {}
 724 #endif
 725 
 726 #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
 727 #ifdef __CYGWIN__
 728 /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
 729 #include <windows.h>
 730 /* this has side-effect of _WIN32 getting defined, which otherwise
 731  * is mutually exclusive with __CYGWIN__... */
 732 #endif
 733 
 734 /* All we really need to do is remove the 'error' state when a thread
 735  * detaches */
 736 
 737 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
 738              LPVOID lpvReserved)
 739         {
 740         switch(fdwReason)
 741                 {
 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                         {
 751                         nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header
 752                                                 + dos_header->e_lfanew);
 753                         if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
 754                             hinstDLL!=(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
 786 int OPENSSL_isservice(void)
 787 { HWINSTA h;
 788   DWORD len;
 789   WCHAR *name;
 790   static union { void *p; int (*f)(void); } _OPENSSL_isservice = { NULL };
 791 
 792     if (_OPENSSL_isservice.p == NULL) {
 793         HANDLE h = GetModuleHandle(NULL);
 794         if (h != NULL)
 795             _OPENSSL_isservice.p = GetProcAddress(h,"_OPENSSL_isservice");
 796         if (_OPENSSL_isservice.p == NULL)
 797             _OPENSSL_isservice.p = (void *)-1;
 798     }
 799 
 800     if (_OPENSSL_isservice.p != (void *)-1)
 801         return (*_OPENSSL_isservice.f)();
 802 
 803     (void)GetDesktopWindow(); /* return value is ignored */
 804 
 805     h = GetProcessWindowStation();
 806     if (h==NULL) return -1;
 807 
 808     if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) ||
 809         GetLastError() != ERROR_INSUFFICIENT_BUFFER)
 810         return -1;
 811 
 812     if (len>512) return -1;          /* paranoia */
 813     len++,len&=~1;                  /* paranoia */
 814     name=(WCHAR *)alloca(len+sizeof(WCHAR));
 815     if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len))
 816         return -1;
 817 
 818     len++,len&=~1;                  /* paranoia */
 819     name[len/sizeof(WCHAR)]=L'\0';      /* paranoia */
 820 #if 1
 821     /* This doesn't cover "interactive" services [working with real
 822      * WinSta0's] nor programs started non-interactively by Task
 823      * Scheduler [those are working with SAWinSta]. */
 824     if (wcsstr(name,L"Service-0x"))     return 1;
 825 #else
 826     /* This covers all non-interactive programs such as services. */
 827     if (!wcsstr(name,L"WinSta0"))       return 1;
 828 #endif
 829     else                                return 0;
 830 }
 831 #else
 832 int OPENSSL_isservice(void) { return 0; }
 833 #endif
 834 
 835 void OPENSSL_showfatal (const char *fmta,...)
 836 { va_list ap;
 837   TCHAR buf[256];
 838   const TCHAR *fmt;
 839 #ifdef STD_ERROR_HANDLE /* what a dirty trick! */
 840   HANDLE h;
 841 
 842     if ((h=GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
 843         GetFileType(h)!=FILE_TYPE_UNKNOWN)
 844     {   /* must be console application */
 845         va_start (ap,fmta);
 846         vfprintf (stderr,fmta,ap);
 847         va_end (ap);
 848         return;
 849     }
 850 #endif
 851 
 852     if (sizeof(TCHAR)==sizeof(char))
 853         fmt=(const TCHAR *)fmta;
 854     else do
 855     { int    keepgoing;
 856       size_t len_0=strlen(fmta)+1,i;
 857       WCHAR *fmtw;
 858 
 859         fmtw = (WCHAR *)alloca(len_0*sizeof(WCHAR));
 860         if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; }
 861 
 862 #ifndef OPENSSL_NO_MULTIBYTE
 863         if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0))
 864 #endif
 865             for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i];
 866 
 867         for (i=0;i<len_0;i++)
 868         {   if (fmtw[i]==L'%') do
 869             {   keepgoing=0;
 870                 switch (fmtw[i+1])
 871                 {   case L'0': case L'1': case L'2': case L'3': case L'4':
 872                     case L'5': case L'6': case L'7': case L'8': case L'9':
 873                     case L'.': case L'*':
 874                     case L'-':  i++; keepgoing=1; break;
 875                     case L's':  fmtw[i+1]=L'S';   break;
 876                     case L'S':  fmtw[i+1]=L's';   break;
 877                     case L'c':  fmtw[i+1]=L'C';   break;
 878                     case L'C':  fmtw[i+1]=L'c';   break;
 879                 }
 880             } while (keepgoing);
 881         }
 882         fmt = (const TCHAR *)fmtw;
 883     } while (0);
 884 
 885     va_start (ap,fmta);
 886     _vsntprintf (buf,sizeof(buf)/sizeof(TCHAR)-1,fmt,ap);
 887     buf [sizeof(buf)/sizeof(TCHAR)-1] = _T('\0');
 888     va_end (ap);
 889 
 890 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
 891     /* this -------------v--- guards NT-specific calls */
 892     if (check_winnt() && OPENSSL_isservice() > 0)
 893     {   HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
 894         const TCHAR *pmsg=buf;
 895         ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
 896         DeregisterEventSource(h);
 897     }
 898     else
 899 #endif
 900         MessageBox (NULL,buf,_T("OpenSSL: FATAL"),MB_OK|MB_ICONSTOP);
 901 }
 902 #else
 903 void OPENSSL_showfatal (const char *fmta,...)
 904 { va_list ap;
 905 
 906     va_start (ap,fmta);
 907     vfprintf (stderr,fmta,ap);
 908     va_end (ap);
 909 }
 910 int OPENSSL_isservice (void) { return 0; }
 911 #endif
 912 
 913 void OpenSSLDie(const char *file,int line,const char *assertion)
 914         {
 915         OPENSSL_showfatal(
 916                 "%s(%d): OpenSSL internal error, assertion failed: %s\n",
 917                 file,line,assertion);
 918 #if !defined(_WIN32) || defined(__CYGWIN__)
 919         abort();
 920 #else
 921         /* Win32 abort() customarily shows a dialog, but we just did that... */
 922         raise(SIGABRT);
 923         _exit(3);
 924 #endif
 925         }
 926 
 927 void *OPENSSL_stderr(void)      { return stderr; }
 928 
 929 int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
 930         {
 931         size_t i;
 932         const unsigned char *a = in_a;
 933         const unsigned char *b = in_b;
 934         unsigned char x = 0;
 935 
 936         for (i = 0; i < len; i++)
 937                 x |= a[i] ^ b[i];
 938 
 939         return x;
 940         }