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