GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/cryptlib.c Lines: 34 154 22.1 %
Date: 2017-11-07 Branches: 9 76 11.8 %

Line Branch Exec Source
1
/* $OpenBSD: cryptlib.c,v 1.41 2017/04/29 21:48:43 jsing 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
		CRYPTOerror(ERR_R_MALLOC_FAILURE);
214
		return (0);
215
	}
216
	if (name == NULL || (str = strdup(name)) == NULL) {
217
		CRYPTOerror(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
18
	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
		CRYPTOerror(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
242
		return (0);
243
	}
244
	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
245
	if ((dyn_locks == NULL) &&
246
	    ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) {
247
		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
248
		CRYPTOerror(ERR_R_MALLOC_FAILURE);
249
		return (0);
250
	}
251
	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
252
253
	pointer = malloc(sizeof(CRYPTO_dynlock));
254
	if (pointer == NULL) {
255
		CRYPTOerror(ERR_R_MALLOC_FAILURE);
256
		return (0);
257
	}
258
	pointer->references = 1;
259
	pointer->data = dynlock_create_callback(__FILE__, __LINE__);
260
	if (pointer->data == NULL) {
261
		free(pointer);
262
		CRYPTOerror(ERR_R_MALLOC_FAILURE);
263
		return (0);
264
	}
265
266
	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
267
	/* First, try to find an existing empty slot */
268
	i = sk_CRYPTO_dynlock_find(dyn_locks, NULL);
269
	/* If there was none, push, thereby creating a new one */
270
	if (i == -1)
271
		/* Since sk_push() returns the number of items on the
272
		   stack, not the location of the pushed item, we need
273
		   to transform the returned number into a position,
274
		   by decreasing it.  */
275
		i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1;
276
	else
277
		/* If we found a place with a NULL pointer, put our pointer
278
		   in it.  */
279
		(void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer);
280
	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
281
282
	if (i == -1) {
283
		dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
284
		free(pointer);
285
	} else
286
		i += 1; /* to avoid 0 */
287
	return -i;
288
}
289
290
void
291
CRYPTO_destroy_dynlockid(int i)
292
{
293
	CRYPTO_dynlock *pointer = NULL;
294
295
	if (i)
296
		i = -i - 1;
297
	if (dynlock_destroy_callback == NULL)
298
		return;
299
300
	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
301
302
	if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) {
303
		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
304
		return;
305
	}
306
	pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
307
	if (pointer != NULL) {
308
		--pointer->references;
309
		if (pointer->references <= 0) {
310
			(void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
311
		} else
312
			pointer = NULL;
313
	}
314
	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
315
316
	if (pointer) {
317
		dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
318
		free(pointer);
319
	}
320
}
321
322
struct CRYPTO_dynlock_value *
323
CRYPTO_get_dynlock_value(int i)
324
{
325
	CRYPTO_dynlock *pointer = NULL;
326
327
	if (i)
328
		i = -i - 1;
329
330
	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
331
332
	if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
333
		pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
334
	if (pointer)
335
		pointer->references++;
336
337
	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
338
339
	if (pointer)
340
		return pointer->data;
341
	return NULL;
342
}
343
344
struct CRYPTO_dynlock_value *
345
(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line)
346
{
347
	return (dynlock_create_callback);
348
}
349
350
void
351
(*CRYPTO_get_dynlock_lock_callback(void))(int mode,
352
    struct CRYPTO_dynlock_value *l, const char *file, int line)
353
{
354
	return (dynlock_lock_callback);
355
}
356
357
void
358
(*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l,
359
    const char *file, int line)
360
{
361
	return (dynlock_destroy_callback);
362
}
363
364
void
365
CRYPTO_set_dynlock_create_callback(
366
    struct CRYPTO_dynlock_value *(*func)(const char *file, int line))
367
{
368
	dynlock_create_callback = func;
369
}
370
371
void
372
CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
373
    struct CRYPTO_dynlock_value *l, const char *file, int line))
374
{
375
	dynlock_lock_callback = func;
376
}
377
378
void
379
CRYPTO_set_dynlock_destroy_callback(
380
    void (*func)(struct CRYPTO_dynlock_value *l, const char *file, int line))
381
{
382
	dynlock_destroy_callback = func;
383
}
384
385
void
386
(*CRYPTO_get_locking_callback(void))(int mode, int type, const char *file,
387
    int line)
388
{
389
	return (locking_callback);
390
}
391
392
int
393
(*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type,
394
    const char *file, int line)
395
{
396
	return (add_lock_callback);
397
}
398
399
void
400
CRYPTO_set_locking_callback(void (*func)(int mode, int type,
401
    const char *file, int line))
402
{
403
	/* Calling this here ensures initialisation before any threads
404
	 * are started.
405
	 */
406
3326
	locking_callback = func;
407
1663
}
408
409
void
410
CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type,
411
    const char *file, int line))
412
{
413
	add_lock_callback = func;
414
}
415
416
/* the memset() here and in set_pointer() seem overkill, but for the sake of
417
 * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
418
 * "equal" THREADID structs to not be memcmp()-identical. */
419
void
420
CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
421
{
422
	memset(id, 0, sizeof(*id));
423
	id->val = val;
424
}
425
426
void
427
CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
428
{
429
174082
	memset(id, 0, sizeof(*id));
430
87041
	id->ptr = ptr;
431
#if ULONG_MAX >= UINTPTR_MAX
432
	/*s u 'ptr' can be embedded in 'val' without loss of uniqueness */
433
87041
	id->val = (uintptr_t)id->ptr;
434
#else
435
	{
436
		SHA256_CTX ctx;
437
		uint8_t results[SHA256_DIGEST_LENGTH];
438
439
		SHA256_Init(&ctx);
440
		SHA256_Update(&ctx, (char *)(&id->ptr), sizeof(id->ptr));
441
		SHA256_Final(results, &ctx);
442
		memcpy(&id->val, results, sizeof(id->val));
443
	}
444
#endif
445
87041
}
446
447
int
448
CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
449
{
450
18
	if (threadid_callback)
451
		return 0;
452
9
	threadid_callback = func;
453
9
	return 1;
454
9
}
455
456
void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
457
{
458
	return threadid_callback;
459
}
460
461
void
462
CRYPTO_THREADID_current(CRYPTO_THREADID *id)
463
{
464
174082
	if (threadid_callback) {
465
		threadid_callback(id);
466
		return;
467
	}
468
#ifndef OPENSSL_NO_DEPRECATED
469
	/* If the deprecated callback was set, fall back to that */
470
87041
	if (id_callback) {
471
		CRYPTO_THREADID_set_numeric(id, id_callback());
472
		return;
473
	}
474
#endif
475
	/* Else pick a backup */
476
	/* For everything else, default to using the address of 'errno' */
477
87041
	CRYPTO_THREADID_set_pointer(id, (void*)&errno);
478
174082
}
479
480
int
481
CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
482
{
483
170326
	return memcmp(a, b, sizeof(*a));
484
}
485
486
void
487
CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
488
{
489
118402
	memcpy(dest, src, sizeof(*src));
490
59201
}
491
492
unsigned long
493
CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
494
{
495
123850
	return id->val;
496
}
497
498
#ifndef OPENSSL_NO_DEPRECATED
499
unsigned long (*CRYPTO_get_id_callback(void))(void)
500
{
501
	return (id_callback);
502
}
503
504
void
505
CRYPTO_set_id_callback(unsigned long (*func)(void))
506
{
507
	id_callback = func;
508
}
509
510
unsigned long
511
CRYPTO_thread_id(void)
512
{
513
	unsigned long ret = 0;
514
515
	if (id_callback == NULL) {
516
		ret = (unsigned long)getpid();
517
	} else
518
		ret = id_callback();
519
	return (ret);
520
}
521
#endif
522
523
void
524
CRYPTO_lock(int mode, int type, const char *file, int line)
525
{
526
#ifdef LOCK_DEBUG
527
	{
528
		CRYPTO_THREADID id;
529
		char *rw_text, *operation_text;
530
531
		if (mode & CRYPTO_LOCK)
532
			operation_text = "lock  ";
533
		else if (mode & CRYPTO_UNLOCK)
534
			operation_text = "unlock";
535
		else
536
			operation_text = "ERROR ";
537
538
		if (mode & CRYPTO_READ)
539
			rw_text = "r";
540
		else if (mode & CRYPTO_WRITE)
541
			rw_text = "w";
542
		else
543
			rw_text = "ERROR";
544
545
		CRYPTO_THREADID_current(&id);
546
		fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n",
547
		    CRYPTO_THREADID_hash(&id), rw_text, operation_text,
548
		    CRYPTO_get_lock_name(type), file, line);
549
	}
550
#endif
551
304591500
	if (type < 0) {
552
		if (dynlock_lock_callback != NULL) {
553
			struct CRYPTO_dynlock_value *pointer =
554
			    CRYPTO_get_dynlock_value(type);
555
556
			OPENSSL_assert(pointer != NULL);
557
558
			dynlock_lock_callback(mode, pointer, file, line);
559
560
			CRYPTO_destroy_dynlockid(type);
561
		}
562
152295750
	} else if (locking_callback != NULL)
563
84981258
		locking_callback(mode, type, file, line);
564
152295750
}
565
566
int
567
CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
568
    int line)
569
{
570
	int ret = 0;
571
572
1080310
	if (add_lock_callback != NULL) {
573
#ifdef LOCK_DEBUG
574
		int before= *pointer;
575
#endif
576
577
		ret = add_lock_callback(pointer, amount, type, file, line);
578
#ifdef LOCK_DEBUG
579
		{
580
			CRYPTO_THREADID id;
581
			CRYPTO_THREADID_current(&id);
582
			fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
583
			    CRYPTO_THREADID_hash(&id), before, amount, ret,
584
			    CRYPTO_get_lock_name(type),
585
			    file, line);
586
		}
587
#endif
588
	} else {
589
540155
		CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line);
590
591
540155
		ret= *pointer + amount;
592
#ifdef LOCK_DEBUG
593
		{
594
			CRYPTO_THREADID id;
595
			CRYPTO_THREADID_current(&id);
596
			fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
597
			    CRYPTO_THREADID_hash(&id), *pointer, amount, ret,
598
			    CRYPTO_get_lock_name(type), file, line);
599
		}
600
#endif
601
540155
		*pointer = ret;
602
540155
		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line);
603
	}
604
540155
	return (ret);
605
}
606
607
const char *
608
CRYPTO_get_lock_name(int type)
609
{
610
	if (type < 0)
611
		return("dynamic");
612
	else if (type < CRYPTO_NUM_LOCKS)
613
		return (lock_names[type]);
614
	else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
615
		return("ERROR");
616
	else
617
		return (sk_OPENSSL_STRING_value(app_locks,
618
		    type - CRYPTO_NUM_LOCKS));
619
}
620
621
#if	defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
622
	defined(__INTEL__) || \
623
	defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
624
625
uint64_t OPENSSL_ia32cap_P;
626
627
uint64_t
628
OPENSSL_cpu_caps(void)
629
{
630
196654
	return OPENSSL_ia32cap_P;
631
}
632
633
#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM)
634
#define OPENSSL_CPUID_SETUP
635
void
636
OPENSSL_cpuid_setup(void)
637
{
638
	static int trigger = 0;
639
	uint64_t OPENSSL_ia32_cpuid(void);
640
641
11314
	if (trigger)
642
		return;
643
4020
	trigger = 1;
644
4020
	OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid();
645
9677
}
646
#endif
647
648
#else
649
uint64_t
650
OPENSSL_cpu_caps(void)
651
{
652
	return 0;
653
}
654
#endif
655
656
#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
657
void
658
OPENSSL_cpuid_setup(void)
659
{
660
}
661
#endif
662
663
static void
664
OPENSSL_showfatal(const char *fmta, ...)
665
{
666
	va_list ap;
667
668
	va_start(ap, fmta);
669
	vfprintf(stderr, fmta, ap);
670
	va_end(ap);
671
}
672
673
void
674
OpenSSLDie(const char *file, int line, const char *assertion)
675
{
676
	OPENSSL_showfatal(
677
	    "%s(%d): OpenSSL internal error, assertion failed: %s\n",
678
	    file, line, assertion);
679
	abort();
680
}
681
682
int
683
CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
684
{
685
	size_t i;
686
	const unsigned char *a = in_a;
687
	const unsigned char *b = in_b;
688
	unsigned char x = 0;
689
690
	for (i = 0; i < len; i++)
691
		x |= a[i] ^ b[i];
692
693
	return x;
694
}