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