cryptlib.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  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. #include "cryptlib.h"
  117. #include <openssl/safestack.h>
  118. #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
  119. static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */
  120. #endif
  121. DECLARE_STACK_OF(CRYPTO_dynlock)
  122. /* real #defines in crypto.h, keep these upto date */
  123. static const char *const lock_names[CRYPTO_NUM_LOCKS] = {
  124. "<<ERROR>>",
  125. "err",
  126. "ex_data",
  127. "x509",
  128. "x509_info",
  129. "x509_pkey",
  130. "x509_crl",
  131. "x509_req",
  132. "dsa",
  133. "rsa",
  134. "evp_pkey",
  135. "x509_store",
  136. "ssl_ctx",
  137. "ssl_cert",
  138. "ssl_session",
  139. "ssl_sess_cert",
  140. "ssl",
  141. "ssl_method",
  142. "rand",
  143. "rand2",
  144. "debug_malloc",
  145. "BIO",
  146. "gethostbyname",
  147. "getservbyname",
  148. "readdir",
  149. "RSA_blinding",
  150. "dh",
  151. "debug_malloc2",
  152. "dso",
  153. "dynlock",
  154. "engine",
  155. "ui",
  156. "ecdsa",
  157. "ec",
  158. "ecdh",
  159. "bn",
  160. "ec_pre_comp",
  161. "store",
  162. "comp",
  163. "fips",
  164. "fips2",
  165. #if CRYPTO_NUM_LOCKS != 41
  166. # error "Inconsistency between crypto.h and cryptlib.c"
  167. #endif
  168. };
  169. /*
  170. * This is for applications to allocate new type names in the non-dynamic
  171. * array of lock names. These are numbered with positive numbers.
  172. */
  173. static STACK_OF(OPENSSL_STRING) *app_locks = NULL;
  174. /*
  175. * For applications that want a more dynamic way of handling threads, the
  176. * following stack is used. These are externally numbered with negative
  177. * numbers.
  178. */
  179. static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
  180. static void (MS_FAR *locking_callback) (int mode, int type,
  181. const char *file, int line) = 0;
  182. static int (MS_FAR *add_lock_callback) (int *pointer, int amount,
  183. int type, const char *file,
  184. int line) = 0;
  185. #ifndef OPENSSL_NO_DEPRECATED
  186. static unsigned long (MS_FAR *id_callback) (void) = 0;
  187. #endif
  188. static void (MS_FAR *threadid_callback) (CRYPTO_THREADID *) = 0;
  189. static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
  190. (const char *file, int line) = 0;
  191. static void (MS_FAR *dynlock_lock_callback) (int mode,
  192. struct CRYPTO_dynlock_value *l,
  193. const char *file, int line) = 0;
  194. static void (MS_FAR *dynlock_destroy_callback) (struct CRYPTO_dynlock_value
  195. *l, const char *file,
  196. int line) = 0;
  197. int CRYPTO_get_new_lockid(char *name)
  198. {
  199. char *str;
  200. int i;
  201. #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
  202. /*
  203. * A hack to make Visual C++ 5.0 work correctly when linking as a DLL
  204. * using /MT. Without this, the application cannot use any floating point
  205. * printf's. It also seems to be needed for Visual C 1.5 (win16)
  206. */
  207. SSLeay_MSVC5_hack = (double)name[0] * (double)name[1];
  208. #endif
  209. if ((app_locks == NULL)
  210. && ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) {
  211. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE);
  212. return (0);
  213. }
  214. if ((str = BUF_strdup(name)) == NULL) {
  215. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE);
  216. return (0);
  217. }
  218. i = sk_OPENSSL_STRING_push(app_locks, str);
  219. if (!i)
  220. OPENSSL_free(str);
  221. else
  222. i += CRYPTO_NUM_LOCKS; /* gap of one :-) */
  223. return (i);
  224. }
  225. int CRYPTO_num_locks(void)
  226. {
  227. return CRYPTO_NUM_LOCKS;
  228. }
  229. int CRYPTO_get_new_dynlockid(void)
  230. {
  231. int i = 0;
  232. CRYPTO_dynlock *pointer = NULL;
  233. if (dynlock_create_callback == NULL) {
  234. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,
  235. CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
  236. return (0);
  237. }
  238. CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
  239. if ((dyn_locks == NULL)
  240. && ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) {
  241. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  242. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE);
  243. return (0);
  244. }
  245. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  246. pointer = (CRYPTO_dynlock *) OPENSSL_malloc(sizeof(CRYPTO_dynlock));
  247. if (pointer == NULL) {
  248. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE);
  249. return (0);
  250. }
  251. pointer->references = 1;
  252. pointer->data = dynlock_create_callback(__FILE__, __LINE__);
  253. if (pointer->data == NULL) {
  254. OPENSSL_free(pointer);
  255. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE);
  256. return (0);
  257. }
  258. CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
  259. /* First, try to find an existing empty slot */
  260. i = sk_CRYPTO_dynlock_find(dyn_locks, NULL);
  261. /* If there was none, push, thereby creating a new one */
  262. if (i == -1)
  263. /*
  264. * Since sk_push() returns the number of items on the stack, not the
  265. * location of the pushed item, we need to transform the returned
  266. * number into a position, by decreasing it.
  267. */
  268. i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1;
  269. else
  270. /*
  271. * If we found a place with a NULL pointer, put our pointer in it.
  272. */
  273. (void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer);
  274. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  275. if (i == -1) {
  276. dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
  277. OPENSSL_free(pointer);
  278. } else
  279. i += 1; /* to avoid 0 */
  280. return -i;
  281. }
  282. void CRYPTO_destroy_dynlockid(int i)
  283. {
  284. CRYPTO_dynlock *pointer = NULL;
  285. if (i)
  286. i = -i - 1;
  287. if (dynlock_destroy_callback == NULL)
  288. return;
  289. CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
  290. if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) {
  291. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  292. return;
  293. }
  294. pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
  295. if (pointer != NULL) {
  296. --pointer->references;
  297. #ifdef REF_CHECK
  298. if (pointer->references < 0) {
  299. fprintf(stderr,
  300. "CRYPTO_destroy_dynlockid, bad reference count\n");
  301. abort();
  302. } else
  303. #endif
  304. if (pointer->references <= 0) {
  305. (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
  306. } else
  307. pointer = NULL;
  308. }
  309. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  310. if (pointer) {
  311. dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
  312. OPENSSL_free(pointer);
  313. }
  314. }
  315. struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
  316. {
  317. CRYPTO_dynlock *pointer = NULL;
  318. if (i)
  319. i = -i - 1;
  320. CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
  321. if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
  322. pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
  323. if (pointer)
  324. pointer->references++;
  325. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  326. if (pointer)
  327. return pointer->data;
  328. return NULL;
  329. }
  330. struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
  331. (const char *file, int line) {
  332. return (dynlock_create_callback);
  333. }
  334. void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode,
  335. struct CRYPTO_dynlock_value
  336. *l, const char *file,
  337. int line) {
  338. return (dynlock_lock_callback);
  339. }
  340. void (*CRYPTO_get_dynlock_destroy_callback(void))
  341. (struct CRYPTO_dynlock_value *l, const char *file, int line) {
  342. return (dynlock_destroy_callback);
  343. }
  344. void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
  345. (const char *file, int line))
  346. {
  347. dynlock_create_callback = func;
  348. }
  349. void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode,
  350. struct
  351. CRYPTO_dynlock_value *l,
  352. const char *file,
  353. int line))
  354. {
  355. dynlock_lock_callback = func;
  356. }
  357. void CRYPTO_set_dynlock_destroy_callback(void (*func)
  358. (struct CRYPTO_dynlock_value *l,
  359. const char *file, int line))
  360. {
  361. dynlock_destroy_callback = func;
  362. }
  363. void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
  364. const char *file, int line) {
  365. return (locking_callback);
  366. }
  367. int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type,
  368. const char *file, int line) {
  369. return (add_lock_callback);
  370. }
  371. void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
  372. const char *file, int line))
  373. {
  374. /*
  375. * Calling this here ensures initialisation before any threads are
  376. * started.
  377. */
  378. OPENSSL_init();
  379. locking_callback = func;
  380. }
  381. void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
  382. const char *file, int line))
  383. {
  384. add_lock_callback = func;
  385. }
  386. /*
  387. * the memset() here and in set_pointer() seem overkill, but for the sake of
  388. * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause
  389. * two "equal" THREADID structs to not be memcmp()-identical.
  390. */
  391. void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
  392. {
  393. memset(id, 0, sizeof(*id));
  394. id->val = val;
  395. }
  396. static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
  397. void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
  398. {
  399. unsigned char *dest = (void *)&id->val;
  400. unsigned int accum = 0;
  401. unsigned char dnum = sizeof(id->val);
  402. memset(id, 0, sizeof(*id));
  403. id->ptr = ptr;
  404. if (sizeof(id->val) >= sizeof(id->ptr)) {
  405. /*
  406. * 'ptr' can be embedded in 'val' without loss of uniqueness
  407. */
  408. id->val = (unsigned long)id->ptr;
  409. return;
  410. }
  411. /*
  412. * hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
  413. * linear function over the bytes in 'ptr', the co-efficients of which
  414. * are a sequence of low-primes (hash_coeffs is an 8-element cycle) - the
  415. * starting prime for the sequence varies for each byte of 'val' (unique
  416. * polynomials unless pointers are >64-bit). For added spice, the totals
  417. * accumulate rather than restarting from zero, and the index of the
  418. * 'val' byte is added each time (position dependence). If I was a
  419. * black-belt, I'd scan big-endian pointers in reverse to give low-order
  420. * bits more play, but this isn't crypto and I'd prefer nobody mistake it
  421. * as such. Plus I'm lazy.
  422. */
  423. while (dnum--) {
  424. const unsigned char *src = (void *)&id->ptr;
  425. unsigned char snum = sizeof(id->ptr);
  426. while (snum--)
  427. accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
  428. accum += dnum;
  429. *(dest++) = accum & 255;
  430. }
  431. }
  432. int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
  433. {
  434. if (threadid_callback)
  435. return 0;
  436. threadid_callback = func;
  437. return 1;
  438. }
  439. void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *) {
  440. return threadid_callback;
  441. }
  442. void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
  443. {
  444. if (threadid_callback) {
  445. threadid_callback(id);
  446. return;
  447. }
  448. #ifndef OPENSSL_NO_DEPRECATED
  449. /* If the deprecated callback was set, fall back to that */
  450. if (id_callback) {
  451. CRYPTO_THREADID_set_numeric(id, id_callback());
  452. return;
  453. }
  454. #endif
  455. /* Else pick a backup */
  456. #ifdef OPENSSL_SYS_WIN16
  457. CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
  458. #elif defined(OPENSSL_SYS_WIN32)
  459. CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
  460. #elif defined(OPENSSL_SYS_BEOS)
  461. CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
  462. #else
  463. /* For everything else, default to using the address of 'errno' */
  464. CRYPTO_THREADID_set_pointer(id, (void *)&errno);
  465. #endif
  466. }
  467. int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
  468. {
  469. return memcmp(a, b, sizeof(*a));
  470. }
  471. void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
  472. {
  473. memcpy(dest, src, sizeof(*src));
  474. }
  475. unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
  476. {
  477. return id->val;
  478. }
  479. #ifndef OPENSSL_NO_DEPRECATED
  480. unsigned long (*CRYPTO_get_id_callback(void)) (void) {
  481. return (id_callback);
  482. }
  483. void CRYPTO_set_id_callback(unsigned long (*func) (void))
  484. {
  485. id_callback = func;
  486. }
  487. unsigned long CRYPTO_thread_id(void)
  488. {
  489. unsigned long ret = 0;
  490. if (id_callback == NULL) {
  491. # ifdef OPENSSL_SYS_WIN16
  492. ret = (unsigned long)GetCurrentTask();
  493. # elif defined(OPENSSL_SYS_WIN32)
  494. ret = (unsigned long)GetCurrentThreadId();
  495. # elif defined(GETPID_IS_MEANINGLESS)
  496. ret = 1L;
  497. # elif defined(OPENSSL_SYS_BEOS)
  498. ret = (unsigned long)find_thread(NULL);
  499. # else
  500. ret = (unsigned long)getpid();
  501. # endif
  502. } else
  503. ret = id_callback();
  504. return (ret);
  505. }
  506. #endif
  507. void CRYPTO_lock(int mode, int type, const char *file, int line)
  508. {
  509. #ifdef LOCK_DEBUG
  510. {
  511. CRYPTO_THREADID id;
  512. char *rw_text, *operation_text;
  513. if (mode & CRYPTO_LOCK)
  514. operation_text = "lock ";
  515. else if (mode & CRYPTO_UNLOCK)
  516. operation_text = "unlock";
  517. else
  518. operation_text = "ERROR ";
  519. if (mode & CRYPTO_READ)
  520. rw_text = "r";
  521. else if (mode & CRYPTO_WRITE)
  522. rw_text = "w";
  523. else
  524. rw_text = "ERROR";
  525. CRYPTO_THREADID_current(&id);
  526. fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n",
  527. CRYPTO_THREADID_hash(&id), rw_text, operation_text,
  528. CRYPTO_get_lock_name(type), file, line);
  529. }
  530. #endif
  531. if (type < 0) {
  532. if (dynlock_lock_callback != NULL) {
  533. struct CRYPTO_dynlock_value *pointer
  534. = CRYPTO_get_dynlock_value(type);
  535. OPENSSL_assert(pointer != NULL);
  536. dynlock_lock_callback(mode, pointer, file, line);
  537. CRYPTO_destroy_dynlockid(type);
  538. }
  539. } else if (locking_callback != NULL)
  540. locking_callback(mode, type, file, line);
  541. }
  542. int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
  543. int line)
  544. {
  545. int ret = 0;
  546. if (add_lock_callback != NULL) {
  547. #ifdef LOCK_DEBUG
  548. int before = *pointer;
  549. #endif
  550. ret = add_lock_callback(pointer, amount, type, file, line);
  551. #ifdef LOCK_DEBUG
  552. {
  553. CRYPTO_THREADID id;
  554. CRYPTO_THREADID_current(&id);
  555. fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
  556. CRYPTO_THREADID_hash(&id), before, amount, ret,
  557. CRYPTO_get_lock_name(type), file, line);
  558. }
  559. #endif
  560. } else {
  561. CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
  562. ret = *pointer + amount;
  563. #ifdef LOCK_DEBUG
  564. {
  565. CRYPTO_THREADID id;
  566. CRYPTO_THREADID_current(&id);
  567. fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
  568. CRYPTO_THREADID_hash(&id),
  569. *pointer, amount, ret,
  570. CRYPTO_get_lock_name(type), file, line);
  571. }
  572. #endif
  573. *pointer = ret;
  574. CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line);
  575. }
  576. return (ret);
  577. }
  578. const char *CRYPTO_get_lock_name(int type)
  579. {
  580. if (type < 0)
  581. return ("dynamic");
  582. else if (type < CRYPTO_NUM_LOCKS)
  583. return (lock_names[type]);
  584. else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
  585. return ("ERROR");
  586. else
  587. return (sk_OPENSSL_STRING_value(app_locks, type - CRYPTO_NUM_LOCKS));
  588. }
  589. #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
  590. defined(__INTEL__) || \
  591. defined(__x86_64) || defined(__x86_64__) || \
  592. defined(_M_AMD64) || defined(_M_X64)
  593. extern unsigned int OPENSSL_ia32cap_P[4];
  594. unsigned long *OPENSSL_ia32cap_loc(void)
  595. {
  596. if (sizeof(long) == 4)
  597. /*
  598. * If 32-bit application pulls address of OPENSSL_ia32cap_P[0]
  599. * clear second element to maintain the illusion that vector
  600. * is 32-bit.
  601. */
  602. OPENSSL_ia32cap_P[1] = 0;
  603. OPENSSL_ia32cap_P[2] = 0;
  604. return (unsigned long *)OPENSSL_ia32cap_P;
  605. }
  606. # if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
  607. # define OPENSSL_CPUID_SETUP
  608. # if defined(_WIN32)
  609. typedef unsigned __int64 IA32CAP;
  610. # else
  611. typedef unsigned long long IA32CAP;
  612. # endif
  613. void OPENSSL_cpuid_setup(void)
  614. {
  615. static int trigger = 0;
  616. IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
  617. IA32CAP vec;
  618. char *env;
  619. if (trigger)
  620. return;
  621. trigger = 1;
  622. if ((env = getenv("OPENSSL_ia32cap"))) {
  623. int off = (env[0] == '~') ? 1 : 0;
  624. # if defined(_WIN32)
  625. if (!sscanf(env + off, "%I64i", &vec))
  626. vec = strtoul(env + off, NULL, 0);
  627. # else
  628. if (!sscanf(env + off, "%lli", (long long *)&vec))
  629. vec = strtoul(env + off, NULL, 0);
  630. # endif
  631. if (off)
  632. vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
  633. else if (env[0] == ':')
  634. vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
  635. OPENSSL_ia32cap_P[2] = 0;
  636. if ((env = strchr(env, ':'))) {
  637. unsigned int vecx;
  638. env++;
  639. off = (env[0] == '~') ? 1 : 0;
  640. vecx = strtoul(env + off, NULL, 0);
  641. if (off)
  642. OPENSSL_ia32cap_P[2] &= ~vecx;
  643. else
  644. OPENSSL_ia32cap_P[2] = vecx;
  645. }
  646. } else
  647. vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
  648. /*
  649. * |(1<<10) sets a reserved bit to signal that variable
  650. * was initialized already... This is to avoid interference
  651. * with cpuid snippets in ELF .init segment.
  652. */
  653. OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
  654. OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
  655. }
  656. # else
  657. unsigned int OPENSSL_ia32cap_P[4];
  658. # endif
  659. #else
  660. unsigned long *OPENSSL_ia32cap_loc(void)
  661. {
  662. return NULL;
  663. }
  664. #endif
  665. int OPENSSL_NONPIC_relocated = 0;
  666. #if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
  667. void OPENSSL_cpuid_setup(void)
  668. {
  669. }
  670. #endif
  671. #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
  672. # ifdef __CYGWIN__
  673. /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
  674. # include <windows.h>
  675. /*
  676. * this has side-effect of _WIN32 getting defined, which otherwise is
  677. * mutually exclusive with __CYGWIN__...
  678. */
  679. # endif
  680. /*
  681. * All we really need to do is remove the 'error' state when a thread
  682. * detaches
  683. */
  684. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  685. {
  686. switch (fdwReason) {
  687. case DLL_PROCESS_ATTACH:
  688. OPENSSL_cpuid_setup();
  689. # if defined(_WIN32_WINNT)
  690. {
  691. IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL;
  692. IMAGE_NT_HEADERS *nt_headers;
  693. if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) {
  694. nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header
  695. + dos_header->e_lfanew);
  696. if (nt_headers->Signature == IMAGE_NT_SIGNATURE &&
  697. hinstDLL !=
  698. (HINSTANCE) (nt_headers->OptionalHeader.ImageBase))
  699. OPENSSL_NONPIC_relocated = 1;
  700. }
  701. }
  702. # endif
  703. break;
  704. case DLL_THREAD_ATTACH:
  705. break;
  706. case DLL_THREAD_DETACH:
  707. break;
  708. case DLL_PROCESS_DETACH:
  709. break;
  710. }
  711. return (TRUE);
  712. }
  713. #endif
  714. #if defined(_WIN32) && !defined(__CYGWIN__)
  715. # include <tchar.h>
  716. # include <signal.h>
  717. # ifdef __WATCOMC__
  718. # if defined(_UNICODE) || defined(__UNICODE__)
  719. # define _vsntprintf _vsnwprintf
  720. # else
  721. # define _vsntprintf _vsnprintf
  722. # endif
  723. # endif
  724. # ifdef _MSC_VER
  725. # define alloca _alloca
  726. # endif
  727. # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
  728. int OPENSSL_isservice(void)
  729. {
  730. HWINSTA h;
  731. DWORD len;
  732. WCHAR *name;
  733. static union {
  734. void *p;
  735. int (*f) (void);
  736. } _OPENSSL_isservice = {
  737. NULL
  738. };
  739. if (_OPENSSL_isservice.p == NULL) {
  740. HANDLE h = GetModuleHandle(NULL);
  741. if (h != NULL)
  742. _OPENSSL_isservice.p = GetProcAddress(h, "_OPENSSL_isservice");
  743. if (_OPENSSL_isservice.p == NULL)
  744. _OPENSSL_isservice.p = (void *)-1;
  745. }
  746. if (_OPENSSL_isservice.p != (void *)-1)
  747. return (*_OPENSSL_isservice.f) ();
  748. h = GetProcessWindowStation();
  749. if (h == NULL)
  750. return -1;
  751. if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
  752. GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  753. return -1;
  754. if (len > 512)
  755. return -1; /* paranoia */
  756. len++, len &= ~1; /* paranoia */
  757. name = (WCHAR *)alloca(len + sizeof(WCHAR));
  758. if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
  759. return -1;
  760. len++, len &= ~1; /* paranoia */
  761. name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
  762. # if 1
  763. /*
  764. * This doesn't cover "interactive" services [working with real
  765. * WinSta0's] nor programs started non-interactively by Task Scheduler
  766. * [those are working with SAWinSta].
  767. */
  768. if (wcsstr(name, L"Service-0x"))
  769. return 1;
  770. # else
  771. /* This covers all non-interactive programs such as services. */
  772. if (!wcsstr(name, L"WinSta0"))
  773. return 1;
  774. # endif
  775. else
  776. return 0;
  777. }
  778. # else
  779. int OPENSSL_isservice(void)
  780. {
  781. return 0;
  782. }
  783. # endif
  784. void OPENSSL_showfatal(const char *fmta, ...)
  785. {
  786. va_list ap;
  787. TCHAR buf[256];
  788. const TCHAR *fmt;
  789. # ifdef STD_ERROR_HANDLE /* what a dirty trick! */
  790. HANDLE h;
  791. if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
  792. GetFileType(h) != FILE_TYPE_UNKNOWN) {
  793. /* must be console application */
  794. int len;
  795. DWORD out;
  796. va_start(ap, fmta);
  797. len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
  798. WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
  799. va_end(ap);
  800. return;
  801. }
  802. # endif
  803. if (sizeof(TCHAR) == sizeof(char))
  804. fmt = (const TCHAR *)fmta;
  805. else
  806. do {
  807. int keepgoing;
  808. size_t len_0 = strlen(fmta) + 1, i;
  809. WCHAR *fmtw;
  810. fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
  811. if (fmtw == NULL) {
  812. fmt = (const TCHAR *)L"no stack?";
  813. break;
  814. }
  815. # ifndef OPENSSL_NO_MULTIBYTE
  816. if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
  817. # endif
  818. for (i = 0; i < len_0; i++)
  819. fmtw[i] = (WCHAR)fmta[i];
  820. for (i = 0; i < len_0; i++) {
  821. if (fmtw[i] == L'%')
  822. do {
  823. keepgoing = 0;
  824. switch (fmtw[i + 1]) {
  825. case L'0':
  826. case L'1':
  827. case L'2':
  828. case L'3':
  829. case L'4':
  830. case L'5':
  831. case L'6':
  832. case L'7':
  833. case L'8':
  834. case L'9':
  835. case L'.':
  836. case L'*':
  837. case L'-':
  838. i++;
  839. keepgoing = 1;
  840. break;
  841. case L's':
  842. fmtw[i + 1] = L'S';
  843. break;
  844. case L'S':
  845. fmtw[i + 1] = L's';
  846. break;
  847. case L'c':
  848. fmtw[i + 1] = L'C';
  849. break;
  850. case L'C':
  851. fmtw[i + 1] = L'c';
  852. break;
  853. }
  854. } while (keepgoing);
  855. }
  856. fmt = (const TCHAR *)fmtw;
  857. } while (0);
  858. va_start(ap, fmta);
  859. _vsntprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap);
  860. buf[sizeof(buf) / sizeof(TCHAR) - 1] = _T('\0');
  861. va_end(ap);
  862. # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
  863. /* this -------------v--- guards NT-specific calls */
  864. if (check_winnt() && OPENSSL_isservice() > 0) {
  865. HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));
  866. if (hEventLog != NULL) {
  867. const TCHAR *pmsg = buf;
  868. if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
  869. 1, 0, &pmsg, NULL)) {
  870. #if defined(DEBUG)
  871. /*
  872. * We are in a situation where we tried to report a critical
  873. * error and this failed for some reason. As a last resort,
  874. * in debug builds, send output to the debugger or any other
  875. * tool like DebugView which can monitor the output.
  876. */
  877. OutputDebugString(pmsg);
  878. #endif
  879. }
  880. (void)DeregisterEventSource(hEventLog);
  881. }
  882. } else
  883. # endif
  884. MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
  885. }
  886. #else
  887. void OPENSSL_showfatal(const char *fmta, ...)
  888. {
  889. va_list ap;
  890. va_start(ap, fmta);
  891. vfprintf(stderr, fmta, ap);
  892. va_end(ap);
  893. }
  894. int OPENSSL_isservice(void)
  895. {
  896. return 0;
  897. }
  898. #endif
  899. void OpenSSLDie(const char *file, int line, const char *assertion)
  900. {
  901. OPENSSL_showfatal
  902. ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line,
  903. assertion);
  904. #if !defined(_WIN32) || defined(__CYGWIN__)
  905. abort();
  906. #else
  907. /*
  908. * Win32 abort() customarily shows a dialog, but we just did that...
  909. */
  910. # if !defined(_WIN32_WCE)
  911. raise(SIGABRT);
  912. # endif
  913. _exit(3);
  914. #endif
  915. }
  916. void *OPENSSL_stderr(void)
  917. {
  918. return stderr;
  919. }
  920. int CRYPTO_memcmp(const volatile void *in_a, const volatile void *in_b, size_t len)
  921. {
  922. size_t i;
  923. const volatile unsigned char *a = in_a;
  924. const volatile unsigned char *b = in_b;
  925. unsigned char x = 0;
  926. for (i = 0; i < len; i++)
  927. x |= a[i] ^ b[i];
  928. return x;
  929. }