1160814Ssimon/* crypto/engine/hw_ubsec.c */ 2280304Sjkim/* 3280304Sjkim * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project 4280304Sjkim * 2000. Cloned shamelessly by Joe Tardo. 5160814Ssimon */ 6160814Ssimon/* ==================================================================== 7160814Ssimon * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. 8160814Ssimon * 9160814Ssimon * Redistribution and use in source and binary forms, with or without 10160814Ssimon * modification, are permitted provided that the following conditions 11160814Ssimon * are met: 12160814Ssimon * 13160814Ssimon * 1. Redistributions of source code must retain the above copyright 14280304Sjkim * notice, this list of conditions and the following disclaimer. 15160814Ssimon * 16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 17160814Ssimon * notice, this list of conditions and the following disclaimer in 18160814Ssimon * the documentation and/or other materials provided with the 19160814Ssimon * distribution. 20160814Ssimon * 21160814Ssimon * 3. All advertising materials mentioning features or use of this 22160814Ssimon * software must display the following acknowledgment: 23160814Ssimon * "This product includes software developed by the OpenSSL Project 24160814Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25160814Ssimon * 26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27160814Ssimon * endorse or promote products derived from this software without 28160814Ssimon * prior written permission. For written permission, please contact 29160814Ssimon * licensing@OpenSSL.org. 30160814Ssimon * 31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 32160814Ssimon * nor may "OpenSSL" appear in their names without prior written 33160814Ssimon * permission of the OpenSSL Project. 34160814Ssimon * 35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 36160814Ssimon * acknowledgment: 37160814Ssimon * "This product includes software developed by the OpenSSL Project 38160814Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39160814Ssimon * 40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 52160814Ssimon * ==================================================================== 53160814Ssimon * 54160814Ssimon * This product includes cryptographic software written by Eric Young 55160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 56160814Ssimon * Hudson (tjh@cryptsoft.com). 57160814Ssimon * 58160814Ssimon */ 59160814Ssimon 60160814Ssimon#include <stdio.h> 61160814Ssimon#include <string.h> 62160814Ssimon#include <openssl/crypto.h> 63160814Ssimon#include <openssl/buffer.h> 64160814Ssimon#include <openssl/dso.h> 65160814Ssimon#include <openssl/engine.h> 66160814Ssimon#ifndef OPENSSL_NO_RSA 67280304Sjkim# include <openssl/rsa.h> 68160814Ssimon#endif 69160814Ssimon#ifndef OPENSSL_NO_DSA 70280304Sjkim# include <openssl/dsa.h> 71160814Ssimon#endif 72160814Ssimon#ifndef OPENSSL_NO_DH 73280304Sjkim# include <openssl/dh.h> 74160814Ssimon#endif 75160814Ssimon#include <openssl/bn.h> 76160814Ssimon 77160814Ssimon#ifndef OPENSSL_NO_HW 78280304Sjkim# ifndef OPENSSL_NO_HW_UBSEC 79160814Ssimon 80280304Sjkim# ifdef FLAT_INC 81280304Sjkim# include "hw_ubsec.h" 82280304Sjkim# else 83280304Sjkim# include "vendor_defns/hw_ubsec.h" 84280304Sjkim# endif 85160814Ssimon 86280304Sjkim# define UBSEC_LIB_NAME "ubsec engine" 87280304Sjkim# include "e_ubsec_err.c" 88160814Ssimon 89280304Sjkim# define FAIL_TO_SOFTWARE -15 90160814Ssimon 91160814Ssimonstatic int ubsec_destroy(ENGINE *e); 92160814Ssimonstatic int ubsec_init(ENGINE *e); 93160814Ssimonstatic int ubsec_finish(ENGINE *e); 94280304Sjkimstatic int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); 95160814Ssimonstatic int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 96280304Sjkim const BIGNUM *m, BN_CTX *ctx); 97280304Sjkim# ifndef OPENSSL_NO_RSA 98160814Ssimonstatic int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 99280304Sjkim const BIGNUM *q, const BIGNUM *dp, 100280304Sjkim const BIGNUM *dq, const BIGNUM *qinv, 101280304Sjkim BN_CTX *ctx); 102280304Sjkimstatic int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, 103280304Sjkim BN_CTX *ctx); 104160814Ssimonstatic int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 105280304Sjkim const BIGNUM *m, BN_CTX *ctx, 106280304Sjkim BN_MONT_CTX *m_ctx); 107280304Sjkim# endif 108280304Sjkim# ifndef OPENSSL_NO_DSA 109280304Sjkim# ifdef NOT_USED 110160814Ssimonstatic int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 111280304Sjkim BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 112280304Sjkim BN_CTX *ctx, BN_MONT_CTX *in_mont); 113160814Ssimonstatic int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 114280304Sjkim const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 115280304Sjkim BN_MONT_CTX *m_ctx); 116280304Sjkim# endif 117280304Sjkimstatic DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, 118280304Sjkim DSA *dsa); 119160814Ssimonstatic int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, 120280304Sjkim DSA_SIG *sig, DSA *dsa); 121280304Sjkim# endif 122280304Sjkim# ifndef OPENSSL_NO_DH 123160814Ssimonstatic int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 124280304Sjkim const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 125280304Sjkim BN_MONT_CTX *m_ctx); 126280304Sjkimstatic int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, 127280304Sjkim DH *dh); 128160814Ssimonstatic int ubsec_dh_generate_key(DH *dh); 129280304Sjkim# endif 130160814Ssimon 131280304Sjkim# ifdef NOT_USED 132160814Ssimonstatic int ubsec_rand_bytes(unsigned char *buf, int num); 133160814Ssimonstatic int ubsec_rand_status(void); 134280304Sjkim# endif 135160814Ssimon 136280304Sjkim# define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE 137160814Ssimonstatic const ENGINE_CMD_DEFN ubsec_cmd_defns[] = { 138280304Sjkim {UBSEC_CMD_SO_PATH, 139280304Sjkim "SO_PATH", 140280304Sjkim "Specifies the path to the 'ubsec' shared library", 141280304Sjkim ENGINE_CMD_FLAG_STRING}, 142280304Sjkim {0, NULL, NULL, 0} 143280304Sjkim}; 144160814Ssimon 145280304Sjkim# ifndef OPENSSL_NO_RSA 146160814Ssimon/* Our internal RSA_METHOD that we provide pointers to */ 147280304Sjkimstatic RSA_METHOD ubsec_rsa = { 148280304Sjkim "UBSEC RSA method", 149280304Sjkim NULL, 150280304Sjkim NULL, 151280304Sjkim NULL, 152280304Sjkim NULL, 153280304Sjkim ubsec_rsa_mod_exp, 154280304Sjkim ubsec_mod_exp_mont, 155280304Sjkim NULL, 156280304Sjkim NULL, 157280304Sjkim 0, 158280304Sjkim NULL, 159280304Sjkim NULL, 160280304Sjkim NULL, 161280304Sjkim NULL 162280304Sjkim}; 163280304Sjkim# endif 164160814Ssimon 165280304Sjkim# ifndef OPENSSL_NO_DSA 166160814Ssimon/* Our internal DSA_METHOD that we provide pointers to */ 167280304Sjkimstatic DSA_METHOD ubsec_dsa = { 168280304Sjkim "UBSEC DSA method", 169280304Sjkim ubsec_dsa_do_sign, /* dsa_do_sign */ 170280304Sjkim NULL, /* dsa_sign_setup */ 171280304Sjkim ubsec_dsa_verify, /* dsa_do_verify */ 172280304Sjkim NULL, /* ubsec_dsa_mod_exp *//* dsa_mod_exp */ 173280304Sjkim NULL, /* ubsec_mod_exp_dsa *//* bn_mod_exp */ 174280304Sjkim NULL, /* init */ 175280304Sjkim NULL, /* finish */ 176280304Sjkim 0, /* flags */ 177280304Sjkim NULL, /* app_data */ 178280304Sjkim NULL, /* dsa_paramgen */ 179280304Sjkim NULL /* dsa_keygen */ 180280304Sjkim}; 181280304Sjkim# endif 182160814Ssimon 183280304Sjkim# ifndef OPENSSL_NO_DH 184160814Ssimon/* Our internal DH_METHOD that we provide pointers to */ 185280304Sjkimstatic DH_METHOD ubsec_dh = { 186280304Sjkim "UBSEC DH method", 187280304Sjkim ubsec_dh_generate_key, 188280304Sjkim ubsec_dh_compute_key, 189280304Sjkim ubsec_mod_exp_dh, 190280304Sjkim NULL, 191280304Sjkim NULL, 192280304Sjkim 0, 193280304Sjkim NULL, 194280304Sjkim NULL 195280304Sjkim}; 196280304Sjkim# endif 197160814Ssimon 198160814Ssimon/* Constants used when creating the ENGINE */ 199160814Ssimonstatic const char *engine_ubsec_id = "ubsec"; 200160814Ssimonstatic const char *engine_ubsec_name = "UBSEC hardware engine support"; 201160814Ssimon 202280304Sjkim/* 203280304Sjkim * This internal function is used by ENGINE_ubsec() and possibly by the 204280304Sjkim * "dynamic" ENGINE support too 205280304Sjkim */ 206160814Ssimonstatic int bind_helper(ENGINE *e) 207280304Sjkim{ 208280304Sjkim# ifndef OPENSSL_NO_RSA 209280304Sjkim const RSA_METHOD *meth1; 210280304Sjkim# endif 211280304Sjkim# ifndef OPENSSL_NO_DH 212280304Sjkim# ifndef HAVE_UBSEC_DH 213280304Sjkim const DH_METHOD *meth3; 214280304Sjkim# endif /* HAVE_UBSEC_DH */ 215280304Sjkim# endif 216280304Sjkim if (!ENGINE_set_id(e, engine_ubsec_id) || 217280304Sjkim !ENGINE_set_name(e, engine_ubsec_name) || 218280304Sjkim# ifndef OPENSSL_NO_RSA 219280304Sjkim !ENGINE_set_RSA(e, &ubsec_rsa) || 220280304Sjkim# endif 221280304Sjkim# ifndef OPENSSL_NO_DSA 222280304Sjkim !ENGINE_set_DSA(e, &ubsec_dsa) || 223280304Sjkim# endif 224280304Sjkim# ifndef OPENSSL_NO_DH 225280304Sjkim !ENGINE_set_DH(e, &ubsec_dh) || 226280304Sjkim# endif 227280304Sjkim !ENGINE_set_destroy_function(e, ubsec_destroy) || 228280304Sjkim !ENGINE_set_init_function(e, ubsec_init) || 229280304Sjkim !ENGINE_set_finish_function(e, ubsec_finish) || 230280304Sjkim !ENGINE_set_ctrl_function(e, ubsec_ctrl) || 231280304Sjkim !ENGINE_set_cmd_defns(e, ubsec_cmd_defns)) 232280304Sjkim return 0; 233160814Ssimon 234280304Sjkim# ifndef OPENSSL_NO_RSA 235280304Sjkim /* 236280304Sjkim * We know that the "PKCS1_SSLeay()" functions hook properly to the 237280304Sjkim * Broadcom-specific mod_exp and mod_exp_crt so we use those functions. 238280304Sjkim * NB: We don't use ENGINE_openssl() or anything "more generic" because 239280304Sjkim * something like the RSAref code may not hook properly, and if you own 240280304Sjkim * one of these cards then you have the right to do RSA operations on it 241280304Sjkim * anyway! 242280304Sjkim */ 243280304Sjkim meth1 = RSA_PKCS1_SSLeay(); 244280304Sjkim ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc; 245280304Sjkim ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 246280304Sjkim ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc; 247280304Sjkim ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec; 248280304Sjkim# endif 249160814Ssimon 250280304Sjkim# ifndef OPENSSL_NO_DH 251280304Sjkim# ifndef HAVE_UBSEC_DH 252280304Sjkim /* Much the same for Diffie-Hellman */ 253280304Sjkim meth3 = DH_OpenSSL(); 254280304Sjkim ubsec_dh.generate_key = meth3->generate_key; 255280304Sjkim ubsec_dh.compute_key = meth3->compute_key; 256280304Sjkim# endif /* HAVE_UBSEC_DH */ 257280304Sjkim# endif 258160814Ssimon 259280304Sjkim /* Ensure the ubsec error handling is set up */ 260280304Sjkim ERR_load_UBSEC_strings(); 261280304Sjkim return 1; 262280304Sjkim} 263160814Ssimon 264280304Sjkim# ifdef OPENSSL_NO_DYNAMIC_ENGINE 265160814Ssimonstatic ENGINE *engine_ubsec(void) 266280304Sjkim{ 267280304Sjkim ENGINE *ret = ENGINE_new(); 268280304Sjkim if (!ret) 269280304Sjkim return NULL; 270280304Sjkim if (!bind_helper(ret)) { 271280304Sjkim ENGINE_free(ret); 272280304Sjkim return NULL; 273280304Sjkim } 274280304Sjkim return ret; 275280304Sjkim} 276160814Ssimon 277160814Ssimonvoid ENGINE_load_ubsec(void) 278280304Sjkim{ 279280304Sjkim /* Copied from eng_[openssl|dyn].c */ 280280304Sjkim ENGINE *toadd = engine_ubsec(); 281280304Sjkim if (!toadd) 282280304Sjkim return; 283280304Sjkim ENGINE_add(toadd); 284280304Sjkim ENGINE_free(toadd); 285280304Sjkim ERR_clear_error(); 286280304Sjkim} 287280304Sjkim# endif 288160814Ssimon 289280304Sjkim/* 290280304Sjkim * This is a process-global DSO handle used for loading and unloading the 291280304Sjkim * UBSEC library. NB: This is only set (or unset) during an init() or 292280304Sjkim * finish() call (reference counts permitting) and they're operating with 293280304Sjkim * global locks, so this should be thread-safe implicitly. 294280304Sjkim */ 295160814Ssimon 296160814Ssimonstatic DSO *ubsec_dso = NULL; 297160814Ssimon 298280304Sjkim/* 299280304Sjkim * These are the function pointers that are (un)set when the library has 300280304Sjkim * successfully (un)loaded. 301280304Sjkim */ 302160814Ssimon 303160814Ssimonstatic t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL; 304160814Ssimonstatic t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL; 305160814Ssimonstatic t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL; 306160814Ssimonstatic t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL; 307280304Sjkim# ifndef OPENSSL_NO_DH 308280304Sjkimstatic t_UBSEC_diffie_hellman_generate_ioctl 309280304Sjkim * p_UBSEC_diffie_hellman_generate_ioctl = NULL; 310280304Sjkimstatic t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl 311280304Sjkim = NULL; 312280304Sjkim# endif 313280304Sjkim# ifndef OPENSSL_NO_RSA 314160814Ssimonstatic t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL; 315160814Ssimonstatic t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 316280304Sjkim# endif 317280304Sjkim# ifndef OPENSSL_NO_DSA 318160814Ssimonstatic t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL; 319160814Ssimonstatic t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL; 320280304Sjkim# endif 321160814Ssimonstatic t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL; 322160814Ssimonstatic t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL; 323160814Ssimonstatic t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL; 324160814Ssimon 325160814Ssimonstatic int max_key_len = 1024; /* ??? */ 326160814Ssimon 327280304Sjkim/* 328160814Ssimon * These are the static string constants for the DSO file name and the function 329280304Sjkim * symbol names to bind to. 330160814Ssimon */ 331160814Ssimon 332160814Ssimonstatic const char *UBSEC_LIBNAME = NULL; 333160814Ssimonstatic const char *get_UBSEC_LIBNAME(void) 334280304Sjkim{ 335280304Sjkim if (UBSEC_LIBNAME) 336280304Sjkim return UBSEC_LIBNAME; 337280304Sjkim return "ubsec"; 338280304Sjkim} 339280304Sjkim 340160814Ssimonstatic void free_UBSEC_LIBNAME(void) 341280304Sjkim{ 342280304Sjkim if (UBSEC_LIBNAME) 343280304Sjkim OPENSSL_free((void *)UBSEC_LIBNAME); 344280304Sjkim UBSEC_LIBNAME = NULL; 345280304Sjkim} 346280304Sjkim 347160814Ssimonstatic long set_UBSEC_LIBNAME(const char *name) 348280304Sjkim{ 349280304Sjkim free_UBSEC_LIBNAME(); 350280304Sjkim return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); 351280304Sjkim} 352280304Sjkim 353160814Ssimonstatic const char *UBSEC_F1 = "ubsec_bytes_to_bits"; 354160814Ssimonstatic const char *UBSEC_F2 = "ubsec_bits_to_bytes"; 355160814Ssimonstatic const char *UBSEC_F3 = "ubsec_open"; 356160814Ssimonstatic const char *UBSEC_F4 = "ubsec_close"; 357280304Sjkim# ifndef OPENSSL_NO_DH 358160814Ssimonstatic const char *UBSEC_F5 = "diffie_hellman_generate_ioctl"; 359160814Ssimonstatic const char *UBSEC_F6 = "diffie_hellman_agree_ioctl"; 360280304Sjkim# endif 361160814Ssimon/* #ifndef OPENSSL_NO_RSA */ 362160814Ssimonstatic const char *UBSEC_F7 = "rsa_mod_exp_ioctl"; 363160814Ssimonstatic const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl"; 364160814Ssimon/* #endif */ 365280304Sjkim# ifndef OPENSSL_NO_DSA 366160814Ssimonstatic const char *UBSEC_F9 = "dsa_sign_ioctl"; 367160814Ssimonstatic const char *UBSEC_F10 = "dsa_verify_ioctl"; 368280304Sjkim# endif 369160814Ssimonstatic const char *UBSEC_F11 = "math_accelerate_ioctl"; 370160814Ssimonstatic const char *UBSEC_F12 = "rng_ioctl"; 371160814Ssimonstatic const char *UBSEC_F13 = "ubsec_max_key_len_ioctl"; 372160814Ssimon 373160814Ssimon/* Destructor (complements the "ENGINE_ubsec()" constructor) */ 374160814Ssimonstatic int ubsec_destroy(ENGINE *e) 375280304Sjkim{ 376280304Sjkim free_UBSEC_LIBNAME(); 377280304Sjkim ERR_unload_UBSEC_strings(); 378280304Sjkim return 1; 379280304Sjkim} 380160814Ssimon 381160814Ssimon/* (de)initialisation functions. */ 382160814Ssimonstatic int ubsec_init(ENGINE *e) 383280304Sjkim{ 384280304Sjkim t_UBSEC_ubsec_bytes_to_bits *p1; 385280304Sjkim t_UBSEC_ubsec_bits_to_bytes *p2; 386280304Sjkim t_UBSEC_ubsec_open *p3; 387280304Sjkim t_UBSEC_ubsec_close *p4; 388280304Sjkim# ifndef OPENSSL_NO_DH 389280304Sjkim t_UBSEC_diffie_hellman_generate_ioctl *p5; 390280304Sjkim t_UBSEC_diffie_hellman_agree_ioctl *p6; 391280304Sjkim# endif 392160814Ssimon/* #ifndef OPENSSL_NO_RSA */ 393280304Sjkim t_UBSEC_rsa_mod_exp_ioctl *p7; 394280304Sjkim t_UBSEC_rsa_mod_exp_crt_ioctl *p8; 395160814Ssimon/* #endif */ 396280304Sjkim# ifndef OPENSSL_NO_DSA 397280304Sjkim t_UBSEC_dsa_sign_ioctl *p9; 398280304Sjkim t_UBSEC_dsa_verify_ioctl *p10; 399280304Sjkim# endif 400280304Sjkim t_UBSEC_math_accelerate_ioctl *p11; 401280304Sjkim t_UBSEC_rng_ioctl *p12; 402280304Sjkim t_UBSEC_max_key_len_ioctl *p13; 403280304Sjkim int fd = 0; 404160814Ssimon 405280304Sjkim if (ubsec_dso != NULL) { 406280304Sjkim UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED); 407280304Sjkim goto err; 408280304Sjkim } 409280304Sjkim /* 410280304Sjkim * Attempt to load libubsec.so/ubsec.dll/whatever. 411280304Sjkim */ 412280304Sjkim ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0); 413280304Sjkim if (ubsec_dso == NULL) { 414280304Sjkim UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); 415280304Sjkim goto err; 416280304Sjkim } 417160814Ssimon 418280304Sjkim if (!(p1 = (t_UBSEC_ubsec_bytes_to_bits *) 419280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F1)) 420280304Sjkim || !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) 421280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F2)) 422280304Sjkim || !(p3 = (t_UBSEC_ubsec_open *) 423280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F3)) 424280304Sjkim || !(p4 = (t_UBSEC_ubsec_close *) 425280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F4)) 426280304Sjkim# ifndef OPENSSL_NO_DH 427280304Sjkim || !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *) 428280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F5)) 429280304Sjkim || !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *) 430280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F6)) 431280304Sjkim# endif 432160814Ssimon/* #ifndef OPENSSL_NO_RSA */ 433280304Sjkim || !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) 434280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F7)) 435280304Sjkim || !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) 436280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F8)) 437160814Ssimon/* #endif */ 438280304Sjkim# ifndef OPENSSL_NO_DSA 439280304Sjkim || !(p9 = (t_UBSEC_dsa_sign_ioctl *) 440280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F9)) 441280304Sjkim || !(p10 = (t_UBSEC_dsa_verify_ioctl *) 442280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F10)) 443280304Sjkim# endif 444280304Sjkim || !(p11 = (t_UBSEC_math_accelerate_ioctl *) 445280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F11)) 446280304Sjkim || !(p12 = (t_UBSEC_rng_ioctl *) 447280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F12)) 448280304Sjkim || !(p13 = (t_UBSEC_max_key_len_ioctl *) 449280304Sjkim DSO_bind_func(ubsec_dso, UBSEC_F13))) { 450280304Sjkim UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); 451280304Sjkim goto err; 452280304Sjkim } 453160814Ssimon 454280304Sjkim /* Copy the pointers */ 455280304Sjkim p_UBSEC_ubsec_bytes_to_bits = p1; 456280304Sjkim p_UBSEC_ubsec_bits_to_bytes = p2; 457280304Sjkim p_UBSEC_ubsec_open = p3; 458280304Sjkim p_UBSEC_ubsec_close = p4; 459280304Sjkim# ifndef OPENSSL_NO_DH 460280304Sjkim p_UBSEC_diffie_hellman_generate_ioctl = p5; 461280304Sjkim p_UBSEC_diffie_hellman_agree_ioctl = p6; 462280304Sjkim# endif 463280304Sjkim# ifndef OPENSSL_NO_RSA 464280304Sjkim p_UBSEC_rsa_mod_exp_ioctl = p7; 465280304Sjkim p_UBSEC_rsa_mod_exp_crt_ioctl = p8; 466280304Sjkim# endif 467280304Sjkim# ifndef OPENSSL_NO_DSA 468280304Sjkim p_UBSEC_dsa_sign_ioctl = p9; 469280304Sjkim p_UBSEC_dsa_verify_ioctl = p10; 470280304Sjkim# endif 471280304Sjkim p_UBSEC_math_accelerate_ioctl = p11; 472280304Sjkim p_UBSEC_rng_ioctl = p12; 473280304Sjkim p_UBSEC_max_key_len_ioctl = p13; 474160814Ssimon 475280304Sjkim /* Perform an open to see if there's actually any unit running. */ 476280304Sjkim if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) 477280304Sjkim && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0)) { 478280304Sjkim p_UBSEC_ubsec_close(fd); 479280304Sjkim return 1; 480280304Sjkim } else { 481280304Sjkim UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); 482280304Sjkim } 483160814Ssimon 484280304Sjkim err: 485280304Sjkim if (ubsec_dso) 486280304Sjkim DSO_free(ubsec_dso); 487280304Sjkim ubsec_dso = NULL; 488280304Sjkim p_UBSEC_ubsec_bytes_to_bits = NULL; 489280304Sjkim p_UBSEC_ubsec_bits_to_bytes = NULL; 490280304Sjkim p_UBSEC_ubsec_open = NULL; 491280304Sjkim p_UBSEC_ubsec_close = NULL; 492280304Sjkim# ifndef OPENSSL_NO_DH 493280304Sjkim p_UBSEC_diffie_hellman_generate_ioctl = NULL; 494280304Sjkim p_UBSEC_diffie_hellman_agree_ioctl = NULL; 495280304Sjkim# endif 496280304Sjkim# ifndef OPENSSL_NO_RSA 497280304Sjkim p_UBSEC_rsa_mod_exp_ioctl = NULL; 498280304Sjkim p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 499280304Sjkim# endif 500280304Sjkim# ifndef OPENSSL_NO_DSA 501280304Sjkim p_UBSEC_dsa_sign_ioctl = NULL; 502280304Sjkim p_UBSEC_dsa_verify_ioctl = NULL; 503280304Sjkim# endif 504280304Sjkim p_UBSEC_math_accelerate_ioctl = NULL; 505280304Sjkim p_UBSEC_rng_ioctl = NULL; 506280304Sjkim p_UBSEC_max_key_len_ioctl = NULL; 507160814Ssimon 508280304Sjkim return 0; 509280304Sjkim} 510160814Ssimon 511160814Ssimonstatic int ubsec_finish(ENGINE *e) 512280304Sjkim{ 513280304Sjkim free_UBSEC_LIBNAME(); 514280304Sjkim if (ubsec_dso == NULL) { 515280304Sjkim UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED); 516280304Sjkim return 0; 517280304Sjkim } 518280304Sjkim if (!DSO_free(ubsec_dso)) { 519280304Sjkim UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE); 520280304Sjkim return 0; 521280304Sjkim } 522280304Sjkim ubsec_dso = NULL; 523280304Sjkim p_UBSEC_ubsec_bytes_to_bits = NULL; 524280304Sjkim p_UBSEC_ubsec_bits_to_bytes = NULL; 525280304Sjkim p_UBSEC_ubsec_open = NULL; 526280304Sjkim p_UBSEC_ubsec_close = NULL; 527280304Sjkim# ifndef OPENSSL_NO_DH 528280304Sjkim p_UBSEC_diffie_hellman_generate_ioctl = NULL; 529280304Sjkim p_UBSEC_diffie_hellman_agree_ioctl = NULL; 530280304Sjkim# endif 531280304Sjkim# ifndef OPENSSL_NO_RSA 532280304Sjkim p_UBSEC_rsa_mod_exp_ioctl = NULL; 533280304Sjkim p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 534280304Sjkim# endif 535280304Sjkim# ifndef OPENSSL_NO_DSA 536280304Sjkim p_UBSEC_dsa_sign_ioctl = NULL; 537280304Sjkim p_UBSEC_dsa_verify_ioctl = NULL; 538280304Sjkim# endif 539280304Sjkim p_UBSEC_math_accelerate_ioctl = NULL; 540280304Sjkim p_UBSEC_rng_ioctl = NULL; 541280304Sjkim p_UBSEC_max_key_len_ioctl = NULL; 542280304Sjkim return 1; 543280304Sjkim} 544160814Ssimon 545280304Sjkimstatic int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 546280304Sjkim{ 547280304Sjkim int initialised = ((ubsec_dso == NULL) ? 0 : 1); 548280304Sjkim switch (cmd) { 549280304Sjkim case UBSEC_CMD_SO_PATH: 550280304Sjkim if (p == NULL) { 551280304Sjkim UBSECerr(UBSEC_F_UBSEC_CTRL, ERR_R_PASSED_NULL_PARAMETER); 552280304Sjkim return 0; 553280304Sjkim } 554280304Sjkim if (initialised) { 555280304Sjkim UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_ALREADY_LOADED); 556280304Sjkim return 0; 557280304Sjkim } 558280304Sjkim return set_UBSEC_LIBNAME((const char *)p); 559280304Sjkim default: 560280304Sjkim break; 561280304Sjkim } 562280304Sjkim UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED); 563280304Sjkim return 0; 564280304Sjkim} 565160814Ssimon 566160814Ssimonstatic int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 567280304Sjkim const BIGNUM *m, BN_CTX *ctx) 568280304Sjkim{ 569280304Sjkim int y_len = 0; 570280304Sjkim int fd; 571160814Ssimon 572280304Sjkim if (ubsec_dso == NULL) { 573280304Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED); 574280304Sjkim return 0; 575280304Sjkim } 576160814Ssimon 577280304Sjkim /* Check if hardware can't handle this argument. */ 578280304Sjkim y_len = BN_num_bits(m); 579280304Sjkim if (y_len > max_key_len) { 580280304Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 581280304Sjkim return BN_mod_exp(r, a, p, m, ctx); 582280304Sjkim } 583160814Ssimon 584280304Sjkim if (!bn_wexpand(r, m->top)) { 585280304Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL); 586280304Sjkim return 0; 587280304Sjkim } 588160814Ssimon 589280304Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 590280304Sjkim fd = 0; 591280304Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE); 592280304Sjkim return BN_mod_exp(r, a, p, m, ctx); 593280304Sjkim } 594160814Ssimon 595280304Sjkim if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a), 596280304Sjkim (unsigned char *)m->d, BN_num_bits(m), 597280304Sjkim (unsigned char *)p->d, BN_num_bits(p), 598280304Sjkim (unsigned char *)r->d, &y_len) != 0) { 599280304Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED); 600280304Sjkim p_UBSEC_ubsec_close(fd); 601160814Ssimon 602280304Sjkim return BN_mod_exp(r, a, p, m, ctx); 603280304Sjkim } 604160814Ssimon 605280304Sjkim p_UBSEC_ubsec_close(fd); 606160814Ssimon 607280304Sjkim r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2; 608280304Sjkim return 1; 609280304Sjkim} 610160814Ssimon 611280304Sjkim# ifndef OPENSSL_NO_RSA 612280304Sjkimstatic int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, 613280304Sjkim BN_CTX *ctx) 614280304Sjkim{ 615280304Sjkim int to_return = 0; 616160814Ssimon 617280304Sjkim if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { 618280304Sjkim UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS); 619280304Sjkim goto err; 620280304Sjkim } 621160814Ssimon 622280304Sjkim to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, 623280304Sjkim rsa->dmq1, rsa->iqmp, ctx); 624280304Sjkim if (to_return == FAIL_TO_SOFTWARE) { 625280304Sjkim /* 626280304Sjkim * Do in software as hardware failed. 627280304Sjkim */ 628280304Sjkim const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 629280304Sjkim to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); 630280304Sjkim } 631280304Sjkim err: 632280304Sjkim return to_return; 633280304Sjkim} 634160814Ssimon 635160814Ssimonstatic int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 636280304Sjkim const BIGNUM *q, const BIGNUM *dp, 637280304Sjkim const BIGNUM *dq, const BIGNUM *qinv, 638280304Sjkim BN_CTX *ctx) 639280304Sjkim{ 640280304Sjkim int y_len, fd; 641160814Ssimon 642280304Sjkim y_len = BN_num_bits(p) + BN_num_bits(q); 643160814Ssimon 644280304Sjkim /* Check if hardware can't handle this argument. */ 645280304Sjkim if (y_len > max_key_len) { 646280304Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, 647280304Sjkim UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 648280304Sjkim return FAIL_TO_SOFTWARE; 649280304Sjkim } 650160814Ssimon 651280304Sjkim if (!bn_wexpand(r, p->top + q->top + 1)) { 652280304Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL); 653280304Sjkim return 0; 654280304Sjkim } 655160814Ssimon 656280304Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 657280304Sjkim fd = 0; 658280304Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE); 659280304Sjkim return FAIL_TO_SOFTWARE; 660280304Sjkim } 661160814Ssimon 662280304Sjkim if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd, 663280304Sjkim (unsigned char *)a->d, BN_num_bits(a), 664280304Sjkim (unsigned char *)qinv->d, 665280304Sjkim BN_num_bits(qinv), 666280304Sjkim (unsigned char *)dp->d, BN_num_bits(dp), 667280304Sjkim (unsigned char *)p->d, BN_num_bits(p), 668280304Sjkim (unsigned char *)dq->d, BN_num_bits(dq), 669280304Sjkim (unsigned char *)q->d, BN_num_bits(q), 670280304Sjkim (unsigned char *)r->d, &y_len) != 0) { 671280304Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED); 672280304Sjkim p_UBSEC_ubsec_close(fd); 673280304Sjkim return FAIL_TO_SOFTWARE; 674280304Sjkim } 675160814Ssimon 676280304Sjkim p_UBSEC_ubsec_close(fd); 677160814Ssimon 678280304Sjkim r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1) / BN_BITS2; 679280304Sjkim return 1; 680160814Ssimon} 681280304Sjkim# endif 682160814Ssimon 683280304Sjkim# ifndef OPENSSL_NO_DSA 684280304Sjkim# ifdef NOT_USED 685160814Ssimonstatic int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 686280304Sjkim BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 687280304Sjkim BN_CTX *ctx, BN_MONT_CTX *in_mont) 688280304Sjkim{ 689280304Sjkim BIGNUM t; 690280304Sjkim int to_return = 0; 691160814Ssimon 692280304Sjkim BN_init(&t); 693280304Sjkim /* let rr = a1 ^ p1 mod m */ 694280304Sjkim if (!ubsec_mod_exp(rr, a1, p1, m, ctx)) 695280304Sjkim goto end; 696280304Sjkim /* let t = a2 ^ p2 mod m */ 697280304Sjkim if (!ubsec_mod_exp(&t, a2, p2, m, ctx)) 698280304Sjkim goto end; 699280304Sjkim /* let rr = rr * t mod m */ 700280304Sjkim if (!BN_mod_mul(rr, rr, &t, m, ctx)) 701280304Sjkim goto end; 702280304Sjkim to_return = 1; 703280304Sjkim end: 704280304Sjkim BN_free(&t); 705280304Sjkim return to_return; 706280304Sjkim} 707280304Sjkim 708160814Ssimonstatic int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 709280304Sjkim const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 710280304Sjkim BN_MONT_CTX *m_ctx) 711280304Sjkim{ 712280304Sjkim return ubsec_mod_exp(r, a, p, m, ctx); 713280304Sjkim} 714280304Sjkim# endif 715280304Sjkim# endif 716160814Ssimon 717280304Sjkim# ifndef OPENSSL_NO_RSA 718238405Sjkim 719160814Ssimon/* 720160814Ssimon * This function is aliased to mod_exp (with the mont stuff dropped). 721160814Ssimon */ 722160814Ssimonstatic int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 723280304Sjkim const BIGNUM *m, BN_CTX *ctx, 724280304Sjkim BN_MONT_CTX *m_ctx) 725280304Sjkim{ 726280304Sjkim int ret = 0; 727160814Ssimon 728280304Sjkim /* Do in software if the key is too large for the hardware. */ 729280304Sjkim if (BN_num_bits(m) > max_key_len) { 730280304Sjkim const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 731280304Sjkim ret = (*meth->bn_mod_exp) (r, a, p, m, ctx, m_ctx); 732280304Sjkim } else { 733280304Sjkim ret = ubsec_mod_exp(r, a, p, m, ctx); 734280304Sjkim } 735160814Ssimon 736280304Sjkim return ret; 737280304Sjkim} 738280304Sjkim# endif 739280304Sjkim 740280304Sjkim# ifndef OPENSSL_NO_DH 741160814Ssimon/* This function is aliased to mod_exp (with the dh and mont dropped). */ 742160814Ssimonstatic int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 743280304Sjkim const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 744280304Sjkim BN_MONT_CTX *m_ctx) 745280304Sjkim{ 746280304Sjkim return ubsec_mod_exp(r, a, p, m, ctx); 747280304Sjkim} 748280304Sjkim# endif 749160814Ssimon 750280304Sjkim# ifndef OPENSSL_NO_DSA 751280304Sjkimstatic DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, 752280304Sjkim DSA *dsa) 753280304Sjkim{ 754280304Sjkim DSA_SIG *to_return = NULL; 755280304Sjkim int s_len = 160, r_len = 160, d_len, fd; 756280304Sjkim BIGNUM m, *r = NULL, *s = NULL; 757160814Ssimon 758280304Sjkim BN_init(&m); 759160814Ssimon 760280304Sjkim s = BN_new(); 761280304Sjkim r = BN_new(); 762280304Sjkim if ((s == NULL) || (r == NULL)) 763280304Sjkim goto err; 764160814Ssimon 765280304Sjkim d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen); 766160814Ssimon 767280304Sjkim if (!bn_wexpand(r, (160 + BN_BITS2 - 1) / BN_BITS2) || 768280304Sjkim (!bn_wexpand(s, (160 + BN_BITS2 - 1) / BN_BITS2))) { 769280304Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 770280304Sjkim goto err; 771280304Sjkim } 772160814Ssimon 773280304Sjkim if (BN_bin2bn(dgst, dlen, &m) == NULL) { 774280304Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 775280304Sjkim goto err; 776280304Sjkim } 777160814Ssimon 778280304Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 779280304Sjkim const DSA_METHOD *meth; 780280304Sjkim fd = 0; 781280304Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE); 782280304Sjkim meth = DSA_OpenSSL(); 783280304Sjkim to_return = meth->dsa_do_sign(dgst, dlen, dsa); 784280304Sjkim goto err; 785280304Sjkim } 786160814Ssimon 787280304Sjkim if (p_UBSEC_dsa_sign_ioctl(fd, 788280304Sjkim /* compute hash before signing */ 789280304Sjkim 0, (unsigned char *)dgst, d_len, NULL, 790280304Sjkim /* compute random value */ 791280304Sjkim 0, 792280304Sjkim (unsigned char *)dsa->p->d, 793280304Sjkim BN_num_bits(dsa->p), 794280304Sjkim (unsigned char *)dsa->q->d, 795280304Sjkim BN_num_bits(dsa->q), 796280304Sjkim (unsigned char *)dsa->g->d, 797280304Sjkim BN_num_bits(dsa->g), 798280304Sjkim (unsigned char *)dsa->priv_key->d, 799280304Sjkim BN_num_bits(dsa->priv_key), 800280304Sjkim (unsigned char *)r->d, &r_len, 801280304Sjkim (unsigned char *)s->d, &s_len) != 0) { 802280304Sjkim const DSA_METHOD *meth; 803160814Ssimon 804280304Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED); 805280304Sjkim p_UBSEC_ubsec_close(fd); 806280304Sjkim meth = DSA_OpenSSL(); 807280304Sjkim to_return = meth->dsa_do_sign(dgst, dlen, dsa); 808160814Ssimon 809280304Sjkim goto err; 810280304Sjkim } 811160814Ssimon 812280304Sjkim p_UBSEC_ubsec_close(fd); 813160814Ssimon 814280304Sjkim r->top = (160 + BN_BITS2 - 1) / BN_BITS2; 815280304Sjkim s->top = (160 + BN_BITS2 - 1) / BN_BITS2; 816160814Ssimon 817280304Sjkim to_return = DSA_SIG_new(); 818280304Sjkim if (to_return == NULL) { 819280304Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 820280304Sjkim goto err; 821280304Sjkim } 822160814Ssimon 823280304Sjkim to_return->r = r; 824280304Sjkim to_return->s = s; 825160814Ssimon 826280304Sjkim err: 827280304Sjkim if (!to_return) { 828280304Sjkim if (r) 829280304Sjkim BN_free(r); 830280304Sjkim if (s) 831280304Sjkim BN_free(s); 832280304Sjkim } 833280304Sjkim BN_clear_free(&m); 834280304Sjkim return to_return; 835160814Ssimon} 836160814Ssimon 837160814Ssimonstatic int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, 838280304Sjkim DSA_SIG *sig, DSA *dsa) 839280304Sjkim{ 840280304Sjkim int v_len, d_len; 841280304Sjkim int to_return = 0; 842280304Sjkim int fd; 843280304Sjkim BIGNUM v, *pv = &v; 844160814Ssimon 845280304Sjkim BN_init(&v); 846160814Ssimon 847280304Sjkim if (!bn_wexpand(pv, dsa->p->top)) { 848280304Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL); 849280304Sjkim goto err; 850280304Sjkim } 851160814Ssimon 852280304Sjkim v_len = BN_num_bits(dsa->p); 853160814Ssimon 854280304Sjkim d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len); 855160814Ssimon 856280304Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 857280304Sjkim const DSA_METHOD *meth; 858280304Sjkim fd = 0; 859280304Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE); 860280304Sjkim meth = DSA_OpenSSL(); 861280304Sjkim to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); 862280304Sjkim goto err; 863280304Sjkim } 864160814Ssimon 865280304Sjkim if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */ 866280304Sjkim (unsigned char *)dgst, d_len, 867280304Sjkim (unsigned char *)dsa->p->d, 868280304Sjkim BN_num_bits(dsa->p), 869280304Sjkim (unsigned char *)dsa->q->d, 870280304Sjkim BN_num_bits(dsa->q), 871280304Sjkim (unsigned char *)dsa->g->d, 872280304Sjkim BN_num_bits(dsa->g), 873280304Sjkim (unsigned char *)dsa->pub_key->d, 874280304Sjkim BN_num_bits(dsa->pub_key), 875280304Sjkim (unsigned char *)sig->r->d, 876280304Sjkim BN_num_bits(sig->r), 877280304Sjkim (unsigned char *)sig->s->d, 878280304Sjkim BN_num_bits(sig->s), (unsigned char *)v.d, 879280304Sjkim &v_len) != 0) { 880280304Sjkim const DSA_METHOD *meth; 881280304Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED); 882280304Sjkim p_UBSEC_ubsec_close(fd); 883160814Ssimon 884280304Sjkim meth = DSA_OpenSSL(); 885280304Sjkim to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); 886160814Ssimon 887280304Sjkim goto err; 888280304Sjkim } 889160814Ssimon 890280304Sjkim p_UBSEC_ubsec_close(fd); 891160814Ssimon 892280304Sjkim to_return = 1; 893280304Sjkim err: 894280304Sjkim BN_clear_free(&v); 895280304Sjkim return to_return; 896280304Sjkim} 897280304Sjkim# endif 898160814Ssimon 899280304Sjkim# ifndef OPENSSL_NO_DH 900280304Sjkimstatic int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, 901280304Sjkim DH *dh) 902280304Sjkim{ 903280304Sjkim int ret = -1, k_len, fd; 904160814Ssimon 905280304Sjkim k_len = BN_num_bits(dh->p); 906160814Ssimon 907280304Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 908280304Sjkim const DH_METHOD *meth; 909280304Sjkim UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE); 910280304Sjkim meth = DH_OpenSSL(); 911280304Sjkim ret = meth->compute_key(key, pub_key, dh); 912280304Sjkim goto err; 913280304Sjkim } 914160814Ssimon 915280304Sjkim if (p_UBSEC_diffie_hellman_agree_ioctl(fd, 916280304Sjkim (unsigned char *)dh->priv_key->d, 917280304Sjkim BN_num_bits(dh->priv_key), 918280304Sjkim (unsigned char *)pub_key->d, 919280304Sjkim BN_num_bits(pub_key), 920280304Sjkim (unsigned char *)dh->p->d, 921280304Sjkim BN_num_bits(dh->p), key, 922280304Sjkim &k_len) != 0) { 923280304Sjkim /* Hardware's a no go, failover to software */ 924280304Sjkim const DH_METHOD *meth; 925280304Sjkim UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED); 926280304Sjkim p_UBSEC_ubsec_close(fd); 927160814Ssimon 928280304Sjkim meth = DH_OpenSSL(); 929280304Sjkim ret = meth->compute_key(key, pub_key, dh); 930160814Ssimon 931280304Sjkim goto err; 932280304Sjkim } 933160814Ssimon 934280304Sjkim p_UBSEC_ubsec_close(fd); 935160814Ssimon 936280304Sjkim ret = p_UBSEC_ubsec_bits_to_bytes(k_len); 937280304Sjkim err: 938280304Sjkim return ret; 939280304Sjkim} 940160814Ssimon 941160814Ssimonstatic int ubsec_dh_generate_key(DH *dh) 942280304Sjkim{ 943280304Sjkim int ret = 0, random_bits = 0, pub_key_len = 0, priv_key_len = 0, fd; 944280304Sjkim BIGNUM *pub_key = NULL; 945280304Sjkim BIGNUM *priv_key = NULL; 946160814Ssimon 947280304Sjkim /* 948280304Sjkim * How many bits should Random x be? dh_key.c 949280304Sjkim * sets the range from 0 to num_bits(modulus) ??? 950280304Sjkim */ 951160814Ssimon 952280304Sjkim if (dh->priv_key == NULL) { 953280304Sjkim priv_key = BN_new(); 954280304Sjkim if (priv_key == NULL) 955280304Sjkim goto err; 956280304Sjkim priv_key_len = BN_num_bits(dh->p); 957280304Sjkim if (bn_wexpand(priv_key, dh->p->top) == NULL) 958280304Sjkim goto err; 959280304Sjkim do 960280304Sjkim if (!BN_rand_range(priv_key, dh->p)) 961160814Ssimon goto err; 962280304Sjkim while (BN_is_zero(priv_key)) ; 963280304Sjkim random_bits = BN_num_bits(priv_key); 964280304Sjkim } else { 965280304Sjkim priv_key = dh->priv_key; 966280304Sjkim } 967160814Ssimon 968280304Sjkim if (dh->pub_key == NULL) { 969280304Sjkim pub_key = BN_new(); 970280304Sjkim if (pub_key == NULL) 971280304Sjkim goto err; 972280304Sjkim pub_key_len = BN_num_bits(dh->p); 973280304Sjkim if (bn_wexpand(pub_key, dh->p->top) == NULL) 974280304Sjkim goto err; 975280304Sjkim } else { 976280304Sjkim pub_key = dh->pub_key; 977280304Sjkim } 978160814Ssimon 979280304Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 980280304Sjkim const DH_METHOD *meth; 981280304Sjkim UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE); 982280304Sjkim meth = DH_OpenSSL(); 983280304Sjkim ret = meth->generate_key(dh); 984280304Sjkim goto err; 985280304Sjkim } 986160814Ssimon 987280304Sjkim if (p_UBSEC_diffie_hellman_generate_ioctl(fd, 988280304Sjkim (unsigned char *)priv_key->d, 989280304Sjkim &priv_key_len, 990280304Sjkim (unsigned char *)pub_key->d, 991280304Sjkim &pub_key_len, 992280304Sjkim (unsigned char *)dh->g->d, 993280304Sjkim BN_num_bits(dh->g), 994280304Sjkim (unsigned char *)dh->p->d, 995280304Sjkim BN_num_bits(dh->p), 0, 0, 996280304Sjkim random_bits) != 0) { 997280304Sjkim /* Hardware's a no go, failover to software */ 998280304Sjkim const DH_METHOD *meth; 999160814Ssimon 1000280304Sjkim UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED); 1001160814Ssimon p_UBSEC_ubsec_close(fd); 1002160814Ssimon 1003280304Sjkim meth = DH_OpenSSL(); 1004280304Sjkim ret = meth->generate_key(dh); 1005160814Ssimon 1006280304Sjkim goto err; 1007280304Sjkim } 1008160814Ssimon 1009280304Sjkim p_UBSEC_ubsec_close(fd); 1010160814Ssimon 1011280304Sjkim dh->pub_key = pub_key; 1012280304Sjkim dh->pub_key->top = (pub_key_len + BN_BITS2 - 1) / BN_BITS2; 1013280304Sjkim dh->priv_key = priv_key; 1014280304Sjkim dh->priv_key->top = (priv_key_len + BN_BITS2 - 1) / BN_BITS2; 1015160814Ssimon 1016280304Sjkim ret = 1; 1017280304Sjkim err: 1018280304Sjkim return ret; 1019280304Sjkim} 1020280304Sjkim# endif 1021160814Ssimon 1022280304Sjkim# ifdef NOT_USED 1023280304Sjkimstatic int ubsec_rand_bytes(unsigned char *buf, int num) 1024280304Sjkim{ 1025280304Sjkim int ret = 0, fd; 1026160814Ssimon 1027280304Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 1028280304Sjkim const RAND_METHOD *meth; 1029280304Sjkim UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE); 1030280304Sjkim num = p_UBSEC_ubsec_bits_to_bytes(num); 1031280304Sjkim meth = RAND_SSLeay(); 1032280304Sjkim meth->seed(buf, num); 1033280304Sjkim ret = meth->bytes(buf, num); 1034280304Sjkim goto err; 1035280304Sjkim } 1036160814Ssimon 1037280304Sjkim num *= 8; /* bytes to bits */ 1038160814Ssimon 1039280304Sjkim if (p_UBSEC_rng_ioctl(fd, UBSEC_RNG_DIRECT, buf, &num) != 0) { 1040280304Sjkim /* Hardware's a no go, failover to software */ 1041280304Sjkim const RAND_METHOD *meth; 1042160814Ssimon 1043280304Sjkim UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED); 1044160814Ssimon p_UBSEC_ubsec_close(fd); 1045160814Ssimon 1046280304Sjkim num = p_UBSEC_ubsec_bits_to_bytes(num); 1047280304Sjkim meth = RAND_SSLeay(); 1048280304Sjkim meth->seed(buf, num); 1049280304Sjkim ret = meth->bytes(buf, num); 1050160814Ssimon 1051280304Sjkim goto err; 1052280304Sjkim } 1053160814Ssimon 1054280304Sjkim p_UBSEC_ubsec_close(fd); 1055280304Sjkim 1056280304Sjkim ret = 1; 1057280304Sjkim err: 1058280304Sjkim return (ret); 1059280304Sjkim} 1060280304Sjkim 1061160814Ssimonstatic int ubsec_rand_status(void) 1062280304Sjkim{ 1063280304Sjkim return 0; 1064280304Sjkim} 1065280304Sjkim# endif 1066160814Ssimon 1067280304Sjkim/* 1068280304Sjkim * This stuff is needed if this ENGINE is being compiled into a 1069280304Sjkim * self-contained shared-library. 1070280304Sjkim */ 1071280304Sjkim# ifndef OPENSSL_NO_DYNAMIC_ENGINE 1072160814Ssimonstatic int bind_fn(ENGINE *e, const char *id) 1073280304Sjkim{ 1074280304Sjkim if (id && (strcmp(id, engine_ubsec_id) != 0)) 1075280304Sjkim return 0; 1076280304Sjkim if (!bind_helper(e)) 1077280304Sjkim return 0; 1078280304Sjkim return 1; 1079280304Sjkim} 1080280304Sjkim 1081160814SsimonIMPLEMENT_DYNAMIC_CHECK_FN() 1082280304Sjkim IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 1083280304Sjkim# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 1084280304Sjkim# endif /* !OPENSSL_NO_HW_UBSEC */ 1085280304Sjkim#endif /* !OPENSSL_NO_HW */ 1086