e_atalla.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  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. BN_init(&t);
  516. /* let rr = a1 ^ p1 mod m */
  517. if (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end;
  518. /* let t = a2 ^ p2 mod m */
  519. if (!atalla_mod_exp(&t,a2,p2,m,ctx)) goto end;
  520. /* let rr = rr * t mod m */
  521. if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
  522. to_return = 1;
  523. end:
  524. BN_free(&t);
  525. return to_return;
  526. }
  527. static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
  528. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  529. BN_MONT_CTX *m_ctx)
  530. {
  531. return atalla_mod_exp(r, a, p, m, ctx);
  532. }
  533. #endif
  534. #ifndef OPENSSL_NO_RSA
  535. /* This function is aliased to mod_exp (with the mont stuff dropped). */
  536. static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  537. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
  538. {
  539. return atalla_mod_exp(r, a, p, m, ctx);
  540. }
  541. #endif
  542. #ifndef OPENSSL_NO_DH
  543. /* This function is aliased to mod_exp (with the dh and mont dropped). */
  544. static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
  545. const BIGNUM *a, const BIGNUM *p,
  546. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
  547. {
  548. return atalla_mod_exp(r, a, p, m, ctx);
  549. }
  550. #endif
  551. /* This stuff is needed if this ENGINE is being compiled into a self-contained
  552. * shared-library. */
  553. #ifndef OPENSSL_NO_DYNAMIC_ENGINE
  554. static int bind_fn(ENGINE *e, const char *id)
  555. {
  556. if(id && (strcmp(id, engine_atalla_id) != 0))
  557. return 0;
  558. if(!bind_helper(e))
  559. return 0;
  560. return 1;
  561. }
  562. IMPLEMENT_DYNAMIC_CHECK_FN()
  563. IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
  564. #endif /* OPENSSL_NO_DYNAMIC_ENGINE */
  565. #endif /* !OPENSSL_NO_HW_ATALLA */
  566. #endif /* !OPENSSL_NO_HW */