155714Skris/* crypto/cryptlib.c */ 2160814Ssimon/* ==================================================================== 3160814Ssimon * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 4160814Ssimon * 5160814Ssimon * Redistribution and use in source and binary forms, with or without 6160814Ssimon * modification, are permitted provided that the following conditions 7160814Ssimon * are met: 8160814Ssimon * 9160814Ssimon * 1. Redistributions of source code must retain the above copyright 10296465Sdelphij * notice, this list of conditions and the following disclaimer. 11160814Ssimon * 12160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 13160814Ssimon * notice, this list of conditions and the following disclaimer in 14160814Ssimon * the documentation and/or other materials provided with the 15160814Ssimon * distribution. 16160814Ssimon * 17160814Ssimon * 3. All advertising materials mentioning features or use of this 18160814Ssimon * software must display the following acknowledgment: 19160814Ssimon * "This product includes software developed by the OpenSSL Project 20160814Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21160814Ssimon * 22160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23160814Ssimon * endorse or promote products derived from this software without 24160814Ssimon * prior written permission. For written permission, please contact 25160814Ssimon * openssl-core@openssl.org. 26160814Ssimon * 27160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 28160814Ssimon * nor may "OpenSSL" appear in their names without prior written 29160814Ssimon * permission of the OpenSSL Project. 30160814Ssimon * 31160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 32160814Ssimon * acknowledgment: 33160814Ssimon * "This product includes software developed by the OpenSSL Project 34160814Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35160814Ssimon * 36160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 48160814Ssimon * ==================================================================== 49160814Ssimon * 50160814Ssimon * This product includes cryptographic software written by Eric Young 51160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 52160814Ssimon * Hudson (tjh@cryptsoft.com). 53160814Ssimon * 54160814Ssimon */ 5555714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 5655714Skris * All rights reserved. 5755714Skris * 5855714Skris * This package is an SSL implementation written 5955714Skris * by Eric Young (eay@cryptsoft.com). 6055714Skris * The implementation was written so as to conform with Netscapes SSL. 61296465Sdelphij * 6255714Skris * This library is free for commercial and non-commercial use as long as 6355714Skris * the following conditions are aheared to. The following conditions 6455714Skris * apply to all code found in this distribution, be it the RC4, RSA, 6555714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 6655714Skris * included with this distribution is covered by the same copyright terms 6755714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 68296465Sdelphij * 6955714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 7055714Skris * the code are not to be removed. 7155714Skris * If this package is used in a product, Eric Young should be given attribution 7255714Skris * as the author of the parts of the library used. 7355714Skris * This can be in the form of a textual message at program startup or 7455714Skris * in documentation (online or textual) provided with the package. 75296465Sdelphij * 7655714Skris * Redistribution and use in source and binary forms, with or without 7755714Skris * modification, are permitted provided that the following conditions 7855714Skris * are met: 7955714Skris * 1. Redistributions of source code must retain the copyright 8055714Skris * notice, this list of conditions and the following disclaimer. 8155714Skris * 2. Redistributions in binary form must reproduce the above copyright 8255714Skris * notice, this list of conditions and the following disclaimer in the 8355714Skris * documentation and/or other materials provided with the distribution. 8455714Skris * 3. All advertising materials mentioning features or use of this software 8555714Skris * must display the following acknowledgement: 8655714Skris * "This product includes cryptographic software written by 8755714Skris * Eric Young (eay@cryptsoft.com)" 8855714Skris * The word 'cryptographic' can be left out if the rouines from the library 8955714Skris * being used are not cryptographic related :-). 90296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 9155714Skris * the apps directory (application code) you must include an acknowledgement: 9255714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 93296465Sdelphij * 9455714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 9555714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9655714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9755714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 9855714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 9955714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 10055714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 10155714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 10255714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 10355714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 10455714Skris * SUCH DAMAGE. 105296465Sdelphij * 10655714Skris * The licence and distribution terms for any publically available version or 10755714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 10855714Skris * copied and put under another distribution licence 10955714Skris * [including the GNU Public Licence.] 11055714Skris */ 111160814Ssimon/* ==================================================================== 112160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 113296465Sdelphij * ECDH support in OpenSSL originally developed by 114160814Ssimon * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 115160814Ssimon */ 11655714Skris 11755714Skris#include "cryptlib.h" 11868651Skris#include <openssl/safestack.h> 11955714Skris 120109998Smarkm#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) 121296465Sdelphijstatic double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */ 12255714Skris#endif 12355714Skris 124296465Sdelphijstatic void (MS_FAR *locking_callback) (int mode, int type, 125296465Sdelphij const char *file, int line) = NULL; 126296465Sdelphijstatic int (MS_FAR *add_lock_callback) (int *pointer, int amount, 127296465Sdelphij int type, const char *file, 128296465Sdelphij int line) = NULL; 129296465Sdelphijstatic unsigned long (MS_FAR *id_callback) (void) = NULL; 13068651Skris 13155714Skrisint CRYPTO_num_locks(void) 132296465Sdelphij{ 133296465Sdelphij return CRYPTO_NUM_LOCKS; 134296465Sdelphij} 13555714Skris 136296465Sdelphijvoid (*CRYPTO_get_locking_callback(void)) (int mode, int type, 137296465Sdelphij const char *file, int line) { 138296465Sdelphij return (locking_callback); 139296465Sdelphij} 14055714Skris 141296465Sdelphijint (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type, 142296465Sdelphij const char *file, int line) { 143296465Sdelphij return (add_lock_callback); 144296465Sdelphij} 14555714Skris 146296465Sdelphijvoid CRYPTO_set_locking_callback(void (*func) (int mode, int type, 147296465Sdelphij const char *file, int line)) 148296465Sdelphij{ 149296465Sdelphij locking_callback = func; 150296465Sdelphij} 15155714Skris 152296465Sdelphijvoid CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type, 153296465Sdelphij const char *file, int line)) 154296465Sdelphij{ 155296465Sdelphij add_lock_callback = func; 156296465Sdelphij} 15755714Skris 158296465Sdelphijunsigned long (*CRYPTO_get_id_callback(void)) (void) { 159296465Sdelphij return (id_callback); 160296465Sdelphij} 16155714Skris 162296465Sdelphijvoid CRYPTO_set_id_callback(unsigned long (*func) (void)) 163296465Sdelphij{ 164296465Sdelphij id_callback = func; 165296465Sdelphij} 16655714Skris 16755714Skrisunsigned long CRYPTO_thread_id(void) 168296465Sdelphij{ 169296465Sdelphij unsigned long ret = 0; 17055714Skris 171296465Sdelphij if (id_callback == NULL) { 172109998Smarkm#ifdef OPENSSL_SYS_WIN16 173296465Sdelphij ret = (unsigned long)GetCurrentTask(); 174109998Smarkm#elif defined(OPENSSL_SYS_WIN32) 175296465Sdelphij ret = (unsigned long)GetCurrentThreadId(); 17659191Skris#elif defined(GETPID_IS_MEANINGLESS) 177296465Sdelphij ret = 1L; 17855714Skris#else 179296465Sdelphij ret = (unsigned long)getpid(); 18055714Skris#endif 181296465Sdelphij } else 182296465Sdelphij ret = id_callback(); 183296465Sdelphij return (ret); 184296465Sdelphij} 18555714Skris 186296465Sdelphijstatic void (*do_dynlock_cb) (int mode, int type, const char *file, int line); 187194206Ssimon 188296465Sdelphijvoid int_CRYPTO_set_do_dynlock_callback(void (*dyn_cb) 189296465Sdelphij (int mode, int type, 190296465Sdelphij const char *file, int line)) 191296465Sdelphij{ 192296465Sdelphij do_dynlock_cb = dyn_cb; 193296465Sdelphij} 194194206Ssimon 19555714Skrisvoid CRYPTO_lock(int mode, int type, const char *file, int line) 196296465Sdelphij{ 19755714Skris#ifdef LOCK_DEBUG 198296465Sdelphij { 199296465Sdelphij char *rw_text, *operation_text; 20055714Skris 201296465Sdelphij if (mode & CRYPTO_LOCK) 202296465Sdelphij operation_text = "lock "; 203296465Sdelphij else if (mode & CRYPTO_UNLOCK) 204296465Sdelphij operation_text = "unlock"; 205296465Sdelphij else 206296465Sdelphij operation_text = "ERROR "; 20755714Skris 208296465Sdelphij if (mode & CRYPTO_READ) 209296465Sdelphij rw_text = "r"; 210296465Sdelphij else if (mode & CRYPTO_WRITE) 211296465Sdelphij rw_text = "w"; 212296465Sdelphij else 213296465Sdelphij rw_text = "ERROR"; 21455714Skris 215296465Sdelphij fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n", 216296465Sdelphij CRYPTO_thread_id(), rw_text, operation_text, 217296465Sdelphij CRYPTO_get_lock_name(type), file, line); 218296465Sdelphij } 21955714Skris#endif 220296465Sdelphij if (type < 0) { 221296465Sdelphij if (do_dynlock_cb) 222296465Sdelphij do_dynlock_cb(mode, type, file, line); 223296465Sdelphij } else if (locking_callback != NULL) 224296465Sdelphij locking_callback(mode, type, file, line); 225296465Sdelphij} 22655714Skris 22755714Skrisint CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, 228296465Sdelphij int line) 229296465Sdelphij{ 230296465Sdelphij int ret = 0; 23155714Skris 232296465Sdelphij if (add_lock_callback != NULL) { 23355714Skris#ifdef LOCK_DEBUG 234296465Sdelphij int before = *pointer; 23555714Skris#endif 23655714Skris 237296465Sdelphij ret = add_lock_callback(pointer, amount, type, file, line); 23855714Skris#ifdef LOCK_DEBUG 239296465Sdelphij fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 240296465Sdelphij CRYPTO_thread_id(), 241296465Sdelphij before, amount, ret, CRYPTO_get_lock_name(type), file, line); 24255714Skris#endif 243296465Sdelphij } else { 244296465Sdelphij CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line); 24555714Skris 246296465Sdelphij ret = *pointer + amount; 24755714Skris#ifdef LOCK_DEBUG 248296465Sdelphij fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 249296465Sdelphij CRYPTO_thread_id(), 250296465Sdelphij *pointer, amount, ret, 251296465Sdelphij CRYPTO_get_lock_name(type), file, line); 25255714Skris#endif 253296465Sdelphij *pointer = ret; 254296465Sdelphij CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line); 255296465Sdelphij } 256296465Sdelphij return (ret); 257296465Sdelphij} 25855714Skris 259296465Sdelphij#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ 260296465Sdelphij defined(__INTEL__) || \ 261296465Sdelphij defined(__x86_64) || defined(__x86_64__) || \ 262296465Sdelphij defined(_M_AMD64) || defined(_M_X64) 26355714Skris 264296465Sdelphijunsigned long OPENSSL_ia32cap_P = 0; 265296465Sdelphijunsigned long *OPENSSL_ia32cap_loc(void) 266296465Sdelphij{ 267296465Sdelphij return &OPENSSL_ia32cap_P; 268296465Sdelphij} 269160814Ssimon 270296465Sdelphij# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) 271296465Sdelphij# define OPENSSL_CPUID_SETUP 272160814Ssimonvoid OPENSSL_cpuid_setup(void) 273296465Sdelphij{ 274296465Sdelphij static int trigger = 0; 275296465Sdelphij unsigned long OPENSSL_ia32_cpuid(void); 276296465Sdelphij char *env; 277160814Ssimon 278296465Sdelphij if (trigger) 279296465Sdelphij return; 280160814Ssimon 281296465Sdelphij trigger = 1; 282296465Sdelphij if ((env = getenv("OPENSSL_ia32cap"))) 283296465Sdelphij OPENSSL_ia32cap_P = strtoul(env, NULL, 0) | (1 << 10); 284160814Ssimon else 285296465Sdelphij OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid() | (1 << 10); 286160814Ssimon /* 287160814Ssimon * |(1<<10) sets a reserved bit to signal that variable 288160814Ssimon * was initialized already... This is to avoid interference 289160814Ssimon * with cpuid snippets in ELF .init segment. 290160814Ssimon */ 291160814Ssimon} 292296465Sdelphij# endif 293160814Ssimon 294160814Ssimon#else 295296465Sdelphijunsigned long *OPENSSL_ia32cap_loc(void) 296296465Sdelphij{ 297296465Sdelphij return NULL; 298296465Sdelphij} 299160814Ssimon#endif 300160814Ssimonint OPENSSL_NONPIC_relocated = 0; 301160814Ssimon#if !defined(OPENSSL_CPUID_SETUP) 302296465Sdelphijvoid OPENSSL_cpuid_setup(void) 303296465Sdelphij{ 304296465Sdelphij} 305160814Ssimon#endif 306160814Ssimon 307160814Ssimon#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) 308194206Ssimon 309296465Sdelphij# ifdef OPENSSL_FIPS 310194206Ssimon 311296465Sdelphij# include <tlhelp32.h> 312296465Sdelphij# if defined(__GNUC__) && __GNUC__>=2 313296465Sdelphijstatic int DllInit(void) __attribute__ ((constructor)); 314296465Sdelphij# elif defined(_MSC_VER) 315194206Ssimonstatic int DllInit(void); 316296465Sdelphij# ifdef _WIN64 317296465Sdelphij# pragma section(".CRT$XCU",read) 318296465Sdelphij__declspec(allocate(".CRT$XCU")) 319296465Sdelphij# else 320296465Sdelphij# pragma data_seg(".CRT$XCU") 321296465Sdelphij# endif 322296465Sdelphijstatic int (*p) (void) = DllInit; 323296465Sdelphij# pragma data_seg() 324296465Sdelphij# endif 325194206Ssimon 326194206Ssimonstatic int DllInit(void) 327194206Ssimon{ 328296465Sdelphij# if defined(_WIN32_WINNT) 329296465Sdelphij union { 330296465Sdelphij int (*f) (void); 331296465Sdelphij BYTE *p; 332296465Sdelphij } t = { 333296465Sdelphij DllInit 334296465Sdelphij }; 335296465Sdelphij HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 336296465Sdelphij IMAGE_DOS_HEADER *dos_header; 337296465Sdelphij IMAGE_NT_HEADERS *nt_headers; 338296465Sdelphij MODULEENTRY32 me32 = { sizeof(me32) }; 339194206Ssimon 340296465Sdelphij hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0); 341296465Sdelphij if (hModuleSnap != INVALID_HANDLE_VALUE && 342296465Sdelphij Module32First(hModuleSnap, &me32)) 343296465Sdelphij do { 344296465Sdelphij if (t.p >= me32.modBaseAddr && 345296465Sdelphij t.p < me32.modBaseAddr + me32.modBaseSize) { 346296465Sdelphij dos_header = (IMAGE_DOS_HEADER *) me32.modBaseAddr; 347296465Sdelphij if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) { 348296465Sdelphij nt_headers = (IMAGE_NT_HEADERS *) 349296465Sdelphij ((BYTE *) dos_header + dos_header->e_lfanew); 350296465Sdelphij if (nt_headers->Signature == IMAGE_NT_SIGNATURE && 351296465Sdelphij me32.modBaseAddr != 352296465Sdelphij (BYTE *) nt_headers->OptionalHeader.ImageBase) 353296465Sdelphij OPENSSL_NONPIC_relocated = 1; 354296465Sdelphij } 355296465Sdelphij break; 356296465Sdelphij } 357296465Sdelphij } while (Module32Next(hModuleSnap, &me32)); 358194206Ssimon 359296465Sdelphij if (hModuleSnap != INVALID_HANDLE_VALUE) 360296465Sdelphij CloseHandle(hModuleSnap); 361296465Sdelphij# endif 362296465Sdelphij OPENSSL_cpuid_setup(); 363296465Sdelphij return 0; 364194206Ssimon} 365194206Ssimon 366296465Sdelphij# else 367194206Ssimon 368296465Sdelphij# ifdef __CYGWIN__ 369160814Ssimon/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ 370296465Sdelphij# include <windows.h> 371296465Sdelphij# endif 372160814Ssimon 373296465Sdelphij/* 374296465Sdelphij * All we really need to do is remove the 'error' state when a thread 375296465Sdelphij * detaches 376296465Sdelphij */ 37755714Skris 378296465SdelphijBOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 379296465Sdelphij{ 380296465Sdelphij switch (fdwReason) { 381296465Sdelphij case DLL_PROCESS_ATTACH: 382296465Sdelphij OPENSSL_cpuid_setup(); 383296465Sdelphij# if defined(_WIN32_WINNT) 384296465Sdelphij { 385296465Sdelphij IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL; 386296465Sdelphij IMAGE_NT_HEADERS *nt_headers; 387160814Ssimon 388296465Sdelphij if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) { 389296465Sdelphij nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header 390296465Sdelphij + dos_header->e_lfanew); 391296465Sdelphij if (nt_headers->Signature == IMAGE_NT_SIGNATURE && 392296465Sdelphij hinstDLL != 393296465Sdelphij (HINSTANCE) (nt_headers->OptionalHeader.ImageBase)) 394296465Sdelphij OPENSSL_NONPIC_relocated = 1; 395296465Sdelphij } 396296465Sdelphij } 397296465Sdelphij# endif 398296465Sdelphij break; 399296465Sdelphij case DLL_THREAD_ATTACH: 400296465Sdelphij break; 401296465Sdelphij case DLL_THREAD_DETACH: 402296465Sdelphij break; 403296465Sdelphij case DLL_PROCESS_DETACH: 404296465Sdelphij break; 405296465Sdelphij } 406296465Sdelphij return (TRUE); 407296465Sdelphij} 408296465Sdelphij# endif 40955714Skris 410194206Ssimon#endif 411194206Ssimon 412160814Ssimon#if defined(_WIN32) && !defined(__CYGWIN__) 413296465Sdelphij# include <tchar.h> 414109998Smarkm 415296465Sdelphij# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 416160814Ssimonint OPENSSL_isservice(void) 417296465Sdelphij{ 418296465Sdelphij HWINSTA h; 419296465Sdelphij DWORD len; 420296465Sdelphij WCHAR *name; 421142425Snectar 422296465Sdelphij (void)GetDesktopWindow(); /* return value is ignored */ 423142425Snectar 424160814Ssimon h = GetProcessWindowStation(); 425296465Sdelphij if (h == NULL) 426296465Sdelphij return -1; 427142425Snectar 428296465Sdelphij if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) || 429296465Sdelphij GetLastError() != ERROR_INSUFFICIENT_BUFFER) 430296465Sdelphij return -1; 431142425Snectar 432296465Sdelphij if (len > 512) 433296465Sdelphij return -1; /* paranoia */ 434296465Sdelphij len++, len &= ~1; /* paranoia */ 435296465Sdelphij# ifdef _MSC_VER 436296465Sdelphij name = (WCHAR *)_alloca(len + sizeof(WCHAR)); 437296465Sdelphij# else 438296465Sdelphij name = (WCHAR *)alloca(len + sizeof(WCHAR)); 439296465Sdelphij# endif 440296465Sdelphij if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len)) 441296465Sdelphij return -1; 442142425Snectar 443296465Sdelphij len++, len &= ~1; /* paranoia */ 444296465Sdelphij name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */ 445296465Sdelphij# if 1 446296465Sdelphij /* 447296465Sdelphij * This doesn't cover "interactive" services [working with real 448296465Sdelphij * WinSta0's] nor programs started non-interactively by Task Scheduler 449296465Sdelphij * [those are working with SAWinSta]. 450296465Sdelphij */ 451296465Sdelphij if (wcsstr(name, L"Service-0x")) 452296465Sdelphij return 1; 453296465Sdelphij# else 454160814Ssimon /* This covers all non-interactive programs such as services. */ 455296465Sdelphij if (!wcsstr(name, L"WinSta0")) 456296465Sdelphij return 1; 457296465Sdelphij# endif 458296465Sdelphij else 459296465Sdelphij return 0; 460160814Ssimon} 461296465Sdelphij# else 462296465Sdelphijint OPENSSL_isservice(void) 463296465Sdelphij{ 464296465Sdelphij return 0; 465296465Sdelphij} 466296465Sdelphij# endif 467142425Snectar 468296465Sdelphijvoid OPENSSL_showfatal(const char *fmta, ...) 469296465Sdelphij{ 470296465Sdelphij va_list ap; 471296465Sdelphij TCHAR buf[256]; 472296465Sdelphij const TCHAR *fmt; 473296465Sdelphij# ifdef STD_ERROR_HANDLE /* what a dirty trick! */ 474296465Sdelphij HANDLE h; 475142425Snectar 476296465Sdelphij if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL && 477296465Sdelphij GetFileType(h) != FILE_TYPE_UNKNOWN) { 478296465Sdelphij /* must be console application */ 479296465Sdelphij va_start(ap, fmta); 480296465Sdelphij vfprintf(stderr, fmta, ap); 481296465Sdelphij va_end(ap); 482296465Sdelphij return; 483160814Ssimon } 484296465Sdelphij# endif 485142425Snectar 486296465Sdelphij if (sizeof(TCHAR) == sizeof(char)) 487296465Sdelphij fmt = (const TCHAR *)fmta; 488296465Sdelphij else 489296465Sdelphij do { 490296465Sdelphij int keepgoing; 491296465Sdelphij size_t len_0 = strlen(fmta) + 1, i; 492296465Sdelphij WCHAR *fmtw; 493142425Snectar 494296465Sdelphij# ifdef _MSC_VER 495296465Sdelphij fmtw = (WCHAR *)_alloca(len_0 * sizeof(WCHAR)); 496296465Sdelphij# else 497296465Sdelphij fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR)); 498296465Sdelphij# endif 499296465Sdelphij if (fmtw == NULL) { 500296465Sdelphij fmt = (const TCHAR *)L"no stack?"; 501296465Sdelphij break; 502296465Sdelphij } 503296465Sdelphij# ifndef OPENSSL_NO_MULTIBYTE 504296465Sdelphij if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0)) 505296465Sdelphij# endif 506296465Sdelphij for (i = 0; i < len_0; i++) 507296465Sdelphij fmtw[i] = (WCHAR)fmta[i]; 508142425Snectar 509296465Sdelphij for (i = 0; i < len_0; i++) { 510296465Sdelphij if (fmtw[i] == L'%') 511296465Sdelphij do { 512296465Sdelphij keepgoing = 0; 513296465Sdelphij switch (fmtw[i + 1]) { 514296465Sdelphij case L'0': 515296465Sdelphij case L'1': 516296465Sdelphij case L'2': 517296465Sdelphij case L'3': 518296465Sdelphij case L'4': 519296465Sdelphij case L'5': 520296465Sdelphij case L'6': 521296465Sdelphij case L'7': 522296465Sdelphij case L'8': 523296465Sdelphij case L'9': 524296465Sdelphij case L'.': 525296465Sdelphij case L'*': 526296465Sdelphij case L'-': 527296465Sdelphij i++; 528296465Sdelphij keepgoing = 1; 529296465Sdelphij break; 530296465Sdelphij case L's': 531296465Sdelphij fmtw[i + 1] = L'S'; 532296465Sdelphij break; 533296465Sdelphij case L'S': 534296465Sdelphij fmtw[i + 1] = L's'; 535296465Sdelphij break; 536296465Sdelphij case L'c': 537296465Sdelphij fmtw[i + 1] = L'C'; 538296465Sdelphij break; 539296465Sdelphij case L'C': 540296465Sdelphij fmtw[i + 1] = L'c'; 541296465Sdelphij break; 542296465Sdelphij } 543296465Sdelphij } while (keepgoing); 544296465Sdelphij } 545296465Sdelphij fmt = (const TCHAR *)fmtw; 546296465Sdelphij } while (0); 547142425Snectar 548296465Sdelphij va_start(ap, fmta); 549296465Sdelphij _vsntprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap); 550296465Sdelphij buf[sizeof(buf) / sizeof(TCHAR) - 1] = _T('\0'); 551296465Sdelphij va_end(ap); 552142425Snectar 553296465Sdelphij# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 554160814Ssimon /* this -------------v--- guards NT-specific calls */ 555296465Sdelphij if (check_winnt() && OPENSSL_isservice() > 0) { 556296465Sdelphij HANDLE h = RegisterEventSource(0, _T("OPENSSL")); 557296465Sdelphij const TCHAR *pmsg = buf; 558296465Sdelphij ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 0, 0, 1, 0, &pmsg, 0); 559296465Sdelphij DeregisterEventSource(h); 560296465Sdelphij } else 561296465Sdelphij# endif 562296465Sdelphij MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONSTOP); 563160814Ssimon} 564160814Ssimon#else 565296465Sdelphijvoid OPENSSL_showfatal(const char *fmta, ...) 566296465Sdelphij{ 567296465Sdelphij va_list ap; 568142425Snectar 569296465Sdelphij va_start(ap, fmta); 570296465Sdelphij vfprintf(stderr, fmta, ap); 571296465Sdelphij va_end(ap); 572160814Ssimon} 573296465Sdelphij 574296465Sdelphijint OPENSSL_isservice(void) 575296465Sdelphij{ 576296465Sdelphij return 0; 577296465Sdelphij} 578160814Ssimon#endif 579142425Snectar 580296465Sdelphijvoid OpenSSLDie(const char *file, int line, const char *assertion) 581296465Sdelphij{ 582296465Sdelphij OPENSSL_showfatal 583296465Sdelphij ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line, 584296465Sdelphij assertion); 585296465Sdelphij abort(); 586296465Sdelphij} 587142425Snectar 588296465Sdelphijvoid *OPENSSL_stderr(void) 589296465Sdelphij{ 590296465Sdelphij return stderr; 591296465Sdelphij} 592248272Sdelphij 593248272Sdelphij#ifndef OPENSSL_FIPS 594248272Sdelphij 595248272Sdelphijint CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) 596296465Sdelphij{ 597296465Sdelphij size_t i; 598296465Sdelphij const unsigned char *a = in_a; 599296465Sdelphij const unsigned char *b = in_b; 600296465Sdelphij unsigned char x = 0; 601248272Sdelphij 602296465Sdelphij for (i = 0; i < len; i++) 603296465Sdelphij x |= a[i] ^ b[i]; 604248272Sdelphij 605296465Sdelphij return x; 606296465Sdelphij} 607248272Sdelphij#endif 608