]>
Commit | Line | Data |
---|---|---|
19b8d06a | 1 | /* ==================================================================== |
48fc582f | 2 | * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. |
19b8d06a BM |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without | |
5 | * modification, are permitted provided that the following conditions | |
6 | * are met: | |
7 | * | |
8 | * 1. Redistributions of source code must retain the above copyright | |
0f113f3e | 9 | * notice, this list of conditions and the following disclaimer. |
19b8d06a BM |
10 | * |
11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in | |
13 | * the documentation and/or other materials provided with the | |
14 | * distribution. | |
15 | * | |
16 | * 3. All advertising materials mentioning features or use of this | |
17 | * software must display the following acknowledgment: | |
18 | * "This product includes software developed by the OpenSSL Project | |
19 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | |
20 | * | |
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
22 | * endorse or promote products derived from this software without | |
23 | * prior written permission. For written permission, please contact | |
24 | * openssl-core@openssl.org. | |
25 | * | |
26 | * 5. Products derived from this software may not be called "OpenSSL" | |
27 | * nor may "OpenSSL" appear in their names without prior written | |
28 | * permission of the OpenSSL Project. | |
29 | * | |
30 | * 6. Redistributions of any form whatsoever must retain the following | |
31 | * acknowledgment: | |
32 | * "This product includes software developed by the OpenSSL Project | |
33 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | |
34 | * | |
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
47 | * ==================================================================== | |
48 | * | |
49 | * This product includes cryptographic software written by Eric Young | |
50 | * (eay@cryptsoft.com). This product includes software written by Tim | |
51 | * Hudson (tjh@cryptsoft.com). | |
52 | * | |
53 | */ | |
58964a49 | 54 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
d02b48c6 RE |
55 | * All rights reserved. |
56 | * | |
57 | * This package is an SSL implementation written | |
58 | * by Eric Young (eay@cryptsoft.com). | |
59 | * The implementation was written so as to conform with Netscapes SSL. | |
0f113f3e | 60 | * |
d02b48c6 RE |
61 | * This library is free for commercial and non-commercial use as long as |
62 | * the following conditions are aheared to. The following conditions | |
63 | * apply to all code found in this distribution, be it the RC4, RSA, | |
64 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | |
65 | * included with this distribution is covered by the same copyright terms | |
66 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | |
0f113f3e | 67 | * |
d02b48c6 RE |
68 | * Copyright remains Eric Young's, and as such any Copyright notices in |
69 | * the code are not to be removed. | |
70 | * If this package is used in a product, Eric Young should be given attribution | |
71 | * as the author of the parts of the library used. | |
72 | * This can be in the form of a textual message at program startup or | |
73 | * in documentation (online or textual) provided with the package. | |
0f113f3e | 74 | * |
d02b48c6 RE |
75 | * Redistribution and use in source and binary forms, with or without |
76 | * modification, are permitted provided that the following conditions | |
77 | * are met: | |
78 | * 1. Redistributions of source code must retain the copyright | |
79 | * notice, this list of conditions and the following disclaimer. | |
80 | * 2. Redistributions in binary form must reproduce the above copyright | |
81 | * notice, this list of conditions and the following disclaimer in the | |
82 | * documentation and/or other materials provided with the distribution. | |
83 | * 3. All advertising materials mentioning features or use of this software | |
84 | * must display the following acknowledgement: | |
85 | * "This product includes cryptographic software written by | |
86 | * Eric Young (eay@cryptsoft.com)" | |
87 | * The word 'cryptographic' can be left out if the rouines from the library | |
88 | * being used are not cryptographic related :-). | |
0f113f3e | 89 | * 4. If you include any Windows specific code (or a derivative thereof) from |
d02b48c6 RE |
90 | * the apps directory (application code) you must include an acknowledgement: |
91 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |
0f113f3e | 92 | * |
d02b48c6 RE |
93 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
94 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
95 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
96 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
97 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
98 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
99 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
100 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
101 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
102 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
103 | * SUCH DAMAGE. | |
0f113f3e | 104 | * |
d02b48c6 RE |
105 | * The licence and distribution terms for any publically available version or |
106 | * derivative of this code cannot be changed. i.e. this code cannot simply be | |
107 | * copied and put under another distribution licence | |
108 | * [including the GNU Public Licence.] | |
109 | */ | |
e172d60d BM |
110 | /* ==================================================================== |
111 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | |
0f113f3e | 112 | * ECDH support in OpenSSL originally developed by |
e172d60d BM |
113 | * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. |
114 | */ | |
d02b48c6 | 115 | |
7b9f8f7f | 116 | #include "internal/cryptlib_int.h" |
c7922304 | 117 | #include <openssl/safestack.h> |
d02b48c6 | 118 | |
0f113f3e | 119 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ |
0f113f3e MC |
120 | defined(__x86_64) || defined(__x86_64__) || \ |
121 | defined(_M_AMD64) || defined(_M_X64) | |
14e21f86 | 122 | |
0f113f3e MC |
123 | extern unsigned int OPENSSL_ia32cap_P[4]; |
124 | unsigned int *OPENSSL_ia32cap_loc(void) | |
125 | { | |
126 | return OPENSSL_ia32cap_P; | |
127 | } | |
14e21f86 | 128 | |
0f113f3e | 129 | # if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) |
984d6c60 | 130 | #include <stdio.h> |
0f113f3e | 131 | # define OPENSSL_CPUID_SETUP |
1c7b2c0e | 132 | typedef uint64_t IA32CAP; |
2b247cf8 | 133 | void OPENSSL_cpuid_setup(void) |
0f113f3e MC |
134 | { |
135 | static int trigger = 0; | |
136 | IA32CAP OPENSSL_ia32_cpuid(unsigned int *); | |
137 | IA32CAP vec; | |
138 | char *env; | |
139 | ||
140 | if (trigger) | |
141 | return; | |
142 | ||
143 | trigger = 1; | |
144 | if ((env = getenv("OPENSSL_ia32cap"))) { | |
145 | int off = (env[0] == '~') ? 1 : 0; | |
146 | # if defined(_WIN32) | |
147 | if (!sscanf(env + off, "%I64i", &vec)) | |
148 | vec = strtoul(env + off, NULL, 0); | |
149 | # else | |
150 | if (!sscanf(env + off, "%lli", (long long *)&vec)) | |
151 | vec = strtoul(env + off, NULL, 0); | |
152 | # endif | |
153 | if (off) | |
154 | vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec; | |
155 | else if (env[0] == ':') | |
156 | vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); | |
157 | ||
158 | OPENSSL_ia32cap_P[2] = 0; | |
159 | if ((env = strchr(env, ':'))) { | |
160 | unsigned int vecx; | |
161 | env++; | |
162 | off = (env[0] == '~') ? 1 : 0; | |
163 | vecx = strtoul(env + off, NULL, 0); | |
164 | if (off) | |
165 | OPENSSL_ia32cap_P[2] &= ~vecx; | |
166 | else | |
167 | OPENSSL_ia32cap_P[2] = vecx; | |
168 | } | |
169 | } else | |
170 | vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); | |
e303f55f | 171 | |
14e21f86 AP |
172 | /* |
173 | * |(1<<10) sets a reserved bit to signal that variable | |
174 | * was initialized already... This is to avoid interference | |
175 | * with cpuid snippets in ELF .init segment. | |
176 | */ | |
0f113f3e MC |
177 | OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10); |
178 | OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32); | |
14e21f86 | 179 | } |
0f113f3e | 180 | # else |
c5cd28bd | 181 | unsigned int OPENSSL_ia32cap_P[4]; |
0f113f3e | 182 | # endif |
14e21f86 | 183 | |
630e4a6e | 184 | #else |
0f113f3e MC |
185 | unsigned int *OPENSSL_ia32cap_loc(void) |
186 | { | |
187 | return NULL; | |
188 | } | |
14e21f86 | 189 | #endif |
1875e6db | 190 | int OPENSSL_NONPIC_relocated = 0; |
a00e414f | 191 | #if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) |
0f113f3e MC |
192 | void OPENSSL_cpuid_setup(void) |
193 | { | |
194 | } | |
14e21f86 AP |
195 | #endif |
196 | ||
0f113f3e MC |
197 | #if defined(_WIN32) && !defined(__CYGWIN__) |
198 | # include <tchar.h> | |
199 | # include <signal.h> | |
200 | # ifdef __WATCOMC__ | |
201 | # if defined(_UNICODE) || defined(__UNICODE__) | |
202 | # define _vsntprintf _vsnwprintf | |
203 | # else | |
204 | # define _vsntprintf _vsnprintf | |
205 | # endif | |
206 | # endif | |
207 | # ifdef _MSC_VER | |
208 | # define alloca _alloca | |
209 | # endif | |
210 | ||
211 | # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 | |
e476f942 | 212 | int OPENSSL_isservice(void) |
0f113f3e MC |
213 | { |
214 | HWINSTA h; | |
215 | DWORD len; | |
216 | WCHAR *name; | |
217 | static union { | |
218 | void *p; | |
156561b0 | 219 | FARPROC f; |
0f113f3e MC |
220 | } _OPENSSL_isservice = { |
221 | NULL | |
222 | }; | |
471d0eb3 AP |
223 | |
224 | if (_OPENSSL_isservice.p == NULL) { | |
156561b0 AP |
225 | HANDLE mod = GetModuleHandle(NULL); |
226 | if (mod != NULL) | |
227 | _OPENSSL_isservice.f = GetProcAddress(mod, "_OPENSSL_isservice"); | |
0f113f3e MC |
228 | if (_OPENSSL_isservice.p == NULL) |
229 | _OPENSSL_isservice.p = (void *)-1; | |
471d0eb3 AP |
230 | } |
231 | ||
232 | if (_OPENSSL_isservice.p != (void *)-1) | |
0f113f3e | 233 | return (*_OPENSSL_isservice.f) (); |
9f2027e5 | 234 | |
9f2027e5 | 235 | h = GetProcessWindowStation(); |
0f113f3e MC |
236 | if (h == NULL) |
237 | return -1; | |
238 | ||
239 | if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) || | |
240 | GetLastError() != ERROR_INSUFFICIENT_BUFFER) | |
241 | return -1; | |
242 | ||
243 | if (len > 512) | |
244 | return -1; /* paranoia */ | |
245 | len++, len &= ~1; /* paranoia */ | |
246 | name = (WCHAR *)alloca(len + sizeof(WCHAR)); | |
247 | if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len)) | |
248 | return -1; | |
249 | ||
250 | len++, len &= ~1; /* paranoia */ | |
251 | name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */ | |
252 | # if 1 | |
253 | /* | |
254 | * This doesn't cover "interactive" services [working with real | |
255 | * WinSta0's] nor programs started non-interactively by Task Scheduler | |
256 | * [those are working with SAWinSta]. | |
257 | */ | |
258 | if (wcsstr(name, L"Service-0x")) | |
259 | return 1; | |
260 | # else | |
9f2027e5 | 261 | /* This covers all non-interactive programs such as services. */ |
0f113f3e MC |
262 | if (!wcsstr(name, L"WinSta0")) |
263 | return 1; | |
264 | # endif | |
265 | else | |
266 | return 0; | |
9f2027e5 | 267 | } |
0f113f3e MC |
268 | # else |
269 | int OPENSSL_isservice(void) | |
270 | { | |
271 | return 0; | |
272 | } | |
273 | # endif | |
274 | ||
275 | void OPENSSL_showfatal(const char *fmta, ...) | |
276 | { | |
277 | va_list ap; | |
278 | TCHAR buf[256]; | |
279 | const TCHAR *fmt; | |
280 | # ifdef STD_ERROR_HANDLE /* what a dirty trick! */ | |
281 | HANDLE h; | |
282 | ||
283 | if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL && | |
284 | GetFileType(h) != FILE_TYPE_UNKNOWN) { | |
285 | /* must be console application */ | |
286 | int len; | |
287 | DWORD out; | |
288 | ||
289 | va_start(ap, fmta); | |
290 | len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap); | |
291 | WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL); | |
292 | va_end(ap); | |
293 | return; | |
9f2027e5 | 294 | } |
0f113f3e | 295 | # endif |
9f2027e5 | 296 | |
0f113f3e MC |
297 | if (sizeof(TCHAR) == sizeof(char)) |
298 | fmt = (const TCHAR *)fmta; | |
9f2027e5 | 299 | else |
0f113f3e MC |
300 | do { |
301 | int keepgoing; | |
302 | size_t len_0 = strlen(fmta) + 1, i; | |
303 | WCHAR *fmtw; | |
304 | ||
305 | fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR)); | |
306 | if (fmtw == NULL) { | |
307 | fmt = (const TCHAR *)L"no stack?"; | |
308 | break; | |
309 | } | |
0f113f3e | 310 | if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0)) |
0f113f3e MC |
311 | for (i = 0; i < len_0; i++) |
312 | fmtw[i] = (WCHAR)fmta[i]; | |
0f113f3e MC |
313 | for (i = 0; i < len_0; i++) { |
314 | if (fmtw[i] == L'%') | |
315 | do { | |
316 | keepgoing = 0; | |
317 | switch (fmtw[i + 1]) { | |
318 | case L'0': | |
319 | case L'1': | |
320 | case L'2': | |
321 | case L'3': | |
322 | case L'4': | |
323 | case L'5': | |
324 | case L'6': | |
325 | case L'7': | |
326 | case L'8': | |
327 | case L'9': | |
328 | case L'.': | |
329 | case L'*': | |
330 | case L'-': | |
331 | i++; | |
332 | keepgoing = 1; | |
333 | break; | |
334 | case L's': | |
335 | fmtw[i + 1] = L'S'; | |
336 | break; | |
337 | case L'S': | |
338 | fmtw[i + 1] = L's'; | |
339 | break; | |
340 | case L'c': | |
341 | fmtw[i + 1] = L'C'; | |
342 | break; | |
343 | case L'C': | |
344 | fmtw[i + 1] = L'c'; | |
345 | break; | |
346 | } | |
347 | } while (keepgoing); | |
348 | } | |
349 | fmt = (const TCHAR *)fmtw; | |
350 | } while (0); | |
351 | ||
352 | va_start(ap, fmta); | |
bdcb1a2c DSH |
353 | _vsntprintf(buf, OSSL_NELEM(buf) - 1, fmt, ap); |
354 | buf[OSSL_NELEM(buf) - 1] = _T('\0'); | |
0f113f3e MC |
355 | va_end(ap); |
356 | ||
357 | # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 | |
358 | /* this -------------v--- guards NT-specific calls */ | |
359 | if (check_winnt() && OPENSSL_isservice() > 0) { | |
4cd94416 GK |
360 | HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL")); |
361 | ||
362 | if (hEventLog != NULL) { | |
363 | const TCHAR *pmsg = buf; | |
364 | ||
365 | if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL, | |
366 | 1, 0, &pmsg, NULL)) { | |
367 | #if defined(DEBUG) | |
368 | /* | |
369 | * We are in a situation where we tried to report a critical | |
370 | * error and this failed for some reason. As a last resort, | |
371 | * in debug builds, send output to the debugger or any other | |
372 | * tool like DebugView which can monitor the output. | |
373 | */ | |
374 | OutputDebugString(pmsg); | |
375 | #endif | |
376 | } | |
377 | ||
378 | (void)DeregisterEventSource(hEventLog); | |
379 | } | |
0f113f3e MC |
380 | } else |
381 | # endif | |
4cd94416 | 382 | MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR); |
9f2027e5 AP |
383 | } |
384 | #else | |
0f113f3e MC |
385 | void OPENSSL_showfatal(const char *fmta, ...) |
386 | { | |
984d6c60 | 387 | #ifndef OPENSSL_NO_STDIO |
0f113f3e MC |
388 | va_list ap; |
389 | ||
390 | va_start(ap, fmta); | |
391 | vfprintf(stderr, fmta, ap); | |
392 | va_end(ap); | |
984d6c60 | 393 | #endif |
0f113f3e | 394 | } |
9f2027e5 | 395 | |
0f113f3e MC |
396 | int OPENSSL_isservice(void) |
397 | { | |
398 | return 0; | |
9f2027e5 AP |
399 | } |
400 | #endif | |
401 | ||
040d43b3 | 402 | void OPENSSL_die(const char *message, const char *file, int line) |
0f113f3e | 403 | { |
040d43b3 RS |
404 | OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n", |
405 | file, line, message); | |
6022fe81 | 406 | #if !defined(_WIN32) || defined(__CYGWIN__) |
0f113f3e | 407 | abort(); |
3b58c74c | 408 | #else |
0f113f3e MC |
409 | /* |
410 | * Win32 abort() customarily shows a dialog, but we just did that... | |
411 | */ | |
412 | # if !defined(_WIN32_WCE) | |
413 | raise(SIGABRT); | |
414 | # endif | |
415 | _exit(3); | |
3b58c74c | 416 | #endif |
0f113f3e | 417 | } |
9e88c827 | 418 | |
eb507efb DM |
419 | /* volatile unsigned char* pointers are there because |
420 | * 1. Accessing a variable declared volatile via a pointer | |
421 | * that lacks a volatile qualifier causes undefined behavior. | |
422 | * 2. When the variable itself is not volatile the compiler is | |
423 | * not required to keep all those reads and can convert | |
424 | * this into canonical memcmp() which doesn't read the whole block. | |
425 | * Pointers to volatile resolve the first problem fully. The second | |
426 | * problem cannot be resolved in any Standard-compliant way but this | |
427 | * works the problem around. Compilers typically react to | |
428 | * pointers to volatile by preserving the reads and writes through them. | |
429 | * The latter is not required by the Standard if the memory pointed to | |
430 | * is not volatile. | |
431 | * Pointers themselves are volatile in the function signature to work | |
432 | * around a subtle bug in gcc 4.6+ which causes writes through | |
433 | * pointers to volatile to not be emitted in some rare, | |
434 | * never needed in real life, pieces of code. | |
435 | */ | |
769adcfe RS |
436 | int CRYPTO_memcmp(const volatile void * volatile in_a, |
437 | const volatile void * volatile in_b, | |
438 | size_t len) | |
0f113f3e MC |
439 | { |
440 | size_t i; | |
98ab5764 RS |
441 | const volatile unsigned char *a = in_a; |
442 | const volatile unsigned char *b = in_b; | |
0f113f3e | 443 | unsigned char x = 0; |
7c770d57 | 444 | |
0f113f3e MC |
445 | for (i = 0; i < len; i++) |
446 | x |= a[i] ^ b[i]; | |
7c770d57 | 447 | |
0f113f3e MC |
448 | return x; |
449 | } |