e_ubsec.c revision 215697
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 61#include <stdio.h> 62#include <string.h> 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> 69#endif 70#ifndef OPENSSL_NO_DSA 71#include <openssl/dsa.h> 72#endif 73#ifndef OPENSSL_NO_DH 74#include <openssl/dh.h> 75#endif 76#include <openssl/bn.h> 77 78#ifndef OPENSSL_NO_HW 79#ifndef OPENSSL_NO_HW_UBSEC 80 81#ifdef FLAT_INC 82#include "hw_ubsec.h" 83#else 84#include "vendor_defns/hw_ubsec.h" 85#endif 86 87#define UBSEC_LIB_NAME "ubsec engine" 88#include "e_ubsec_err.c" 89 90#define FAIL_TO_SOFTWARE -15 91 92static int ubsec_destroy(ENGINE *e); 93static int ubsec_init(ENGINE *e); 94static int ubsec_finish(ENGINE *e); 95static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 96static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 97 const BIGNUM *m, BN_CTX *ctx); 98static 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 102static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); 103#endif 104static 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 107#ifdef NOT_USED 108static 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); 111static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 112 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 113 BN_MONT_CTX *m_ctx); 114#endif 115static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); 116static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, 117 DSA_SIG *sig, DSA *dsa); 118#endif 119#ifndef OPENSSL_NO_DH 120static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 121 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 122 BN_MONT_CTX *m_ctx); 123static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh); 124static int ubsec_dh_generate_key(DH *dh); 125#endif 126 127#ifdef NOT_USED 128static int ubsec_rand_bytes(unsigned char *buf, int num); 129static int ubsec_rand_status(void); 130#endif 131 132#define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE 133static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = { 134 {UBSEC_CMD_SO_PATH, 135 "SO_PATH", 136 "Specifies the path to the 'ubsec' shared library", 137 ENGINE_CMD_FLAG_STRING}, 138 {0, NULL, NULL, 0} 139 }; 140 141#ifndef OPENSSL_NO_RSA 142/* Our internal RSA_METHOD that we provide pointers to */ 143static RSA_METHOD ubsec_rsa = 144 { 145 "UBSEC RSA method", 146 NULL, 147 NULL, 148 NULL, 149 NULL, 150 ubsec_rsa_mod_exp, 151 ubsec_mod_exp_mont, 152 NULL, 153 NULL, 154 0, 155 NULL, 156 NULL, 157 NULL, 158 NULL 159 }; 160#endif 161 162#ifndef OPENSSL_NO_DSA 163/* Our internal DSA_METHOD that we provide pointers to */ 164static DSA_METHOD ubsec_dsa = 165 { 166 "UBSEC DSA method", 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 */ 172 NULL, /* init */ 173 NULL, /* finish */ 174 0, /* flags */ 175 NULL, /* app_data */ 176 NULL, /* dsa_paramgen */ 177 NULL /* dsa_keygen */ 178 }; 179#endif 180 181#ifndef OPENSSL_NO_DH 182/* Our internal DH_METHOD that we provide pointers to */ 183static DH_METHOD ubsec_dh = 184 { 185 "UBSEC DH method", 186 ubsec_dh_generate_key, 187 ubsec_dh_compute_key, 188 ubsec_mod_exp_dh, 189 NULL, 190 NULL, 191 0, 192 NULL, 193 NULL 194 }; 195#endif 196 197/* Constants used when creating the ENGINE */ 198static const char *engine_ubsec_id = "ubsec"; 199static const char *engine_ubsec_name = "UBSEC hardware engine support"; 200 201/* This internal function is used by ENGINE_ubsec() and possibly by the 202 * "dynamic" ENGINE support too */ 203static int bind_helper(ENGINE *e) 204 { 205#ifndef OPENSSL_NO_RSA 206 const RSA_METHOD *meth1; 207#endif 208#ifndef OPENSSL_NO_DH 209#ifndef HAVE_UBSEC_DH 210 const DH_METHOD *meth3; 211#endif /* HAVE_UBSEC_DH */ 212#endif 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) || 217#endif 218#ifndef OPENSSL_NO_DSA 219 !ENGINE_set_DSA(e, &ubsec_dsa) || 220#endif 221#ifndef OPENSSL_NO_DH 222 !ENGINE_set_DH(e, &ubsec_dh) || 223#endif 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)) 229 return 0; 230 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 238 * anyway! */ 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; 244#endif 245 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 */ 253#endif 254 255 /* Ensure the ubsec error handling is set up */ 256 ERR_load_UBSEC_strings(); 257 return 1; 258 } 259 260#ifdef OPENSSL_NO_DYNAMIC_ENGINE 261static ENGINE *engine_ubsec(void) 262 { 263 ENGINE *ret = ENGINE_new(); 264 if(!ret) 265 return NULL; 266 if(!bind_helper(ret)) 267 { 268 ENGINE_free(ret); 269 return NULL; 270 } 271 return ret; 272 } 273 274void ENGINE_load_ubsec(void) 275 { 276 /* Copied from eng_[openssl|dyn].c */ 277 ENGINE *toadd = engine_ubsec(); 278 if(!toadd) return; 279 ENGINE_add(toadd); 280 ENGINE_free(toadd); 281 ERR_clear_error(); 282 } 283#endif 284 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 289 * implicitly. */ 290 291static DSO *ubsec_dso = NULL; 292 293/* These are the function pointers that are (un)set when the library has 294 * successfully (un)loaded. */ 295 296static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL; 297static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL; 298static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL; 299static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL; 300#ifndef OPENSSL_NO_DH 301static t_UBSEC_diffie_hellman_generate_ioctl 302 *p_UBSEC_diffie_hellman_generate_ioctl = NULL; 303static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL; 304#endif 305/* #ifndef OPENSSL_NO_RSA */ 306static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL; 307static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 308/* #endif */ 309#ifndef OPENSSL_NO_DSA 310static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL; 311static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL; 312#endif 313static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL; 314static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL; 315static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL; 316 317static int max_key_len = 1024; /* ??? */ 318 319/* 320 * These are the static string constants for the DSO file name and the function 321 * symbol names to bind to. 322 */ 323 324static const char *UBSEC_LIBNAME = NULL; 325static const char *get_UBSEC_LIBNAME(void) 326 { 327 if(UBSEC_LIBNAME) 328 return UBSEC_LIBNAME; 329 return "ubsec"; 330 } 331static void free_UBSEC_LIBNAME(void) 332 { 333 if(UBSEC_LIBNAME) 334 OPENSSL_free((void*)UBSEC_LIBNAME); 335 UBSEC_LIBNAME = NULL; 336 } 337static long set_UBSEC_LIBNAME(const char *name) 338 { 339 free_UBSEC_LIBNAME(); 340 return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); 341 } 342static const char *UBSEC_F1 = "ubsec_bytes_to_bits"; 343static const char *UBSEC_F2 = "ubsec_bits_to_bytes"; 344static const char *UBSEC_F3 = "ubsec_open"; 345static const char *UBSEC_F4 = "ubsec_close"; 346#ifndef OPENSSL_NO_DH 347static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl"; 348static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl"; 349#endif 350/* #ifndef OPENSSL_NO_RSA */ 351static const char *UBSEC_F7 = "rsa_mod_exp_ioctl"; 352static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl"; 353/* #endif */ 354#ifndef OPENSSL_NO_DSA 355static const char *UBSEC_F9 = "dsa_sign_ioctl"; 356static const char *UBSEC_F10 = "dsa_verify_ioctl"; 357#endif 358static const char *UBSEC_F11 = "math_accelerate_ioctl"; 359static const char *UBSEC_F12 = "rng_ioctl"; 360static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl"; 361 362/* Destructor (complements the "ENGINE_ubsec()" constructor) */ 363static int ubsec_destroy(ENGINE *e) 364 { 365 free_UBSEC_LIBNAME(); 366 ERR_unload_UBSEC_strings(); 367 return 1; 368 } 369 370/* (de)initialisation functions. */ 371static int ubsec_init(ENGINE *e) 372 { 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; 380#endif 381/* #ifndef OPENSSL_NO_RSA */ 382 t_UBSEC_rsa_mod_exp_ioctl *p7; 383 t_UBSEC_rsa_mod_exp_crt_ioctl *p8; 384/* #endif */ 385#ifndef OPENSSL_NO_DSA 386 t_UBSEC_dsa_sign_ioctl *p9; 387 t_UBSEC_dsa_verify_ioctl *p10; 388#endif 389 t_UBSEC_math_accelerate_ioctl *p11; 390 t_UBSEC_rng_ioctl *p12; 391 t_UBSEC_max_key_len_ioctl *p13; 392 int fd = 0; 393 394 if(ubsec_dso != NULL) 395 { 396 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED); 397 goto err; 398 } 399 /* 400 * Attempt to load libubsec.so/ubsec.dll/whatever. 401 */ 402 ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0); 403 if(ubsec_dso == NULL) 404 { 405 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); 406 goto err; 407 } 408 409 if ( 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)) || 419#endif 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)) || 423/* #endif */ 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)) || 427#endif 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))) 432 { 433 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); 434 goto err; 435 } 436 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; 445#endif 446#ifndef OPENSSL_NO_RSA 447 p_UBSEC_rsa_mod_exp_ioctl = p7; 448 p_UBSEC_rsa_mod_exp_crt_ioctl = p8; 449#endif 450#ifndef OPENSSL_NO_DSA 451 p_UBSEC_dsa_sign_ioctl = p9; 452 p_UBSEC_dsa_verify_ioctl = p10; 453#endif 454 p_UBSEC_math_accelerate_ioctl = p11; 455 p_UBSEC_rng_ioctl = p12; 456 p_UBSEC_max_key_len_ioctl = p13; 457 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)) 460 { 461 p_UBSEC_ubsec_close(fd); 462 return 1; 463 } 464 else 465 { 466 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); 467 } 468 469err: 470 if(ubsec_dso) 471 DSO_free(ubsec_dso); 472 ubsec_dso = NULL; 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; 480#endif 481#ifndef OPENSSL_NO_RSA 482 p_UBSEC_rsa_mod_exp_ioctl = NULL; 483 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 484#endif 485#ifndef OPENSSL_NO_DSA 486 p_UBSEC_dsa_sign_ioctl = NULL; 487 p_UBSEC_dsa_verify_ioctl = NULL; 488#endif 489 p_UBSEC_math_accelerate_ioctl = NULL; 490 p_UBSEC_rng_ioctl = NULL; 491 p_UBSEC_max_key_len_ioctl = NULL; 492 493 return 0; 494 } 495 496static int ubsec_finish(ENGINE *e) 497 { 498 free_UBSEC_LIBNAME(); 499 if(ubsec_dso == NULL) 500 { 501 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED); 502 return 0; 503 } 504 if(!DSO_free(ubsec_dso)) 505 { 506 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE); 507 return 0; 508 } 509 ubsec_dso = NULL; 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; 517#endif 518#ifndef OPENSSL_NO_RSA 519 p_UBSEC_rsa_mod_exp_ioctl = NULL; 520 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 521#endif 522#ifndef OPENSSL_NO_DSA 523 p_UBSEC_dsa_sign_ioctl = NULL; 524 p_UBSEC_dsa_verify_ioctl = NULL; 525#endif 526 p_UBSEC_math_accelerate_ioctl = NULL; 527 p_UBSEC_rng_ioctl = NULL; 528 p_UBSEC_max_key_len_ioctl = NULL; 529 return 1; 530 } 531 532static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) 533 { 534 int initialised = ((ubsec_dso == NULL) ? 0 : 1); 535 switch(cmd) 536 { 537 case UBSEC_CMD_SO_PATH: 538 if(p == NULL) 539 { 540 UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER); 541 return 0; 542 } 543 if(initialised) 544 { 545 UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED); 546 return 0; 547 } 548 return set_UBSEC_LIBNAME((const char *)p); 549 default: 550 break; 551 } 552 UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED); 553 return 0; 554 } 555 556static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 557 const BIGNUM *m, BN_CTX *ctx) 558 { 559 int y_len = 0; 560 int fd; 561 562 if(ubsec_dso == NULL) 563 { 564 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED); 565 return 0; 566 } 567 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); 573 } 574 575 if(!bn_wexpand(r, m->top)) 576 { 577 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL); 578 return 0; 579 } 580 581 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 582 fd = 0; 583 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE); 584 return BN_mod_exp(r, a, p, m, ctx); 585 } 586 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) 590 { 591 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED); 592 p_UBSEC_ubsec_close(fd); 593 594 return BN_mod_exp(r, a, p, m, ctx); 595 } 596 597 p_UBSEC_ubsec_close(fd); 598 599 r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2; 600 return 1; 601 } 602 603#ifndef OPENSSL_NO_RSA 604static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) 605 { 606 int to_return = 0; 607 608 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) 609 { 610 UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS); 611 goto err; 612 } 613 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) 617 { 618 /* 619 * Do in software as hardware failed. 620 */ 621 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 622 to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); 623 } 624err: 625 return to_return; 626 } 627#endif 628 629static 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) 632 { 633 int y_len, 634 fd; 635 636 y_len = BN_num_bits(p) + BN_num_bits(q); 637 638 /* Check if hardware can't handle this argument. */ 639 if (y_len > max_key_len) { 640 UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 641 return FAIL_TO_SOFTWARE; 642 } 643 644 if (!bn_wexpand(r, p->top + q->top + 1)) { 645 UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL); 646 return 0; 647 } 648 649 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 650 fd = 0; 651 UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE); 652 return FAIL_TO_SOFTWARE; 653 } 654 655 if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd, 656 (unsigned char *)a->d, BN_num_bits(a), 657 (unsigned char *)qinv->d, BN_num_bits(qinv), 658 (unsigned char *)dp->d, BN_num_bits(dp), 659 (unsigned char *)p->d, BN_num_bits(p), 660 (unsigned char *)dq->d, BN_num_bits(dq), 661 (unsigned char *)q->d, BN_num_bits(q), 662 (unsigned char *)r->d, &y_len) != 0) { 663 UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED); 664 p_UBSEC_ubsec_close(fd); 665 return FAIL_TO_SOFTWARE; 666 } 667 668 p_UBSEC_ubsec_close(fd); 669 670 r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2; 671 return 1; 672} 673 674#ifndef OPENSSL_NO_DSA 675#ifdef NOT_USED 676static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 677 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 678 BN_CTX *ctx, BN_MONT_CTX *in_mont) 679 { 680 BIGNUM t; 681 int to_return = 0; 682 683 BN_init(&t); 684 /* let rr = a1 ^ p1 mod m */ 685 if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end; 686 /* let t = a2 ^ p2 mod m */ 687 if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end; 688 /* let rr = rr * t mod m */ 689 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end; 690 to_return = 1; 691end: 692 BN_free(&t); 693 return to_return; 694 } 695 696static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 697 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 698 BN_MONT_CTX *m_ctx) 699 { 700 return ubsec_mod_exp(r, a, p, m, ctx); 701 } 702#endif 703#endif 704 705/* 706 * This function is aliased to mod_exp (with the mont stuff dropped). 707 */ 708static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 709 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 710 { 711 int ret = 0; 712 713#ifndef OPENSSL_NO_RSA 714 /* Do in software if the key is too large for the hardware. */ 715 if (BN_num_bits(m) > max_key_len) 716 { 717 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 718 ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx); 719 } 720 else 721#endif 722 { 723 ret = ubsec_mod_exp(r, a, p, m, ctx); 724 } 725 726 return ret; 727 } 728 729#ifndef OPENSSL_NO_DH 730/* This function is aliased to mod_exp (with the dh and mont dropped). */ 731static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 732 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 733 BN_MONT_CTX *m_ctx) 734 { 735 return ubsec_mod_exp(r, a, p, m, ctx); 736 } 737#endif 738 739#ifndef OPENSSL_NO_DSA 740static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) 741 { 742 DSA_SIG *to_return = NULL; 743 int s_len = 160, r_len = 160, d_len, fd; 744 BIGNUM m, *r=NULL, *s=NULL; 745 746 BN_init(&m); 747 748 s = BN_new(); 749 r = BN_new(); 750 if ((s == NULL) || (r==NULL)) 751 goto err; 752 753 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen); 754 755 if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) || 756 (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) { 757 UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 758 goto err; 759 } 760 761 if (BN_bin2bn(dgst,dlen,&m) == NULL) { 762 UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 763 goto err; 764 } 765 766 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 767 const DSA_METHOD *meth; 768 fd = 0; 769 UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE); 770 meth = DSA_OpenSSL(); 771 to_return = meth->dsa_do_sign(dgst, dlen, dsa); 772 goto err; 773 } 774 775 if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */ 776 (unsigned char *)dgst, d_len, 777 NULL, 0, /* compute random value */ 778 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p), 779 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q), 780 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g), 781 (unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key), 782 (unsigned char *)r->d, &r_len, 783 (unsigned char *)s->d, &s_len ) != 0) { 784 const DSA_METHOD *meth; 785 786 UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED); 787 p_UBSEC_ubsec_close(fd); 788 meth = DSA_OpenSSL(); 789 to_return = meth->dsa_do_sign(dgst, dlen, dsa); 790 791 goto err; 792 } 793 794 p_UBSEC_ubsec_close(fd); 795 796 r->top = (160+BN_BITS2-1)/BN_BITS2; 797 s->top = (160+BN_BITS2-1)/BN_BITS2; 798 799 to_return = DSA_SIG_new(); 800 if(to_return == NULL) { 801 UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 802 goto err; 803 } 804 805 to_return->r = r; 806 to_return->s = s; 807 808err: 809 if (!to_return) { 810 if (r) BN_free(r); 811 if (s) BN_free(s); 812 } 813 BN_clear_free(&m); 814 return to_return; 815} 816 817static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, 818 DSA_SIG *sig, DSA *dsa) 819 { 820 int v_len, d_len; 821 int to_return = 0; 822 int fd; 823 BIGNUM v, *pv = &v; 824 825 BN_init(&v); 826 827 if(!bn_wexpand(pv, dsa->p->top)) { 828 UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL); 829 goto err; 830 } 831 832 v_len = BN_num_bits(dsa->p); 833 834 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len); 835 836 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 837 const DSA_METHOD *meth; 838 fd = 0; 839 UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE); 840 meth = DSA_OpenSSL(); 841 to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); 842 goto err; 843 } 844 845 if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */ 846 (unsigned char *)dgst, d_len, 847 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p), 848 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q), 849 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g), 850 (unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key), 851 (unsigned char *)sig->r->d, BN_num_bits(sig->r), 852 (unsigned char *)sig->s->d, BN_num_bits(sig->s), 853 (unsigned char *)v.d, &v_len) != 0) { 854 const DSA_METHOD *meth; 855 UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED); 856 p_UBSEC_ubsec_close(fd); 857 858 meth = DSA_OpenSSL(); 859 to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); 860 861 goto err; 862 } 863 864 p_UBSEC_ubsec_close(fd); 865 866 to_return = 1; 867err: 868 BN_clear_free(&v); 869 return to_return; 870 } 871#endif 872 873#ifndef OPENSSL_NO_DH 874static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh) 875 { 876 int ret = -1, 877 k_len, 878 fd; 879 880 k_len = BN_num_bits(dh->p); 881 882 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) 883 { 884 const DH_METHOD *meth; 885 UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE); 886 meth = DH_OpenSSL(); 887 ret = meth->compute_key(key, pub_key, dh); 888 goto err; 889 } 890 891 if (p_UBSEC_diffie_hellman_agree_ioctl(fd, 892 (unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key), 893 (unsigned char *)pub_key->d, BN_num_bits(pub_key), 894 (unsigned char *)dh->p->d, BN_num_bits(dh->p), 895 key, &k_len) != 0) 896 { 897 /* Hardware's a no go, failover to software */ 898 const DH_METHOD *meth; 899 UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED); 900 p_UBSEC_ubsec_close(fd); 901 902 meth = DH_OpenSSL(); 903 ret = meth->compute_key(key, pub_key, dh); 904 905 goto err; 906 } 907 908 p_UBSEC_ubsec_close(fd); 909 910 ret = p_UBSEC_ubsec_bits_to_bytes(k_len); 911err: 912 return ret; 913 } 914 915static int ubsec_dh_generate_key(DH *dh) 916 { 917 int ret = 0, 918 random_bits = 0, 919 pub_key_len = 0, 920 priv_key_len = 0, 921 fd; 922 BIGNUM *pub_key = NULL; 923 BIGNUM *priv_key = NULL; 924 925 /* 926 * How many bits should Random x be? dh_key.c 927 * sets the range from 0 to num_bits(modulus) ??? 928 */ 929 930 if (dh->priv_key == NULL) 931 { 932 priv_key = BN_new(); 933 if (priv_key == NULL) goto err; 934 priv_key_len = BN_num_bits(dh->p); 935 if(bn_wexpand(priv_key, dh->p->top) == NULL) goto err; 936 do 937 if (!BN_rand_range(priv_key, dh->p)) goto err; 938 while (BN_is_zero(priv_key)); 939 random_bits = BN_num_bits(priv_key); 940 } 941 else 942 { 943 priv_key = dh->priv_key; 944 } 945 946 if (dh->pub_key == NULL) 947 { 948 pub_key = BN_new(); 949 pub_key_len = BN_num_bits(dh->p); 950 if(bn_wexpand(pub_key, dh->p->top) == NULL) goto err; 951 if(pub_key == NULL) goto err; 952 } 953 else 954 { 955 pub_key = dh->pub_key; 956 } 957 958 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) 959 { 960 const DH_METHOD *meth; 961 UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE); 962 meth = DH_OpenSSL(); 963 ret = meth->generate_key(dh); 964 goto err; 965 } 966 967 if (p_UBSEC_diffie_hellman_generate_ioctl(fd, 968 (unsigned char *)priv_key->d, &priv_key_len, 969 (unsigned char *)pub_key->d, &pub_key_len, 970 (unsigned char *)dh->g->d, BN_num_bits(dh->g), 971 (unsigned char *)dh->p->d, BN_num_bits(dh->p), 972 0, 0, random_bits) != 0) 973 { 974 /* Hardware's a no go, failover to software */ 975 const DH_METHOD *meth; 976 977 UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED); 978 p_UBSEC_ubsec_close(fd); 979 980 meth = DH_OpenSSL(); 981 ret = meth->generate_key(dh); 982 983 goto err; 984 } 985 986 p_UBSEC_ubsec_close(fd); 987 988 dh->pub_key = pub_key; 989 dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2; 990 dh->priv_key = priv_key; 991 dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2; 992 993 ret = 1; 994err: 995 return ret; 996 } 997#endif 998 999#ifdef NOT_USED 1000static int ubsec_rand_bytes(unsigned char * buf, 1001 int num) 1002 { 1003 int ret = 0, 1004 fd; 1005 1006 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) 1007 { 1008 const RAND_METHOD *meth; 1009 UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE); 1010 num = p_UBSEC_ubsec_bits_to_bytes(num); 1011 meth = RAND_SSLeay(); 1012 meth->seed(buf, num); 1013 ret = meth->bytes(buf, num); 1014 goto err; 1015 } 1016 1017 num *= 8; /* bytes to bits */ 1018 1019 if (p_UBSEC_rng_ioctl(fd, 1020 UBSEC_RNG_DIRECT, 1021 buf, 1022 &num) != 0) 1023 { 1024 /* Hardware's a no go, failover to software */ 1025 const RAND_METHOD *meth; 1026 1027 UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED); 1028 p_UBSEC_ubsec_close(fd); 1029 1030 num = p_UBSEC_ubsec_bits_to_bytes(num); 1031 meth = RAND_SSLeay(); 1032 meth->seed(buf, num); 1033 ret = meth->bytes(buf, num); 1034 1035 goto err; 1036 } 1037 1038 p_UBSEC_ubsec_close(fd); 1039 1040 ret = 1; 1041err: 1042 return(ret); 1043 } 1044 1045 1046static int ubsec_rand_status(void) 1047 { 1048 return 0; 1049 } 1050#endif 1051 1052/* This stuff is needed if this ENGINE is being compiled into a self-contained 1053 * shared-library. */ 1054#ifndef OPENSSL_NO_DYNAMIC_ENGINE 1055static int bind_fn(ENGINE *e, const char *id) 1056 { 1057 if(id && (strcmp(id, engine_ubsec_id) != 0)) 1058 return 0; 1059 if(!bind_helper(e)) 1060 return 0; 1061 return 1; 1062 } 1063IMPLEMENT_DYNAMIC_CHECK_FN() 1064IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 1065#endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 1066 1067#endif /* !OPENSSL_NO_HW_UBSEC */ 1068#endif /* !OPENSSL_NO_HW */ 1069