e_ubsec.c 34 KB

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