e_aep.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144
  1. /* ====================================================================
  2. * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. *
  16. * 3. All advertising materials mentioning features or use of this
  17. * software must display the following acknowledgment:
  18. * "This product includes software developed by the OpenSSL Project
  19. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  20. *
  21. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  22. * endorse or promote products derived from this software without
  23. * prior written permission. For written permission, please contact
  24. * licensing@OpenSSL.org.
  25. *
  26. * 5. Products derived from this software may not be called "OpenSSL"
  27. * nor may "OpenSSL" appear in their names without prior written
  28. * permission of the OpenSSL Project.
  29. *
  30. * 6. Redistributions of any form whatsoever must retain the following
  31. * acknowledgment:
  32. * "This product includes software developed by the OpenSSL Project
  33. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  36. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46. * OF THE POSSIBILITY OF SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This product includes cryptographic software written by Eric Young
  50. * (eay@cryptsoft.com). This product includes software written by Tim
  51. * Hudson (tjh@cryptsoft.com).
  52. *
  53. */
  54. #include <stdio.h>
  55. #include <openssl/bn.h>
  56. #include <string.h>
  57. #include <openssl/e_os2.h>
  58. #if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) || defined(__MINGW32__)
  59. #include <sys/types.h>
  60. #include <unistd.h>
  61. #else
  62. #include <process.h>
  63. typedef int pid_t;
  64. #endif
  65. #if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
  66. #define getpid GetThreadID
  67. extern int GetThreadID(void);
  68. #endif
  69. #include <openssl/crypto.h>
  70. #include <openssl/dso.h>
  71. #include <openssl/engine.h>
  72. #include <openssl/buffer.h>
  73. #ifndef OPENSSL_NO_RSA
  74. #include <openssl/rsa.h>
  75. #endif
  76. #ifndef OPENSSL_NO_DSA
  77. #include <openssl/dsa.h>
  78. #endif
  79. #ifndef OPENSSL_NO_DH
  80. #include <openssl/dh.h>
  81. #endif
  82. #include <openssl/bn.h>
  83. #ifndef OPENSSL_NO_HW
  84. #ifndef OPENSSL_NO_HW_AEP
  85. #ifdef FLAT_INC
  86. #include "aep.h"
  87. #else
  88. #include "vendor_defns/aep.h"
  89. #endif
  90. #define AEP_LIB_NAME "aep engine"
  91. #define FAIL_TO_SW 0x10101010
  92. #include "e_aep_err.c"
  93. static int aep_init(ENGINE *e);
  94. static int aep_finish(ENGINE *e);
  95. static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
  96. static int aep_destroy(ENGINE *e);
  97. static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
  98. static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
  99. static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
  100. static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);
  101. /* BIGNUM stuff */
  102. #ifndef OPENSSL_NO_RSA
  103. static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  104. const BIGNUM *m, BN_CTX *ctx);
  105. static AEP_RV aep_mod_exp_crt(BIGNUM *r,const BIGNUM *a, const BIGNUM *p,
  106. const BIGNUM *q, const BIGNUM *dmp1,const BIGNUM *dmq1,
  107. const BIGNUM *iqmp, BN_CTX *ctx);
  108. #endif
  109. /* RSA stuff */
  110. #ifndef OPENSSL_NO_RSA
  111. static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
  112. #endif
  113. /* This function is aliased to mod_exp (with the mont stuff dropped). */
  114. #ifndef OPENSSL_NO_RSA
  115. static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  116. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  117. #endif
  118. /* DSA stuff */
  119. #ifndef OPENSSL_NO_DSA
  120. static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
  121. BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
  122. BN_CTX *ctx, BN_MONT_CTX *in_mont);
  123. static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
  124. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  125. BN_MONT_CTX *m_ctx);
  126. #endif
  127. /* DH stuff */
  128. /* This function is aliased to mod_exp (with the DH and mont dropped). */
  129. #ifndef OPENSSL_NO_DH
  130. static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
  131. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  132. #endif
  133. /* rand stuff */
  134. #ifdef AEPRAND
  135. static int aep_rand(unsigned char *buf, int num);
  136. static int aep_rand_status(void);
  137. #endif
  138. /* Bignum conversion stuff */
  139. static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize);
  140. static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
  141. unsigned char* AEP_BigNum);
  142. static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
  143. unsigned char* AEP_BigNum);
  144. /* The definitions for control commands specific to this engine */
  145. #define AEP_CMD_SO_PATH ENGINE_CMD_BASE
  146. static const ENGINE_CMD_DEFN aep_cmd_defns[] =
  147. {
  148. { AEP_CMD_SO_PATH,
  149. "SO_PATH",
  150. "Specifies the path to the 'aep' shared library",
  151. ENGINE_CMD_FLAG_STRING
  152. },
  153. {0, NULL, NULL, 0}
  154. };
  155. #ifndef OPENSSL_NO_RSA
  156. /* Our internal RSA_METHOD that we provide pointers to */
  157. static RSA_METHOD aep_rsa =
  158. {
  159. "Aep RSA method",
  160. NULL, /*rsa_pub_encrypt*/
  161. NULL, /*rsa_pub_decrypt*/
  162. NULL, /*rsa_priv_encrypt*/
  163. NULL, /*rsa_priv_encrypt*/
  164. aep_rsa_mod_exp, /*rsa_mod_exp*/
  165. aep_mod_exp_mont, /*bn_mod_exp*/
  166. NULL, /*init*/
  167. NULL, /*finish*/
  168. 0, /*flags*/
  169. NULL, /*app_data*/
  170. NULL, /*rsa_sign*/
  171. NULL, /*rsa_verify*/
  172. NULL /*rsa_keygen*/
  173. };
  174. #endif
  175. #ifndef OPENSSL_NO_DSA
  176. /* Our internal DSA_METHOD that we provide pointers to */
  177. static DSA_METHOD aep_dsa =
  178. {
  179. "Aep DSA method",
  180. NULL, /* dsa_do_sign */
  181. NULL, /* dsa_sign_setup */
  182. NULL, /* dsa_do_verify */
  183. aep_dsa_mod_exp, /* dsa_mod_exp */
  184. aep_mod_exp_dsa, /* bn_mod_exp */
  185. NULL, /* init */
  186. NULL, /* finish */
  187. 0, /* flags */
  188. NULL, /* app_data */
  189. NULL, /* dsa_paramgen */
  190. NULL /* dsa_keygen */
  191. };
  192. #endif
  193. #ifndef OPENSSL_NO_DH
  194. /* Our internal DH_METHOD that we provide pointers to */
  195. static DH_METHOD aep_dh =
  196. {
  197. "Aep DH method",
  198. NULL,
  199. NULL,
  200. aep_mod_exp_dh,
  201. NULL,
  202. NULL,
  203. 0,
  204. NULL,
  205. NULL
  206. };
  207. #endif
  208. #ifdef AEPRAND
  209. /* our internal RAND_method that we provide pointers to */
  210. static RAND_METHOD aep_random =
  211. {
  212. /*"AEP RAND method", */
  213. NULL,
  214. aep_rand,
  215. NULL,
  216. NULL,
  217. aep_rand,
  218. aep_rand_status,
  219. };
  220. #endif
  221. /*Define an array of structures to hold connections*/
  222. static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS];
  223. /*Used to determine if this is a new process*/
  224. static pid_t recorded_pid = 0;
  225. #ifdef AEPRAND
  226. static AEP_U8 rand_block[RAND_BLK_SIZE];
  227. static AEP_U32 rand_block_bytes = 0;
  228. #endif
  229. /* Constants used when creating the ENGINE */
  230. static const char *engine_aep_id = "aep";
  231. static const char *engine_aep_name = "Aep hardware engine support";
  232. static int max_key_len = 2176;
  233. /* This internal function is used by ENGINE_aep() and possibly by the
  234. * "dynamic" ENGINE support too */
  235. static int bind_aep(ENGINE *e)
  236. {
  237. #ifndef OPENSSL_NO_RSA
  238. const RSA_METHOD *meth1;
  239. #endif
  240. #ifndef OPENSSL_NO_DSA
  241. const DSA_METHOD *meth2;
  242. #endif
  243. #ifndef OPENSSL_NO_DH
  244. const DH_METHOD *meth3;
  245. #endif
  246. if(!ENGINE_set_id(e, engine_aep_id) ||
  247. !ENGINE_set_name(e, engine_aep_name) ||
  248. #ifndef OPENSSL_NO_RSA
  249. !ENGINE_set_RSA(e, &aep_rsa) ||
  250. #endif
  251. #ifndef OPENSSL_NO_DSA
  252. !ENGINE_set_DSA(e, &aep_dsa) ||
  253. #endif
  254. #ifndef OPENSSL_NO_DH
  255. !ENGINE_set_DH(e, &aep_dh) ||
  256. #endif
  257. #ifdef AEPRAND
  258. !ENGINE_set_RAND(e, &aep_random) ||
  259. #endif
  260. !ENGINE_set_init_function(e, aep_init) ||
  261. !ENGINE_set_destroy_function(e, aep_destroy) ||
  262. !ENGINE_set_finish_function(e, aep_finish) ||
  263. !ENGINE_set_ctrl_function(e, aep_ctrl) ||
  264. !ENGINE_set_cmd_defns(e, aep_cmd_defns))
  265. return 0;
  266. #ifndef OPENSSL_NO_RSA
  267. /* We know that the "PKCS1_SSLeay()" functions hook properly
  268. * to the aep-specific mod_exp and mod_exp_crt so we use
  269. * those functions. NB: We don't use ENGINE_openssl() or
  270. * anything "more generic" because something like the RSAref
  271. * code may not hook properly, and if you own one of these
  272. * cards then you have the right to do RSA operations on it
  273. * anyway! */
  274. meth1 = RSA_PKCS1_SSLeay();
  275. aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
  276. aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
  277. aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
  278. aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
  279. #endif
  280. #ifndef OPENSSL_NO_DSA
  281. /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
  282. * bits. */
  283. meth2 = DSA_OpenSSL();
  284. aep_dsa.dsa_do_sign = meth2->dsa_do_sign;
  285. aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
  286. aep_dsa.dsa_do_verify = meth2->dsa_do_verify;
  287. aep_dsa = *DSA_get_default_method();
  288. aep_dsa.dsa_mod_exp = aep_dsa_mod_exp;
  289. aep_dsa.bn_mod_exp = aep_mod_exp_dsa;
  290. #endif
  291. #ifndef OPENSSL_NO_DH
  292. /* Much the same for Diffie-Hellman */
  293. meth3 = DH_OpenSSL();
  294. aep_dh.generate_key = meth3->generate_key;
  295. aep_dh.compute_key = meth3->compute_key;
  296. aep_dh.bn_mod_exp = meth3->bn_mod_exp;
  297. #endif
  298. /* Ensure the aep error handling is set up */
  299. ERR_load_AEPHK_strings();
  300. return 1;
  301. }
  302. #ifndef OPENSSL_NO_DYNAMIC_ENGINE
  303. static int bind_helper(ENGINE *e, const char *id)
  304. {
  305. if(id && (strcmp(id, engine_aep_id) != 0))
  306. return 0;
  307. if(!bind_aep(e))
  308. return 0;
  309. return 1;
  310. }
  311. IMPLEMENT_DYNAMIC_CHECK_FN()
  312. IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
  313. #else
  314. static ENGINE *engine_aep(void)
  315. {
  316. ENGINE *ret = ENGINE_new();
  317. if(!ret)
  318. return NULL;
  319. if(!bind_aep(ret))
  320. {
  321. ENGINE_free(ret);
  322. return NULL;
  323. }
  324. return ret;
  325. }
  326. void ENGINE_load_aep(void)
  327. {
  328. /* Copied from eng_[openssl|dyn].c */
  329. ENGINE *toadd = engine_aep();
  330. if(!toadd) return;
  331. ENGINE_add(toadd);
  332. ENGINE_free(toadd);
  333. ERR_clear_error();
  334. }
  335. #endif
  336. /* This is a process-global DSO handle used for loading and unloading
  337. * the Aep library. NB: This is only set (or unset) during an
  338. * init() or finish() call (reference counts permitting) and they're
  339. * operating with global locks, so this should be thread-safe
  340. * implicitly. */
  341. static DSO *aep_dso = NULL;
  342. /* These are the static string constants for the DSO file name and the function
  343. * symbol names to bind to.
  344. */
  345. static const char *AEP_LIBNAME = NULL;
  346. static const char *get_AEP_LIBNAME(void)
  347. {
  348. if(AEP_LIBNAME)
  349. return AEP_LIBNAME;
  350. return "aep";
  351. }
  352. static void free_AEP_LIBNAME(void)
  353. {
  354. if(AEP_LIBNAME)
  355. OPENSSL_free((void*)AEP_LIBNAME);
  356. AEP_LIBNAME = NULL;
  357. }
  358. static long set_AEP_LIBNAME(const char *name)
  359. {
  360. free_AEP_LIBNAME();
  361. return ((AEP_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
  362. }
  363. static const char *AEP_F1 = "AEP_ModExp";
  364. static const char *AEP_F2 = "AEP_ModExpCrt";
  365. #ifdef AEPRAND
  366. static const char *AEP_F3 = "AEP_GenRandom";
  367. #endif
  368. static const char *AEP_F4 = "AEP_Finalize";
  369. static const char *AEP_F5 = "AEP_Initialize";
  370. static const char *AEP_F6 = "AEP_OpenConnection";
  371. static const char *AEP_F7 = "AEP_SetBNCallBacks";
  372. static const char *AEP_F8 = "AEP_CloseConnection";
  373. /* These are the function pointers that are (un)set when the library has
  374. * successfully (un)loaded. */
  375. static t_AEP_OpenConnection *p_AEP_OpenConnection = NULL;
  376. static t_AEP_CloseConnection *p_AEP_CloseConnection = NULL;
  377. static t_AEP_ModExp *p_AEP_ModExp = NULL;
  378. static t_AEP_ModExpCrt *p_AEP_ModExpCrt = NULL;
  379. #ifdef AEPRAND
  380. static t_AEP_GenRandom *p_AEP_GenRandom = NULL;
  381. #endif
  382. static t_AEP_Initialize *p_AEP_Initialize = NULL;
  383. static t_AEP_Finalize *p_AEP_Finalize = NULL;
  384. static t_AEP_SetBNCallBacks *p_AEP_SetBNCallBacks = NULL;
  385. /* (de)initialisation functions. */
  386. static int aep_init(ENGINE *e)
  387. {
  388. t_AEP_ModExp *p1;
  389. t_AEP_ModExpCrt *p2;
  390. #ifdef AEPRAND
  391. t_AEP_GenRandom *p3;
  392. #endif
  393. t_AEP_Finalize *p4;
  394. t_AEP_Initialize *p5;
  395. t_AEP_OpenConnection *p6;
  396. t_AEP_SetBNCallBacks *p7;
  397. t_AEP_CloseConnection *p8;
  398. int to_return = 0;
  399. if(aep_dso != NULL)
  400. {
  401. AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
  402. goto err;
  403. }
  404. /* Attempt to load libaep.so. */
  405. aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0);
  406. if(aep_dso == NULL)
  407. {
  408. AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
  409. goto err;
  410. }
  411. if( !(p1 = (t_AEP_ModExp *) DSO_bind_func( aep_dso,AEP_F1)) ||
  412. !(p2 = (t_AEP_ModExpCrt*) DSO_bind_func( aep_dso,AEP_F2)) ||
  413. #ifdef AEPRAND
  414. !(p3 = (t_AEP_GenRandom*) DSO_bind_func( aep_dso,AEP_F3)) ||
  415. #endif
  416. !(p4 = (t_AEP_Finalize*) DSO_bind_func( aep_dso,AEP_F4)) ||
  417. !(p5 = (t_AEP_Initialize*) DSO_bind_func( aep_dso,AEP_F5)) ||
  418. !(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6)) ||
  419. !(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7)) ||
  420. !(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
  421. {
  422. AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
  423. goto err;
  424. }
  425. /* Copy the pointers */
  426. p_AEP_ModExp = p1;
  427. p_AEP_ModExpCrt = p2;
  428. #ifdef AEPRAND
  429. p_AEP_GenRandom = p3;
  430. #endif
  431. p_AEP_Finalize = p4;
  432. p_AEP_Initialize = p5;
  433. p_AEP_OpenConnection = p6;
  434. p_AEP_SetBNCallBacks = p7;
  435. p_AEP_CloseConnection = p8;
  436. to_return = 1;
  437. return to_return;
  438. err:
  439. if(aep_dso)
  440. DSO_free(aep_dso);
  441. aep_dso = NULL;
  442. p_AEP_OpenConnection = NULL;
  443. p_AEP_ModExp = NULL;
  444. p_AEP_ModExpCrt = NULL;
  445. #ifdef AEPRAND
  446. p_AEP_GenRandom = NULL;
  447. #endif
  448. p_AEP_Initialize = NULL;
  449. p_AEP_Finalize = NULL;
  450. p_AEP_SetBNCallBacks = NULL;
  451. p_AEP_CloseConnection = NULL;
  452. return to_return;
  453. }
  454. /* Destructor (complements the "ENGINE_aep()" constructor) */
  455. static int aep_destroy(ENGINE *e)
  456. {
  457. free_AEP_LIBNAME();
  458. ERR_unload_AEPHK_strings();
  459. return 1;
  460. }
  461. static int aep_finish(ENGINE *e)
  462. {
  463. int to_return = 0, in_use;
  464. AEP_RV rv;
  465. if(aep_dso == NULL)
  466. {
  467. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
  468. goto err;
  469. }
  470. rv = aep_close_all_connections(0, &in_use);
  471. if (rv != AEP_R_OK)
  472. {
  473. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
  474. goto err;
  475. }
  476. if (in_use)
  477. {
  478. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
  479. goto err;
  480. }
  481. rv = p_AEP_Finalize();
  482. if (rv != AEP_R_OK)
  483. {
  484. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
  485. goto err;
  486. }
  487. if(!DSO_free(aep_dso))
  488. {
  489. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
  490. goto err;
  491. }
  492. aep_dso = NULL;
  493. p_AEP_CloseConnection = NULL;
  494. p_AEP_OpenConnection = NULL;
  495. p_AEP_ModExp = NULL;
  496. p_AEP_ModExpCrt = NULL;
  497. #ifdef AEPRAND
  498. p_AEP_GenRandom = NULL;
  499. #endif
  500. p_AEP_Initialize = NULL;
  501. p_AEP_Finalize = NULL;
  502. p_AEP_SetBNCallBacks = NULL;
  503. to_return = 1;
  504. err:
  505. return to_return;
  506. }
  507. static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
  508. {
  509. int initialised = ((aep_dso == NULL) ? 0 : 1);
  510. switch(cmd)
  511. {
  512. case AEP_CMD_SO_PATH:
  513. if(p == NULL)
  514. {
  515. AEPHKerr(AEPHK_F_AEP_CTRL,
  516. ERR_R_PASSED_NULL_PARAMETER);
  517. return 0;
  518. }
  519. if(initialised)
  520. {
  521. AEPHKerr(AEPHK_F_AEP_CTRL,
  522. AEPHK_R_ALREADY_LOADED);
  523. return 0;
  524. }
  525. return set_AEP_LIBNAME((const char*)p);
  526. default:
  527. break;
  528. }
  529. AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
  530. return 0;
  531. }
  532. static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  533. const BIGNUM *m, BN_CTX *ctx)
  534. {
  535. int to_return = 0;
  536. int r_len = 0;
  537. AEP_CONNECTION_HNDL hConnection;
  538. AEP_RV rv;
  539. r_len = BN_num_bits(m);
  540. /* Perform in software if modulus is too large for hardware. */
  541. if (r_len > max_key_len){
  542. AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  543. return BN_mod_exp(r, a, p, m, ctx);
  544. }
  545. /*Grab a connection from the pool*/
  546. rv = aep_get_connection(&hConnection);
  547. if (rv != AEP_R_OK)
  548. {
  549. AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED);
  550. return BN_mod_exp(r, a, p, m, ctx);
  551. }
  552. /*To the card with the mod exp*/
  553. rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL);
  554. if (rv != AEP_R_OK)
  555. {
  556. AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED);
  557. rv = aep_close_connection(hConnection);
  558. return BN_mod_exp(r, a, p, m, ctx);
  559. }
  560. /*Return the connection to the pool*/
  561. rv = aep_return_connection(hConnection);
  562. if (rv != AEP_R_OK)
  563. {
  564. AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_RETURN_CONNECTION_FAILED);
  565. goto err;
  566. }
  567. to_return = 1;
  568. err:
  569. return to_return;
  570. }
  571. #ifndef OPENSSL_NO_RSA
  572. static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  573. const BIGNUM *q, const BIGNUM *dmp1,
  574. const BIGNUM *dmq1,const BIGNUM *iqmp, BN_CTX *ctx)
  575. {
  576. AEP_RV rv = AEP_R_OK;
  577. AEP_CONNECTION_HNDL hConnection;
  578. /*Grab a connection from the pool*/
  579. rv = aep_get_connection(&hConnection);
  580. if (rv != AEP_R_OK)
  581. {
  582. AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
  583. return FAIL_TO_SW;
  584. }
  585. /*To the card with the mod exp*/
  586. rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1,
  587. (void*)iqmp,(void*)r,NULL);
  588. if (rv != AEP_R_OK)
  589. {
  590. AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_MOD_EXP_CRT_FAILED);
  591. rv = aep_close_connection(hConnection);
  592. return FAIL_TO_SW;
  593. }
  594. /*Return the connection to the pool*/
  595. rv = aep_return_connection(hConnection);
  596. if (rv != AEP_R_OK)
  597. {
  598. AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_RETURN_CONNECTION_FAILED);
  599. goto err;
  600. }
  601. err:
  602. return rv;
  603. }
  604. #endif
  605. #ifdef AEPRAND
  606. static int aep_rand(unsigned char *buf,int len )
  607. {
  608. AEP_RV rv = AEP_R_OK;
  609. AEP_CONNECTION_HNDL hConnection;
  610. CRYPTO_w_lock(CRYPTO_LOCK_RAND);
  611. /*Can the request be serviced with what's already in the buffer?*/
  612. if (len <= rand_block_bytes)
  613. {
  614. memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
  615. rand_block_bytes -= len;
  616. CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
  617. }
  618. else
  619. /*If not the get another block of random bytes*/
  620. {
  621. CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
  622. rv = aep_get_connection(&hConnection);
  623. if (rv != AEP_R_OK)
  624. {
  625. AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);
  626. goto err_nounlock;
  627. }
  628. if (len > RAND_BLK_SIZE)
  629. {
  630. rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
  631. if (rv != AEP_R_OK)
  632. {
  633. AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
  634. goto err_nounlock;
  635. }
  636. }
  637. else
  638. {
  639. CRYPTO_w_lock(CRYPTO_LOCK_RAND);
  640. rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
  641. if (rv != AEP_R_OK)
  642. {
  643. AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
  644. goto err;
  645. }
  646. rand_block_bytes = RAND_BLK_SIZE;
  647. memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
  648. rand_block_bytes -= len;
  649. CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
  650. }
  651. rv = aep_return_connection(hConnection);
  652. if (rv != AEP_R_OK)
  653. {
  654. AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
  655. goto err_nounlock;
  656. }
  657. }
  658. return 1;
  659. err:
  660. CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
  661. err_nounlock:
  662. return 0;
  663. }
  664. static int aep_rand_status(void)
  665. {
  666. return 1;
  667. }
  668. #endif
  669. #ifndef OPENSSL_NO_RSA
  670. static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
  671. {
  672. int to_return = 0;
  673. AEP_RV rv = AEP_R_OK;
  674. if (!aep_dso)
  675. {
  676. AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
  677. goto err;
  678. }
  679. /*See if we have all the necessary bits for a crt*/
  680. if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp)
  681. {
  682. rv = aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx);
  683. if (rv == FAIL_TO_SW){
  684. const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
  685. to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
  686. goto err;
  687. }
  688. else if (rv != AEP_R_OK)
  689. goto err;
  690. }
  691. else
  692. {
  693. if (!rsa->d || !rsa->n)
  694. {
  695. AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
  696. goto err;
  697. }
  698. rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx);
  699. if (rv != AEP_R_OK)
  700. goto err;
  701. }
  702. to_return = 1;
  703. err:
  704. return to_return;
  705. }
  706. #endif
  707. #ifndef OPENSSL_NO_DSA
  708. static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
  709. BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
  710. BN_CTX *ctx, BN_MONT_CTX *in_mont)
  711. {
  712. BIGNUM t;
  713. int to_return = 0;
  714. BN_init(&t);
  715. /* let rr = a1 ^ p1 mod m */
  716. if (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end;
  717. /* let t = a2 ^ p2 mod m */
  718. if (!aep_mod_exp(&t,a2,p2,m,ctx)) goto end;
  719. /* let rr = rr * t mod m */
  720. if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
  721. to_return = 1;
  722. end:
  723. BN_free(&t);
  724. return to_return;
  725. }
  726. static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
  727. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  728. BN_MONT_CTX *m_ctx)
  729. {
  730. return aep_mod_exp(r, a, p, m, ctx);
  731. }
  732. #endif
  733. #ifndef OPENSSL_NO_RSA
  734. /* This function is aliased to mod_exp (with the mont stuff dropped). */
  735. static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  736. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
  737. {
  738. return aep_mod_exp(r, a, p, m, ctx);
  739. }
  740. #endif
  741. #ifndef OPENSSL_NO_DH
  742. /* This function is aliased to mod_exp (with the dh and mont dropped). */
  743. static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
  744. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  745. BN_MONT_CTX *m_ctx)
  746. {
  747. return aep_mod_exp(r, a, p, m, ctx);
  748. }
  749. #endif
  750. static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
  751. {
  752. int count;
  753. AEP_RV rv = AEP_R_OK;
  754. /*Get the current process id*/
  755. pid_t curr_pid;
  756. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  757. #ifdef NETWARE_CLIB
  758. curr_pid = GetThreadID();
  759. #elif defined(_WIN32)
  760. curr_pid = _getpid();
  761. #else
  762. curr_pid = getpid();
  763. #endif
  764. /*Check if this is the first time this is being called from the current
  765. process*/
  766. if (recorded_pid != curr_pid)
  767. {
  768. /*Remember our pid so we can check if we're in a new process*/
  769. recorded_pid = curr_pid;
  770. /*Call Finalize to make sure we have not inherited some data
  771. from a parent process*/
  772. p_AEP_Finalize();
  773. /*Initialise the AEP API*/
  774. rv = p_AEP_Initialize(NULL);
  775. if (rv != AEP_R_OK)
  776. {
  777. AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
  778. recorded_pid = 0;
  779. goto end;
  780. }
  781. /*Set the AEP big num call back functions*/
  782. rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
  783. &ConvertAEPBigNum);
  784. if (rv != AEP_R_OK)
  785. {
  786. AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
  787. recorded_pid = 0;
  788. goto end;
  789. }
  790. #ifdef AEPRAND
  791. /*Reset the rand byte count*/
  792. rand_block_bytes = 0;
  793. #endif
  794. /*Init the structures*/
  795. for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  796. {
  797. aep_app_conn_table[count].conn_state = NotConnected;
  798. aep_app_conn_table[count].conn_hndl = 0;
  799. }
  800. /*Open a connection*/
  801. rv = p_AEP_OpenConnection(phConnection);
  802. if (rv != AEP_R_OK)
  803. {
  804. AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
  805. recorded_pid = 0;
  806. goto end;
  807. }
  808. aep_app_conn_table[0].conn_state = InUse;
  809. aep_app_conn_table[0].conn_hndl = *phConnection;
  810. goto end;
  811. }
  812. /*Check the existing connections to see if we can find a free one*/
  813. for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  814. {
  815. if (aep_app_conn_table[count].conn_state == Connected)
  816. {
  817. aep_app_conn_table[count].conn_state = InUse;
  818. *phConnection = aep_app_conn_table[count].conn_hndl;
  819. goto end;
  820. }
  821. }
  822. /*If no connections available, we're going to have to try
  823. to open a new one*/
  824. for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  825. {
  826. if (aep_app_conn_table[count].conn_state == NotConnected)
  827. {
  828. /*Open a connection*/
  829. rv = p_AEP_OpenConnection(phConnection);
  830. if (rv != AEP_R_OK)
  831. {
  832. AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
  833. goto end;
  834. }
  835. aep_app_conn_table[count].conn_state = InUse;
  836. aep_app_conn_table[count].conn_hndl = *phConnection;
  837. goto end;
  838. }
  839. }
  840. rv = AEP_R_GENERAL_ERROR;
  841. end:
  842. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  843. return rv;
  844. }
  845. static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
  846. {
  847. int count;
  848. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  849. /*Find the connection item that matches this connection handle*/
  850. for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  851. {
  852. if (aep_app_conn_table[count].conn_hndl == hConnection)
  853. {
  854. aep_app_conn_table[count].conn_state = Connected;
  855. break;
  856. }
  857. }
  858. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  859. return AEP_R_OK;
  860. }
  861. static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
  862. {
  863. int count;
  864. AEP_RV rv = AEP_R_OK;
  865. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  866. /*Find the connection item that matches this connection handle*/
  867. for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  868. {
  869. if (aep_app_conn_table[count].conn_hndl == hConnection)
  870. {
  871. rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
  872. if (rv != AEP_R_OK)
  873. goto end;
  874. aep_app_conn_table[count].conn_state = NotConnected;
  875. aep_app_conn_table[count].conn_hndl = 0;
  876. break;
  877. }
  878. }
  879. end:
  880. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  881. return rv;
  882. }
  883. static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
  884. {
  885. int count;
  886. AEP_RV rv = AEP_R_OK;
  887. *in_use = 0;
  888. if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  889. for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  890. {
  891. switch (aep_app_conn_table[count].conn_state)
  892. {
  893. case Connected:
  894. rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
  895. if (rv != AEP_R_OK)
  896. goto end;
  897. aep_app_conn_table[count].conn_state = NotConnected;
  898. aep_app_conn_table[count].conn_hndl = 0;
  899. break;
  900. case InUse:
  901. (*in_use)++;
  902. break;
  903. case NotConnected:
  904. break;
  905. }
  906. }
  907. end:
  908. if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  909. return rv;
  910. }
  911. /*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
  912. Note only 32bit Openssl build support*/
  913. static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize)
  914. {
  915. BIGNUM* bn;
  916. /*Cast the ArbBigNum pointer to our BIGNUM struct*/
  917. bn = (BIGNUM*) ArbBigNum;
  918. #ifdef SIXTY_FOUR_BIT_LONG
  919. *BigNumSize = bn->top << 3;
  920. #else
  921. /*Size of the bignum in bytes is equal to the bn->top (no of 32 bit
  922. words) multiplies by 4*/
  923. *BigNumSize = bn->top << 2;
  924. #endif
  925. return AEP_R_OK;
  926. }
  927. static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
  928. unsigned char* AEP_BigNum)
  929. {
  930. BIGNUM* bn;
  931. #ifndef SIXTY_FOUR_BIT_LONG
  932. unsigned char* buf;
  933. int i;
  934. #endif
  935. /*Cast the ArbBigNum pointer to our BIGNUM struct*/
  936. bn = (BIGNUM*) ArbBigNum;
  937. #ifdef SIXTY_FOUR_BIT_LONG
  938. memcpy(AEP_BigNum, bn->d, BigNumSize);
  939. #else
  940. /*Must copy data into a (monotone) least significant byte first format
  941. performing endian conversion if necessary*/
  942. for(i=0;i<bn->top;i++)
  943. {
  944. buf = (unsigned char*)&bn->d[i];
  945. *((AEP_U32*)AEP_BigNum) = (AEP_U32)
  946. ((unsigned) buf[1] << 8 | buf[0]) |
  947. ((unsigned) buf[3] << 8 | buf[2]) << 16;
  948. AEP_BigNum += 4;
  949. }
  950. #endif
  951. return AEP_R_OK;
  952. }
  953. /*Turn an AEP Big Num back to a user big num*/
  954. static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
  955. unsigned char* AEP_BigNum)
  956. {
  957. BIGNUM* bn;
  958. #ifndef SIXTY_FOUR_BIT_LONG
  959. int i;
  960. #endif
  961. bn = (BIGNUM*)ArbBigNum;
  962. /*Expand the result bn so that it can hold our big num.
  963. Size is in bits*/
  964. bn_expand(bn, (int)(BigNumSize << 3));
  965. #ifdef SIXTY_FOUR_BIT_LONG
  966. bn->top = BigNumSize >> 3;
  967. if((BigNumSize & 7) != 0)
  968. bn->top++;
  969. memset(bn->d, 0, bn->top << 3);
  970. memcpy(bn->d, AEP_BigNum, BigNumSize);
  971. #else
  972. bn->top = BigNumSize >> 2;
  973. for(i=0;i<bn->top;i++)
  974. {
  975. bn->d[i] = (AEP_U32)
  976. ((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 |
  977. ((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]);
  978. AEP_BigNum += 4;
  979. }
  980. #endif
  981. return AEP_R_OK;
  982. }
  983. #endif /* !OPENSSL_NO_HW_AEP */
  984. #endif /* !OPENSSL_NO_HW */