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-2001 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).
63
#include <openssl/crypto.h>
64
#include <openssl/buffer.h>
65
#include <openssl/dso.h>
66
#include <openssl/engine.h>
67
#ifndef OPENSSL_NO_RSA
68
#include <openssl/rsa.h>
70
#ifndef OPENSSL_NO_DSA
71
#include <openssl/dsa.h>
74
#include <openssl/dh.h>
76
#include <openssl/bn.h>
79
#ifndef OPENSSL_NO_HW_UBSEC
84
#include "vendor_defns/hw_ubsec.h"
87
#define UBSEC_LIB_NAME "ubsec engine"
88
#include "e_ubsec_err.c"
90
#define FAIL_TO_SOFTWARE -15
92
static int ubsec_destroy(ENGINE *e);
93
static int ubsec_init(ENGINE *e);
94
static int ubsec_finish(ENGINE *e);
95
static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
96
static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
97
const BIGNUM *m, BN_CTX *ctx);
98
static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
99
const BIGNUM *q, const BIGNUM *dp,
100
const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
101
#ifndef OPENSSL_NO_RSA
102
static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
104
static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
105
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
106
#ifndef OPENSSL_NO_DSA
108
static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
109
BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
110
BN_CTX *ctx, BN_MONT_CTX *in_mont);
111
static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
112
const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
115
static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
116
static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
117
DSA_SIG *sig, DSA *dsa);
119
#ifndef OPENSSL_NO_DH
120
static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
121
const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
123
static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
124
static int ubsec_dh_generate_key(DH *dh);
128
static int ubsec_rand_bytes(unsigned char *buf, int num);
129
static int ubsec_rand_status(void);
132
#define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE
133
static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
136
"Specifies the path to the 'ubsec' shared library",
137
ENGINE_CMD_FLAG_STRING},
141
#ifndef OPENSSL_NO_RSA
142
/* Our internal RSA_METHOD that we provide pointers to */
143
static RSA_METHOD ubsec_rsa =
162
#ifndef OPENSSL_NO_DSA
163
/* Our internal DSA_METHOD that we provide pointers to */
164
static DSA_METHOD ubsec_dsa =
167
ubsec_dsa_do_sign, /* dsa_do_sign */
168
NULL, /* dsa_sign_setup */
169
ubsec_dsa_verify, /* dsa_do_verify */
170
NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
171
NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
176
NULL, /* dsa_paramgen */
177
NULL /* dsa_keygen */
181
#ifndef OPENSSL_NO_DH
182
/* Our internal DH_METHOD that we provide pointers to */
183
static DH_METHOD ubsec_dh =
186
ubsec_dh_generate_key,
187
ubsec_dh_compute_key,
197
/* Constants used when creating the ENGINE */
198
static const char *engine_ubsec_id = "ubsec";
199
static const char *engine_ubsec_name = "UBSEC hardware engine support";
201
/* This internal function is used by ENGINE_ubsec() and possibly by the
202
* "dynamic" ENGINE support too */
203
static int bind_helper(ENGINE *e)
205
#ifndef OPENSSL_NO_RSA
206
const RSA_METHOD *meth1;
208
#ifndef OPENSSL_NO_DH
209
#ifndef HAVE_UBSEC_DH
210
const DH_METHOD *meth3;
211
#endif /* HAVE_UBSEC_DH */
213
if(!ENGINE_set_id(e, engine_ubsec_id) ||
214
!ENGINE_set_name(e, engine_ubsec_name) ||
215
#ifndef OPENSSL_NO_RSA
216
!ENGINE_set_RSA(e, &ubsec_rsa) ||
218
#ifndef OPENSSL_NO_DSA
219
!ENGINE_set_DSA(e, &ubsec_dsa) ||
221
#ifndef OPENSSL_NO_DH
222
!ENGINE_set_DH(e, &ubsec_dh) ||
224
!ENGINE_set_destroy_function(e, ubsec_destroy) ||
225
!ENGINE_set_init_function(e, ubsec_init) ||
226
!ENGINE_set_finish_function(e, ubsec_finish) ||
227
!ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
228
!ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
231
#ifndef OPENSSL_NO_RSA
232
/* We know that the "PKCS1_SSLeay()" functions hook properly
233
* to the Broadcom-specific mod_exp and mod_exp_crt so we use
234
* those functions. NB: We don't use ENGINE_openssl() or
235
* anything "more generic" because something like the RSAref
236
* code may not hook properly, and if you own one of these
237
* cards then you have the right to do RSA operations on it
239
meth1 = RSA_PKCS1_SSLeay();
240
ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
241
ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
242
ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
243
ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
246
#ifndef OPENSSL_NO_DH
247
#ifndef HAVE_UBSEC_DH
248
/* Much the same for Diffie-Hellman */
249
meth3 = DH_OpenSSL();
250
ubsec_dh.generate_key = meth3->generate_key;
251
ubsec_dh.compute_key = meth3->compute_key;
252
#endif /* HAVE_UBSEC_DH */
255
/* Ensure the ubsec error handling is set up */
256
ERR_load_UBSEC_strings();
260
#ifdef OPENSSL_NO_DYNAMIC_ENGINE
261
static ENGINE *engine_ubsec(void)
263
ENGINE *ret = ENGINE_new();
266
if(!bind_helper(ret))
274
void ENGINE_load_ubsec(void)
276
/* Copied from eng_[openssl|dyn].c */
277
ENGINE *toadd = engine_ubsec();
285
/* This is a process-global DSO handle used for loading and unloading
286
* the UBSEC library. NB: This is only set (or unset) during an
287
* init() or finish() call (reference counts permitting) and they're
288
* operating with global locks, so this should be thread-safe
291
static DSO *ubsec_dso = NULL;
293
/* These are the function pointers that are (un)set when the library has
294
* successfully (un)loaded. */
296
static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
297
static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
298
static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
299
static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
300
#ifndef OPENSSL_NO_DH
301
static t_UBSEC_diffie_hellman_generate_ioctl
302
*p_UBSEC_diffie_hellman_generate_ioctl = NULL;
303
static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
305
/* #ifndef OPENSSL_NO_RSA */
306
static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
307
static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
309
#ifndef OPENSSL_NO_DSA
310
static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
311
static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
313
static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
314
static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
315
static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
317
static int max_key_len = 1024; /* ??? */
320
* These are the static string constants for the DSO file name and the function
321
* symbol names to bind to.
324
static const char *UBSEC_LIBNAME = NULL;
325
static const char *get_UBSEC_LIBNAME(void)
328
return UBSEC_LIBNAME;
331
static void free_UBSEC_LIBNAME(void)
334
OPENSSL_free((void*)UBSEC_LIBNAME);
335
UBSEC_LIBNAME = NULL;
337
static long set_UBSEC_LIBNAME(const char *name)
339
free_UBSEC_LIBNAME();
340
return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
342
static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
343
static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
344
static const char *UBSEC_F3 = "ubsec_open";
345
static const char *UBSEC_F4 = "ubsec_close";
346
#ifndef OPENSSL_NO_DH
347
static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
348
static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
350
/* #ifndef OPENSSL_NO_RSA */
351
static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
352
static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
354
#ifndef OPENSSL_NO_DSA
355
static const char *UBSEC_F9 = "dsa_sign_ioctl";
356
static const char *UBSEC_F10 = "dsa_verify_ioctl";
358
static const char *UBSEC_F11 = "math_accelerate_ioctl";
359
static const char *UBSEC_F12 = "rng_ioctl";
360
static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
362
/* Destructor (complements the "ENGINE_ubsec()" constructor) */
363
static int ubsec_destroy(ENGINE *e)
365
free_UBSEC_LIBNAME();
366
ERR_unload_UBSEC_strings();
370
/* (de)initialisation functions. */
371
static int ubsec_init(ENGINE *e)
373
t_UBSEC_ubsec_bytes_to_bits *p1;
374
t_UBSEC_ubsec_bits_to_bytes *p2;
375
t_UBSEC_ubsec_open *p3;
376
t_UBSEC_ubsec_close *p4;
377
#ifndef OPENSSL_NO_DH
378
t_UBSEC_diffie_hellman_generate_ioctl *p5;
379
t_UBSEC_diffie_hellman_agree_ioctl *p6;
381
/* #ifndef OPENSSL_NO_RSA */
382
t_UBSEC_rsa_mod_exp_ioctl *p7;
383
t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
385
#ifndef OPENSSL_NO_DSA
386
t_UBSEC_dsa_sign_ioctl *p9;
387
t_UBSEC_dsa_verify_ioctl *p10;
389
t_UBSEC_math_accelerate_ioctl *p11;
390
t_UBSEC_rng_ioctl *p12;
391
t_UBSEC_max_key_len_ioctl *p13;
394
if(ubsec_dso != NULL)
396
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED);
400
* Attempt to load libubsec.so/ubsec.dll/whatever.
402
ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0);
403
if(ubsec_dso == NULL)
405
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
410
!(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
411
!(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
412
!(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
413
!(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
414
#ifndef OPENSSL_NO_DH
415
!(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *)
416
DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
417
!(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *)
418
DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
420
/* #ifndef OPENSSL_NO_RSA */
421
!(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
422
!(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
424
#ifndef OPENSSL_NO_DSA
425
!(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
426
!(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
428
!(p11 = (t_UBSEC_math_accelerate_ioctl *)
429
DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
430
!(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
431
!(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
433
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
437
/* Copy the pointers */
438
p_UBSEC_ubsec_bytes_to_bits = p1;
439
p_UBSEC_ubsec_bits_to_bytes = p2;
440
p_UBSEC_ubsec_open = p3;
441
p_UBSEC_ubsec_close = p4;
442
#ifndef OPENSSL_NO_DH
443
p_UBSEC_diffie_hellman_generate_ioctl = p5;
444
p_UBSEC_diffie_hellman_agree_ioctl = p6;
446
#ifndef OPENSSL_NO_RSA
447
p_UBSEC_rsa_mod_exp_ioctl = p7;
448
p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
450
#ifndef OPENSSL_NO_DSA
451
p_UBSEC_dsa_sign_ioctl = p9;
452
p_UBSEC_dsa_verify_ioctl = p10;
454
p_UBSEC_math_accelerate_ioctl = p11;
455
p_UBSEC_rng_ioctl = p12;
456
p_UBSEC_max_key_len_ioctl = p13;
458
/* Perform an open to see if there's actually any unit running. */
459
if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
461
p_UBSEC_ubsec_close(fd);
466
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
473
p_UBSEC_ubsec_bytes_to_bits = NULL;
474
p_UBSEC_ubsec_bits_to_bytes = NULL;
475
p_UBSEC_ubsec_open = NULL;
476
p_UBSEC_ubsec_close = NULL;
477
#ifndef OPENSSL_NO_DH
478
p_UBSEC_diffie_hellman_generate_ioctl = NULL;
479
p_UBSEC_diffie_hellman_agree_ioctl = NULL;
481
#ifndef OPENSSL_NO_RSA
482
p_UBSEC_rsa_mod_exp_ioctl = NULL;
483
p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
485
#ifndef OPENSSL_NO_DSA
486
p_UBSEC_dsa_sign_ioctl = NULL;
487
p_UBSEC_dsa_verify_ioctl = NULL;
489
p_UBSEC_math_accelerate_ioctl = NULL;
490
p_UBSEC_rng_ioctl = NULL;
491
p_UBSEC_max_key_len_ioctl = NULL;
496
static int ubsec_finish(ENGINE *e)
498
free_UBSEC_LIBNAME();
499
if(ubsec_dso == NULL)
501
UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED);
504
if(!DSO_free(ubsec_dso))
506
UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE);
510
p_UBSEC_ubsec_bytes_to_bits = NULL;
511
p_UBSEC_ubsec_bits_to_bytes = NULL;
512
p_UBSEC_ubsec_open = NULL;
513
p_UBSEC_ubsec_close = NULL;
514
#ifndef OPENSSL_NO_DH
515
p_UBSEC_diffie_hellman_generate_ioctl = NULL;
516
p_UBSEC_diffie_hellman_agree_ioctl = NULL;
518
#ifndef OPENSSL_NO_RSA
519
p_UBSEC_rsa_mod_exp_ioctl = NULL;
520
p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
522
#ifndef OPENSSL_NO_DSA
523
p_UBSEC_dsa_sign_ioctl = NULL;
524
p_UBSEC_dsa_verify_ioctl = NULL;
526
p_UBSEC_math_accelerate_ioctl = NULL;
527
p_UBSEC_rng_ioctl = NULL;
528
p_UBSEC_max_key_len_ioctl = NULL;
532
static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
534
int initialised = ((ubsec_dso == NULL) ? 0 : 1);
537
case UBSEC_CMD_SO_PATH:
540
UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER);
545
UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED);
548
return set_UBSEC_LIBNAME((const char *)p);
552
UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED);
556
static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
557
const BIGNUM *m, BN_CTX *ctx)
562
if(ubsec_dso == NULL)
564
UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED);
568
/* Check if hardware can't handle this argument. */
569
y_len = BN_num_bits(m);
570
if (y_len > max_key_len) {
571
UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
572
return BN_mod_exp(r, a, p, m, ctx);
575
if(!bn_wexpand(r, m->top))
577
UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL);
581
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
583
UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE);
584
return BN_mod_exp(r, a, p, m, ctx);
587
if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
588
(unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d,
589
BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
591
UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
592
p_UBSEC_ubsec_close(fd);
594
return BN_mod_exp(r, a, p, m, ctx);
597
p_UBSEC_ubsec_close(fd);
599
r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2;
603
#ifndef OPENSSL_NO_RSA
604
static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
608
if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
610
UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS);
614
to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
615
rsa->dmq1, rsa->iqmp, ctx);
616
if (to_return == FAIL_TO_SOFTWARE)
619
* Do in software as hardware failed.
621
const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
622
to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
629
static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
630
const BIGNUM *q, const BIGNUM *dp,
631
const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx)
637
m_len = BN_num_bytes(p) + BN_num_bytes(q) + 1;
638
y_len = BN_num_bits(p) + BN_num_bits(q);
640
/* Check if hardware can't handle this argument. */
641
if (y_len > max_key_len) {
642
UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
643
return FAIL_TO_SOFTWARE;
646
if (!bn_wexpand(r, p->top + q->top + 1)) {
647
UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL);
651
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
653
UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE);
654
return FAIL_TO_SOFTWARE;
657
if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
658
(unsigned char *)a->d, BN_num_bits(a),
659
(unsigned char *)qinv->d, BN_num_bits(qinv),
660
(unsigned char *)dp->d, BN_num_bits(dp),
661
(unsigned char *)p->d, BN_num_bits(p),
662
(unsigned char *)dq->d, BN_num_bits(dq),
663
(unsigned char *)q->d, BN_num_bits(q),
664
(unsigned char *)r->d, &y_len) != 0) {
665
UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED);
666
p_UBSEC_ubsec_close(fd);
667
return FAIL_TO_SOFTWARE;
670
p_UBSEC_ubsec_close(fd);
672
r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2;
676
#ifndef OPENSSL_NO_DSA
678
static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
679
BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
680
BN_CTX *ctx, BN_MONT_CTX *in_mont)
686
/* let rr = a1 ^ p1 mod m */
687
if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end;
688
/* let t = a2 ^ p2 mod m */
689
if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end;
690
/* let rr = rr * t mod m */
691
if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
698
static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
699
const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
702
return ubsec_mod_exp(r, a, p, m, ctx);
708
* This function is aliased to mod_exp (with the mont stuff dropped).
710
static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
711
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
715
#ifndef OPENSSL_NO_RSA
716
/* Do in software if the key is too large for the hardware. */
717
if (BN_num_bits(m) > max_key_len)
719
const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
720
ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
725
ret = ubsec_mod_exp(r, a, p, m, ctx);
731
#ifndef OPENSSL_NO_DH
732
/* This function is aliased to mod_exp (with the dh and mont dropped). */
733
static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
734
const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
737
return ubsec_mod_exp(r, a, p, m, ctx);
741
#ifndef OPENSSL_NO_DSA
742
static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
744
DSA_SIG *to_return = NULL;
745
int s_len = 160, r_len = 160, d_len, fd;
746
BIGNUM m, *r=NULL, *s=NULL;
752
if ((s == NULL) || (r==NULL))
755
d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);
757
if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
758
(!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
759
UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
763
if (BN_bin2bn(dgst,dlen,&m) == NULL) {
764
UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
768
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
769
const DSA_METHOD *meth;
771
UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE);
772
meth = DSA_OpenSSL();
773
to_return = meth->dsa_do_sign(dgst, dlen, dsa);
777
if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
778
(unsigned char *)dgst, d_len,
779
NULL, 0, /* compute random value */
780
(unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
781
(unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
782
(unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
783
(unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
784
(unsigned char *)r->d, &r_len,
785
(unsigned char *)s->d, &s_len ) != 0) {
786
const DSA_METHOD *meth;
788
UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED);
789
p_UBSEC_ubsec_close(fd);
790
meth = DSA_OpenSSL();
791
to_return = meth->dsa_do_sign(dgst, dlen, dsa);
796
p_UBSEC_ubsec_close(fd);
798
r->top = (160+BN_BITS2-1)/BN_BITS2;
799
s->top = (160+BN_BITS2-1)/BN_BITS2;
801
to_return = DSA_SIG_new();
802
if(to_return == NULL) {
803
UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
819
static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
820
DSA_SIG *sig, DSA *dsa)
829
if(!bn_wexpand(&v, dsa->p->top)) {
830
UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL);
834
v_len = BN_num_bits(dsa->p);
836
d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
838
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
839
const DSA_METHOD *meth;
841
UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE);
842
meth = DSA_OpenSSL();
843
to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
847
if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
848
(unsigned char *)dgst, d_len,
849
(unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
850
(unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
851
(unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
852
(unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key),
853
(unsigned char *)sig->r->d, BN_num_bits(sig->r),
854
(unsigned char *)sig->s->d, BN_num_bits(sig->s),
855
(unsigned char *)v.d, &v_len) != 0) {
856
const DSA_METHOD *meth;
857
UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED);
858
p_UBSEC_ubsec_close(fd);
860
meth = DSA_OpenSSL();
861
to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
866
p_UBSEC_ubsec_close(fd);
875
#ifndef OPENSSL_NO_DH
876
static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh)
882
k_len = BN_num_bits(dh->p);
884
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
886
const DH_METHOD *meth;
887
UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE);
889
ret = meth->compute_key(key, pub_key, dh);
893
if (p_UBSEC_diffie_hellman_agree_ioctl(fd,
894
(unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key),
895
(unsigned char *)pub_key->d, BN_num_bits(pub_key),
896
(unsigned char *)dh->p->d, BN_num_bits(dh->p),
899
/* Hardware's a no go, failover to software */
900
const DH_METHOD *meth;
901
UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
902
p_UBSEC_ubsec_close(fd);
905
ret = meth->compute_key(key, pub_key, dh);
910
p_UBSEC_ubsec_close(fd);
912
ret = p_UBSEC_ubsec_bits_to_bytes(k_len);
917
static int ubsec_dh_generate_key(DH *dh)
924
BIGNUM *pub_key = NULL;
925
BIGNUM *priv_key = NULL;
928
* How many bits should Random x be? dh_key.c
929
* sets the range from 0 to num_bits(modulus) ???
932
if (dh->priv_key == NULL)
935
if (priv_key == NULL) goto err;
936
priv_key_len = BN_num_bits(dh->p);
937
bn_wexpand(priv_key, dh->p->top);
939
if (!BN_rand_range(priv_key, dh->p)) goto err;
940
while (BN_is_zero(priv_key));
941
random_bits = BN_num_bits(priv_key);
945
priv_key = dh->priv_key;
948
if (dh->pub_key == NULL)
951
pub_key_len = BN_num_bits(dh->p);
952
bn_wexpand(pub_key, dh->p->top);
953
if(pub_key == NULL) goto err;
957
pub_key = dh->pub_key;
960
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
962
const DH_METHOD *meth;
963
UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE);
965
ret = meth->generate_key(dh);
969
if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
970
(unsigned char *)priv_key->d, &priv_key_len,
971
(unsigned char *)pub_key->d, &pub_key_len,
972
(unsigned char *)dh->g->d, BN_num_bits(dh->g),
973
(unsigned char *)dh->p->d, BN_num_bits(dh->p),
974
0, 0, random_bits) != 0)
976
/* Hardware's a no go, failover to software */
977
const DH_METHOD *meth;
979
UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED);
980
p_UBSEC_ubsec_close(fd);
983
ret = meth->generate_key(dh);
988
p_UBSEC_ubsec_close(fd);
990
dh->pub_key = pub_key;
991
dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
992
dh->priv_key = priv_key;
993
dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;
1002
static int ubsec_rand_bytes(unsigned char * buf,
1008
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
1010
const RAND_METHOD *meth;
1011
UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE);
1012
num = p_UBSEC_ubsec_bits_to_bytes(num);
1013
meth = RAND_SSLeay();
1014
meth->seed(buf, num);
1015
ret = meth->bytes(buf, num);
1019
num *= 8; /* bytes to bits */
1021
if (p_UBSEC_rng_ioctl(fd,
1026
/* Hardware's a no go, failover to software */
1027
const RAND_METHOD *meth;
1029
UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED);
1030
p_UBSEC_ubsec_close(fd);
1032
num = p_UBSEC_ubsec_bits_to_bytes(num);
1033
meth = RAND_SSLeay();
1034
meth->seed(buf, num);
1035
ret = meth->bytes(buf, num);
1040
p_UBSEC_ubsec_close(fd);
1048
static int ubsec_rand_status(void)
1054
/* This stuff is needed if this ENGINE is being compiled into a self-contained
1055
* shared-library. */
1056
#ifndef OPENSSL_NO_DYNAMIC_ENGINE
1057
static int bind_fn(ENGINE *e, const char *id)
1059
if(id && (strcmp(id, engine_ubsec_id) != 0))
1065
IMPLEMENT_DYNAMIC_CHECK_FN()
1066
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1067
#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
1069
#endif /* !OPENSSL_NO_HW_UBSEC */
1070
#endif /* !OPENSSL_NO_HW */