1/* 2 * Copyright 1998-2019 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 "crypto/cryptlib.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 "crypto/ctype.h" 53 54static int todigit(variant_char c) 55{ 56 if (ossl_isdigit(c)) 57 return c - '0'; 58 else if (ossl_isxdigit(c)) 59 return ossl_tolower(c) - 'a' + 10; 60 61 /* return largest base value to make caller terminate the loop */ 62 return 16; 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') { 71 base = 8, str++; 72 if (ossl_tolower(*str) == 'x') 73 base = 16, str++; 74 } 75 76 while((digit = todigit(*str++)) < base) 77 ret = ret * base + digit; 78 79 return ret; 80} 81 82static variant_char *ossl_strchr(const variant_char *str, char srch) 83{ variant_char c; 84 85 while((c = *str)) { 86 if (c == srch) 87 return (variant_char *)str; 88 str++; 89 } 90 91 return NULL; 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) 105 return; 106 107 trigger = 1; 108 if ((env = ossl_getenv("OPENSSL_ia32cap")) != NULL) { 109 int off = (env[0] == '~') ? 1 : 0; 110 111 vec = ossl_strtouint64(env + off); 112 113 if (off) { 114 IA32CAP mask = vec; 115 vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~mask; 116 if (mask & (1<<24)) { 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 } 127 } else if (env[0] == ':') { 128 vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); 129 } 130 131 if ((env = ossl_strchr(env, ':')) != NULL) { 132 IA32CAP vecx; 133 134 env++; 135 off = (env[0] == '~') ? 1 : 0; 136 vecx = ossl_strtouint64(env + off); 137 if (off) { 138 OPENSSL_ia32cap_P[2] &= ~(unsigned int)vecx; 139 OPENSSL_ia32cap_P[3] &= ~(unsigned int)(vecx >> 32); 140 } else { 141 OPENSSL_ia32cap_P[2] = (unsigned int)vecx; 142 OPENSSL_ia32cap_P[3] = (unsigned int)(vecx >> 32); 143 } 144 } else { 145 OPENSSL_ia32cap_P[2] = 0; 146 OPENSSL_ia32cap_P[3] = 0; 147 } 148 } else { 149 vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); 150 } 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} 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} 409 410int OPENSSL_isservice(void) 411{ 412 return 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(); 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 464size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt) 465{ 466 return 0; 467} 468 469size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max) 470{ 471 return 0; 472} 473#endif 474