cryptlib.c 9.5 KB

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