e_aep.c 28 KB

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