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