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

其他游戏

开发平台:

Visual C++

  1. /* crypto/engine/hw_atalla.c */
  2. /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
  3.  * project 2000.
  4.  */
  5. /* ====================================================================
  6.  * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  *
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer. 
  14.  *
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in
  17.  *    the documentation and/or other materials provided with the
  18.  *    distribution.
  19.  *
  20.  * 3. All advertising materials mentioning features or use of this
  21.  *    software must display the following acknowledgment:
  22.  *    "This product includes software developed by the OpenSSL Project
  23.  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24.  *
  25.  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26.  *    endorse or promote products derived from this software without
  27.  *    prior written permission. For written permission, please contact
  28.  *    licensing@OpenSSL.org.
  29.  *
  30.  * 5. Products derived from this software may not be called "OpenSSL"
  31.  *    nor may "OpenSSL" appear in their names without prior written
  32.  *    permission of the OpenSSL Project.
  33.  *
  34.  * 6. Redistributions of any form whatsoever must retain the following
  35.  *    acknowledgment:
  36.  *    "This product includes software developed by the OpenSSL Project
  37.  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38.  *
  39.  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  51.  * ====================================================================
  52.  *
  53.  * This product includes cryptographic software written by Eric Young
  54.  * (eay@cryptsoft.com).  This product includes software written by Tim
  55.  * Hudson (tjh@cryptsoft.com).
  56.  *
  57.  */
  58. #include <stdio.h>
  59. #include <string.h>
  60. #include <openssl/crypto.h>
  61. #include <openssl/buffer.h>
  62. #include <openssl/dso.h>
  63. #include <openssl/engine.h>
  64. #ifndef OPENSSL_NO_RSA
  65. #include <openssl/rsa.h>
  66. #endif
  67. #ifndef OPENSSL_NO_DSA
  68. #include <openssl/dsa.h>
  69. #endif
  70. #ifndef OPENSSL_NO_DH
  71. #include <openssl/dh.h>
  72. #endif
  73. #include <openssl/bn.h>
  74. #ifndef OPENSSL_NO_HW
  75. #ifndef OPENSSL_NO_HW_ATALLA
  76. #ifdef FLAT_INC
  77. #include "atalla.h"
  78. #else
  79. #include "vendor_defns/atalla.h"
  80. #endif
  81. #define ATALLA_LIB_NAME "atalla engine"
  82. #include "e_atalla_err.c"
  83. static int atalla_destroy(ENGINE *e);
  84. static int atalla_init(ENGINE *e);
  85. static int atalla_finish(ENGINE *e);
  86. static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
  87. /* BIGNUM stuff */
  88. static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  89. const BIGNUM *m, BN_CTX *ctx);
  90. #ifndef OPENSSL_NO_RSA
  91. /* RSA stuff */
  92. static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
  93. /* This function is aliased to mod_exp (with the mont stuff dropped). */
  94. static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  95. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  96. #endif
  97. #ifndef OPENSSL_NO_DSA
  98. /* DSA stuff */
  99. static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
  100. BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
  101. BN_CTX *ctx, BN_MONT_CTX *in_mont);
  102. static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
  103. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  104. BN_MONT_CTX *m_ctx);
  105. #endif
  106. #ifndef OPENSSL_NO_DH
  107. /* DH stuff */
  108. /* This function is alised to mod_exp (with the DH and mont dropped). */
  109. static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
  110. const BIGNUM *a, const BIGNUM *p,
  111. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  112. #endif
  113. /* The definitions for control commands specific to this engine */
  114. #define ATALLA_CMD_SO_PATH ENGINE_CMD_BASE
  115. static const ENGINE_CMD_DEFN atalla_cmd_defns[] = {
  116. {ATALLA_CMD_SO_PATH,
  117. "SO_PATH",
  118. "Specifies the path to the 'atasi' shared library",
  119. ENGINE_CMD_FLAG_STRING},
  120. {0, NULL, NULL, 0}
  121. };
  122. #ifndef OPENSSL_NO_RSA
  123. /* Our internal RSA_METHOD that we provide pointers to */
  124. static RSA_METHOD atalla_rsa =
  125. {
  126. "Atalla RSA method",
  127. NULL,
  128. NULL,
  129. NULL,
  130. NULL,
  131. atalla_rsa_mod_exp,
  132. atalla_mod_exp_mont,
  133. NULL,
  134. NULL,
  135. 0,
  136. NULL,
  137. NULL,
  138. NULL,
  139. NULL
  140. };
  141. #endif
  142. #ifndef OPENSSL_NO_DSA
  143. /* Our internal DSA_METHOD that we provide pointers to */
  144. static DSA_METHOD atalla_dsa =
  145. {
  146. "Atalla DSA method",
  147. NULL, /* dsa_do_sign */
  148. NULL, /* dsa_sign_setup */
  149. NULL, /* dsa_do_verify */
  150. atalla_dsa_mod_exp, /* dsa_mod_exp */
  151. atalla_mod_exp_dsa, /* bn_mod_exp */
  152. NULL, /* init */
  153. NULL, /* finish */
  154. 0, /* flags */
  155. NULL, /* app_data */
  156. NULL, /* dsa_paramgen */
  157. NULL /* dsa_keygen */
  158. };
  159. #endif
  160. #ifndef OPENSSL_NO_DH
  161. /* Our internal DH_METHOD that we provide pointers to */
  162. static DH_METHOD atalla_dh =
  163. {
  164. "Atalla DH method",
  165. NULL,
  166. NULL,
  167. atalla_mod_exp_dh,
  168. NULL,
  169. NULL,
  170. 0,
  171. NULL,
  172. NULL
  173. };
  174. #endif
  175. /* Constants used when creating the ENGINE */
  176. static const char *engine_atalla_id = "atalla";
  177. static const char *engine_atalla_name = "Atalla hardware engine support";
  178. /* This internal function is used by ENGINE_atalla() and possibly by the
  179.  * "dynamic" ENGINE support too */
  180. static int bind_helper(ENGINE *e)
  181. {
  182. #ifndef OPENSSL_NO_RSA
  183. const RSA_METHOD *meth1;
  184. #endif
  185. #ifndef OPENSSL_NO_DSA
  186. const DSA_METHOD *meth2;
  187. #endif
  188. #ifndef OPENSSL_NO_DH
  189. const DH_METHOD *meth3;
  190. #endif
  191. if(!ENGINE_set_id(e, engine_atalla_id) ||
  192. !ENGINE_set_name(e, engine_atalla_name) ||
  193. #ifndef OPENSSL_NO_RSA
  194. !ENGINE_set_RSA(e, &atalla_rsa) ||
  195. #endif
  196. #ifndef OPENSSL_NO_DSA
  197. !ENGINE_set_DSA(e, &atalla_dsa) ||
  198. #endif
  199. #ifndef OPENSSL_NO_DH
  200. !ENGINE_set_DH(e, &atalla_dh) ||
  201. #endif
  202. !ENGINE_set_destroy_function(e, atalla_destroy) ||
  203. !ENGINE_set_init_function(e, atalla_init) ||
  204. !ENGINE_set_finish_function(e, atalla_finish) ||
  205. !ENGINE_set_ctrl_function(e, atalla_ctrl) ||
  206. !ENGINE_set_cmd_defns(e, atalla_cmd_defns))
  207. return 0;
  208. #ifndef OPENSSL_NO_RSA
  209. /* We know that the "PKCS1_SSLeay()" functions hook properly
  210.  * to the atalla-specific mod_exp and mod_exp_crt so we use
  211.  * those functions. NB: We don't use ENGINE_openssl() or
  212.  * anything "more generic" because something like the RSAref
  213.  * code may not hook properly, and if you own one of these
  214.  * cards then you have the right to do RSA operations on it
  215.  * anyway! */ 
  216. meth1 = RSA_PKCS1_SSLeay();
  217. atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
  218. atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
  219. atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
  220. atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
  221. #endif
  222. #ifndef OPENSSL_NO_DSA
  223. /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
  224.  * bits. */
  225. meth2 = DSA_OpenSSL();
  226. atalla_dsa.dsa_do_sign = meth2->dsa_do_sign;
  227. atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
  228. atalla_dsa.dsa_do_verify = meth2->dsa_do_verify;
  229. #endif
  230. #ifndef OPENSSL_NO_DH
  231. /* Much the same for Diffie-Hellman */
  232. meth3 = DH_OpenSSL();
  233. atalla_dh.generate_key = meth3->generate_key;
  234. atalla_dh.compute_key = meth3->compute_key;
  235. #endif
  236. /* Ensure the atalla error handling is set up */
  237. ERR_load_ATALLA_strings();
  238. return 1;
  239. }
  240. #ifdef OPENSSL_NO_DYNAMIC_ENGINE
  241. static ENGINE *engine_atalla(void)
  242. {
  243. ENGINE *ret = ENGINE_new();
  244. if(!ret)
  245. return NULL;
  246. if(!bind_helper(ret))
  247. {
  248. ENGINE_free(ret);
  249. return NULL;
  250. }
  251. return ret;
  252. }
  253. void ENGINE_load_atalla(void)
  254. {
  255. /* Copied from eng_[openssl|dyn].c */
  256. ENGINE *toadd = engine_atalla();
  257. if(!toadd) return;
  258. ENGINE_add(toadd);
  259. ENGINE_free(toadd);
  260. ERR_clear_error();
  261. }
  262. #endif
  263. /* This is a process-global DSO handle used for loading and unloading
  264.  * the Atalla library. NB: This is only set (or unset) during an
  265.  * init() or finish() call (reference counts permitting) and they're
  266.  * operating with global locks, so this should be thread-safe
  267.  * implicitly. */
  268. static DSO *atalla_dso = NULL;
  269. /* These are the function pointers that are (un)set when the library has
  270.  * successfully (un)loaded. */
  271. static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL;
  272. static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL;
  273. static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL;
  274. /* These are the static string constants for the DSO file name and the function
  275.  * symbol names to bind to. Regrettably, the DSO name on *nix appears to be
  276.  * "atasi.so" rather than something more consistent like "libatasi.so". At the
  277.  * time of writing, I'm not sure what the file name on win32 is but clearly
  278.  * native name translation is not possible (eg libatasi.so on *nix, and
  279.  * atasi.dll on win32). For the purposes of testing, I have created a symbollic
  280.  * link called "libatasi.so" so that we can use native name-translation - a
  281.  * better solution will be needed. */
  282. static const char *ATALLA_LIBNAME = NULL;
  283. static const char *get_ATALLA_LIBNAME(void)
  284. {
  285. if(ATALLA_LIBNAME)
  286. return ATALLA_LIBNAME;
  287. return "atasi";
  288. }
  289. static void free_ATALLA_LIBNAME(void)
  290. {
  291. if(ATALLA_LIBNAME)
  292. OPENSSL_free((void*)ATALLA_LIBNAME);
  293. ATALLA_LIBNAME = NULL;
  294. }
  295. static long set_ATALLA_LIBNAME(const char *name)
  296. {
  297. free_ATALLA_LIBNAME();
  298. return (((ATALLA_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
  299. }
  300. static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
  301. static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
  302. static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";
  303. /* Destructor (complements the "ENGINE_atalla()" constructor) */
  304. static int atalla_destroy(ENGINE *e)
  305. {
  306. free_ATALLA_LIBNAME();
  307. /* Unload the atalla error strings so any error state including our
  308.  * functs or reasons won't lead to a segfault (they simply get displayed
  309.  * without corresponding string data because none will be found). */
  310. ERR_unload_ATALLA_strings();
  311. return 1;
  312. }
  313. /* (de)initialisation functions. */
  314. static int atalla_init(ENGINE *e)
  315. {
  316. tfnASI_GetHardwareConfig *p1;
  317. tfnASI_RSAPrivateKeyOpFn *p2;
  318. tfnASI_GetPerformanceStatistics *p3;
  319. /* Not sure of the origin of this magic value, but Ben's code had it
  320.  * and it seemed to have been working for a few people. :-) */
  321. unsigned int config_buf[1024];
  322. if(atalla_dso != NULL)
  323. {
  324. ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_ALREADY_LOADED);
  325. goto err;
  326. }
  327. /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
  328.  * changed unfortunately because the Atalla drivers don't have
  329.  * standard library names that can be platform-translated well. */
  330. /* TODO: Work out how to actually map to the names the Atalla
  331.  * drivers really use - for now a symbollic link needs to be
  332.  * created on the host system from libatasi.so to atasi.so on
  333.  * unix variants. */
  334. atalla_dso = DSO_load(NULL, get_ATALLA_LIBNAME(), NULL, 0);
  335. if(atalla_dso == NULL)
  336. {
  337. ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
  338. goto err;
  339. }
  340. if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func(
  341. atalla_dso, ATALLA_F1)) ||
  342. !(p2 = (tfnASI_RSAPrivateKeyOpFn *)DSO_bind_func(
  343. atalla_dso, ATALLA_F2)) ||
  344. !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func(
  345. atalla_dso, ATALLA_F3)))
  346. {
  347. ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
  348. goto err;
  349. }
  350. /* Copy the pointers */
  351. p_Atalla_GetHardwareConfig = p1;
  352. p_Atalla_RSAPrivateKeyOpFn = p2;
  353. p_Atalla_GetPerformanceStatistics = p3;
  354. /* Perform a basic test to see if there's actually any unit
  355.  * running. */
  356. if(p1(0L, config_buf) != 0)
  357. {
  358. ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_UNIT_FAILURE);
  359. goto err;
  360. }
  361. /* Everything's fine. */
  362. return 1;
  363. err:
  364. if(atalla_dso)
  365. DSO_free(atalla_dso);
  366. atalla_dso = NULL;
  367. p_Atalla_GetHardwareConfig = NULL;
  368. p_Atalla_RSAPrivateKeyOpFn = NULL;
  369. p_Atalla_GetPerformanceStatistics = NULL;
  370. return 0;
  371. }
  372. static int atalla_finish(ENGINE *e)
  373. {
  374. free_ATALLA_LIBNAME();
  375. if(atalla_dso == NULL)
  376. {
  377. ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_NOT_LOADED);
  378. return 0;
  379. }
  380. if(!DSO_free(atalla_dso))
  381. {
  382. ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_UNIT_FAILURE);
  383. return 0;
  384. }
  385. atalla_dso = NULL;
  386. p_Atalla_GetHardwareConfig = NULL;
  387. p_Atalla_RSAPrivateKeyOpFn = NULL;
  388. p_Atalla_GetPerformanceStatistics = NULL;
  389. return 1;
  390. }
  391. static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
  392. {
  393. int initialised = ((atalla_dso == NULL) ? 0 : 1);
  394. switch(cmd)
  395. {
  396. case ATALLA_CMD_SO_PATH:
  397. if(p == NULL)
  398. {
  399. ATALLAerr(ATALLA_F_ATALLA_CTRL,ERR_R_PASSED_NULL_PARAMETER);
  400. return 0;
  401. }
  402. if(initialised)
  403. {
  404. ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_ALREADY_LOADED);
  405. return 0;
  406. }
  407. return set_ATALLA_LIBNAME((const char *)p);
  408. default:
  409. break;
  410. }
  411. ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED);
  412. return 0;
  413. }
  414. static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  415. const BIGNUM *m, BN_CTX *ctx)
  416. {
  417. /* I need somewhere to store temporary serialised values for
  418.  * use with the Atalla API calls. A neat cheat - I'll use
  419.  * BIGNUMs from the BN_CTX but access their arrays directly as
  420.  * byte arrays <grin>. This way I don't have to clean anything
  421.  * up. */
  422. BIGNUM *modulus;
  423. BIGNUM *exponent;
  424. BIGNUM *argument;
  425. BIGNUM *result;
  426. RSAPrivateKey keydata;
  427. int to_return, numbytes;
  428. modulus = exponent = argument = result = NULL;
  429. to_return = 0; /* expect failure */
  430. if(!atalla_dso)
  431. {
  432. ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_NOT_LOADED);
  433. goto err;
  434. }
  435. /* Prepare the params */
  436. BN_CTX_start(ctx);
  437. modulus = BN_CTX_get(ctx);
  438. exponent = BN_CTX_get(ctx);
  439. argument = BN_CTX_get(ctx);
  440. result = BN_CTX_get(ctx);
  441. if (!result)
  442. {
  443. ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_CTX_FULL);
  444. goto err;
  445. }
  446. if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) ||
  447.    !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top))
  448. {
  449. ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_EXPAND_FAIL);
  450. goto err;
  451. }
  452. /* Prepare the key-data */
  453. memset(&keydata, 0,sizeof keydata);
  454. numbytes = BN_num_bytes(m);
  455. memset(exponent->d, 0, numbytes);
  456. memset(modulus->d, 0, numbytes);
  457. BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p));
  458. BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m));
  459. keydata.privateExponent.data = (unsigned char *)exponent->d;
  460. keydata.privateExponent.len = numbytes;
  461. keydata.modulus.data = (unsigned char *)modulus->d;
  462. keydata.modulus.len = numbytes;
  463. /* Prepare the argument */
  464. memset(argument->d, 0, numbytes);
  465. memset(result->d, 0, numbytes);
  466. BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a));
  467. /* Perform the operation */
  468. if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d,
  469. (unsigned char *)argument->d,
  470. keydata.modulus.len) != 0)
  471. {
  472. ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_REQUEST_FAILED);
  473. goto err;
  474. }
  475. /* Convert the response */
  476. BN_bin2bn((unsigned char *)result->d, numbytes, r);
  477. to_return = 1;
  478. err:
  479. BN_CTX_end(ctx);
  480. return to_return;
  481. }
  482. #ifndef OPENSSL_NO_RSA
  483. static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
  484. {
  485. int to_return = 0;
  486. if(!atalla_dso)
  487. {
  488. ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_NOT_LOADED);
  489. goto err;
  490. }
  491. if(!rsa->d || !rsa->n)
  492. {
  493. ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_MISSING_KEY_COMPONENTS);
  494. goto err;
  495. }
  496. to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx);
  497. err:
  498. return to_return;
  499. }
  500. #endif
  501. #ifndef OPENSSL_NO_DSA
  502. /* This code was liberated and adapted from the commented-out code in
  503.  * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
  504.  * (it doesn't have a CRT form for RSA), this function means that an
  505.  * Atalla system running with a DSA server certificate can handshake
  506.  * around 5 or 6 times faster/more than an equivalent system running with
  507.  * RSA. Just check out the "signs" statistics from the RSA and DSA parts
  508.  * of "openssl speed -engine atalla dsa1024 rsa1024". */
  509. static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
  510. BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
  511. BN_CTX *ctx, BN_MONT_CTX *in_mont)
  512. {
  513. BIGNUM t;
  514. int to_return = 0;
  515.  
  516. BN_init(&t);
  517. /* let rr = a1 ^ p1 mod m */
  518. if (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end;
  519. /* let t = a2 ^ p2 mod m */
  520. if (!atalla_mod_exp(&t,a2,p2,m,ctx)) goto end;
  521. /* let rr = rr * t mod m */
  522. if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
  523. to_return = 1;
  524. end:
  525. BN_free(&t);
  526. return to_return;
  527. }
  528. static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
  529. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  530. BN_MONT_CTX *m_ctx)
  531. {
  532. return atalla_mod_exp(r, a, p, m, ctx);
  533. }
  534. #endif
  535. #ifndef OPENSSL_NO_RSA
  536. /* This function is aliased to mod_exp (with the mont stuff dropped). */
  537. static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  538. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
  539. {
  540. return atalla_mod_exp(r, a, p, m, ctx);
  541. }
  542. #endif
  543. #ifndef OPENSSL_NO_DH
  544. /* This function is aliased to mod_exp (with the dh and mont dropped). */
  545. static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
  546. const BIGNUM *a, const BIGNUM *p,
  547. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
  548. {
  549. return atalla_mod_exp(r, a, p, m, ctx);
  550. }
  551. #endif
  552. /* This stuff is needed if this ENGINE is being compiled into a self-contained
  553.  * shared-library. */
  554. #ifndef OPENSSL_NO_DYNAMIC_ENGINE
  555. static int bind_fn(ENGINE *e, const char *id)
  556. {
  557. if(id && (strcmp(id, engine_atalla_id) != 0))
  558. return 0;
  559. if(!bind_helper(e))
  560. return 0;
  561. return 1;
  562. }
  563. IMPLEMENT_DYNAMIC_CHECK_FN()
  564. IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
  565. #endif /* OPENSSL_NO_DYNAMIC_ENGINE */
  566. #endif /* !OPENSSL_NO_HW_ATALLA */
  567. #endif /* !OPENSSL_NO_HW */