Branch data Line data Source code
1 : : /* crypto/cryptlib.c */
2 : : /* ====================================================================
3 : : * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
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
10 : : * notice, this list of conditions and the following disclaimer.
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 : : */
55 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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.
61 : : *
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).
68 : : *
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.
75 : : *
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 :-).
90 : : * 4. If you include any Windows specific code (or a derivative thereof) from
91 : : * the apps directory (application code) you must include an acknowledgement:
92 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
93 : : *
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.
105 : : *
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 : : */
111 : : /* ====================================================================
112 : : * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113 : : * ECDH support in OpenSSL originally developed by
114 : : * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115 : : */
116 : :
117 : : #include "cryptlib.h"
118 : : #include <openssl/safestack.h>
119 : :
120 : : #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
121 : : static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
122 : : #endif
123 : :
124 : : #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
125 : : defined(__INTEL__) || \
126 : : defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
127 : :
128 : : extern unsigned int OPENSSL_ia32cap_P[4];
129 : 0 : unsigned int *OPENSSL_ia32cap_loc(void) { return OPENSSL_ia32cap_P; }
130 : :
131 : : #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
132 : : #define OPENSSL_CPUID_SETUP
133 : : #if defined(_WIN32)
134 : : typedef unsigned __int64 IA32CAP;
135 : : #else
136 : : typedef unsigned long long IA32CAP;
137 : : #endif
138 : 3105 : void OPENSSL_cpuid_setup(void)
139 : : { static int trigger=0;
140 : : IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
141 : : IA32CAP vec;
142 : : char *env;
143 : :
144 [ + + ]: 3105 : if (trigger) return;
145 : :
146 : 1651 : trigger=1;
147 [ - + ]: 1651 : if ((env=getenv("OPENSSL_ia32cap"))) {
148 : 0 : int off = (env[0]=='~')?1:0;
149 : : #if defined(_WIN32)
150 : : if (!sscanf(env+off,"%I64i",&vec)) vec = strtoul(env+off,NULL,0);
151 : : #else
152 [ # # ]: 0 : if (!sscanf(env+off,"%lli",(long long *)&vec)) vec = strtoul(env+off,NULL,0);
153 : : #endif
154 [ # # ]: 0 : if (off) vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P)&~vec;
155 [ # # ]: 0 : else if (env[0]==':') vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
156 : :
157 : 0 : OPENSSL_ia32cap_P[2] = 0;
158 [ # # ]: 0 : if ((env=strchr(env,':'))) {
159 : : unsigned int vecx;
160 : 0 : env++;
161 : 0 : off = (env[0]=='~')?1:0;
162 : 0 : vecx = strtoul(env+off,NULL,0);
163 [ # # ]: 0 : if (off) OPENSSL_ia32cap_P[2] &= ~vecx;
164 : 0 : else OPENSSL_ia32cap_P[2] = vecx;
165 : : }
166 : : }
167 : : else
168 : 1651 : vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
169 : :
170 : : /*
171 : : * |(1<<10) sets a reserved bit to signal that variable
172 : : * was initialized already... This is to avoid interference
173 : : * with cpuid snippets in ELF .init segment.
174 : : */
175 : 1651 : OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10);
176 : 1651 : OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32);
177 : : }
178 : : #else
179 : : unsigned int OPENSSL_ia32cap_P[4];
180 : : #endif
181 : :
182 : : #else
183 : : unsigned int *OPENSSL_ia32cap_loc(void) { return NULL; }
184 : : #endif
185 : : int OPENSSL_NONPIC_relocated = 0;
186 : : #if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
187 : : void OPENSSL_cpuid_setup(void) {}
188 : : #endif
189 : :
190 : : #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
191 : : #ifdef __CYGWIN__
192 : : /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
193 : : #include <windows.h>
194 : : /* this has side-effect of _WIN32 getting defined, which otherwise
195 : : * is mutually exclusive with __CYGWIN__... */
196 : : #endif
197 : :
198 : : /* All we really need to do is remove the 'error' state when a thread
199 : : * detaches */
200 : :
201 : : BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
202 : : LPVOID lpvReserved)
203 : : {
204 : : switch(fdwReason)
205 : : {
206 : : case DLL_PROCESS_ATTACH:
207 : : OPENSSL_cpuid_setup();
208 : : #if defined(_WIN32_WINNT)
209 : : {
210 : : IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)hinstDLL;
211 : : IMAGE_NT_HEADERS *nt_headers;
212 : :
213 : : if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
214 : : {
215 : : nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header
216 : : + dos_header->e_lfanew);
217 : : if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
218 : : hinstDLL!=(HINSTANCE)(nt_headers->OptionalHeader.ImageBase))
219 : : OPENSSL_NONPIC_relocated=1;
220 : : }
221 : : }
222 : : #endif
223 : : break;
224 : : case DLL_THREAD_ATTACH:
225 : : break;
226 : : case DLL_THREAD_DETACH:
227 : : break;
228 : : case DLL_PROCESS_DETACH:
229 : : break;
230 : : }
231 : : return(TRUE);
232 : : }
233 : : #endif
234 : :
235 : : #if defined(_WIN32) && !defined(__CYGWIN__)
236 : : #include <tchar.h>
237 : : #include <signal.h>
238 : : #ifdef __WATCOMC__
239 : : #if defined(_UNICODE) || defined(__UNICODE__)
240 : : #define _vsntprintf _vsnwprintf
241 : : #else
242 : : #define _vsntprintf _vsnprintf
243 : : #endif
244 : : #endif
245 : : #ifdef _MSC_VER
246 : : #define alloca _alloca
247 : : #endif
248 : :
249 : : #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
250 : : int OPENSSL_isservice(void)
251 : : { HWINSTA h;
252 : : DWORD len;
253 : : WCHAR *name;
254 : : static union { void *p; int (*f)(void); } _OPENSSL_isservice = { NULL };
255 : :
256 : : if (_OPENSSL_isservice.p == NULL) {
257 : : HANDLE h = GetModuleHandle(NULL);
258 : : if (h != NULL)
259 : : _OPENSSL_isservice.p = GetProcAddress(h,"_OPENSSL_isservice");
260 : : if (_OPENSSL_isservice.p == NULL)
261 : : _OPENSSL_isservice.p = (void *)-1;
262 : : }
263 : :
264 : : if (_OPENSSL_isservice.p != (void *)-1)
265 : : return (*_OPENSSL_isservice.f)();
266 : :
267 : : (void)GetDesktopWindow(); /* return value is ignored */
268 : :
269 : : h = GetProcessWindowStation();
270 : : if (h==NULL) return -1;
271 : :
272 : : if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) ||
273 : : GetLastError() != ERROR_INSUFFICIENT_BUFFER)
274 : : return -1;
275 : :
276 : : if (len>512) return -1; /* paranoia */
277 : : len++,len&=~1; /* paranoia */
278 : : name=(WCHAR *)alloca(len+sizeof(WCHAR));
279 : : if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len))
280 : : return -1;
281 : :
282 : : len++,len&=~1; /* paranoia */
283 : : name[len/sizeof(WCHAR)]=L'\0'; /* paranoia */
284 : : #if 1
285 : : /* This doesn't cover "interactive" services [working with real
286 : : * WinSta0's] nor programs started non-interactively by Task
287 : : * Scheduler [those are working with SAWinSta]. */
288 : : if (wcsstr(name,L"Service-0x")) return 1;
289 : : #else
290 : : /* This covers all non-interactive programs such as services. */
291 : : if (!wcsstr(name,L"WinSta0")) return 1;
292 : : #endif
293 : : else return 0;
294 : : }
295 : : #else
296 : : int OPENSSL_isservice(void) { return 0; }
297 : : #endif
298 : :
299 : : void OPENSSL_showfatal (const char *fmta,...)
300 : : { va_list ap;
301 : : TCHAR buf[256];
302 : : const TCHAR *fmt;
303 : : #ifdef STD_ERROR_HANDLE /* what a dirty trick! */
304 : : HANDLE h;
305 : :
306 : : if ((h=GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
307 : : GetFileType(h)!=FILE_TYPE_UNKNOWN)
308 : : { /* must be console application */
309 : : int len;
310 : : DWORD out;
311 : :
312 : : va_start (ap,fmta);
313 : : len=_vsnprintf((char *)buf,sizeof(buf),fmta,ap);
314 : : WriteFile(h,buf,len<0?sizeof(buf):(DWORD)len,&out,NULL);
315 : : va_end (ap);
316 : : return;
317 : : }
318 : : #endif
319 : :
320 : : if (sizeof(TCHAR)==sizeof(char))
321 : : fmt=(const TCHAR *)fmta;
322 : : else do
323 : : { int keepgoing;
324 : : size_t len_0=strlen(fmta)+1,i;
325 : : WCHAR *fmtw;
326 : :
327 : : fmtw = (WCHAR *)alloca(len_0*sizeof(WCHAR));
328 : : if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; }
329 : :
330 : : #ifndef OPENSSL_NO_MULTIBYTE
331 : : if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0))
332 : : #endif
333 : : for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i];
334 : :
335 : : for (i=0;i<len_0;i++)
336 : : { if (fmtw[i]==L'%') do
337 : : { keepgoing=0;
338 : : switch (fmtw[i+1])
339 : : { case L'0': case L'1': case L'2': case L'3': case L'4':
340 : : case L'5': case L'6': case L'7': case L'8': case L'9':
341 : : case L'.': case L'*':
342 : : case L'-': i++; keepgoing=1; break;
343 : : case L's': fmtw[i+1]=L'S'; break;
344 : : case L'S': fmtw[i+1]=L's'; break;
345 : : case L'c': fmtw[i+1]=L'C'; break;
346 : : case L'C': fmtw[i+1]=L'c'; break;
347 : : }
348 : : } while (keepgoing);
349 : : }
350 : : fmt = (const TCHAR *)fmtw;
351 : : } while (0);
352 : :
353 : : va_start (ap,fmta);
354 : : _vsntprintf (buf,sizeof(buf)/sizeof(TCHAR)-1,fmt,ap);
355 : : buf [sizeof(buf)/sizeof(TCHAR)-1] = _T('\0');
356 : : va_end (ap);
357 : :
358 : : #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
359 : : /* this -------------v--- guards NT-specific calls */
360 : : if (check_winnt() && OPENSSL_isservice() > 0)
361 : : { HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
362 : : const TCHAR *pmsg=buf;
363 : : ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
364 : : DeregisterEventSource(h);
365 : : }
366 : : else
367 : : #endif
368 : : MessageBox (NULL,buf,_T("OpenSSL: FATAL"),MB_OK|MB_ICONSTOP);
369 : : }
370 : : #else
371 : 0 : void OPENSSL_showfatal (const char *fmta,...)
372 : : { va_list ap;
373 : :
374 : 0 : va_start (ap,fmta);
375 : 0 : vfprintf (stderr,fmta,ap);
376 : 0 : va_end (ap);
377 : 0 : }
378 : 0 : int OPENSSL_isservice (void) { return 0; }
379 : : #endif
380 : :
381 : 0 : void OpenSSLDie(const char *file,int line,const char *assertion)
382 : : {
383 : 0 : OPENSSL_showfatal(
384 : : "%s(%d): OpenSSL internal error, assertion failed: %s\n",
385 : : file,line,assertion);
386 : : #if !defined(_WIN32) || defined(__CYGWIN__)
387 : 0 : abort();
388 : : #else
389 : : /* Win32 abort() customarily shows a dialog, but we just did that... */
390 : : #if !defined(_WIN32_WCE)
391 : : raise(SIGABRT);
392 : : #endif
393 : : _exit(3);
394 : : #endif
395 : : }
396 : :
397 : : #ifndef OPENSSL_FIPSCANISTER
398 : 0 : void *OPENSSL_stderr(void) { return stderr; }
399 : : #endif
400 : :
401 : 16789 : int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
402 : : {
403 : : size_t i;
404 : 16789 : const unsigned char *a = in_a;
405 : 16789 : const unsigned char *b = in_b;
406 : 16789 : unsigned char x = 0;
407 : :
408 [ + + ]: 399130 : for (i = 0; i < len; i++)
409 : 382341 : x |= a[i] ^ b[i];
410 : :
411 : 16789 : return x;
412 : : }
|