/*
- * Copyright 1998-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
* Licensed under the OpenSSL license (the "License"). You may not use
* https://www.openssl.org/source/license.html
*/
-#include "internal/cryptlib_int.h"
#include "e_os.h"
+#include "internal/cryptlib_int.h"
#include <openssl/safestack.h>
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
if (!sscanf(env + off, "%lli", (long long *)&vec))
vec = strtoul(env + off, NULL, 0);
# endif
- if (off)
- vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
- else if (env[0] == ':')
+ if (off) {
+ IA32CAP mask = vec;
+ vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~mask;
+ if (mask & (1<<24)) {
+ /*
+ * User disables FXSR bit, mask even other capabilities
+ * that operate exclusively on XMM, so we don't have to
+ * double-check all the time. We mask PCLMULQDQ, AMD XOP,
+ * AES-NI and AVX. Formally speaking we don't have to
+ * do it in x86_64 case, but we can safely assume that
+ * x86_64 users won't actually flip this flag.
+ */
+ vec &= ~((IA32CAP)(1<<1|1<<11|1<<25|1<<28) << 32);
+ }
+ } else if (env[0] == ':') {
vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+ }
- OPENSSL_ia32cap_P[2] = 0;
if ((env = strchr(env, ':'))) {
- unsigned int vecx;
+ IA32CAP vecx;
env++;
off = (env[0] == '~') ? 1 : 0;
- vecx = strtoul(env + off, NULL, 0);
- if (off)
- OPENSSL_ia32cap_P[2] &= ~vecx;
- else
- OPENSSL_ia32cap_P[2] = vecx;
+# if defined(_WIN32)
+ if (!sscanf(env + off, "%I64i", &vecx))
+ vecx = strtoul(env + off, NULL, 0);
+# else
+ if (!sscanf(env + off, "%lli", (long long *)&vecx))
+ vecx = strtoul(env + off, NULL, 0);
+# endif
+ if (off) {
+ OPENSSL_ia32cap_P[2] &= ~(unsigned int)vecx;
+ OPENSSL_ia32cap_P[3] &= ~(unsigned int)(vecx >> 32);
+ } else {
+ OPENSSL_ia32cap_P[2] = (unsigned int)vecx;
+ OPENSSL_ia32cap_P[3] = (unsigned int)(vecx >> 32);
+ }
+ } else {
+ OPENSSL_ia32cap_P[2] = 0;
+ OPENSSL_ia32cap_P[3] = 0;
}
- } else
+ } else {
vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+ }
/*
* |(1<<10) sets a reserved bit to signal that variable
}
#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32)
# include <tchar.h>
# include <signal.h>
# ifdef __WATCOMC__
# endif
# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
+# ifdef OPENSSL_SYS_WIN_CORE
+
+int OPENSSL_isservice(void)
+{
+ /* OneCore API cannot interact with GUI */
+ return 1;
+}
+# else
int OPENSSL_isservice(void)
{
HWINSTA h;
len++, len &= ~1; /* paranoia */
name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
-# if 1
+# if 1
/*
* This doesn't cover "interactive" services [working with real
* WinSta0's] nor programs started non-interactively by Task Scheduler
*/
if (wcsstr(name, L"Service-0x"))
return 1;
-# else
+# else
/* This covers all non-interactive programs such as services. */
if (!wcsstr(name, L"WinSta0"))
return 1;
-# endif
+# endif
else
return 0;
}
+# endif
# else
int OPENSSL_isservice(void)
{
va_end(ap);
# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
+# ifdef OPENSSL_SYS_WIN_CORE
+ /* ONECORE is always NONGUI and NT >= 0x0601 */
+
+ /*
+ * TODO: (For non GUI and no std error cases)
+ * Add event logging feature here.
+ */
+
+# if !defined(NDEBUG)
+ /*
+ * We are in a situation where we tried to report a critical
+ * error and this failed for some reason. As a last resort,
+ * in debug builds, send output to the debugger or any other
+ * tool like DebugView which can monitor the output.
+ */
+ OutputDebugString(buf);
+# endif
+# else
/* this -------------v--- guards NT-specific calls */
if (check_winnt() && OPENSSL_isservice() > 0) {
HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));
if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
1, 0, &pmsg, NULL)) {
-#if defined(DEBUG)
+# if !defined(NDEBUG)
/*
* We are in a situation where we tried to report a critical
* error and this failed for some reason. As a last resort,
* tool like DebugView which can monitor the output.
*/
OutputDebugString(pmsg);
-#endif
+# endif
}
(void)DeregisterEventSource(hEventLog);
}
- } else
-# endif
+ } else {
MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
+ }
+# endif
+# else
+ MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
+# endif
}
#else
void OPENSSL_showfatal(const char *fmta, ...)
{
OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n",
file, line, message);
-#if !defined(_WIN32) || defined(__CYGWIN__)
+#if !defined(_WIN32)
abort();
#else
/*
return x;
}
+
+/*
+ * For systems that don't provide an instruction counter register or equivalent.
+ */
+uint32_t OPENSSL_rdtsc(void)
+{
+ return 0;
+}
#endif