e_aep.c 28 KB

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