1 /* crypto/engine/hw_ubsec.c */
2 /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
5 * Cloned shamelessly by Joe Tardo.
7 /* ====================================================================
8 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
36 * 6. Redistributions of any form whatsoever must retain the following
38 * "This product includes software developed by the OpenSSL Project
39 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
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 * ====================================================================
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).
62 #include <openssl/crypto.h>
64 #include <openssl/dso.h>
65 #include <openssl/engine.h>
68 #ifndef OPENSSL_NO_HW_UBSEC
73 #include "vendor_defns/hw_ubsec.h"
76 static int ubsec_init(ENGINE *e);
77 static int ubsec_finish(ENGINE *e);
78 static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
79 static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
80 const BIGNUM *m, BN_CTX *ctx);
81 static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
82 const BIGNUM *q, const BIGNUM *dp,
83 const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
84 static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
85 static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
86 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
88 static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
89 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
90 BN_CTX *ctx, BN_MONT_CTX *in_mont);
91 static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
92 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
95 static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
96 static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
97 DSA_SIG *sig, DSA *dsa);
98 static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
99 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
101 static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
102 static int ubsec_dh_generate_key(DH *dh);
105 static int ubsec_rand_bytes(unsigned char *buf, int num);
106 static int ubsec_rand_status(void);
109 #define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE
110 static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
113 "Specifies the path to the 'ubsec' shared library",
114 ENGINE_CMD_FLAG_STRING},
118 /* Our internal RSA_METHOD that we provide pointers to */
120 static RSA_METHOD ubsec_rsa =
137 /* Our internal DSA_METHOD that we provide pointers to */
138 static DSA_METHOD ubsec_dsa =
141 ubsec_dsa_do_sign, /* dsa_do_sign */
142 NULL, /* dsa_sign_setup */
143 ubsec_dsa_verify, /* dsa_do_verify */
144 NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
145 NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
152 /* Our internal DH_METHOD that we provide pointers to */
153 static DH_METHOD ubsec_dh =
156 ubsec_dh_generate_key,
157 ubsec_dh_compute_key,
165 /* Constants used when creating the ENGINE */
166 static const char *engine_ubsec_id = "ubsec";
167 static const char *engine_ubsec_name = "UBSEC hardware engine support";
169 /* As this is only ever called once, there's no need for locking
170 * (indeed - the lock will already be held by our caller!!!) */
171 ENGINE *ENGINE_ubsec()
173 const RSA_METHOD *meth1;
174 #ifndef HAVE_UBSEC_DH
175 const DH_METHOD *meth3;
176 #endif /* HAVE_UBSEC_DH */
177 ENGINE *ret = ENGINE_new();
180 if(!ENGINE_set_id(ret, engine_ubsec_id) ||
181 !ENGINE_set_name(ret, engine_ubsec_name) ||
182 !ENGINE_set_RSA(ret, &ubsec_rsa) ||
183 !ENGINE_set_DSA(ret, &ubsec_dsa) ||
184 !ENGINE_set_DH(ret, &ubsec_dh) ||
185 !ENGINE_set_BN_mod_exp(ret, ubsec_mod_exp) ||
186 !ENGINE_set_BN_mod_exp_crt(ret, ubsec_mod_exp_crt) ||
187 !ENGINE_set_init_function(ret, ubsec_init) ||
188 !ENGINE_set_finish_function(ret, ubsec_finish) ||
189 !ENGINE_set_ctrl_function(ret, ubsec_ctrl) ||
190 !ENGINE_set_cmd_defns(ret, ubsec_cmd_defns))
196 /* We know that the "PKCS1_SSLeay()" functions hook properly
197 * to the Broadcom-specific mod_exp and mod_exp_crt so we use
198 * those functions. NB: We don't use ENGINE_openssl() or
199 * anything "more generic" because something like the RSAref
200 * code may not hook properly, and if you own one of these
201 * cards then you have the right to do RSA operations on it
203 meth1 = RSA_PKCS1_SSLeay();
204 ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
205 ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
206 ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
207 ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
209 #ifndef HAVE_UBSEC_DH
210 /* Much the same for Diffie-Hellman */
211 meth3 = DH_OpenSSL();
212 ubsec_dh.generate_key = meth3->generate_key;
213 ubsec_dh.compute_key = meth3->compute_key;
214 #endif /* HAVE_UBSEC_DH */
219 /* This is a process-global DSO handle used for loading and unloading
220 * the UBSEC library. NB: This is only set (or unset) during an
221 * init() or finish() call (reference counts permitting) and they're
222 * operating with global locks, so this should be thread-safe
225 static DSO *ubsec_dso = NULL;
227 /* These are the function pointers that are (un)set when the library has
228 * successfully (un)loaded. */
230 static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
231 static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
232 static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
233 static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
234 static t_UBSEC_diffie_hellman_generate_ioctl
235 *p_UBSEC_diffie_hellman_generate_ioctl = NULL;
236 static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
237 static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
238 static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
239 static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
240 static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
241 static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
242 static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
245 * These are the static string constants for the DSO file name and the function
246 * symbol names to bind to.
249 static const char *UBSEC_LIBNAME = "ubsec";
250 static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
251 static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
252 static const char *UBSEC_F3 = "ubsec_open";
253 static const char *UBSEC_F4 = "ubsec_close";
254 static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
255 static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
256 static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
257 static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
258 static const char *UBSEC_F9 = "dsa_sign_ioctl";
259 static const char *UBSEC_F10 = "dsa_verify_ioctl";
260 static const char *UBSEC_F11 = "math_accelerate_ioctl";
261 static const char *UBSEC_F12 = "rng_ioctl";
263 /* (de)initialisation functions. */
264 static int ubsec_init(ENGINE *e)
266 t_UBSEC_ubsec_bytes_to_bits *p1;
267 t_UBSEC_ubsec_bits_to_bytes *p2;
268 t_UBSEC_ubsec_open *p3;
269 t_UBSEC_ubsec_close *p4;
270 t_UBSEC_diffie_hellman_generate_ioctl *p5;
271 t_UBSEC_diffie_hellman_agree_ioctl *p6;
272 t_UBSEC_rsa_mod_exp_ioctl *p7;
273 t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
274 t_UBSEC_dsa_sign_ioctl *p9;
275 t_UBSEC_dsa_verify_ioctl *p10;
276 t_UBSEC_math_accelerate_ioctl *p11;
277 t_UBSEC_rng_ioctl *p12;
280 if(ubsec_dso != NULL)
282 ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_ALREADY_LOADED);
286 * Attempt to load libubsec.so/ubsec.dll/whatever.
288 ubsec_dso = DSO_load(NULL, UBSEC_LIBNAME, NULL, 0);
289 if(ubsec_dso == NULL)
291 ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_DSO_FAILURE);
296 !(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
297 !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
298 !(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
299 !(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
300 !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *)
301 DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
302 !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *)
303 DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
304 !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
305 !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
306 !(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
307 !(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
308 !(p11 = (t_UBSEC_math_accelerate_ioctl *)
309 DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
310 !(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)))
312 ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_DSO_FAILURE);
316 /* Copy the pointers */
317 p_UBSEC_ubsec_bytes_to_bits = p1;
318 p_UBSEC_ubsec_bits_to_bytes = p2;
319 p_UBSEC_ubsec_open = p3;
320 p_UBSEC_ubsec_close = p4;
321 p_UBSEC_diffie_hellman_generate_ioctl = p5;
322 p_UBSEC_diffie_hellman_agree_ioctl = p6;
323 p_UBSEC_rsa_mod_exp_ioctl = p7;
324 p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
325 p_UBSEC_dsa_sign_ioctl = p9;
326 p_UBSEC_dsa_verify_ioctl = p10;
327 p_UBSEC_math_accelerate_ioctl = p11;
328 p_UBSEC_rng_ioctl = p12;
330 /* Perform an open to see if there's actually any unit running. */
331 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0)
333 p_UBSEC_ubsec_close(fd);
338 ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE);
344 p_UBSEC_ubsec_bytes_to_bits = NULL;
345 p_UBSEC_ubsec_bits_to_bytes = NULL;
346 p_UBSEC_ubsec_open = NULL;
347 p_UBSEC_ubsec_close = NULL;
348 p_UBSEC_diffie_hellman_generate_ioctl = NULL;
349 p_UBSEC_diffie_hellman_agree_ioctl = NULL;
350 p_UBSEC_rsa_mod_exp_ioctl = NULL;
351 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
352 p_UBSEC_dsa_sign_ioctl = NULL;
353 p_UBSEC_dsa_verify_ioctl = NULL;
354 p_UBSEC_math_accelerate_ioctl = NULL;
355 p_UBSEC_rng_ioctl = NULL;
360 static int ubsec_finish(ENGINE *e)
362 if(ubsec_dso == NULL)
364 ENGINEerr(ENGINE_F_UBSEC_FINISH, ENGINE_R_NOT_LOADED);
367 if(!DSO_free(ubsec_dso))
369 ENGINEerr(ENGINE_F_UBSEC_FINISH, ENGINE_R_DSO_FAILURE);
373 p_UBSEC_ubsec_bytes_to_bits = NULL;
374 p_UBSEC_ubsec_bits_to_bytes = NULL;
375 p_UBSEC_ubsec_open = NULL;
376 p_UBSEC_ubsec_close = NULL;
377 p_UBSEC_diffie_hellman_generate_ioctl = NULL;
378 p_UBSEC_diffie_hellman_agree_ioctl = NULL;
379 p_UBSEC_rsa_mod_exp_ioctl = NULL;
380 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
381 p_UBSEC_dsa_sign_ioctl = NULL;
382 p_UBSEC_dsa_verify_ioctl = NULL;
383 p_UBSEC_math_accelerate_ioctl = NULL;
384 p_UBSEC_rng_ioctl = NULL;
388 static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
390 int initialised = ((ubsec_dso == NULL) ? 0 : 1);
393 case UBSEC_CMD_SO_PATH:
396 ENGINEerr(ENGINE_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER);
401 ENGINEerr(ENGINE_F_UBSEC_CTRL,ENGINE_R_ALREADY_LOADED);
404 UBSEC_LIBNAME = (const char *)p;
409 ENGINEerr(ENGINE_F_UBSEC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
413 static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
414 const BIGNUM *m, BN_CTX *ctx)
419 if(ubsec_dso == NULL)
421 ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_NOT_LOADED);
425 /* Check if hardware can't handle this argument. */
426 y_len = BN_num_bits(m);
428 ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
432 if(!bn_wexpand(r, m->top))
434 ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_BN_EXPAND_FAIL);
437 memset(r->d, 0, BN_num_bytes(m));
439 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
441 ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE);
445 if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
446 (unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d,
447 BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
449 ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_REQUEST_FAILED);
453 p_UBSEC_ubsec_close(fd);
455 r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2;
459 static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
464 if((ctx = BN_CTX_new()) == NULL)
467 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
469 ENGINEerr(ENGINE_F_UBSEC_RSA_MOD_EXP, ENGINE_R_MISSING_KEY_COMPONENTS);
474 * Do in software if argument is too large for hardware.
476 if ((BN_num_bits(rsa->p)+BN_num_bits(rsa->q)) > 1024) {
477 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
478 to_return = (*meth->rsa_mod_exp)(r0, I, rsa);
480 to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
481 rsa->dmq1, rsa->iqmp, ctx);
489 static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
490 const BIGNUM *q, const BIGNUM *dp,
491 const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx)
497 m_len = BN_num_bytes(p) + BN_num_bytes(q) + 1;
498 y_len = BN_num_bits(p) + BN_num_bits(q);
500 /* Check if hardware can't handle this argument. */
502 ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
506 if (!bn_wexpand(r, p->top + q->top + 1)) {
507 ENGINEerr(ENGINE_F_UBSEC_RSA_MOD_EXP_CRT, ENGINE_R_BN_EXPAND_FAIL);
511 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
513 ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE);
517 if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
518 (unsigned char *)a->d, BN_num_bits(a),
519 (unsigned char *)qinv->d, BN_num_bits(qinv),
520 (unsigned char *)dp->d, BN_num_bits(dp),
521 (unsigned char *)p->d, BN_num_bits(p),
522 (unsigned char *)dq->d, BN_num_bits(dq),
523 (unsigned char *)q->d, BN_num_bits(q),
524 (unsigned char *)r->d, &y_len) != 0) {
525 ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_REQUEST_FAILED);
529 p_UBSEC_ubsec_close(fd);
531 r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2;
536 static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
537 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
538 BN_CTX *ctx, BN_MONT_CTX *in_mont)
544 /* let rr = a1 ^ p1 mod m */
545 if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end;
546 /* let t = a2 ^ p2 mod m */
547 if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end;
548 /* let rr = rr * t mod m */
549 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
556 static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
557 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
560 return ubsec_mod_exp(r, a, p, m, ctx);
565 * This function is aliased to mod_exp (with the mont stuff dropped).
567 static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
568 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
572 /* Do in software if the key is too large for the hardware. */
573 if (BN_num_bits(m) > 1024) {
574 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
575 ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
577 ret = ubsec_mod_exp(r, a, p, m, ctx);
583 /* This function is aliased to mod_exp (with the dh and mont dropped). */
584 static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
585 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
588 return ubsec_mod_exp(r, a, p, m, ctx);
591 static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
593 DSA_SIG *to_return = NULL;
594 int s_len = 160, r_len = 160, d_len, fd;
595 BIGNUM m, *r=NULL, *s=NULL;
601 if ((s == NULL) || (r==NULL))
604 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);
606 if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
607 (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
608 ENGINEerr(ENGINE_F_UBSEC_DSA_SIGN, ENGINE_R_BN_EXPAND_FAIL);
612 if (BN_bin2bn(dgst,dlen,&m) == NULL) {
613 ENGINEerr(ENGINE_F_UBSEC_DSA_SIGN, ENGINE_R_BN_EXPAND_FAIL);
617 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
619 ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE);
623 if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
624 (unsigned char *)dgst, d_len,
625 NULL, 0, /* compute random value */
626 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
627 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
628 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
629 (unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
630 (unsigned char *)r->d, &r_len,
631 (unsigned char *)s->d, &s_len ) != 0) {
632 ENGINEerr(ENGINE_F_UBSEC_DSA_SIGN, ENGINE_R_REQUEST_FAILED);
636 p_UBSEC_ubsec_close(fd);
638 r->top = (160+BN_BITS2-1)/BN_BITS2;
639 s->top = (160+BN_BITS2-1)/BN_BITS2;
641 to_return = DSA_SIG_new();
642 if(to_return == NULL) {
643 ENGINEerr(ENGINE_F_UBSEC_DSA_SIGN, ENGINE_R_BN_EXPAND_FAIL);
659 static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
660 DSA_SIG *sig, DSA *dsa)
669 if(!bn_wexpand(&v, dsa->p->top)) {
670 ENGINEerr(ENGINE_F_UBSEC_DSA_VERIFY ,ENGINE_R_BN_EXPAND_FAIL);
674 v_len = BN_num_bits(dsa->p);
676 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
678 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
680 ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE);
684 if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
685 (unsigned char *)dgst, d_len,
686 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
687 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
688 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
689 (unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key),
690 (unsigned char *)sig->r->d, BN_num_bits(sig->r),
691 (unsigned char *)sig->s->d, BN_num_bits(sig->s),
692 (unsigned char *)v.d, &v_len) != 0) {
693 ENGINEerr(ENGINE_F_UBSEC_DSA_VERIFY , ENGINE_R_REQUEST_FAILED);
697 p_UBSEC_ubsec_close(fd);
705 static int ubsec_dh_compute_key (unsigned char *key,const BIGNUM *pub_key,DH *dh)
710 static int ubsec_dh_generate_key (DH *dh)
716 static int ubsec_rand_bytes(unsigned char *buf, int num)
721 static int ubsec_rand_status(void)
727 #endif /* !OPENSSL_NO_HW_UBSEC */
728 #endif /* !OPENSSL_NO_HW */