OpenCoverage

cryptlib.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/cryptlib.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright 1998-2018 The OpenSSL Project Authors. All Rights Reserved.-
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved-
4 *-
5 * Licensed under the OpenSSL license (the "License"). You may not use-
6 * this file except in compliance with the License. You can obtain a copy-
7 * in the file LICENSE in the source distribution or at-
8 * https://www.openssl.org/source/license.html-
9 */-
10-
11#include "e_os.h"-
12#include "internal/cryptlib_int.h"-
13#include <openssl/safestack.h>-
14-
15#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \-
16 defined(__x86_64) || defined(__x86_64__) || \-
17 defined(_M_AMD64) || defined(_M_X64)-
18-
19extern unsigned int OPENSSL_ia32cap_P[4];-
20-
21# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)-
22-
23/*-
24 * Purpose of these minimalistic and character-type-agnostic subroutines-
25 * is to break dependency on MSVCRT (on Windows) and locale. This makes-
26 * OPENSSL_cpuid_setup safe to use as "constructor". "Character-type--
27 * agnostic" means that they work with either wide or 8-bit characters,-
28 * exploiting the fact that first 127 characters can be simply casted-
29 * between the sets, while the rest would be simply rejected by ossl_is*-
30 * subroutines.-
31 */-
32# ifdef _WIN32-
33typedef WCHAR variant_char;-
34-
35static variant_char *ossl_getenv(const char *name)-
36{-
37 /*-
38 * Since we pull only one environment variable, it's simpler to-
39 * to just ignore |name| and use equivalent wide-char L-literal.-
40 * As well as to ignore excessively long values...-
41 */-
42 static WCHAR value[48];-
43 DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, 48);-
44-
45 return (len > 0 && len < 48) ? value : NULL;-
46}-
47# else-
48typedef char variant_char;-
49# define ossl_getenv getenv-
50# endif-
51-
52# include "internal/ctype.h"-
53-
54static int todigit(variant_char c)-
55{-
56 if (ossl_isdigit(c))
(ossl_ctype_check((c), 0x4))Description
TRUEevaluated 5505 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
367-5505
57 return c - '0';
executed 5505 times by 1 test: return c - '0';
Executed by:
  • libcrypto.so.1.1
5505
58 else if (ossl_isxdigit(c))
(ossl_ctype_check((c), 0x10))Description
TRUEnever evaluated
FALSEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-367
59 return ossl_tolower(c) - 'a' + 10;
never executed: return ossl_tolower(c) - 'a' + 10;
0
60-
61 /* return largest base value to make caller terminate the loop */-
62 return 16;
executed 367 times by 1 test: return 16;
Executed by:
  • libcrypto.so.1.1
367
63}-
64-
65static uint64_t ossl_strtouint64(const variant_char *str)-
66{-
67 uint64_t ret = 0;-
68 unsigned int digit, base = 10;-
69-
70 if (*str == '0') {
*str == '0'Description
TRUEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-367
71 base = 8, str++;-
72 if (ossl_tolower(*str) == 'x')
ossl_tolower(*str) == 'x'Description
TRUEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-367
73 base = 16, str++;
executed 367 times by 1 test: base = 16, str++;
Executed by:
  • libcrypto.so.1.1
367
74 }
executed 367 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
367
75-
76 while((digit = todigit(*str++)) < base)
(digit = todig...str++)) < baseDescription
TRUEevaluated 5505 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
367-5505
77 ret = ret * base + digit;
executed 5505 times by 1 test: ret = ret * base + digit;
Executed by:
  • libcrypto.so.1.1
5505
78-
79 return ret;
executed 367 times by 1 test: return ret;
Executed by:
  • libcrypto.so.1.1
367
80}-
81-
82static variant_char *ossl_strchr(const variant_char *str, char srch)-
83{ variant_char c;-
84-
85 while((c = *str)) {
(c = *str)Description
TRUEevaluated 6606 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
367-6606
86 if (c == srch)
c == srchDescription
TRUEnever evaluated
FALSEevaluated 6606 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-6606
87 return (variant_char *)str;
never executed: return (variant_char *)str;
0
88 str++;-
89 }
executed 6606 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
6606
90-
91 return NULL;
executed 367 times by 1 test: return ((void *)0) ;
Executed by:
  • libcrypto.so.1.1
367
92}-
93-
94# define OPENSSL_CPUID_SETUP-
95typedef uint64_t IA32CAP;-
96-
97void OPENSSL_cpuid_setup(void)-
98{-
99 static int trigger = 0;-
100 IA32CAP OPENSSL_ia32_cpuid(unsigned int *);-
101 IA32CAP vec;-
102 const variant_char *env;-
103-
104 if (trigger)
triggerDescription
TRUEevaluated 4035 times by 12 tests
Evaluated by:
  • asn1_internal_test
  • chacha_internal_test
  • ctype_internal_test
  • curve448_internal_test
  • libcrypto.so.1.1
  • modes_internal_test
  • poly1305_internal_test
  • rdrand_sanitytest
  • siphash_internal_test
  • sm2_internal_test
  • sm4_internal_test
  • x509_internal_test
FALSEevaluated 2079 times by 12 tests
Evaluated by:
  • asn1_internal_test
  • chacha_internal_test
  • ctype_internal_test
  • curve448_internal_test
  • libcrypto.so.1.1
  • modes_internal_test
  • poly1305_internal_test
  • rdrand_sanitytest
  • siphash_internal_test
  • sm2_internal_test
  • sm4_internal_test
  • x509_internal_test
2079-4035
105 return;
executed 4035 times by 12 tests: return;
Executed by:
  • asn1_internal_test
  • chacha_internal_test
  • ctype_internal_test
  • curve448_internal_test
  • libcrypto.so.1.1
  • modes_internal_test
  • poly1305_internal_test
  • rdrand_sanitytest
  • siphash_internal_test
  • sm2_internal_test
  • sm4_internal_test
  • x509_internal_test
4035
106-
107 trigger = 1;-
108 if ((env = ossl_getenv("OPENSSL_ia32cap")) != NULL) {
(env = getenv(...!= ((void *)0)Description
TRUEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 1712 times by 12 tests
Evaluated by:
  • asn1_internal_test
  • chacha_internal_test
  • ctype_internal_test
  • curve448_internal_test
  • libcrypto.so.1.1
  • modes_internal_test
  • poly1305_internal_test
  • rdrand_sanitytest
  • siphash_internal_test
  • sm2_internal_test
  • sm4_internal_test
  • x509_internal_test
367-1712
109 int off = (env[0] == '~') ? 1 : 0;
(env[0] == '~')Description
TRUEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-367
110-
111 vec = ossl_strtouint64(env + off);-
112-
113 if (off) {
offDescription
TRUEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-367
114 IA32CAP mask = vec;-
115 vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~mask;-
116 if (mask & (1<<24)) {
mask & (1<<24)Description
TRUEnever evaluated
FALSEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-367
117 /*-
118 * User disables FXSR bit, mask even other capabilities-
119 * that operate exclusively on XMM, so we don't have to-
120 * double-check all the time. We mask PCLMULQDQ, AMD XOP,-
121 * AES-NI and AVX. Formally speaking we don't have to-
122 * do it in x86_64 case, but we can safely assume that-
123 * x86_64 users won't actually flip this flag.-
124 */-
125 vec &= ~((IA32CAP)(1<<1|1<<11|1<<25|1<<28) << 32);-
126 }
never executed: end of block
0
127 } else if (env[0] == ':') {
executed 367 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
env[0] == ':'Description
TRUEnever evaluated
FALSEnever evaluated
0-367
128 vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);-
129 }
never executed: end of block
0
130-
131 if ((env = ossl_strchr(env, ':')) != NULL) {
(env = ossl_st...!= ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 367 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-367
132 IA32CAP vecx;-
133-
134 env++;-
135 off = (env[0] == '~') ? 1 : 0;
(env[0] == '~')Description
TRUEnever evaluated
FALSEnever evaluated
0
136 vecx = ossl_strtouint64(env + off);-
137 if (off) {
offDescription
TRUEnever evaluated
FALSEnever evaluated
0
138 OPENSSL_ia32cap_P[2] &= ~(unsigned int)vecx;-
139 OPENSSL_ia32cap_P[3] &= ~(unsigned int)(vecx >> 32);-
140 } else {
never executed: end of block
0
141 OPENSSL_ia32cap_P[2] = (unsigned int)vecx;-
142 OPENSSL_ia32cap_P[3] = (unsigned int)(vecx >> 32);-
143 }
never executed: end of block
0
144 } else {-
145 OPENSSL_ia32cap_P[2] = 0;-
146 OPENSSL_ia32cap_P[3] = 0;-
147 }
executed 367 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
367
148 } else {-
149 vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);-
150 }
executed 1712 times by 12 tests: end of block
Executed by:
  • asn1_internal_test
  • chacha_internal_test
  • ctype_internal_test
  • curve448_internal_test
  • libcrypto.so.1.1
  • modes_internal_test
  • poly1305_internal_test
  • rdrand_sanitytest
  • siphash_internal_test
  • sm2_internal_test
  • sm4_internal_test
  • x509_internal_test
1712
151-
152 /*-
153 * |(1<<10) sets a reserved bit to signal that variable-
154 * was initialized already... This is to avoid interference-
155 * with cpuid snippets in ELF .init segment.-
156 */-
157 OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);-
158 OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);-
159}
executed 2079 times by 12 tests: end of block
Executed by:
  • asn1_internal_test
  • chacha_internal_test
  • ctype_internal_test
  • curve448_internal_test
  • libcrypto.so.1.1
  • modes_internal_test
  • poly1305_internal_test
  • rdrand_sanitytest
  • siphash_internal_test
  • sm2_internal_test
  • sm4_internal_test
  • x509_internal_test
2079
160# else-
161unsigned int OPENSSL_ia32cap_P[4];-
162# endif-
163#endif-
164#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)-
165void OPENSSL_cpuid_setup(void)-
166{-
167}-
168#endif-
169-
170#if defined(_WIN32)-
171# include <tchar.h>-
172# include <signal.h>-
173# ifdef __WATCOMC__-
174# if defined(_UNICODE) || defined(__UNICODE__)-
175# define _vsntprintf _vsnwprintf-
176# else-
177# define _vsntprintf _vsnprintf-
178# endif-
179# endif-
180# ifdef _MSC_VER-
181# define alloca _alloca-
182# endif-
183-
184# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333-
185# ifdef OPENSSL_SYS_WIN_CORE-
186-
187int OPENSSL_isservice(void)-
188{-
189 /* OneCore API cannot interact with GUI */-
190 return 1;-
191}-
192# else-
193int OPENSSL_isservice(void)-
194{-
195 HWINSTA h;-
196 DWORD len;-
197 WCHAR *name;-
198 static union {-
199 void *p;-
200 FARPROC f;-
201 } _OPENSSL_isservice = {-
202 NULL-
203 };-
204-
205 if (_OPENSSL_isservice.p == NULL) {-
206 HANDLE mod = GetModuleHandle(NULL);-
207 FARPROC f = NULL;-
208-
209 if (mod != NULL)-
210 f = GetProcAddress(mod, "_OPENSSL_isservice");-
211 if (f == NULL)-
212 _OPENSSL_isservice.p = (void *)-1;-
213 else-
214 _OPENSSL_isservice.f = f;-
215 }-
216-
217 if (_OPENSSL_isservice.p != (void *)-1)-
218 return (*_OPENSSL_isservice.f) ();-
219-
220 h = GetProcessWindowStation();-
221 if (h == NULL)-
222 return -1;-
223-
224 if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||-
225 GetLastError() != ERROR_INSUFFICIENT_BUFFER)-
226 return -1;-
227-
228 if (len > 512)-
229 return -1; /* paranoia */-
230 len++, len &= ~1; /* paranoia */-
231 name = (WCHAR *)alloca(len + sizeof(WCHAR));-
232 if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))-
233 return -1;-
234-
235 len++, len &= ~1; /* paranoia */-
236 name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */-
237# if 1-
238 /*-
239 * This doesn't cover "interactive" services [working with real-
240 * WinSta0's] nor programs started non-interactively by Task Scheduler-
241 * [those are working with SAWinSta].-
242 */-
243 if (wcsstr(name, L"Service-0x"))-
244 return 1;-
245# else-
246 /* This covers all non-interactive programs such as services. */-
247 if (!wcsstr(name, L"WinSta0"))-
248 return 1;-
249# endif-
250 else-
251 return 0;-
252}-
253# endif-
254# else-
255int OPENSSL_isservice(void)-
256{-
257 return 0;-
258}-
259# endif-
260-
261void OPENSSL_showfatal(const char *fmta, ...)-
262{-
263 va_list ap;-
264 TCHAR buf[256];-
265 const TCHAR *fmt;-
266 /*-
267 * First check if it's a console application, in which case the-
268 * error message would be printed to standard error.-
269 * Windows CE does not have a concept of a console application,-
270 * so we need to guard the check.-
271 */-
272# ifdef STD_ERROR_HANDLE-
273 HANDLE h;-
274-
275 if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&-
276 GetFileType(h) != FILE_TYPE_UNKNOWN) {-
277 /* must be console application */-
278 int len;-
279 DWORD out;-
280-
281 va_start(ap, fmta);-
282 len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);-
283 WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);-
284 va_end(ap);-
285 return;-
286 }-
287# endif-
288-
289 if (sizeof(TCHAR) == sizeof(char))-
290 fmt = (const TCHAR *)fmta;-
291 else-
292 do {-
293 int keepgoing;-
294 size_t len_0 = strlen(fmta) + 1, i;-
295 WCHAR *fmtw;-
296-
297 fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));-
298 if (fmtw == NULL) {-
299 fmt = (const TCHAR *)L"no stack?";-
300 break;-
301 }-
302 if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))-
303 for (i = 0; i < len_0; i++)-
304 fmtw[i] = (WCHAR)fmta[i];-
305 for (i = 0; i < len_0; i++) {-
306 if (fmtw[i] == L'%')-
307 do {-
308 keepgoing = 0;-
309 switch (fmtw[i + 1]) {-
310 case L'0':-
311 case L'1':-
312 case L'2':-
313 case L'3':-
314 case L'4':-
315 case L'5':-
316 case L'6':-
317 case L'7':-
318 case L'8':-
319 case L'9':-
320 case L'.':-
321 case L'*':-
322 case L'-':-
323 i++;-
324 keepgoing = 1;-
325 break;-
326 case L's':-
327 fmtw[i + 1] = L'S';-
328 break;-
329 case L'S':-
330 fmtw[i + 1] = L's';-
331 break;-
332 case L'c':-
333 fmtw[i + 1] = L'C';-
334 break;-
335 case L'C':-
336 fmtw[i + 1] = L'c';-
337 break;-
338 }-
339 } while (keepgoing);-
340 }-
341 fmt = (const TCHAR *)fmtw;-
342 } while (0);-
343-
344 va_start(ap, fmta);-
345 _vsntprintf(buf, OSSL_NELEM(buf) - 1, fmt, ap);-
346 buf[OSSL_NELEM(buf) - 1] = _T('\0');-
347 va_end(ap);-
348-
349# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333-
350# ifdef OPENSSL_SYS_WIN_CORE-
351 /* ONECORE is always NONGUI and NT >= 0x0601 */-
352-
353 /*-
354 * TODO: (For non GUI and no std error cases)-
355 * Add event logging feature here. -
356 */-
357 -
358# if !defined(NDEBUG)-
359 /*-
360 * We are in a situation where we tried to report a critical-
361 * error and this failed for some reason. As a last resort,-
362 * in debug builds, send output to the debugger or any other-
363 * tool like DebugView which can monitor the output.-
364 */-
365 OutputDebugString(buf);-
366# endif-
367# else-
368 /* this -------------v--- guards NT-specific calls */-
369 if (check_winnt() && OPENSSL_isservice() > 0) {-
370 HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));-
371-
372 if (hEventLog != NULL) {-
373 const TCHAR *pmsg = buf;-
374-
375 if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,-
376 1, 0, &pmsg, NULL)) {-
377# if !defined(NDEBUG)-
378 /*-
379 * We are in a situation where we tried to report a critical-
380 * error and this failed for some reason. As a last resort,-
381 * in debug builds, send output to the debugger or any other-
382 * tool like DebugView which can monitor the output.-
383 */-
384 OutputDebugString(pmsg);-
385# endif-
386 }-
387-
388 (void)DeregisterEventSource(hEventLog);-
389 }-
390 } else {-
391 MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);-
392 }-
393# endif-
394# else-
395 MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);-
396# endif -
397}-
398#else-
399void OPENSSL_showfatal(const char *fmta, ...)-
400{-
401#ifndef OPENSSL_NO_STDIO-
402 va_list ap;-
403-
404 va_start(ap, fmta);-
405 vfprintf(stderr, fmta, ap);-
406 va_end(ap);-
407#endif-
408}
never executed: end of block
0
409-
410int OPENSSL_isservice(void)-
411{-
412 return 0;
never executed: return 0;
0
413}-
414#endif-
415-
416void OPENSSL_die(const char *message, const char *file, int line)-
417{-
418 OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n",-
419 file, line, message);-
420#if !defined(_WIN32)-
421 abort();
never executed: abort();
0
422#else-
423 /*-
424 * Win32 abort() customarily shows a dialog, but we just did that...-
425 */-
426# if !defined(_WIN32_WCE)-
427 raise(SIGABRT);-
428# endif-
429 _exit(3);-
430#endif-
431}-
432-
433#if !defined(OPENSSL_CPUID_OBJ)-
434/*-
435 * The volatile is used to to ensure that the compiler generates code that reads-
436 * all values from the array and doesn't try to optimize this away. The standard-
437 * doesn't actually require this behavior if the original data pointed to is-
438 * not volatile, but compilers do this in practice anyway.-
439 *-
440 * There are also assembler versions of this function.-
441 */-
442# undef CRYPTO_memcmp-
443int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len)-
444{-
445 size_t i;-
446 const volatile unsigned char *a = in_a;-
447 const volatile unsigned char *b = in_b;-
448 unsigned char x = 0;-
449-
450 for (i = 0; i < len; i++)-
451 x |= a[i] ^ b[i];-
452-
453 return x;-
454}-
455-
456/*-
457 * For systems that don't provide an instruction counter register or equivalent.-
458 */-
459uint32_t OPENSSL_rdtsc(void)-
460{-
461 return 0;-
462}-
463#endif-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2