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