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