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 19 extern 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 33 typedef WCHAR variant_char; 34 35 static 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 48 typedef char variant_char; 49 # define ossl_getenv getenv 50 # endif 51 52 # include "crypto/ctype.h" 53 54 static 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 65 static 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 82 static 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 95 typedef uint64_t IA32CAP; 96 97 void 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 161 unsigned int OPENSSL_ia32cap_P[4]; 162 # endif 163 #endif 164 #if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) 165 void 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 187 int OPENSSL_isservice(void) 188 { 189 /* OneCore API cannot interact with GUI */ 190 return 1; 191 } 192 # else 193 int 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 255 int OPENSSL_isservice(void) 256 { 257 return 0; 258 } 259 # endif 260 261 void 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 399 void 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 410 int OPENSSL_isservice(void) 411 { 412 return 0; 413 } 414 #endif 415 416 void 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 443 int 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 */ 459 uint32_t OPENSSL_rdtsc(void) 460 { 461 return 0; 462 } 463 464 size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt) 465 { 466 return 0; 467 } 468 469 size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max) 470 { 471 return 0; 472 } 473 #endif 474