Move e_os.h to be the very first include.
[openssl.git] / crypto / cryptlib.c
1 /*
2  * Copyright 1998-2017 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
19 extern unsigned int OPENSSL_ia32cap_P[4];
20
21 # if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
22 #include <stdio.h>
23 #  define OPENSSL_CPUID_SETUP
24 typedef uint64_t IA32CAP;
25 void OPENSSL_cpuid_setup(void)
26 {
27     static int trigger = 0;
28     IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
29     IA32CAP vec;
30     char *env;
31
32     if (trigger)
33         return;
34
35     trigger = 1;
36     if ((env = getenv("OPENSSL_ia32cap"))) {
37         int off = (env[0] == '~') ? 1 : 0;
38 #  if defined(_WIN32)
39         if (!sscanf(env + off, "%I64i", &vec))
40             vec = strtoul(env + off, NULL, 0);
41 #  else
42         if (!sscanf(env + off, "%lli", (long long *)&vec))
43             vec = strtoul(env + off, NULL, 0);
44 #  endif
45         if (off)
46             vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
47         else if (env[0] == ':')
48             vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
49
50         OPENSSL_ia32cap_P[2] = 0;
51         if ((env = strchr(env, ':'))) {
52             unsigned int vecx;
53             env++;
54             off = (env[0] == '~') ? 1 : 0;
55             vecx = strtoul(env + off, NULL, 0);
56             if (off)
57                 OPENSSL_ia32cap_P[2] &= ~vecx;
58             else
59                 OPENSSL_ia32cap_P[2] = vecx;
60         }
61     } else
62         vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
63
64     /*
65      * |(1<<10) sets a reserved bit to signal that variable
66      * was initialized already... This is to avoid interference
67      * with cpuid snippets in ELF .init segment.
68      */
69     OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
70     OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
71 }
72 # else
73 unsigned int OPENSSL_ia32cap_P[4];
74 # endif
75 #endif
76 int OPENSSL_NONPIC_relocated = 0;
77 #if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
78 void OPENSSL_cpuid_setup(void)
79 {
80 }
81 #endif
82
83 #if defined(_WIN32) && !defined(__CYGWIN__)
84 # include <tchar.h>
85 # include <signal.h>
86 # ifdef __WATCOMC__
87 #  if defined(_UNICODE) || defined(__UNICODE__)
88 #   define _vsntprintf _vsnwprintf
89 #  else
90 #   define _vsntprintf _vsnprintf
91 #  endif
92 # endif
93 # ifdef _MSC_VER
94 #  define alloca _alloca
95 # endif
96
97 # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
98 int OPENSSL_isservice(void)
99 {
100     HWINSTA h;
101     DWORD len;
102     WCHAR *name;
103     static union {
104         void *p;
105         FARPROC f;
106     } _OPENSSL_isservice = {
107         NULL
108     };
109
110     if (_OPENSSL_isservice.p == NULL) {
111         HANDLE mod = GetModuleHandle(NULL);
112         if (mod != NULL)
113             _OPENSSL_isservice.f = GetProcAddress(mod, "_OPENSSL_isservice");
114         if (_OPENSSL_isservice.p == NULL)
115             _OPENSSL_isservice.p = (void *)-1;
116     }
117
118     if (_OPENSSL_isservice.p != (void *)-1)
119         return (*_OPENSSL_isservice.f) ();
120
121     h = GetProcessWindowStation();
122     if (h == NULL)
123         return -1;
124
125     if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
126         GetLastError() != ERROR_INSUFFICIENT_BUFFER)
127         return -1;
128
129     if (len > 512)
130         return -1;              /* paranoia */
131     len++, len &= ~1;           /* paranoia */
132     name = (WCHAR *)alloca(len + sizeof(WCHAR));
133     if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
134         return -1;
135
136     len++, len &= ~1;           /* paranoia */
137     name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
138 #  if 1
139     /*
140      * This doesn't cover "interactive" services [working with real
141      * WinSta0's] nor programs started non-interactively by Task Scheduler
142      * [those are working with SAWinSta].
143      */
144     if (wcsstr(name, L"Service-0x"))
145         return 1;
146 #  else
147     /* This covers all non-interactive programs such as services. */
148     if (!wcsstr(name, L"WinSta0"))
149         return 1;
150 #  endif
151     else
152         return 0;
153 }
154 # else
155 int OPENSSL_isservice(void)
156 {
157     return 0;
158 }
159 # endif
160
161 void OPENSSL_showfatal(const char *fmta, ...)
162 {
163     va_list ap;
164     TCHAR buf[256];
165     const TCHAR *fmt;
166     /*
167      * First check if it's a console application, in which case the
168      * error message would be printed to standard error.
169      * Windows CE does not have a concept of a console application,
170      * so we need to guard the check.
171      */
172 # ifdef STD_ERROR_HANDLE
173     HANDLE h;
174
175     if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
176         GetFileType(h) != FILE_TYPE_UNKNOWN) {
177         /* must be console application */
178         int len;
179         DWORD out;
180
181         va_start(ap, fmta);
182         len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
183         WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
184         va_end(ap);
185         return;
186     }
187 # endif
188
189     if (sizeof(TCHAR) == sizeof(char))
190         fmt = (const TCHAR *)fmta;
191     else
192         do {
193             int keepgoing;
194             size_t len_0 = strlen(fmta) + 1, i;
195             WCHAR *fmtw;
196
197             fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
198             if (fmtw == NULL) {
199                 fmt = (const TCHAR *)L"no stack?";
200                 break;
201             }
202             if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
203                 for (i = 0; i < len_0; i++)
204                     fmtw[i] = (WCHAR)fmta[i];
205             for (i = 0; i < len_0; i++) {
206                 if (fmtw[i] == L'%')
207                     do {
208                         keepgoing = 0;
209                         switch (fmtw[i + 1]) {
210                         case L'0':
211                         case L'1':
212                         case L'2':
213                         case L'3':
214                         case L'4':
215                         case L'5':
216                         case L'6':
217                         case L'7':
218                         case L'8':
219                         case L'9':
220                         case L'.':
221                         case L'*':
222                         case L'-':
223                             i++;
224                             keepgoing = 1;
225                             break;
226                         case L's':
227                             fmtw[i + 1] = L'S';
228                             break;
229                         case L'S':
230                             fmtw[i + 1] = L's';
231                             break;
232                         case L'c':
233                             fmtw[i + 1] = L'C';
234                             break;
235                         case L'C':
236                             fmtw[i + 1] = L'c';
237                             break;
238                         }
239                     } while (keepgoing);
240             }
241             fmt = (const TCHAR *)fmtw;
242         } while (0);
243
244     va_start(ap, fmta);
245     _vsntprintf(buf, OSSL_NELEM(buf) - 1, fmt, ap);
246     buf[OSSL_NELEM(buf) - 1] = _T('\0');
247     va_end(ap);
248
249 # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
250     /* this -------------v--- guards NT-specific calls */
251     if (check_winnt() && OPENSSL_isservice() > 0) {
252         HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));
253
254         if (hEventLog != NULL) {
255             const TCHAR *pmsg = buf;
256
257             if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
258                              1, 0, &pmsg, NULL)) {
259 #if defined(DEBUG)
260                 /*
261                  * We are in a situation where we tried to report a critical
262                  * error and this failed for some reason. As a last resort,
263                  * in debug builds, send output to the debugger or any other
264                  * tool like DebugView which can monitor the output.
265                  */
266                 OutputDebugString(pmsg);
267 #endif
268             }
269
270             (void)DeregisterEventSource(hEventLog);
271         }
272     } else
273 # endif
274         MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
275 }
276 #else
277 void OPENSSL_showfatal(const char *fmta, ...)
278 {
279 #ifndef OPENSSL_NO_STDIO
280     va_list ap;
281
282     va_start(ap, fmta);
283     vfprintf(stderr, fmta, ap);
284     va_end(ap);
285 #endif
286 }
287
288 int OPENSSL_isservice(void)
289 {
290     return 0;
291 }
292 #endif
293
294 void OPENSSL_die(const char *message, const char *file, int line)
295 {
296     OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n",
297                       file, line, message);
298 #if !defined(_WIN32) || defined(__CYGWIN__)
299     abort();
300 #else
301     /*
302      * Win32 abort() customarily shows a dialog, but we just did that...
303      */
304 # if !defined(_WIN32_WCE)
305     raise(SIGABRT);
306 # endif
307     _exit(3);
308 #endif
309 }
310
311 #if !defined(OPENSSL_CPUID_OBJ)
312 /*
313  * The volatile is used to to ensure that the compiler generates code that reads
314  * all values from the array and doesn't try to optimize this away. The standard
315  * doesn't actually require this behavior if the original data pointed to is
316  * not volatile, but compilers do this in practice anyway.
317  *
318  * There are also assembler versions of this function.
319  */
320 # undef CRYPTO_memcmp
321 int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len)
322 {
323     size_t i;
324     const volatile unsigned char *a = in_a;
325     const volatile unsigned char *b = in_b;
326     unsigned char x = 0;
327
328     for (i = 0; i < len; i++)
329         x |= a[i] ^ b[i];
330
331     return x;
332 }
333 #endif