e_ubsec.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. /* crypto/engine/hw_ubsec.c */
  2. /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
  3. * project 2000.
  4. *
  5. * Cloned shamelessly by Joe Tardo.
  6. */
  7. /* ====================================================================
  8. * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. *
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. *
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in
  19. * the documentation and/or other materials provided with the
  20. * distribution.
  21. *
  22. * 3. All advertising materials mentioning features or use of this
  23. * software must display the following acknowledgment:
  24. * "This product includes software developed by the OpenSSL Project
  25. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  26. *
  27. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  28. * endorse or promote products derived from this software without
  29. * prior written permission. For written permission, please contact
  30. * licensing@OpenSSL.org.
  31. *
  32. * 5. Products derived from this software may not be called "OpenSSL"
  33. * nor may "OpenSSL" appear in their names without prior written
  34. * permission of the OpenSSL Project.
  35. *
  36. * 6. Redistributions of any form whatsoever must retain the following
  37. * acknowledgment:
  38. * "This product includes software developed by the OpenSSL Project
  39. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  42. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  44. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  45. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  46. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  47. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  49. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  50. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  51. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  52. * OF THE POSSIBILITY OF SUCH DAMAGE.
  53. * ====================================================================
  54. *
  55. * This product includes cryptographic software written by Eric Young
  56. * (eay@cryptsoft.com). This product includes software written by Tim
  57. * Hudson (tjh@cryptsoft.com).
  58. *
  59. */
  60. #include <stdio.h>
  61. #include <string.h>
  62. #include <openssl/crypto.h>
  63. #include <openssl/buffer.h>
  64. #include <openssl/dso.h>
  65. #include <openssl/engine.h>
  66. #ifndef OPENSSL_NO_RSA
  67. #include <openssl/rsa.h>
  68. #endif
  69. #ifndef OPENSSL_NO_DSA
  70. #include <openssl/dsa.h>
  71. #endif
  72. #ifndef OPENSSL_NO_DH
  73. #include <openssl/dh.h>
  74. #endif
  75. #include <openssl/bn.h>
  76. #ifndef OPENSSL_NO_HW
  77. #ifndef OPENSSL_NO_HW_UBSEC
  78. #ifdef FLAT_INC
  79. #include "hw_ubsec.h"
  80. #else
  81. #include "vendor_defns/hw_ubsec.h"
  82. #endif
  83. #define UBSEC_LIB_NAME "ubsec engine"
  84. #include "e_ubsec_err.c"
  85. #define FAIL_TO_SOFTWARE -15
  86. static int ubsec_destroy(ENGINE *e);
  87. static int ubsec_init(ENGINE *e);
  88. static int ubsec_finish(ENGINE *e);
  89. static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
  90. static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  91. const BIGNUM *m, BN_CTX *ctx);
  92. #ifndef OPENSSL_NO_RSA
  93. static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  94. const BIGNUM *q, const BIGNUM *dp,
  95. const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
  96. static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
  97. static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  98. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  99. #endif
  100. #ifndef OPENSSL_NO_DSA
  101. #ifdef NOT_USED
  102. static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
  103. BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
  104. BN_CTX *ctx, BN_MONT_CTX *in_mont);
  105. static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
  106. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  107. BN_MONT_CTX *m_ctx);
  108. #endif
  109. static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
  110. static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
  111. DSA_SIG *sig, DSA *dsa);
  112. #endif
  113. #ifndef OPENSSL_NO_DH
  114. static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
  115. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  116. BN_MONT_CTX *m_ctx);
  117. static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
  118. static int ubsec_dh_generate_key(DH *dh);
  119. #endif
  120. #ifdef NOT_USED
  121. static int ubsec_rand_bytes(unsigned char *buf, int num);
  122. static int ubsec_rand_status(void);
  123. #endif
  124. #define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE
  125. static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
  126. {UBSEC_CMD_SO_PATH,
  127. "SO_PATH",
  128. "Specifies the path to the 'ubsec' shared library",
  129. ENGINE_CMD_FLAG_STRING},
  130. {0, NULL, NULL, 0}
  131. };
  132. #ifndef OPENSSL_NO_RSA
  133. /* Our internal RSA_METHOD that we provide pointers to */
  134. static RSA_METHOD ubsec_rsa =
  135. {
  136. "UBSEC RSA method",
  137. NULL,
  138. NULL,
  139. NULL,
  140. NULL,
  141. ubsec_rsa_mod_exp,
  142. ubsec_mod_exp_mont,
  143. NULL,
  144. NULL,
  145. 0,
  146. NULL,
  147. NULL,
  148. NULL,
  149. NULL
  150. };
  151. #endif
  152. #ifndef OPENSSL_NO_DSA
  153. /* Our internal DSA_METHOD that we provide pointers to */
  154. static DSA_METHOD ubsec_dsa =
  155. {
  156. "UBSEC DSA method",
  157. ubsec_dsa_do_sign, /* dsa_do_sign */
  158. NULL, /* dsa_sign_setup */
  159. ubsec_dsa_verify, /* dsa_do_verify */
  160. NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
  161. NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
  162. NULL, /* init */
  163. NULL, /* finish */
  164. 0, /* flags */
  165. NULL, /* app_data */
  166. NULL, /* dsa_paramgen */
  167. NULL /* dsa_keygen */
  168. };
  169. #endif
  170. #ifndef OPENSSL_NO_DH
  171. /* Our internal DH_METHOD that we provide pointers to */
  172. static DH_METHOD ubsec_dh =
  173. {
  174. "UBSEC DH method",
  175. ubsec_dh_generate_key,
  176. ubsec_dh_compute_key,
  177. ubsec_mod_exp_dh,
  178. NULL,
  179. NULL,
  180. 0,
  181. NULL,
  182. NULL
  183. };
  184. #endif
  185. /* Constants used when creating the ENGINE */
  186. static const char *engine_ubsec_id = "ubsec";
  187. static const char *engine_ubsec_name = "UBSEC hardware engine support";
  188. /* This internal function is used by ENGINE_ubsec() and possibly by the
  189. * "dynamic" ENGINE support too */
  190. static int bind_helper(ENGINE *e)
  191. {
  192. #ifndef OPENSSL_NO_RSA
  193. const RSA_METHOD *meth1;
  194. #endif
  195. #ifndef OPENSSL_NO_DH
  196. #ifndef HAVE_UBSEC_DH
  197. const DH_METHOD *meth3;
  198. #endif /* HAVE_UBSEC_DH */
  199. #endif
  200. if(!ENGINE_set_id(e, engine_ubsec_id) ||
  201. !ENGINE_set_name(e, engine_ubsec_name) ||
  202. #ifndef OPENSSL_NO_RSA
  203. !ENGINE_set_RSA(e, &ubsec_rsa) ||
  204. #endif
  205. #ifndef OPENSSL_NO_DSA
  206. !ENGINE_set_DSA(e, &ubsec_dsa) ||
  207. #endif
  208. #ifndef OPENSSL_NO_DH
  209. !ENGINE_set_DH(e, &ubsec_dh) ||
  210. #endif
  211. !ENGINE_set_destroy_function(e, ubsec_destroy) ||
  212. !ENGINE_set_init_function(e, ubsec_init) ||
  213. !ENGINE_set_finish_function(e, ubsec_finish) ||
  214. !ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
  215. !ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
  216. return 0;
  217. #ifndef OPENSSL_NO_RSA
  218. /* We know that the "PKCS1_SSLeay()" functions hook properly
  219. * to the Broadcom-specific mod_exp and mod_exp_crt so we use
  220. * those functions. NB: We don't use ENGINE_openssl() or
  221. * anything "more generic" because something like the RSAref
  222. * code may not hook properly, and if you own one of these
  223. * cards then you have the right to do RSA operations on it
  224. * anyway! */
  225. meth1 = RSA_PKCS1_SSLeay();
  226. ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
  227. ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
  228. ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
  229. ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
  230. #endif
  231. #ifndef OPENSSL_NO_DH
  232. #ifndef HAVE_UBSEC_DH
  233. /* Much the same for Diffie-Hellman */
  234. meth3 = DH_OpenSSL();
  235. ubsec_dh.generate_key = meth3->generate_key;
  236. ubsec_dh.compute_key = meth3->compute_key;
  237. #endif /* HAVE_UBSEC_DH */
  238. #endif
  239. /* Ensure the ubsec error handling is set up */
  240. ERR_load_UBSEC_strings();
  241. return 1;
  242. }
  243. #ifdef OPENSSL_NO_DYNAMIC_ENGINE
  244. static ENGINE *engine_ubsec(void)
  245. {
  246. ENGINE *ret = ENGINE_new();
  247. if(!ret)
  248. return NULL;
  249. if(!bind_helper(ret))
  250. {
  251. ENGINE_free(ret);
  252. return NULL;
  253. }
  254. return ret;
  255. }
  256. void ENGINE_load_ubsec(void)
  257. {
  258. /* Copied from eng_[openssl|dyn].c */
  259. ENGINE *toadd = engine_ubsec();
  260. if(!toadd) return;
  261. ENGINE_add(toadd);
  262. ENGINE_free(toadd);
  263. ERR_clear_error();
  264. }
  265. #endif
  266. /* This is a process-global DSO handle used for loading and unloading
  267. * the UBSEC library. NB: This is only set (or unset) during an
  268. * init() or finish() call (reference counts permitting) and they're
  269. * operating with global locks, so this should be thread-safe
  270. * implicitly. */
  271. static DSO *ubsec_dso = NULL;
  272. /* These are the function pointers that are (un)set when the library has
  273. * successfully (un)loaded. */
  274. static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
  275. static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
  276. static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
  277. static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
  278. #ifndef OPENSSL_NO_DH
  279. static t_UBSEC_diffie_hellman_generate_ioctl
  280. *p_UBSEC_diffie_hellman_generate_ioctl = NULL;
  281. static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
  282. #endif
  283. #ifndef OPENSSL_NO_RSA
  284. static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
  285. static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
  286. #endif
  287. #ifndef OPENSSL_NO_DSA
  288. static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
  289. static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
  290. #endif
  291. static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
  292. static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
  293. static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
  294. static int max_key_len = 1024; /* ??? */
  295. /*
  296. * These are the static string constants for the DSO file name and the function
  297. * symbol names to bind to.
  298. */
  299. static const char *UBSEC_LIBNAME = NULL;
  300. static const char *get_UBSEC_LIBNAME(void)
  301. {
  302. if(UBSEC_LIBNAME)
  303. return UBSEC_LIBNAME;
  304. return "ubsec";
  305. }
  306. static void free_UBSEC_LIBNAME(void)
  307. {
  308. if(UBSEC_LIBNAME)
  309. OPENSSL_free((void*)UBSEC_LIBNAME);
  310. UBSEC_LIBNAME = NULL;
  311. }
  312. static long set_UBSEC_LIBNAME(const char *name)
  313. {
  314. free_UBSEC_LIBNAME();
  315. return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
  316. }
  317. static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
  318. static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
  319. static const char *UBSEC_F3 = "ubsec_open";
  320. static const char *UBSEC_F4 = "ubsec_close";
  321. #ifndef OPENSSL_NO_DH
  322. static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
  323. static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
  324. #endif
  325. /* #ifndef OPENSSL_NO_RSA */
  326. static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
  327. static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
  328. /* #endif */
  329. #ifndef OPENSSL_NO_DSA
  330. static const char *UBSEC_F9 = "dsa_sign_ioctl";
  331. static const char *UBSEC_F10 = "dsa_verify_ioctl";
  332. #endif
  333. static const char *UBSEC_F11 = "math_accelerate_ioctl";
  334. static const char *UBSEC_F12 = "rng_ioctl";
  335. static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
  336. /* Destructor (complements the "ENGINE_ubsec()" constructor) */
  337. static int ubsec_destroy(ENGINE *e)
  338. {
  339. free_UBSEC_LIBNAME();
  340. ERR_unload_UBSEC_strings();
  341. return 1;
  342. }
  343. /* (de)initialisation functions. */
  344. static int ubsec_init(ENGINE *e)
  345. {
  346. t_UBSEC_ubsec_bytes_to_bits *p1;
  347. t_UBSEC_ubsec_bits_to_bytes *p2;
  348. t_UBSEC_ubsec_open *p3;
  349. t_UBSEC_ubsec_close *p4;
  350. #ifndef OPENSSL_NO_DH
  351. t_UBSEC_diffie_hellman_generate_ioctl *p5;
  352. t_UBSEC_diffie_hellman_agree_ioctl *p6;
  353. #endif
  354. /* #ifndef OPENSSL_NO_RSA */
  355. t_UBSEC_rsa_mod_exp_ioctl *p7;
  356. t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
  357. /* #endif */
  358. #ifndef OPENSSL_NO_DSA
  359. t_UBSEC_dsa_sign_ioctl *p9;
  360. t_UBSEC_dsa_verify_ioctl *p10;
  361. #endif
  362. t_UBSEC_math_accelerate_ioctl *p11;
  363. t_UBSEC_rng_ioctl *p12;
  364. t_UBSEC_max_key_len_ioctl *p13;
  365. int fd = 0;
  366. if(ubsec_dso != NULL)
  367. {
  368. UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED);
  369. goto err;
  370. }
  371. /*
  372. * Attempt to load libubsec.so/ubsec.dll/whatever.
  373. */
  374. ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0);
  375. if(ubsec_dso == NULL)
  376. {
  377. UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
  378. goto err;
  379. }
  380. if (
  381. !(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
  382. !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
  383. !(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
  384. !(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
  385. #ifndef OPENSSL_NO_DH
  386. !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *)
  387. DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
  388. !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *)
  389. DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
  390. #endif
  391. /* #ifndef OPENSSL_NO_RSA */
  392. !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
  393. !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
  394. /* #endif */
  395. #ifndef OPENSSL_NO_DSA
  396. !(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
  397. !(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
  398. #endif
  399. !(p11 = (t_UBSEC_math_accelerate_ioctl *)
  400. DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
  401. !(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
  402. !(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
  403. {
  404. UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
  405. goto err;
  406. }
  407. /* Copy the pointers */
  408. p_UBSEC_ubsec_bytes_to_bits = p1;
  409. p_UBSEC_ubsec_bits_to_bytes = p2;
  410. p_UBSEC_ubsec_open = p3;
  411. p_UBSEC_ubsec_close = p4;
  412. #ifndef OPENSSL_NO_DH
  413. p_UBSEC_diffie_hellman_generate_ioctl = p5;
  414. p_UBSEC_diffie_hellman_agree_ioctl = p6;
  415. #endif
  416. #ifndef OPENSSL_NO_RSA
  417. p_UBSEC_rsa_mod_exp_ioctl = p7;
  418. p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
  419. #endif
  420. #ifndef OPENSSL_NO_DSA
  421. p_UBSEC_dsa_sign_ioctl = p9;
  422. p_UBSEC_dsa_verify_ioctl = p10;
  423. #endif
  424. p_UBSEC_math_accelerate_ioctl = p11;
  425. p_UBSEC_rng_ioctl = p12;
  426. p_UBSEC_max_key_len_ioctl = p13;
  427. /* Perform an open to see if there's actually any unit running. */
  428. if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
  429. {
  430. p_UBSEC_ubsec_close(fd);
  431. return 1;
  432. }
  433. else
  434. {
  435. UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
  436. }
  437. err:
  438. if(ubsec_dso)
  439. DSO_free(ubsec_dso);
  440. ubsec_dso = NULL;
  441. p_UBSEC_ubsec_bytes_to_bits = NULL;
  442. p_UBSEC_ubsec_bits_to_bytes = NULL;
  443. p_UBSEC_ubsec_open = NULL;
  444. p_UBSEC_ubsec_close = NULL;
  445. #ifndef OPENSSL_NO_DH
  446. p_UBSEC_diffie_hellman_generate_ioctl = NULL;
  447. p_UBSEC_diffie_hellman_agree_ioctl = NULL;
  448. #endif
  449. #ifndef OPENSSL_NO_RSA
  450. p_UBSEC_rsa_mod_exp_ioctl = NULL;
  451. p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
  452. #endif
  453. #ifndef OPENSSL_NO_DSA
  454. p_UBSEC_dsa_sign_ioctl = NULL;
  455. p_UBSEC_dsa_verify_ioctl = NULL;
  456. #endif
  457. p_UBSEC_math_accelerate_ioctl = NULL;
  458. p_UBSEC_rng_ioctl = NULL;
  459. p_UBSEC_max_key_len_ioctl = NULL;
  460. return 0;
  461. }
  462. static int ubsec_finish(ENGINE *e)
  463. {
  464. free_UBSEC_LIBNAME();
  465. if(ubsec_dso == NULL)
  466. {
  467. UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED);
  468. return 0;
  469. }
  470. if(!DSO_free(ubsec_dso))
  471. {
  472. UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE);
  473. return 0;
  474. }
  475. ubsec_dso = NULL;
  476. p_UBSEC_ubsec_bytes_to_bits = NULL;
  477. p_UBSEC_ubsec_bits_to_bytes = NULL;
  478. p_UBSEC_ubsec_open = NULL;
  479. p_UBSEC_ubsec_close = NULL;
  480. #ifndef OPENSSL_NO_DH
  481. p_UBSEC_diffie_hellman_generate_ioctl = NULL;
  482. p_UBSEC_diffie_hellman_agree_ioctl = NULL;
  483. #endif
  484. #ifndef OPENSSL_NO_RSA
  485. p_UBSEC_rsa_mod_exp_ioctl = NULL;
  486. p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
  487. #endif
  488. #ifndef OPENSSL_NO_DSA
  489. p_UBSEC_dsa_sign_ioctl = NULL;
  490. p_UBSEC_dsa_verify_ioctl = NULL;
  491. #endif
  492. p_UBSEC_math_accelerate_ioctl = NULL;
  493. p_UBSEC_rng_ioctl = NULL;
  494. p_UBSEC_max_key_len_ioctl = NULL;
  495. return 1;
  496. }
  497. static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
  498. {
  499. int initialised = ((ubsec_dso == NULL) ? 0 : 1);
  500. switch(cmd)
  501. {
  502. case UBSEC_CMD_SO_PATH:
  503. if(p == NULL)
  504. {
  505. UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER);
  506. return 0;
  507. }
  508. if(initialised)
  509. {
  510. UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED);
  511. return 0;
  512. }
  513. return set_UBSEC_LIBNAME((const char *)p);
  514. default:
  515. break;
  516. }
  517. UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED);
  518. return 0;
  519. }
  520. static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  521. const BIGNUM *m, BN_CTX *ctx)
  522. {
  523. int y_len = 0;
  524. int fd;
  525. if(ubsec_dso == NULL)
  526. {
  527. UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED);
  528. return 0;
  529. }
  530. /* Check if hardware can't handle this argument. */
  531. y_len = BN_num_bits(m);
  532. if (y_len > max_key_len) {
  533. UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  534. return BN_mod_exp(r, a, p, m, ctx);
  535. }
  536. if(!bn_wexpand(r, m->top))
  537. {
  538. UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL);
  539. return 0;
  540. }
  541. if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
  542. fd = 0;
  543. UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE);
  544. return BN_mod_exp(r, a, p, m, ctx);
  545. }
  546. if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
  547. (unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d,
  548. BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
  549. {
  550. UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
  551. p_UBSEC_ubsec_close(fd);
  552. return BN_mod_exp(r, a, p, m, ctx);
  553. }
  554. p_UBSEC_ubsec_close(fd);
  555. r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2;
  556. return 1;
  557. }
  558. #ifndef OPENSSL_NO_RSA
  559. static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
  560. {
  561. int to_return = 0;
  562. if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
  563. {
  564. UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS);
  565. goto err;
  566. }
  567. to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
  568. rsa->dmq1, rsa->iqmp, ctx);
  569. if (to_return == FAIL_TO_SOFTWARE)
  570. {
  571. /*
  572. * Do in software as hardware failed.
  573. */
  574. const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
  575. to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
  576. }
  577. err:
  578. return to_return;
  579. }
  580. static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  581. const BIGNUM *q, const BIGNUM *dp,
  582. const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx)
  583. {
  584. int y_len,
  585. fd;
  586. y_len = BN_num_bits(p) + BN_num_bits(q);
  587. /* Check if hardware can't handle this argument. */
  588. if (y_len > max_key_len) {
  589. UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  590. return FAIL_TO_SOFTWARE;
  591. }
  592. if (!bn_wexpand(r, p->top + q->top + 1)) {
  593. UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL);
  594. return 0;
  595. }
  596. if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
  597. fd = 0;
  598. UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE);
  599. return FAIL_TO_SOFTWARE;
  600. }
  601. if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
  602. (unsigned char *)a->d, BN_num_bits(a),
  603. (unsigned char *)qinv->d, BN_num_bits(qinv),
  604. (unsigned char *)dp->d, BN_num_bits(dp),
  605. (unsigned char *)p->d, BN_num_bits(p),
  606. (unsigned char *)dq->d, BN_num_bits(dq),
  607. (unsigned char *)q->d, BN_num_bits(q),
  608. (unsigned char *)r->d, &y_len) != 0) {
  609. UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED);
  610. p_UBSEC_ubsec_close(fd);
  611. return FAIL_TO_SOFTWARE;
  612. }
  613. p_UBSEC_ubsec_close(fd);
  614. r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2;
  615. return 1;
  616. }
  617. #endif
  618. #ifndef OPENSSL_NO_DSA
  619. #ifdef NOT_USED
  620. static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
  621. BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
  622. BN_CTX *ctx, BN_MONT_CTX *in_mont)
  623. {
  624. BIGNUM t;
  625. int to_return = 0;
  626. BN_init(&t);
  627. /* let rr = a1 ^ p1 mod m */
  628. if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end;
  629. /* let t = a2 ^ p2 mod m */
  630. if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end;
  631. /* let rr = rr * t mod m */
  632. if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
  633. to_return = 1;
  634. end:
  635. BN_free(&t);
  636. return to_return;
  637. }
  638. static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
  639. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  640. BN_MONT_CTX *m_ctx)
  641. {
  642. return ubsec_mod_exp(r, a, p, m, ctx);
  643. }
  644. #endif
  645. #endif
  646. #ifndef OPENSSL_NO_RSA
  647. /*
  648. * This function is aliased to mod_exp (with the mont stuff dropped).
  649. */
  650. static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  651. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
  652. {
  653. int ret = 0;
  654. /* Do in software if the key is too large for the hardware. */
  655. if (BN_num_bits(m) > max_key_len)
  656. {
  657. const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
  658. ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
  659. }
  660. else
  661. {
  662. ret = ubsec_mod_exp(r, a, p, m, ctx);
  663. }
  664. return ret;
  665. }
  666. #endif
  667. #ifndef OPENSSL_NO_DH
  668. /* This function is aliased to mod_exp (with the dh and mont dropped). */
  669. static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
  670. const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  671. BN_MONT_CTX *m_ctx)
  672. {
  673. return ubsec_mod_exp(r, a, p, m, ctx);
  674. }
  675. #endif
  676. #ifndef OPENSSL_NO_DSA
  677. static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
  678. {
  679. DSA_SIG *to_return = NULL;
  680. int s_len = 160, r_len = 160, d_len, fd;
  681. BIGNUM m, *r=NULL, *s=NULL;
  682. BN_init(&m);
  683. s = BN_new();
  684. r = BN_new();
  685. if ((s == NULL) || (r==NULL))
  686. goto err;
  687. d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);
  688. if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
  689. (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
  690. UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
  691. goto err;
  692. }
  693. if (BN_bin2bn(dgst,dlen,&m) == NULL) {
  694. UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
  695. goto err;
  696. }
  697. if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
  698. const DSA_METHOD *meth;
  699. fd = 0;
  700. UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE);
  701. meth = DSA_OpenSSL();
  702. to_return = meth->dsa_do_sign(dgst, dlen, dsa);
  703. goto err;
  704. }
  705. if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
  706. (unsigned char *)dgst, d_len,
  707. NULL, 0, /* compute random value */
  708. (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
  709. (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
  710. (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
  711. (unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
  712. (unsigned char *)r->d, &r_len,
  713. (unsigned char *)s->d, &s_len ) != 0) {
  714. const DSA_METHOD *meth;
  715. UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED);
  716. p_UBSEC_ubsec_close(fd);
  717. meth = DSA_OpenSSL();
  718. to_return = meth->dsa_do_sign(dgst, dlen, dsa);
  719. goto err;
  720. }
  721. p_UBSEC_ubsec_close(fd);
  722. r->top = (160+BN_BITS2-1)/BN_BITS2;
  723. s->top = (160+BN_BITS2-1)/BN_BITS2;
  724. to_return = DSA_SIG_new();
  725. if(to_return == NULL) {
  726. UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
  727. goto err;
  728. }
  729. to_return->r = r;
  730. to_return->s = s;
  731. err:
  732. if (!to_return) {
  733. if (r) BN_free(r);
  734. if (s) BN_free(s);
  735. }
  736. BN_clear_free(&m);
  737. return to_return;
  738. }
  739. static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
  740. DSA_SIG *sig, DSA *dsa)
  741. {
  742. int v_len, d_len;
  743. int to_return = 0;
  744. int fd;
  745. BIGNUM v, *pv = &v;
  746. BN_init(&v);
  747. if(!bn_wexpand(pv, dsa->p->top)) {
  748. UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL);
  749. goto err;
  750. }
  751. v_len = BN_num_bits(dsa->p);
  752. d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
  753. if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
  754. const DSA_METHOD *meth;
  755. fd = 0;
  756. UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE);
  757. meth = DSA_OpenSSL();
  758. to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
  759. goto err;
  760. }
  761. if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
  762. (unsigned char *)dgst, d_len,
  763. (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
  764. (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
  765. (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
  766. (unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key),
  767. (unsigned char *)sig->r->d, BN_num_bits(sig->r),
  768. (unsigned char *)sig->s->d, BN_num_bits(sig->s),
  769. (unsigned char *)v.d, &v_len) != 0) {
  770. const DSA_METHOD *meth;
  771. UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED);
  772. p_UBSEC_ubsec_close(fd);
  773. meth = DSA_OpenSSL();
  774. to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
  775. goto err;
  776. }
  777. p_UBSEC_ubsec_close(fd);
  778. to_return = 1;
  779. err:
  780. BN_clear_free(&v);
  781. return to_return;
  782. }
  783. #endif
  784. #ifndef OPENSSL_NO_DH
  785. static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh)
  786. {
  787. int ret = -1,
  788. k_len,
  789. fd;
  790. k_len = BN_num_bits(dh->p);
  791. if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
  792. {
  793. const DH_METHOD *meth;
  794. UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE);
  795. meth = DH_OpenSSL();
  796. ret = meth->compute_key(key, pub_key, dh);
  797. goto err;
  798. }
  799. if (p_UBSEC_diffie_hellman_agree_ioctl(fd,
  800. (unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key),
  801. (unsigned char *)pub_key->d, BN_num_bits(pub_key),
  802. (unsigned char *)dh->p->d, BN_num_bits(dh->p),
  803. key, &k_len) != 0)
  804. {
  805. /* Hardware's a no go, failover to software */
  806. const DH_METHOD *meth;
  807. UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
  808. p_UBSEC_ubsec_close(fd);
  809. meth = DH_OpenSSL();
  810. ret = meth->compute_key(key, pub_key, dh);
  811. goto err;
  812. }
  813. p_UBSEC_ubsec_close(fd);
  814. ret = p_UBSEC_ubsec_bits_to_bytes(k_len);
  815. err:
  816. return ret;
  817. }
  818. static int ubsec_dh_generate_key(DH *dh)
  819. {
  820. int ret = 0,
  821. random_bits = 0,
  822. pub_key_len = 0,
  823. priv_key_len = 0,
  824. fd;
  825. BIGNUM *pub_key = NULL;
  826. BIGNUM *priv_key = NULL;
  827. /*
  828. * How many bits should Random x be? dh_key.c
  829. * sets the range from 0 to num_bits(modulus) ???
  830. */
  831. if (dh->priv_key == NULL)
  832. {
  833. priv_key = BN_new();
  834. if (priv_key == NULL) goto err;
  835. priv_key_len = BN_num_bits(dh->p);
  836. if(bn_wexpand(priv_key, dh->p->top) == NULL) goto err;
  837. do
  838. if (!BN_rand_range(priv_key, dh->p)) goto err;
  839. while (BN_is_zero(priv_key));
  840. random_bits = BN_num_bits(priv_key);
  841. }
  842. else
  843. {
  844. priv_key = dh->priv_key;
  845. }
  846. if (dh->pub_key == NULL)
  847. {
  848. pub_key = BN_new();
  849. pub_key_len = BN_num_bits(dh->p);
  850. if(bn_wexpand(pub_key, dh->p->top) == NULL) goto err;
  851. if(pub_key == NULL) goto err;
  852. }
  853. else
  854. {
  855. pub_key = dh->pub_key;
  856. }
  857. if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
  858. {
  859. const DH_METHOD *meth;
  860. UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE);
  861. meth = DH_OpenSSL();
  862. ret = meth->generate_key(dh);
  863. goto err;
  864. }
  865. if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
  866. (unsigned char *)priv_key->d, &priv_key_len,
  867. (unsigned char *)pub_key->d, &pub_key_len,
  868. (unsigned char *)dh->g->d, BN_num_bits(dh->g),
  869. (unsigned char *)dh->p->d, BN_num_bits(dh->p),
  870. 0, 0, random_bits) != 0)
  871. {
  872. /* Hardware's a no go, failover to software */
  873. const DH_METHOD *meth;
  874. UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED);
  875. p_UBSEC_ubsec_close(fd);
  876. meth = DH_OpenSSL();
  877. ret = meth->generate_key(dh);
  878. goto err;
  879. }
  880. p_UBSEC_ubsec_close(fd);
  881. dh->pub_key = pub_key;
  882. dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
  883. dh->priv_key = priv_key;
  884. dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;
  885. ret = 1;
  886. err:
  887. return ret;
  888. }
  889. #endif
  890. #ifdef NOT_USED
  891. static int ubsec_rand_bytes(unsigned char * buf,
  892. int num)
  893. {
  894. int ret = 0,
  895. fd;
  896. if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
  897. {
  898. const RAND_METHOD *meth;
  899. UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE);
  900. num = p_UBSEC_ubsec_bits_to_bytes(num);
  901. meth = RAND_SSLeay();
  902. meth->seed(buf, num);
  903. ret = meth->bytes(buf, num);
  904. goto err;
  905. }
  906. num *= 8; /* bytes to bits */
  907. if (p_UBSEC_rng_ioctl(fd,
  908. UBSEC_RNG_DIRECT,
  909. buf,
  910. &num) != 0)
  911. {
  912. /* Hardware's a no go, failover to software */
  913. const RAND_METHOD *meth;
  914. UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED);
  915. p_UBSEC_ubsec_close(fd);
  916. num = p_UBSEC_ubsec_bits_to_bytes(num);
  917. meth = RAND_SSLeay();
  918. meth->seed(buf, num);
  919. ret = meth->bytes(buf, num);
  920. goto err;
  921. }
  922. p_UBSEC_ubsec_close(fd);
  923. ret = 1;
  924. err:
  925. return(ret);
  926. }
  927. static int ubsec_rand_status(void)
  928. {
  929. return 0;
  930. }
  931. #endif
  932. /* This stuff is needed if this ENGINE is being compiled into a self-contained
  933. * shared-library. */
  934. #ifndef OPENSSL_NO_DYNAMIC_ENGINE
  935. static int bind_fn(ENGINE *e, const char *id)
  936. {
  937. if(id && (strcmp(id, engine_ubsec_id) != 0))
  938. return 0;
  939. if(!bind_helper(e))
  940. return 0;
  941. return 1;
  942. }
  943. IMPLEMENT_DYNAMIC_CHECK_FN()
  944. IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
  945. #endif /* OPENSSL_NO_DYNAMIC_ENGINE */
  946. #endif /* !OPENSSL_NO_HW_UBSEC */
  947. #endif /* !OPENSSL_NO_HW */