1 /* $OpenBSD: cryptlib.c,v 1.36 2015/09/13 10:02:49 miod Exp $ */ 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 <limits.h> 118 #include <stdarg.h> 119 #include <stdint.h> 120 #include <string.h> 121 #include <unistd.h> 122 123 #include <openssl/opensslconf.h> 124 125 #include <openssl/crypto.h> 126 #include <openssl/buffer.h> 127 #include <openssl/err.h> 128 #include <openssl/safestack.h> 129 #include <openssl/sha.h> 130 131 DECLARE_STACK_OF(CRYPTO_dynlock) 132 133 /* real #defines in crypto.h, keep these upto date */ 134 static const char* const lock_names[CRYPTO_NUM_LOCKS] = { 135 "<<ERROR>>", 136 "err", 137 "ex_data", 138 "x509", 139 "x509_info", 140 "x509_pkey", 141 "x509_crl", 142 "x509_req", 143 "dsa", 144 "rsa", 145 "evp_pkey", 146 "x509_store", 147 "ssl_ctx", 148 "ssl_cert", 149 "ssl_session", 150 "ssl_sess_cert", 151 "ssl", 152 "ssl_method", 153 "rand", 154 "rand2", 155 "debug_malloc", 156 "BIO", 157 "gethostbyname", 158 "getservbyname", 159 "readdir", 160 "RSA_blinding", 161 "dh", 162 "debug_malloc2", 163 "dso", 164 "dynlock", 165 "engine", 166 "ui", 167 "ecdsa", 168 "ec", 169 "ecdh", 170 "bn", 171 "ec_pre_comp", 172 "store", 173 "comp", 174 "fips", 175 "fips2", 176 #if CRYPTO_NUM_LOCKS != 41 177 # error "Inconsistency between crypto.h and cryptlib.c" 178 #endif 179 }; 180 181 /* This is for applications to allocate new type names in the non-dynamic 182 array of lock names. These are numbered with positive numbers. */ 183 static STACK_OF(OPENSSL_STRING) *app_locks = NULL; 184 185 /* For applications that want a more dynamic way of handling threads, the 186 following stack is used. These are externally numbered with negative 187 numbers. */ 188 static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL; 189 190 static void (*locking_callback)(int mode, int type, 191 const char *file, int line) = 0; 192 static int (*add_lock_callback)(int *pointer, int amount, 193 int type, const char *file, int line) = 0; 194 #ifndef OPENSSL_NO_DEPRECATED 195 static unsigned long (*id_callback)(void) = 0; 196 #endif 197 static void (*threadid_callback)(CRYPTO_THREADID *) = 0; 198 static struct CRYPTO_dynlock_value *(*dynlock_create_callback)( 199 const char *file, int line) = 0; 200 static void (*dynlock_lock_callback)(int mode, 201 struct CRYPTO_dynlock_value *l, const char *file, int line) = 0; 202 static void (*dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, 203 const char *file, int line) = 0; 204 205 int 206 CRYPTO_get_new_lockid(char *name) 207 { 208 char *str; 209 int i; 210 211 if ((app_locks == NULL) && 212 ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) { 213 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE); 214 return (0); 215 } 216 if (name == NULL || (str = strdup(name)) == NULL) { 217 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE); 218 return (0); 219 } 220 i = sk_OPENSSL_STRING_push(app_locks, str); 221 if (!i) 222 free(str); 223 else 224 i += CRYPTO_NUM_LOCKS; /* gap of one :-) */ 225 return (i); 226 } 227 228 int 229 CRYPTO_num_locks(void) 230 { 231 return CRYPTO_NUM_LOCKS; 232 } 233 234 int 235 CRYPTO_get_new_dynlockid(void) 236 { 237 int i = 0; 238 CRYPTO_dynlock *pointer = NULL; 239 240 if (dynlock_create_callback == NULL) { 241 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, 242 CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); 243 return (0); 244 } 245 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); 246 if ((dyn_locks == NULL) && 247 ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) { 248 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); 249 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, 250 ERR_R_MALLOC_FAILURE); 251 return (0); 252 } 253 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); 254 255 pointer = malloc(sizeof(CRYPTO_dynlock)); 256 if (pointer == NULL) { 257 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, 258 ERR_R_MALLOC_FAILURE); 259 return (0); 260 } 261 pointer->references = 1; 262 pointer->data = dynlock_create_callback(__FILE__, __LINE__); 263 if (pointer->data == NULL) { 264 free(pointer); 265 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, 266 ERR_R_MALLOC_FAILURE); 267 return (0); 268 } 269 270 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); 271 /* First, try to find an existing empty slot */ 272 i = sk_CRYPTO_dynlock_find(dyn_locks, NULL); 273 /* If there was none, push, thereby creating a new one */ 274 if (i == -1) 275 /* Since sk_push() returns the number of items on the 276 stack, not the location of the pushed item, we need 277 to transform the returned number into a position, 278 by decreasing it. */ 279 i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1; 280 else 281 /* If we found a place with a NULL pointer, put our pointer 282 in it. */ 283 (void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer); 284 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); 285 286 if (i == -1) { 287 dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); 288 free(pointer); 289 } else 290 i += 1; /* to avoid 0 */ 291 return -i; 292 } 293 294 void 295 CRYPTO_destroy_dynlockid(int i) 296 { 297 CRYPTO_dynlock *pointer = NULL; 298 299 if (i) 300 i = -i - 1; 301 if (dynlock_destroy_callback == NULL) 302 return; 303 304 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); 305 306 if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) { 307 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); 308 return; 309 } 310 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); 311 if (pointer != NULL) { 312 --pointer->references; 313 if (pointer->references <= 0) { 314 (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); 315 } else 316 pointer = NULL; 317 } 318 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); 319 320 if (pointer) { 321 dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); 322 free(pointer); 323 } 324 } 325 326 struct CRYPTO_dynlock_value * 327 CRYPTO_get_dynlock_value(int i) 328 { 329 CRYPTO_dynlock *pointer = NULL; 330 331 if (i) 332 i = -i - 1; 333 334 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); 335 336 if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) 337 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); 338 if (pointer) 339 pointer->references++; 340 341 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); 342 343 if (pointer) 344 return pointer->data; 345 return NULL; 346 } 347 348 struct CRYPTO_dynlock_value * 349 (*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line) 350 { 351 return (dynlock_create_callback); 352 } 353 354 void 355 (*CRYPTO_get_dynlock_lock_callback(void))(int mode, 356 struct CRYPTO_dynlock_value *l, const char *file, int line) 357 { 358 return (dynlock_lock_callback); 359 } 360 361 void 362 (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, 363 const char *file, int line) 364 { 365 return (dynlock_destroy_callback); 366 } 367 368 void 369 CRYPTO_set_dynlock_create_callback( 370 struct CRYPTO_dynlock_value *(*func)(const char *file, int line)) 371 { 372 dynlock_create_callback = func; 373 } 374 375 void 376 CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, 377 struct CRYPTO_dynlock_value *l, const char *file, int line)) 378 { 379 dynlock_lock_callback = func; 380 } 381 382 void 383 CRYPTO_set_dynlock_destroy_callback( 384 void (*func)(struct CRYPTO_dynlock_value *l, const char *file, int line)) 385 { 386 dynlock_destroy_callback = func; 387 } 388 389 void 390 (*CRYPTO_get_locking_callback(void))(int mode, int type, const char *file, 391 int line) 392 { 393 return (locking_callback); 394 } 395 396 int 397 (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, 398 const char *file, int line) 399 { 400 return (add_lock_callback); 401 } 402 403 void 404 CRYPTO_set_locking_callback(void (*func)(int mode, int type, 405 const char *file, int line)) 406 { 407 /* Calling this here ensures initialisation before any threads 408 * are started. 409 */ 410 OPENSSL_init(); 411 locking_callback = func; 412 } 413 414 void 415 CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, 416 const char *file, int line)) 417 { 418 add_lock_callback = func; 419 } 420 421 /* the memset() here and in set_pointer() seem overkill, but for the sake of 422 * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two 423 * "equal" THREADID structs to not be memcmp()-identical. */ 424 void 425 CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) 426 { 427 memset(id, 0, sizeof(*id)); 428 id->val = val; 429 } 430 431 void 432 CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) 433 { 434 memset(id, 0, sizeof(*id)); 435 id->ptr = ptr; 436 #if ULONG_MAX >= UINTPTR_MAX 437 /*s u 'ptr' can be embedded in 'val' without loss of uniqueness */ 438 id->val = (uintptr_t)id->ptr; 439 #else 440 { 441 SHA256_CTX ctx; 442 uint8_t results[SHA256_DIGEST_LENGTH]; 443 444 SHA256_Init(&ctx); 445 SHA256_Update(&ctx, (char *)(&id->ptr), sizeof(id->ptr)); 446 SHA256_Final(results, &ctx); 447 memcpy(&id->val, results, sizeof(id->val)); 448 } 449 #endif 450 } 451 452 int 453 CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) 454 { 455 if (threadid_callback) 456 return 0; 457 threadid_callback = func; 458 return 1; 459 } 460 461 void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *) 462 { 463 return threadid_callback; 464 } 465 466 void 467 CRYPTO_THREADID_current(CRYPTO_THREADID *id) 468 { 469 if (threadid_callback) { 470 threadid_callback(id); 471 return; 472 } 473 #ifndef OPENSSL_NO_DEPRECATED 474 /* If the deprecated callback was set, fall back to that */ 475 if (id_callback) { 476 CRYPTO_THREADID_set_numeric(id, id_callback()); 477 return; 478 } 479 #endif 480 /* Else pick a backup */ 481 /* For everything else, default to using the address of 'errno' */ 482 CRYPTO_THREADID_set_pointer(id, (void*)&errno); 483 } 484 485 int 486 CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b) 487 { 488 return memcmp(a, b, sizeof(*a)); 489 } 490 491 void 492 CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src) 493 { 494 memcpy(dest, src, sizeof(*src)); 495 } 496 497 unsigned long 498 CRYPTO_THREADID_hash(const CRYPTO_THREADID *id) 499 { 500 return id->val; 501 } 502 503 #ifndef OPENSSL_NO_DEPRECATED 504 unsigned long (*CRYPTO_get_id_callback(void))(void) 505 { 506 return (id_callback); 507 } 508 509 void 510 CRYPTO_set_id_callback(unsigned long (*func)(void)) 511 { 512 id_callback = func; 513 } 514 515 unsigned long 516 CRYPTO_thread_id(void) 517 { 518 unsigned long ret = 0; 519 520 if (id_callback == NULL) { 521 ret = (unsigned long)getpid(); 522 } else 523 ret = id_callback(); 524 return (ret); 525 } 526 #endif 527 528 void 529 CRYPTO_lock(int mode, int type, const char *file, int line) 530 { 531 #ifdef LOCK_DEBUG 532 { 533 CRYPTO_THREADID id; 534 char *rw_text, *operation_text; 535 536 if (mode & CRYPTO_LOCK) 537 operation_text = "lock "; 538 else if (mode & CRYPTO_UNLOCK) 539 operation_text = "unlock"; 540 else 541 operation_text = "ERROR "; 542 543 if (mode & CRYPTO_READ) 544 rw_text = "r"; 545 else if (mode & CRYPTO_WRITE) 546 rw_text = "w"; 547 else 548 rw_text = "ERROR"; 549 550 CRYPTO_THREADID_current(&id); 551 fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n", 552 CRYPTO_THREADID_hash(&id), rw_text, operation_text, 553 CRYPTO_get_lock_name(type), file, line); 554 } 555 #endif 556 if (type < 0) { 557 if (dynlock_lock_callback != NULL) { 558 struct CRYPTO_dynlock_value *pointer = 559 CRYPTO_get_dynlock_value(type); 560 561 OPENSSL_assert(pointer != NULL); 562 563 dynlock_lock_callback(mode, pointer, file, line); 564 565 CRYPTO_destroy_dynlockid(type); 566 } 567 } else if (locking_callback != NULL) 568 locking_callback(mode, type, file, line); 569 } 570 571 int 572 CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, 573 int line) 574 { 575 int ret = 0; 576 577 if (add_lock_callback != NULL) { 578 #ifdef LOCK_DEBUG 579 int before= *pointer; 580 #endif 581 582 ret = add_lock_callback(pointer, amount, type, file, line); 583 #ifdef LOCK_DEBUG 584 { 585 CRYPTO_THREADID id; 586 CRYPTO_THREADID_current(&id); 587 fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 588 CRYPTO_THREADID_hash(&id), before, amount, ret, 589 CRYPTO_get_lock_name(type), 590 file, line); 591 } 592 #endif 593 } else { 594 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line); 595 596 ret= *pointer + amount; 597 #ifdef LOCK_DEBUG 598 { 599 CRYPTO_THREADID id; 600 CRYPTO_THREADID_current(&id); 601 fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 602 CRYPTO_THREADID_hash(&id), *pointer, amount, ret, 603 CRYPTO_get_lock_name(type), file, line); 604 } 605 #endif 606 *pointer = ret; 607 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line); 608 } 609 return (ret); 610 } 611 612 const char * 613 CRYPTO_get_lock_name(int type) 614 { 615 if (type < 0) 616 return("dynamic"); 617 else if (type < CRYPTO_NUM_LOCKS) 618 return (lock_names[type]); 619 else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks)) 620 return("ERROR"); 621 else 622 return (sk_OPENSSL_STRING_value(app_locks, 623 type - CRYPTO_NUM_LOCKS)); 624 } 625 626 #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ 627 defined(__INTEL__) || \ 628 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) 629 630 unsigned int OPENSSL_ia32cap_P[2]; 631 632 uint64_t 633 OPENSSL_cpu_caps(void) 634 { 635 return *(uint64_t *)OPENSSL_ia32cap_P; 636 } 637 638 #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) 639 #define OPENSSL_CPUID_SETUP 640 typedef unsigned long long IA32CAP; 641 void 642 OPENSSL_cpuid_setup(void) 643 { 644 static int trigger = 0; 645 IA32CAP OPENSSL_ia32_cpuid(void); 646 IA32CAP vec; 647 648 if (trigger) 649 return; 650 trigger = 1; 651 652 vec = OPENSSL_ia32_cpuid(); 653 654 /* 655 * |(1<<10) sets a reserved bit to signal that variable 656 * was initialized already... This is to avoid interference 657 * with cpuid snippets in ELF .init segment. 658 */ 659 OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10); 660 OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32); 661 } 662 #endif 663 664 #else 665 unsigned long * 666 OPENSSL_ia32cap_loc(void) 667 { 668 return NULL; 669 } 670 671 uint64_t 672 OPENSSL_cpu_caps(void) 673 { 674 return 0; 675 } 676 #endif 677 678 #if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) 679 void 680 OPENSSL_cpuid_setup(void) 681 { 682 } 683 #endif 684 685 static void 686 OPENSSL_showfatal(const char *fmta, ...) 687 { 688 va_list ap; 689 690 va_start(ap, fmta); 691 vfprintf(stderr, fmta, ap); 692 va_end(ap); 693 } 694 695 void 696 OpenSSLDie(const char *file, int line, const char *assertion) 697 { 698 OPENSSL_showfatal( 699 "%s(%d): OpenSSL internal error, assertion failed: %s\n", 700 file, line, assertion); 701 abort(); 702 } 703 704 int 705 CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) 706 { 707 size_t i; 708 const unsigned char *a = in_a; 709 const unsigned char *b = in_b; 710 unsigned char x = 0; 711 712 for (i = 0; i < len; i++) 713 x |= a[i] ^ b[i]; 714 715 return x; 716 } 717