e_aep.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:28k
源码类别:

其他游戏

开发平台:

Visual C++

  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.  
  396. if(aep_dso != NULL)
  397. {
  398. AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
  399. goto err;
  400. }
  401. /* Attempt to load libaep.so. */
  402. aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0);
  403.   
  404. if(aep_dso == NULL)
  405. {
  406. AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
  407. goto err;
  408. }
  409. if( !(p1 = (t_AEP_ModExp *)     DSO_bind_func( aep_dso,AEP_F1))  ||
  410. !(p2 = (t_AEP_ModExpCrt*)   DSO_bind_func( aep_dso,AEP_F2))  ||
  411. #ifdef AEPRAND
  412. !(p3 = (t_AEP_GenRandom*)   DSO_bind_func( aep_dso,AEP_F3))  ||
  413. #endif
  414. !(p4 = (t_AEP_Finalize*)    DSO_bind_func( aep_dso,AEP_F4))  ||
  415. !(p5 = (t_AEP_Initialize*)  DSO_bind_func( aep_dso,AEP_F5))  ||
  416. !(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6))  ||
  417. !(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7))  ||
  418. !(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
  419. {
  420. AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
  421. goto err;
  422. }
  423. /* Copy the pointers */
  424.   
  425. p_AEP_ModExp           = p1;
  426. p_AEP_ModExpCrt        = p2;
  427. #ifdef AEPRAND
  428. p_AEP_GenRandom        = p3;
  429. #endif
  430. p_AEP_Finalize         = p4;
  431. p_AEP_Initialize       = p5;
  432. p_AEP_OpenConnection   = p6;
  433. p_AEP_SetBNCallBacks   = p7;
  434. p_AEP_CloseConnection  = p8;
  435.  
  436. to_return = 1;
  437.  
  438. return to_return;
  439.  err: 
  440. if(aep_dso)
  441. DSO_free(aep_dso);
  442. aep_dso = NULL;
  443. p_AEP_OpenConnection    = NULL;
  444. p_AEP_ModExp            = NULL;
  445. p_AEP_ModExpCrt         = NULL;
  446. #ifdef AEPRAND
  447. p_AEP_GenRandom         = NULL;
  448. #endif
  449. p_AEP_Initialize        = NULL;
  450. p_AEP_Finalize          = NULL;
  451. p_AEP_SetBNCallBacks    = NULL;
  452. p_AEP_CloseConnection   = NULL;
  453. return to_return;
  454. }
  455. /* Destructor (complements the "ENGINE_aep()" constructor) */
  456. static int aep_destroy(ENGINE *e)
  457. {
  458. free_AEP_LIBNAME();
  459. ERR_unload_AEPHK_strings();
  460. return 1;
  461. }
  462. static int aep_finish(ENGINE *e)
  463. {
  464. int to_return = 0, in_use;
  465. AEP_RV rv;
  466. if(aep_dso == NULL)
  467. {
  468. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
  469. goto err;
  470. }
  471. rv = aep_close_all_connections(0, &in_use);
  472. if (rv != AEP_R_OK)
  473. {
  474. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
  475. goto err;
  476. }
  477. if (in_use)
  478. {
  479. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
  480. goto err;
  481. }
  482. rv = p_AEP_Finalize();
  483. if (rv != AEP_R_OK)
  484. {
  485. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
  486. goto err;
  487. }
  488. if(!DSO_free(aep_dso))
  489. {
  490. AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
  491. goto err;
  492. }
  493. aep_dso = NULL;
  494. p_AEP_CloseConnection   = NULL;
  495. p_AEP_OpenConnection    = NULL;
  496. p_AEP_ModExp            = NULL;
  497. p_AEP_ModExpCrt         = NULL;
  498. #ifdef AEPRAND
  499. p_AEP_GenRandom         = NULL;
  500. #endif
  501. p_AEP_Initialize        = NULL;
  502. p_AEP_Finalize          = NULL;
  503. p_AEP_SetBNCallBacks    = NULL;
  504. to_return = 1;
  505.  err:
  506. return to_return;
  507. }
  508. static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
  509. {
  510. int initialised = ((aep_dso == NULL) ? 0 : 1);
  511. switch(cmd)
  512. {
  513. case AEP_CMD_SO_PATH:
  514. if(p == NULL)
  515. {
  516. AEPHKerr(AEPHK_F_AEP_CTRL,
  517. ERR_R_PASSED_NULL_PARAMETER);
  518. return 0;
  519. }
  520. if(initialised)
  521. {
  522. AEPHKerr(AEPHK_F_AEP_CTRL,
  523. AEPHK_R_ALREADY_LOADED);
  524. return 0;
  525. }
  526. return set_AEP_LIBNAME((const char*)p);
  527. default:
  528. break;
  529. }
  530. AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
  531. return 0;
  532. }
  533. static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  534. const BIGNUM *m, BN_CTX *ctx)
  535. {
  536. int to_return = 0;
  537. int  r_len = 0;
  538. AEP_CONNECTION_HNDL hConnection;
  539. AEP_RV rv;
  540. r_len = BN_num_bits(m);
  541. /* Perform in software if modulus is too large for hardware. */
  542. if (r_len > max_key_len){
  543. AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  544. return BN_mod_exp(r, a, p, m, ctx);
  545. /*Grab a connection from the pool*/
  546. rv = aep_get_connection(&hConnection);
  547. if (rv != AEP_R_OK)
  548. {     
  549. AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED);
  550. return BN_mod_exp(r, a, p, m, ctx);
  551. }
  552. /*To the card with the mod exp*/
  553. rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL);
  554. if (rv !=  AEP_R_OK)
  555. {
  556. AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED);
  557. rv = aep_close_connection(hConnection);
  558. return BN_mod_exp(r, a, p, m, ctx);
  559. }
  560. /*Return the connection to the pool*/
  561. rv = aep_return_connection(hConnection);
  562. if (rv != AEP_R_OK)
  563. {
  564. AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_RETURN_CONNECTION_FAILED); 
  565. goto err;
  566. }
  567. to_return = 1;
  568.  err:
  569. return to_return;
  570. }
  571. #ifndef OPENSSL_NO_RSA
  572. static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  573. const BIGNUM *q, const BIGNUM *dmp1,
  574. const BIGNUM *dmq1,const BIGNUM *iqmp, BN_CTX *ctx)
  575. {
  576. AEP_RV rv = AEP_R_OK;
  577. AEP_CONNECTION_HNDL hConnection;
  578. /*Grab a connection from the pool*/
  579. rv = aep_get_connection(&hConnection);
  580. if (rv != AEP_R_OK)
  581. {
  582. AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
  583. return FAIL_TO_SW;
  584. }
  585. /*To the card with the mod exp*/
  586. rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1,
  587. (void*)iqmp,(void*)r,NULL);
  588. if (rv != AEP_R_OK)
  589. {
  590. AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_MOD_EXP_CRT_FAILED);
  591. rv = aep_close_connection(hConnection);
  592. return FAIL_TO_SW;
  593. }
  594. /*Return the connection to the pool*/
  595. rv = aep_return_connection(hConnection);
  596. if (rv != AEP_R_OK)
  597. {
  598. AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_RETURN_CONNECTION_FAILED); 
  599. goto err;
  600. }
  601.  
  602.  err:
  603. return rv;
  604. }
  605. #endif
  606. #ifdef AEPRAND
  607. static int aep_rand(unsigned char *buf,int len )
  608. {
  609. AEP_RV rv = AEP_R_OK;
  610. AEP_CONNECTION_HNDL hConnection;
  611. CRYPTO_w_lock(CRYPTO_LOCK_RAND);
  612. /*Can the request be serviced with what's already in the buffer?*/
  613. if (len <= rand_block_bytes)
  614. {
  615. memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
  616. rand_block_bytes -= len;
  617. CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
  618. }
  619. else
  620. /*If not the get another block of random bytes*/
  621. {
  622. CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
  623. rv = aep_get_connection(&hConnection);
  624. if (rv !=  AEP_R_OK)
  625. AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);             
  626. goto err_nounlock;
  627. }
  628. if (len > RAND_BLK_SIZE)
  629. {
  630. rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
  631. if (rv !=  AEP_R_OK)
  632. {  
  633. AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
  634. goto err_nounlock;
  635. }
  636. }
  637. else
  638. {
  639. CRYPTO_w_lock(CRYPTO_LOCK_RAND);
  640. rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
  641. if (rv !=  AEP_R_OK)
  642. {       
  643. AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
  644.       
  645. goto err;
  646. }
  647. rand_block_bytes = RAND_BLK_SIZE;
  648. memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
  649. rand_block_bytes -= len;
  650. CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
  651. }
  652. rv = aep_return_connection(hConnection);
  653. if (rv != AEP_R_OK)
  654. {
  655. AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); 
  656.   
  657. goto err_nounlock;
  658. }
  659. }
  660.   
  661. return 1;
  662.  err:
  663. CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
  664.  err_nounlock:
  665. return 0;
  666. }
  667. static int aep_rand_status(void)
  668. {
  669. return 1;
  670. }
  671. #endif
  672. #ifndef OPENSSL_NO_RSA
  673. static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
  674. {
  675. int to_return = 0;
  676. AEP_RV rv = AEP_R_OK;
  677. if (!aep_dso)
  678. {
  679. AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
  680. goto err;
  681. }
  682. /*See if we have all the necessary bits for a crt*/
  683. if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp)
  684. {
  685. rv =  aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx);
  686. if (rv == FAIL_TO_SW){
  687. const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
  688. to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
  689. goto err;
  690. }
  691. else if (rv != AEP_R_OK)
  692. goto err;
  693. }
  694. else
  695. {
  696. if (!rsa->d || !rsa->n)
  697. {
  698. AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
  699. goto err;
  700. }
  701.  
  702. rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx);
  703. if  (rv != AEP_R_OK)
  704. goto err;
  705. }
  706. to_return = 1;
  707.  err:
  708. return to_return;
  709. }
  710. #endif
  711. #ifndef OPENSSL_NO_DSA
  712. static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
  713. BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
  714. BN_CTX *ctx, BN_MONT_CTX *in_mont)
  715. {
  716. BIGNUM t;
  717. int to_return = 0;
  718. BN_init(&t);
  719. /* let rr = a1 ^ p1 mod m */
  720. if (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end;
  721. /* let t = a2 ^ p2 mod m */
  722. if (!aep_mod_exp(&t,a2,p2,m,ctx)) goto end;
  723. /* let rr = rr * t mod m */
  724. if (!BN_mod_mul(rr,rr,&t,m,ctx)) 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. /*Get the current process id*/
  759. pid_t curr_pid;
  760. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  761. #ifndef NETWARE_CLIB
  762. curr_pid = getpid();
  763. #else
  764. curr_pid = GetThreadID();
  765. #endif
  766. /*Check if this is the first time this is being called from the current
  767.   process*/
  768. if (recorded_pid != curr_pid)
  769. {
  770. /*Remember our pid so we can check if we're in a new process*/
  771. recorded_pid = curr_pid;
  772. /*Call Finalize to make sure we have not inherited some data
  773.   from a parent process*/
  774. p_AEP_Finalize();
  775.      
  776. /*Initialise the AEP API*/
  777. rv = p_AEP_Initialize(NULL);
  778. if (rv != AEP_R_OK)
  779. {
  780. AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
  781. recorded_pid = 0;
  782. goto end;
  783. }
  784. /*Set the AEP big num call back functions*/
  785. rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
  786. &ConvertAEPBigNum);
  787. if (rv != AEP_R_OK)
  788. {
  789. AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
  790. recorded_pid = 0;
  791. goto end;
  792. }
  793. #ifdef AEPRAND
  794. /*Reset the rand byte count*/
  795. rand_block_bytes = 0;
  796. #endif
  797. /*Init the structures*/
  798. for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  799. {
  800. aep_app_conn_table[count].conn_state = NotConnected;
  801. aep_app_conn_table[count].conn_hndl  = 0;
  802. }
  803. /*Open a connection*/
  804. rv = p_AEP_OpenConnection(phConnection);
  805. if (rv != AEP_R_OK)
  806. {
  807. AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
  808. recorded_pid = 0;
  809. goto end;
  810. }
  811. aep_app_conn_table[0].conn_state = InUse;
  812. aep_app_conn_table[0].conn_hndl = *phConnection;
  813. goto end;
  814. }
  815. /*Check the existing connections to see if we can find a free one*/
  816. for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  817. {
  818. if (aep_app_conn_table[count].conn_state == Connected)
  819. {
  820. aep_app_conn_table[count].conn_state = InUse;
  821. *phConnection = aep_app_conn_table[count].conn_hndl;
  822. goto end;
  823. }
  824. }
  825. /*If no connections available, we're going to have to try
  826.   to open a new one*/
  827. for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  828. {
  829. if (aep_app_conn_table[count].conn_state == NotConnected)
  830. {
  831. /*Open a connection*/
  832. rv = p_AEP_OpenConnection(phConnection);
  833. if (rv != AEP_R_OK)
  834. {       
  835. AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
  836. goto end;
  837. }
  838. aep_app_conn_table[count].conn_state = InUse;
  839. aep_app_conn_table[count].conn_hndl = *phConnection;
  840. goto end;
  841. }
  842. }
  843. rv = AEP_R_GENERAL_ERROR;
  844.  end:
  845. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  846. return rv;
  847. }
  848. static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
  849. {
  850. int count;
  851. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  852. /*Find the connection item that matches this connection handle*/
  853. for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  854. {
  855. if (aep_app_conn_table[count].conn_hndl == hConnection)
  856. {
  857. aep_app_conn_table[count].conn_state = Connected;
  858. break;
  859. }
  860. }
  861. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  862. return AEP_R_OK;
  863. }
  864. static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
  865. {
  866. int count;
  867. AEP_RV rv = AEP_R_OK;
  868. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  869. /*Find the connection item that matches this connection handle*/
  870. for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  871. {
  872. if (aep_app_conn_table[count].conn_hndl == hConnection)
  873. {
  874. rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
  875. if (rv != AEP_R_OK)
  876. goto end;
  877. aep_app_conn_table[count].conn_state = NotConnected;
  878. aep_app_conn_table[count].conn_hndl  = 0;
  879. break;
  880. }
  881. }
  882.  end:
  883. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  884. return rv;
  885. }
  886. static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
  887. {
  888. int count;
  889. AEP_RV rv = AEP_R_OK;
  890. *in_use = 0;
  891. if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  892. for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
  893. {
  894. switch (aep_app_conn_table[count].conn_state)
  895. {
  896. case Connected:
  897. rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
  898. if (rv != AEP_R_OK)
  899. goto end;
  900. aep_app_conn_table[count].conn_state = NotConnected;
  901. aep_app_conn_table[count].conn_hndl  = 0;
  902. break;
  903. case InUse:
  904. (*in_use)++;
  905. break;
  906. case NotConnected:
  907. break;
  908. }
  909. }
  910.  end:
  911. if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  912. return rv;
  913. }
  914. /*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
  915.   Note only 32bit Openssl build support*/
  916. static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize)
  917. {
  918. BIGNUM* bn;
  919. /*Cast the ArbBigNum pointer to our BIGNUM struct*/
  920. bn = (BIGNUM*) ArbBigNum;
  921. #ifdef SIXTY_FOUR_BIT_LONG
  922. *BigNumSize = bn->top << 3;
  923. #else
  924. /*Size of the bignum in bytes is equal to the bn->top (no of 32 bit
  925.   words) multiplies by 4*/
  926. *BigNumSize = bn->top << 2;
  927. #endif
  928. return AEP_R_OK;
  929. }
  930. static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
  931. unsigned char* AEP_BigNum)
  932. {
  933. BIGNUM* bn;
  934. #ifndef SIXTY_FOUR_BIT_LONG
  935. unsigned char* buf;
  936. int i;
  937. #endif
  938. /*Cast the ArbBigNum pointer to our BIGNUM struct*/
  939. bn = (BIGNUM*) ArbBigNum;
  940. #ifdef SIXTY_FOUR_BIT_LONG
  941.    memcpy(AEP_BigNum, bn->d, BigNumSize);
  942. #else
  943. /*Must copy data into a (monotone) least significant byte first format
  944.   performing endian conversion if necessary*/
  945. for(i=0;i<bn->top;i++)
  946. {
  947. buf = (unsigned char*)&bn->d[i];
  948. *((AEP_U32*)AEP_BigNum) = (AEP_U32)
  949. ((unsigned) buf[1] << 8 | buf[0]) |
  950. ((unsigned) buf[3] << 8 | buf[2])  << 16;
  951. AEP_BigNum += 4;
  952. }
  953. #endif
  954. return AEP_R_OK;
  955. }
  956. /*Turn an AEP Big Num back to a user big num*/
  957. static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
  958. unsigned char* AEP_BigNum)
  959. {
  960. BIGNUM* bn;
  961. #ifndef SIXTY_FOUR_BIT_LONG
  962. int i;
  963. #endif
  964. bn = (BIGNUM*)ArbBigNum;
  965. /*Expand the result bn so that it can hold our big num.
  966.   Size is in bits*/
  967. bn_expand(bn, (int)(BigNumSize << 3));
  968. #ifdef SIXTY_FOUR_BIT_LONG
  969. bn->top = BigNumSize >> 3;
  970. if((BigNumSize & 7) != 0)
  971. bn->top++;
  972. memset(bn->d, 0, bn->top << 3);
  973. memcpy(bn->d, AEP_BigNum, BigNumSize);
  974. #else
  975. bn->top = BigNumSize >> 2;
  976.  
  977. for(i=0;i<bn->top;i++)
  978. {
  979. bn->d[i] = (AEP_U32)
  980. ((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 |
  981. ((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]);
  982. AEP_BigNum += 4;
  983. }
  984. #endif
  985. return AEP_R_OK;
  986. }
  987. #endif /* !OPENSSL_NO_HW_AEP */
  988. #endif /* !OPENSSL_NO_HW */