GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/cryptlib.c Lines: 42 168 25.0 %
Date: 2016-12-06 Branches: 8 76 10.5 %

Line Branch Exec Source
1
/* $OpenBSD: cryptlib.c,v 1.37 2015/09/13 16:56:11 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
8
{
407
	/* Calling this here ensures initialisation before any threads
408
	 * are started.
409
	 */
410
8
	OPENSSL_init();
411
8
	locking_callback = func;
412
8
}
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
713
{
434
713
	memset(id, 0, sizeof(*id));
435
713
	id->ptr = ptr;
436
#if ULONG_MAX >= UINTPTR_MAX
437
	/*s u 'ptr' can be embedded in 'val' without loss of uniqueness */
438
713
	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
713
}
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
713
{
469
713
	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
713
	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
713
	CRYPTO_THREADID_set_pointer(id, (void*)&errno);
483
}
484
485
int
486
CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
487
688
{
488
688
	return memcmp(a, b, sizeof(*a));
489
}
490
491
void
492
CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
493
693
{
494
693
	memcpy(dest, src, sizeof(*src));
495
693
}
496
497
unsigned long
498
CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
499
723
{
500
723
	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
915138
{
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
915138
	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
915138
	} else if (locking_callback != NULL)
568
430896
		locking_callback(mode, type, file, line);
569
915138
}
570
571
int
572
CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
573
    int line)
574
3222
{
575
3222
	int ret = 0;
576
577
3222
	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
3222
		CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line);
595
596
3222
		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
3222
		*pointer = ret;
607
3222
		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line);
608
	}
609
3222
	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
2
{
635
2
	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
65
{
644
	static int trigger = 0;
645
	IA32CAP OPENSSL_ia32_cpuid(void);
646
	IA32CAP vec;
647
648
65
	if (trigger)
649
14
		return;
650
51
	trigger = 1;
651
652
51
	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
51
	OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
660
51
	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
}