e_aep.c 32 KB

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