Merge branch 'vendor/LIBRESSL'
[dragonfly.git] / crypto / libressl / crypto / cryptlib.c
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 }