1160814Ssimon/* crypto/engine/hw_ubsec.c */ 2280297Sjkim/* 3280297Sjkim * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project 4280297Sjkim * 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 14280297Sjkim * 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 67280297Sjkim# include <openssl/rsa.h> 68160814Ssimon#endif 69160814Ssimon#ifndef OPENSSL_NO_DSA 70280297Sjkim# include <openssl/dsa.h> 71160814Ssimon#endif 72160814Ssimon#ifndef OPENSSL_NO_DH 73280297Sjkim# include <openssl/dh.h> 74160814Ssimon#endif 75160814Ssimon#include <openssl/bn.h> 76160814Ssimon 77160814Ssimon#ifndef OPENSSL_NO_HW 78280297Sjkim# ifndef OPENSSL_NO_HW_UBSEC 79160814Ssimon 80280297Sjkim# ifdef FLAT_INC 81280297Sjkim# include "hw_ubsec.h" 82280297Sjkim# else 83280297Sjkim# include "vendor_defns/hw_ubsec.h" 84280297Sjkim# endif 85160814Ssimon 86280297Sjkim# define UBSEC_LIB_NAME "ubsec engine" 87280297Sjkim# include "e_ubsec_err.c" 88160814Ssimon 89280297Sjkim# define FAIL_TO_SOFTWARE -15 90160814Ssimon 91160814Ssimonstatic int ubsec_destroy(ENGINE *e); 92160814Ssimonstatic int ubsec_init(ENGINE *e); 93160814Ssimonstatic int ubsec_finish(ENGINE *e); 94280297Sjkimstatic 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, 96280297Sjkim const BIGNUM *m, BN_CTX *ctx); 97280297Sjkim# ifndef OPENSSL_NO_RSA 98160814Ssimonstatic int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 99280297Sjkim const BIGNUM *q, const BIGNUM *dp, 100280297Sjkim const BIGNUM *dq, const BIGNUM *qinv, 101280297Sjkim BN_CTX *ctx); 102280297Sjkimstatic int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, 103280297Sjkim BN_CTX *ctx); 104160814Ssimonstatic int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 105280297Sjkim const BIGNUM *m, BN_CTX *ctx, 106280297Sjkim BN_MONT_CTX *m_ctx); 107280297Sjkim# endif 108280297Sjkim# ifndef OPENSSL_NO_DSA 109280297Sjkim# ifdef NOT_USED 110160814Ssimonstatic int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 111280297Sjkim BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 112280297Sjkim BN_CTX *ctx, BN_MONT_CTX *in_mont); 113160814Ssimonstatic int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 114280297Sjkim const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 115280297Sjkim BN_MONT_CTX *m_ctx); 116280297Sjkim# endif 117280297Sjkimstatic DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, 118280297Sjkim DSA *dsa); 119160814Ssimonstatic int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, 120280297Sjkim DSA_SIG *sig, DSA *dsa); 121280297Sjkim# endif 122280297Sjkim# ifndef OPENSSL_NO_DH 123160814Ssimonstatic int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 124280297Sjkim const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 125280297Sjkim BN_MONT_CTX *m_ctx); 126280297Sjkimstatic int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, 127280297Sjkim DH *dh); 128160814Ssimonstatic int ubsec_dh_generate_key(DH *dh); 129280297Sjkim# endif 130160814Ssimon 131280297Sjkim# ifdef NOT_USED 132160814Ssimonstatic int ubsec_rand_bytes(unsigned char *buf, int num); 133160814Ssimonstatic int ubsec_rand_status(void); 134280297Sjkim# endif 135160814Ssimon 136280297Sjkim# define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE 137160814Ssimonstatic const ENGINE_CMD_DEFN ubsec_cmd_defns[] = { 138280297Sjkim {UBSEC_CMD_SO_PATH, 139280297Sjkim "SO_PATH", 140280297Sjkim "Specifies the path to the 'ubsec' shared library", 141280297Sjkim ENGINE_CMD_FLAG_STRING}, 142280297Sjkim {0, NULL, NULL, 0} 143280297Sjkim}; 144160814Ssimon 145280297Sjkim# ifndef OPENSSL_NO_RSA 146160814Ssimon/* Our internal RSA_METHOD that we provide pointers to */ 147280297Sjkimstatic RSA_METHOD ubsec_rsa = { 148280297Sjkim "UBSEC RSA method", 149280297Sjkim NULL, 150280297Sjkim NULL, 151280297Sjkim NULL, 152280297Sjkim NULL, 153280297Sjkim ubsec_rsa_mod_exp, 154280297Sjkim ubsec_mod_exp_mont, 155280297Sjkim NULL, 156280297Sjkim NULL, 157280297Sjkim 0, 158280297Sjkim NULL, 159280297Sjkim NULL, 160280297Sjkim NULL, 161280297Sjkim NULL 162280297Sjkim}; 163280297Sjkim# endif 164160814Ssimon 165280297Sjkim# ifndef OPENSSL_NO_DSA 166160814Ssimon/* Our internal DSA_METHOD that we provide pointers to */ 167280297Sjkimstatic DSA_METHOD ubsec_dsa = { 168280297Sjkim "UBSEC DSA method", 169280297Sjkim ubsec_dsa_do_sign, /* dsa_do_sign */ 170280297Sjkim NULL, /* dsa_sign_setup */ 171280297Sjkim ubsec_dsa_verify, /* dsa_do_verify */ 172280297Sjkim NULL, /* ubsec_dsa_mod_exp *//* dsa_mod_exp */ 173280297Sjkim NULL, /* ubsec_mod_exp_dsa *//* bn_mod_exp */ 174280297Sjkim NULL, /* init */ 175280297Sjkim NULL, /* finish */ 176280297Sjkim 0, /* flags */ 177280297Sjkim NULL, /* app_data */ 178280297Sjkim NULL, /* dsa_paramgen */ 179280297Sjkim NULL /* dsa_keygen */ 180280297Sjkim}; 181280297Sjkim# endif 182160814Ssimon 183280297Sjkim# ifndef OPENSSL_NO_DH 184160814Ssimon/* Our internal DH_METHOD that we provide pointers to */ 185280297Sjkimstatic DH_METHOD ubsec_dh = { 186280297Sjkim "UBSEC DH method", 187280297Sjkim ubsec_dh_generate_key, 188280297Sjkim ubsec_dh_compute_key, 189280297Sjkim ubsec_mod_exp_dh, 190280297Sjkim NULL, 191280297Sjkim NULL, 192280297Sjkim 0, 193280297Sjkim NULL, 194280297Sjkim NULL 195280297Sjkim}; 196280297Sjkim# 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 202280297Sjkim/* 203280297Sjkim * This internal function is used by ENGINE_ubsec() and possibly by the 204280297Sjkim * "dynamic" ENGINE support too 205280297Sjkim */ 206160814Ssimonstatic int bind_helper(ENGINE *e) 207280297Sjkim{ 208280297Sjkim# ifndef OPENSSL_NO_RSA 209280297Sjkim const RSA_METHOD *meth1; 210280297Sjkim# endif 211280297Sjkim# ifndef OPENSSL_NO_DH 212280297Sjkim# ifndef HAVE_UBSEC_DH 213280297Sjkim const DH_METHOD *meth3; 214280297Sjkim# endif /* HAVE_UBSEC_DH */ 215280297Sjkim# endif 216280297Sjkim if (!ENGINE_set_id(e, engine_ubsec_id) || 217280297Sjkim !ENGINE_set_name(e, engine_ubsec_name) || 218280297Sjkim# ifndef OPENSSL_NO_RSA 219280297Sjkim !ENGINE_set_RSA(e, &ubsec_rsa) || 220280297Sjkim# endif 221280297Sjkim# ifndef OPENSSL_NO_DSA 222280297Sjkim !ENGINE_set_DSA(e, &ubsec_dsa) || 223280297Sjkim# endif 224280297Sjkim# ifndef OPENSSL_NO_DH 225280297Sjkim !ENGINE_set_DH(e, &ubsec_dh) || 226280297Sjkim# endif 227280297Sjkim !ENGINE_set_destroy_function(e, ubsec_destroy) || 228280297Sjkim !ENGINE_set_init_function(e, ubsec_init) || 229280297Sjkim !ENGINE_set_finish_function(e, ubsec_finish) || 230280297Sjkim !ENGINE_set_ctrl_function(e, ubsec_ctrl) || 231280297Sjkim !ENGINE_set_cmd_defns(e, ubsec_cmd_defns)) 232280297Sjkim return 0; 233160814Ssimon 234280297Sjkim# ifndef OPENSSL_NO_RSA 235280297Sjkim /* 236280297Sjkim * We know that the "PKCS1_SSLeay()" functions hook properly to the 237280297Sjkim * Broadcom-specific mod_exp and mod_exp_crt so we use those functions. 238280297Sjkim * NB: We don't use ENGINE_openssl() or anything "more generic" because 239280297Sjkim * something like the RSAref code may not hook properly, and if you own 240280297Sjkim * one of these cards then you have the right to do RSA operations on it 241280297Sjkim * anyway! 242280297Sjkim */ 243280297Sjkim meth1 = RSA_PKCS1_SSLeay(); 244280297Sjkim ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc; 245280297Sjkim ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 246280297Sjkim ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc; 247280297Sjkim ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec; 248280297Sjkim# endif 249160814Ssimon 250280297Sjkim# ifndef OPENSSL_NO_DH 251280297Sjkim# ifndef HAVE_UBSEC_DH 252280297Sjkim /* Much the same for Diffie-Hellman */ 253280297Sjkim meth3 = DH_OpenSSL(); 254280297Sjkim ubsec_dh.generate_key = meth3->generate_key; 255280297Sjkim ubsec_dh.compute_key = meth3->compute_key; 256280297Sjkim# endif /* HAVE_UBSEC_DH */ 257280297Sjkim# endif 258160814Ssimon 259280297Sjkim /* Ensure the ubsec error handling is set up */ 260280297Sjkim ERR_load_UBSEC_strings(); 261280297Sjkim return 1; 262280297Sjkim} 263160814Ssimon 264280297Sjkim# ifdef OPENSSL_NO_DYNAMIC_ENGINE 265160814Ssimonstatic ENGINE *engine_ubsec(void) 266280297Sjkim{ 267280297Sjkim ENGINE *ret = ENGINE_new(); 268280297Sjkim if (!ret) 269280297Sjkim return NULL; 270280297Sjkim if (!bind_helper(ret)) { 271280297Sjkim ENGINE_free(ret); 272280297Sjkim return NULL; 273280297Sjkim } 274280297Sjkim return ret; 275280297Sjkim} 276160814Ssimon 277160814Ssimonvoid ENGINE_load_ubsec(void) 278280297Sjkim{ 279280297Sjkim /* Copied from eng_[openssl|dyn].c */ 280280297Sjkim ENGINE *toadd = engine_ubsec(); 281280297Sjkim if (!toadd) 282280297Sjkim return; 283280297Sjkim ENGINE_add(toadd); 284280297Sjkim ENGINE_free(toadd); 285280297Sjkim ERR_clear_error(); 286280297Sjkim} 287280297Sjkim# endif 288160814Ssimon 289280297Sjkim/* 290280297Sjkim * This is a process-global DSO handle used for loading and unloading the 291280297Sjkim * UBSEC library. NB: This is only set (or unset) during an init() or 292280297Sjkim * finish() call (reference counts permitting) and they're operating with 293280297Sjkim * global locks, so this should be thread-safe implicitly. 294280297Sjkim */ 295160814Ssimon 296160814Ssimonstatic DSO *ubsec_dso = NULL; 297160814Ssimon 298280297Sjkim/* 299280297Sjkim * These are the function pointers that are (un)set when the library has 300280297Sjkim * successfully (un)loaded. 301280297Sjkim */ 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; 307280297Sjkim# ifndef OPENSSL_NO_DH 308280297Sjkimstatic t_UBSEC_diffie_hellman_generate_ioctl 309280297Sjkim * p_UBSEC_diffie_hellman_generate_ioctl = NULL; 310280297Sjkimstatic t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl 311280297Sjkim = NULL; 312280297Sjkim# endif 313280297Sjkim# 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; 316280297Sjkim# endif 317280297Sjkim# 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; 320280297Sjkim# 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 327280297Sjkim/* 328160814Ssimon * These are the static string constants for the DSO file name and the function 329280297Sjkim * symbol names to bind to. 330160814Ssimon */ 331160814Ssimon 332160814Ssimonstatic const char *UBSEC_LIBNAME = NULL; 333160814Ssimonstatic const char *get_UBSEC_LIBNAME(void) 334280297Sjkim{ 335280297Sjkim if (UBSEC_LIBNAME) 336280297Sjkim return UBSEC_LIBNAME; 337280297Sjkim return "ubsec"; 338280297Sjkim} 339280297Sjkim 340160814Ssimonstatic void free_UBSEC_LIBNAME(void) 341280297Sjkim{ 342280297Sjkim if (UBSEC_LIBNAME) 343280297Sjkim OPENSSL_free((void *)UBSEC_LIBNAME); 344280297Sjkim UBSEC_LIBNAME = NULL; 345280297Sjkim} 346280297Sjkim 347160814Ssimonstatic long set_UBSEC_LIBNAME(const char *name) 348280297Sjkim{ 349280297Sjkim free_UBSEC_LIBNAME(); 350280297Sjkim return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); 351280297Sjkim} 352280297Sjkim 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"; 357280297Sjkim# ifndef OPENSSL_NO_DH 358160814Ssimonstatic const char *UBSEC_F5 = "diffie_hellman_generate_ioctl"; 359160814Ssimonstatic const char *UBSEC_F6 = "diffie_hellman_agree_ioctl"; 360280297Sjkim# 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 */ 365280297Sjkim# ifndef OPENSSL_NO_DSA 366160814Ssimonstatic const char *UBSEC_F9 = "dsa_sign_ioctl"; 367160814Ssimonstatic const char *UBSEC_F10 = "dsa_verify_ioctl"; 368280297Sjkim# 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) 375280297Sjkim{ 376280297Sjkim free_UBSEC_LIBNAME(); 377280297Sjkim ERR_unload_UBSEC_strings(); 378280297Sjkim return 1; 379280297Sjkim} 380160814Ssimon 381160814Ssimon/* (de)initialisation functions. */ 382160814Ssimonstatic int ubsec_init(ENGINE *e) 383280297Sjkim{ 384280297Sjkim t_UBSEC_ubsec_bytes_to_bits *p1; 385280297Sjkim t_UBSEC_ubsec_bits_to_bytes *p2; 386280297Sjkim t_UBSEC_ubsec_open *p3; 387280297Sjkim t_UBSEC_ubsec_close *p4; 388280297Sjkim# ifndef OPENSSL_NO_DH 389280297Sjkim t_UBSEC_diffie_hellman_generate_ioctl *p5; 390280297Sjkim t_UBSEC_diffie_hellman_agree_ioctl *p6; 391280297Sjkim# endif 392160814Ssimon/* #ifndef OPENSSL_NO_RSA */ 393280297Sjkim t_UBSEC_rsa_mod_exp_ioctl *p7; 394280297Sjkim t_UBSEC_rsa_mod_exp_crt_ioctl *p8; 395160814Ssimon/* #endif */ 396280297Sjkim# ifndef OPENSSL_NO_DSA 397280297Sjkim t_UBSEC_dsa_sign_ioctl *p9; 398280297Sjkim t_UBSEC_dsa_verify_ioctl *p10; 399280297Sjkim# endif 400280297Sjkim t_UBSEC_math_accelerate_ioctl *p11; 401280297Sjkim t_UBSEC_rng_ioctl *p12; 402280297Sjkim t_UBSEC_max_key_len_ioctl *p13; 403280297Sjkim int fd = 0; 404160814Ssimon 405280297Sjkim if (ubsec_dso != NULL) { 406280297Sjkim UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED); 407280297Sjkim goto err; 408280297Sjkim } 409280297Sjkim /* 410280297Sjkim * Attempt to load libubsec.so/ubsec.dll/whatever. 411280297Sjkim */ 412280297Sjkim ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0); 413280297Sjkim if (ubsec_dso == NULL) { 414280297Sjkim UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); 415280297Sjkim goto err; 416280297Sjkim } 417160814Ssimon 418280297Sjkim if (!(p1 = (t_UBSEC_ubsec_bytes_to_bits *) 419280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F1)) 420280297Sjkim || !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) 421280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F2)) 422280297Sjkim || !(p3 = (t_UBSEC_ubsec_open *) 423280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F3)) 424280297Sjkim || !(p4 = (t_UBSEC_ubsec_close *) 425280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F4)) 426280297Sjkim# ifndef OPENSSL_NO_DH 427280297Sjkim || !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *) 428280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F5)) 429280297Sjkim || !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *) 430280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F6)) 431280297Sjkim# endif 432160814Ssimon/* #ifndef OPENSSL_NO_RSA */ 433280297Sjkim || !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) 434280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F7)) 435280297Sjkim || !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) 436280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F8)) 437160814Ssimon/* #endif */ 438280297Sjkim# ifndef OPENSSL_NO_DSA 439280297Sjkim || !(p9 = (t_UBSEC_dsa_sign_ioctl *) 440280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F9)) 441280297Sjkim || !(p10 = (t_UBSEC_dsa_verify_ioctl *) 442280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F10)) 443280297Sjkim# endif 444280297Sjkim || !(p11 = (t_UBSEC_math_accelerate_ioctl *) 445280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F11)) 446280297Sjkim || !(p12 = (t_UBSEC_rng_ioctl *) 447280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F12)) 448280297Sjkim || !(p13 = (t_UBSEC_max_key_len_ioctl *) 449280297Sjkim DSO_bind_func(ubsec_dso, UBSEC_F13))) { 450280297Sjkim UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); 451280297Sjkim goto err; 452280297Sjkim } 453160814Ssimon 454280297Sjkim /* Copy the pointers */ 455280297Sjkim p_UBSEC_ubsec_bytes_to_bits = p1; 456280297Sjkim p_UBSEC_ubsec_bits_to_bytes = p2; 457280297Sjkim p_UBSEC_ubsec_open = p3; 458280297Sjkim p_UBSEC_ubsec_close = p4; 459280297Sjkim# ifndef OPENSSL_NO_DH 460280297Sjkim p_UBSEC_diffie_hellman_generate_ioctl = p5; 461280297Sjkim p_UBSEC_diffie_hellman_agree_ioctl = p6; 462280297Sjkim# endif 463280297Sjkim# ifndef OPENSSL_NO_RSA 464280297Sjkim p_UBSEC_rsa_mod_exp_ioctl = p7; 465280297Sjkim p_UBSEC_rsa_mod_exp_crt_ioctl = p8; 466280297Sjkim# endif 467280297Sjkim# ifndef OPENSSL_NO_DSA 468280297Sjkim p_UBSEC_dsa_sign_ioctl = p9; 469280297Sjkim p_UBSEC_dsa_verify_ioctl = p10; 470280297Sjkim# endif 471280297Sjkim p_UBSEC_math_accelerate_ioctl = p11; 472280297Sjkim p_UBSEC_rng_ioctl = p12; 473280297Sjkim p_UBSEC_max_key_len_ioctl = p13; 474160814Ssimon 475280297Sjkim /* Perform an open to see if there's actually any unit running. */ 476280297Sjkim if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) 477280297Sjkim && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0)) { 478280297Sjkim p_UBSEC_ubsec_close(fd); 479280297Sjkim return 1; 480280297Sjkim } else { 481280297Sjkim UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); 482280297Sjkim } 483160814Ssimon 484280297Sjkim err: 485280297Sjkim if (ubsec_dso) 486280297Sjkim DSO_free(ubsec_dso); 487280297Sjkim ubsec_dso = NULL; 488280297Sjkim p_UBSEC_ubsec_bytes_to_bits = NULL; 489280297Sjkim p_UBSEC_ubsec_bits_to_bytes = NULL; 490280297Sjkim p_UBSEC_ubsec_open = NULL; 491280297Sjkim p_UBSEC_ubsec_close = NULL; 492280297Sjkim# ifndef OPENSSL_NO_DH 493280297Sjkim p_UBSEC_diffie_hellman_generate_ioctl = NULL; 494280297Sjkim p_UBSEC_diffie_hellman_agree_ioctl = NULL; 495280297Sjkim# endif 496280297Sjkim# ifndef OPENSSL_NO_RSA 497280297Sjkim p_UBSEC_rsa_mod_exp_ioctl = NULL; 498280297Sjkim p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 499280297Sjkim# endif 500280297Sjkim# ifndef OPENSSL_NO_DSA 501280297Sjkim p_UBSEC_dsa_sign_ioctl = NULL; 502280297Sjkim p_UBSEC_dsa_verify_ioctl = NULL; 503280297Sjkim# endif 504280297Sjkim p_UBSEC_math_accelerate_ioctl = NULL; 505280297Sjkim p_UBSEC_rng_ioctl = NULL; 506280297Sjkim p_UBSEC_max_key_len_ioctl = NULL; 507160814Ssimon 508280297Sjkim return 0; 509280297Sjkim} 510160814Ssimon 511160814Ssimonstatic int ubsec_finish(ENGINE *e) 512280297Sjkim{ 513280297Sjkim free_UBSEC_LIBNAME(); 514280297Sjkim if (ubsec_dso == NULL) { 515280297Sjkim UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED); 516280297Sjkim return 0; 517280297Sjkim } 518280297Sjkim if (!DSO_free(ubsec_dso)) { 519280297Sjkim UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE); 520280297Sjkim return 0; 521280297Sjkim } 522280297Sjkim ubsec_dso = NULL; 523280297Sjkim p_UBSEC_ubsec_bytes_to_bits = NULL; 524280297Sjkim p_UBSEC_ubsec_bits_to_bytes = NULL; 525280297Sjkim p_UBSEC_ubsec_open = NULL; 526280297Sjkim p_UBSEC_ubsec_close = NULL; 527280297Sjkim# ifndef OPENSSL_NO_DH 528280297Sjkim p_UBSEC_diffie_hellman_generate_ioctl = NULL; 529280297Sjkim p_UBSEC_diffie_hellman_agree_ioctl = NULL; 530280297Sjkim# endif 531280297Sjkim# ifndef OPENSSL_NO_RSA 532280297Sjkim p_UBSEC_rsa_mod_exp_ioctl = NULL; 533280297Sjkim p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 534280297Sjkim# endif 535280297Sjkim# ifndef OPENSSL_NO_DSA 536280297Sjkim p_UBSEC_dsa_sign_ioctl = NULL; 537280297Sjkim p_UBSEC_dsa_verify_ioctl = NULL; 538280297Sjkim# endif 539280297Sjkim p_UBSEC_math_accelerate_ioctl = NULL; 540280297Sjkim p_UBSEC_rng_ioctl = NULL; 541280297Sjkim p_UBSEC_max_key_len_ioctl = NULL; 542280297Sjkim return 1; 543280297Sjkim} 544160814Ssimon 545280297Sjkimstatic int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 546280297Sjkim{ 547280297Sjkim int initialised = ((ubsec_dso == NULL) ? 0 : 1); 548280297Sjkim switch (cmd) { 549280297Sjkim case UBSEC_CMD_SO_PATH: 550280297Sjkim if (p == NULL) { 551280297Sjkim UBSECerr(UBSEC_F_UBSEC_CTRL, ERR_R_PASSED_NULL_PARAMETER); 552280297Sjkim return 0; 553280297Sjkim } 554280297Sjkim if (initialised) { 555280297Sjkim UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_ALREADY_LOADED); 556280297Sjkim return 0; 557280297Sjkim } 558280297Sjkim return set_UBSEC_LIBNAME((const char *)p); 559280297Sjkim default: 560280297Sjkim break; 561280297Sjkim } 562280297Sjkim UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED); 563280297Sjkim return 0; 564280297Sjkim} 565160814Ssimon 566160814Ssimonstatic int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 567280297Sjkim const BIGNUM *m, BN_CTX *ctx) 568280297Sjkim{ 569280297Sjkim int y_len = 0; 570280297Sjkim int fd; 571160814Ssimon 572280297Sjkim if (ubsec_dso == NULL) { 573280297Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED); 574280297Sjkim return 0; 575280297Sjkim } 576160814Ssimon 577280297Sjkim /* Check if hardware can't handle this argument. */ 578280297Sjkim y_len = BN_num_bits(m); 579280297Sjkim if (y_len > max_key_len) { 580280297Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 581280297Sjkim return BN_mod_exp(r, a, p, m, ctx); 582280297Sjkim } 583160814Ssimon 584280297Sjkim if (!bn_wexpand(r, m->top)) { 585280297Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL); 586280297Sjkim return 0; 587280297Sjkim } 588160814Ssimon 589280297Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 590280297Sjkim fd = 0; 591280297Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE); 592280297Sjkim return BN_mod_exp(r, a, p, m, ctx); 593280297Sjkim } 594160814Ssimon 595280297Sjkim if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a), 596280297Sjkim (unsigned char *)m->d, BN_num_bits(m), 597280297Sjkim (unsigned char *)p->d, BN_num_bits(p), 598280297Sjkim (unsigned char *)r->d, &y_len) != 0) { 599280297Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED); 600280297Sjkim p_UBSEC_ubsec_close(fd); 601160814Ssimon 602280297Sjkim return BN_mod_exp(r, a, p, m, ctx); 603280297Sjkim } 604160814Ssimon 605280297Sjkim p_UBSEC_ubsec_close(fd); 606160814Ssimon 607280297Sjkim r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2; 608280297Sjkim return 1; 609280297Sjkim} 610160814Ssimon 611280297Sjkim# ifndef OPENSSL_NO_RSA 612280297Sjkimstatic int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, 613280297Sjkim BN_CTX *ctx) 614280297Sjkim{ 615280297Sjkim int to_return = 0; 616160814Ssimon 617280297Sjkim if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { 618280297Sjkim UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS); 619280297Sjkim goto err; 620280297Sjkim } 621160814Ssimon 622280297Sjkim to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, 623280297Sjkim rsa->dmq1, rsa->iqmp, ctx); 624280297Sjkim if (to_return == FAIL_TO_SOFTWARE) { 625280297Sjkim /* 626280297Sjkim * Do in software as hardware failed. 627280297Sjkim */ 628280297Sjkim const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 629280297Sjkim to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); 630280297Sjkim } 631280297Sjkim err: 632280297Sjkim return to_return; 633280297Sjkim} 634160814Ssimon 635160814Ssimonstatic int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 636280297Sjkim const BIGNUM *q, const BIGNUM *dp, 637280297Sjkim const BIGNUM *dq, const BIGNUM *qinv, 638280297Sjkim BN_CTX *ctx) 639280297Sjkim{ 640280297Sjkim int y_len, fd; 641160814Ssimon 642280297Sjkim y_len = BN_num_bits(p) + BN_num_bits(q); 643160814Ssimon 644280297Sjkim /* Check if hardware can't handle this argument. */ 645280297Sjkim if (y_len > max_key_len) { 646280297Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, 647280297Sjkim UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 648280297Sjkim return FAIL_TO_SOFTWARE; 649280297Sjkim } 650160814Ssimon 651280297Sjkim if (!bn_wexpand(r, p->top + q->top + 1)) { 652280297Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL); 653280297Sjkim return 0; 654280297Sjkim } 655160814Ssimon 656280297Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 657280297Sjkim fd = 0; 658280297Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE); 659280297Sjkim return FAIL_TO_SOFTWARE; 660280297Sjkim } 661160814Ssimon 662280297Sjkim if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd, 663280297Sjkim (unsigned char *)a->d, BN_num_bits(a), 664280297Sjkim (unsigned char *)qinv->d, 665280297Sjkim BN_num_bits(qinv), 666280297Sjkim (unsigned char *)dp->d, BN_num_bits(dp), 667280297Sjkim (unsigned char *)p->d, BN_num_bits(p), 668280297Sjkim (unsigned char *)dq->d, BN_num_bits(dq), 669280297Sjkim (unsigned char *)q->d, BN_num_bits(q), 670280297Sjkim (unsigned char *)r->d, &y_len) != 0) { 671280297Sjkim UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED); 672280297Sjkim p_UBSEC_ubsec_close(fd); 673280297Sjkim return FAIL_TO_SOFTWARE; 674280297Sjkim } 675160814Ssimon 676280297Sjkim p_UBSEC_ubsec_close(fd); 677160814Ssimon 678280297Sjkim r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1) / BN_BITS2; 679280297Sjkim return 1; 680160814Ssimon} 681280297Sjkim# endif 682160814Ssimon 683280297Sjkim# ifndef OPENSSL_NO_DSA 684280297Sjkim# ifdef NOT_USED 685160814Ssimonstatic int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 686280297Sjkim BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 687280297Sjkim BN_CTX *ctx, BN_MONT_CTX *in_mont) 688280297Sjkim{ 689280297Sjkim BIGNUM t; 690280297Sjkim int to_return = 0; 691160814Ssimon 692280297Sjkim BN_init(&t); 693280297Sjkim /* let rr = a1 ^ p1 mod m */ 694280297Sjkim if (!ubsec_mod_exp(rr, a1, p1, m, ctx)) 695280297Sjkim goto end; 696280297Sjkim /* let t = a2 ^ p2 mod m */ 697280297Sjkim if (!ubsec_mod_exp(&t, a2, p2, m, ctx)) 698280297Sjkim goto end; 699280297Sjkim /* let rr = rr * t mod m */ 700280297Sjkim if (!BN_mod_mul(rr, rr, &t, m, ctx)) 701280297Sjkim goto end; 702280297Sjkim to_return = 1; 703280297Sjkim end: 704280297Sjkim BN_free(&t); 705280297Sjkim return to_return; 706280297Sjkim} 707280297Sjkim 708160814Ssimonstatic int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 709280297Sjkim const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 710280297Sjkim BN_MONT_CTX *m_ctx) 711280297Sjkim{ 712280297Sjkim return ubsec_mod_exp(r, a, p, m, ctx); 713280297Sjkim} 714280297Sjkim# endif 715280297Sjkim# endif 716160814Ssimon 717280297Sjkim# 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, 723280297Sjkim const BIGNUM *m, BN_CTX *ctx, 724280297Sjkim BN_MONT_CTX *m_ctx) 725280297Sjkim{ 726280297Sjkim int ret = 0; 727160814Ssimon 728280297Sjkim /* Do in software if the key is too large for the hardware. */ 729280297Sjkim if (BN_num_bits(m) > max_key_len) { 730280297Sjkim const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 731280297Sjkim ret = (*meth->bn_mod_exp) (r, a, p, m, ctx, m_ctx); 732280297Sjkim } else { 733280297Sjkim ret = ubsec_mod_exp(r, a, p, m, ctx); 734280297Sjkim } 735160814Ssimon 736280297Sjkim return ret; 737280297Sjkim} 738280297Sjkim# endif 739280297Sjkim 740280297Sjkim# 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, 743280297Sjkim const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 744280297Sjkim BN_MONT_CTX *m_ctx) 745280297Sjkim{ 746280297Sjkim return ubsec_mod_exp(r, a, p, m, ctx); 747280297Sjkim} 748280297Sjkim# endif 749160814Ssimon 750280297Sjkim# ifndef OPENSSL_NO_DSA 751280297Sjkimstatic DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, 752280297Sjkim DSA *dsa) 753280297Sjkim{ 754280297Sjkim DSA_SIG *to_return = NULL; 755280297Sjkim int s_len = 160, r_len = 160, d_len, fd; 756280297Sjkim BIGNUM m, *r = NULL, *s = NULL; 757160814Ssimon 758280297Sjkim BN_init(&m); 759160814Ssimon 760280297Sjkim s = BN_new(); 761280297Sjkim r = BN_new(); 762280297Sjkim if ((s == NULL) || (r == NULL)) 763280297Sjkim goto err; 764160814Ssimon 765280297Sjkim d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen); 766160814Ssimon 767280297Sjkim if (!bn_wexpand(r, (160 + BN_BITS2 - 1) / BN_BITS2) || 768280297Sjkim (!bn_wexpand(s, (160 + BN_BITS2 - 1) / BN_BITS2))) { 769280297Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 770280297Sjkim goto err; 771280297Sjkim } 772160814Ssimon 773280297Sjkim if (BN_bin2bn(dgst, dlen, &m) == NULL) { 774280297Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 775280297Sjkim goto err; 776280297Sjkim } 777160814Ssimon 778280297Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 779280297Sjkim const DSA_METHOD *meth; 780280297Sjkim fd = 0; 781280297Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE); 782280297Sjkim meth = DSA_OpenSSL(); 783280297Sjkim to_return = meth->dsa_do_sign(dgst, dlen, dsa); 784280297Sjkim goto err; 785280297Sjkim } 786160814Ssimon 787280297Sjkim if (p_UBSEC_dsa_sign_ioctl(fd, 788280297Sjkim /* compute hash before signing */ 789280297Sjkim 0, (unsigned char *)dgst, d_len, NULL, 790280297Sjkim /* compute random value */ 791280297Sjkim 0, 792280297Sjkim (unsigned char *)dsa->p->d, 793280297Sjkim BN_num_bits(dsa->p), 794280297Sjkim (unsigned char *)dsa->q->d, 795280297Sjkim BN_num_bits(dsa->q), 796280297Sjkim (unsigned char *)dsa->g->d, 797280297Sjkim BN_num_bits(dsa->g), 798280297Sjkim (unsigned char *)dsa->priv_key->d, 799280297Sjkim BN_num_bits(dsa->priv_key), 800280297Sjkim (unsigned char *)r->d, &r_len, 801280297Sjkim (unsigned char *)s->d, &s_len) != 0) { 802280297Sjkim const DSA_METHOD *meth; 803160814Ssimon 804280297Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED); 805280297Sjkim p_UBSEC_ubsec_close(fd); 806280297Sjkim meth = DSA_OpenSSL(); 807280297Sjkim to_return = meth->dsa_do_sign(dgst, dlen, dsa); 808160814Ssimon 809280297Sjkim goto err; 810280297Sjkim } 811160814Ssimon 812280297Sjkim p_UBSEC_ubsec_close(fd); 813160814Ssimon 814280297Sjkim r->top = (160 + BN_BITS2 - 1) / BN_BITS2; 815280297Sjkim s->top = (160 + BN_BITS2 - 1) / BN_BITS2; 816160814Ssimon 817280297Sjkim to_return = DSA_SIG_new(); 818280297Sjkim if (to_return == NULL) { 819280297Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 820280297Sjkim goto err; 821280297Sjkim } 822160814Ssimon 823280297Sjkim to_return->r = r; 824280297Sjkim to_return->s = s; 825160814Ssimon 826280297Sjkim err: 827280297Sjkim if (!to_return) { 828280297Sjkim if (r) 829280297Sjkim BN_free(r); 830280297Sjkim if (s) 831280297Sjkim BN_free(s); 832280297Sjkim } 833280297Sjkim BN_clear_free(&m); 834280297Sjkim return to_return; 835160814Ssimon} 836160814Ssimon 837160814Ssimonstatic int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, 838280297Sjkim DSA_SIG *sig, DSA *dsa) 839280297Sjkim{ 840280297Sjkim int v_len, d_len; 841280297Sjkim int to_return = 0; 842280297Sjkim int fd; 843280297Sjkim BIGNUM v, *pv = &v; 844160814Ssimon 845280297Sjkim BN_init(&v); 846160814Ssimon 847280297Sjkim if (!bn_wexpand(pv, dsa->p->top)) { 848280297Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL); 849280297Sjkim goto err; 850280297Sjkim } 851160814Ssimon 852280297Sjkim v_len = BN_num_bits(dsa->p); 853160814Ssimon 854280297Sjkim d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len); 855160814Ssimon 856280297Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 857280297Sjkim const DSA_METHOD *meth; 858280297Sjkim fd = 0; 859280297Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE); 860280297Sjkim meth = DSA_OpenSSL(); 861280297Sjkim to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); 862280297Sjkim goto err; 863280297Sjkim } 864160814Ssimon 865280297Sjkim if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */ 866280297Sjkim (unsigned char *)dgst, d_len, 867280297Sjkim (unsigned char *)dsa->p->d, 868280297Sjkim BN_num_bits(dsa->p), 869280297Sjkim (unsigned char *)dsa->q->d, 870280297Sjkim BN_num_bits(dsa->q), 871280297Sjkim (unsigned char *)dsa->g->d, 872280297Sjkim BN_num_bits(dsa->g), 873280297Sjkim (unsigned char *)dsa->pub_key->d, 874280297Sjkim BN_num_bits(dsa->pub_key), 875280297Sjkim (unsigned char *)sig->r->d, 876280297Sjkim BN_num_bits(sig->r), 877280297Sjkim (unsigned char *)sig->s->d, 878280297Sjkim BN_num_bits(sig->s), (unsigned char *)v.d, 879280297Sjkim &v_len) != 0) { 880280297Sjkim const DSA_METHOD *meth; 881280297Sjkim UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED); 882280297Sjkim p_UBSEC_ubsec_close(fd); 883160814Ssimon 884280297Sjkim meth = DSA_OpenSSL(); 885280297Sjkim to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); 886160814Ssimon 887280297Sjkim goto err; 888280297Sjkim } 889160814Ssimon 890280297Sjkim p_UBSEC_ubsec_close(fd); 891160814Ssimon 892280297Sjkim to_return = 1; 893280297Sjkim err: 894280297Sjkim BN_clear_free(&v); 895280297Sjkim return to_return; 896280297Sjkim} 897280297Sjkim# endif 898160814Ssimon 899280297Sjkim# ifndef OPENSSL_NO_DH 900280297Sjkimstatic int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, 901280297Sjkim DH *dh) 902280297Sjkim{ 903280297Sjkim int ret = -1, k_len, fd; 904160814Ssimon 905280297Sjkim k_len = BN_num_bits(dh->p); 906160814Ssimon 907280297Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 908280297Sjkim const DH_METHOD *meth; 909280297Sjkim UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE); 910280297Sjkim meth = DH_OpenSSL(); 911280297Sjkim ret = meth->compute_key(key, pub_key, dh); 912280297Sjkim goto err; 913280297Sjkim } 914160814Ssimon 915280297Sjkim if (p_UBSEC_diffie_hellman_agree_ioctl(fd, 916280297Sjkim (unsigned char *)dh->priv_key->d, 917280297Sjkim BN_num_bits(dh->priv_key), 918280297Sjkim (unsigned char *)pub_key->d, 919280297Sjkim BN_num_bits(pub_key), 920280297Sjkim (unsigned char *)dh->p->d, 921280297Sjkim BN_num_bits(dh->p), key, 922280297Sjkim &k_len) != 0) { 923280297Sjkim /* Hardware's a no go, failover to software */ 924280297Sjkim const DH_METHOD *meth; 925280297Sjkim UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED); 926280297Sjkim p_UBSEC_ubsec_close(fd); 927160814Ssimon 928280297Sjkim meth = DH_OpenSSL(); 929280297Sjkim ret = meth->compute_key(key, pub_key, dh); 930160814Ssimon 931280297Sjkim goto err; 932280297Sjkim } 933160814Ssimon 934280297Sjkim p_UBSEC_ubsec_close(fd); 935160814Ssimon 936280297Sjkim ret = p_UBSEC_ubsec_bits_to_bytes(k_len); 937280297Sjkim err: 938280297Sjkim return ret; 939280297Sjkim} 940160814Ssimon 941160814Ssimonstatic int ubsec_dh_generate_key(DH *dh) 942280297Sjkim{ 943280297Sjkim int ret = 0, random_bits = 0, pub_key_len = 0, priv_key_len = 0, fd; 944280297Sjkim BIGNUM *pub_key = NULL; 945280297Sjkim BIGNUM *priv_key = NULL; 946160814Ssimon 947280297Sjkim /* 948280297Sjkim * How many bits should Random x be? dh_key.c 949280297Sjkim * sets the range from 0 to num_bits(modulus) ??? 950280297Sjkim */ 951160814Ssimon 952280297Sjkim if (dh->priv_key == NULL) { 953280297Sjkim priv_key = BN_new(); 954280297Sjkim if (priv_key == NULL) 955280297Sjkim goto err; 956280297Sjkim priv_key_len = BN_num_bits(dh->p); 957280297Sjkim if (bn_wexpand(priv_key, dh->p->top) == NULL) 958280297Sjkim goto err; 959280297Sjkim do 960280297Sjkim if (!BN_rand_range(priv_key, dh->p)) 961160814Ssimon goto err; 962280297Sjkim while (BN_is_zero(priv_key)) ; 963280297Sjkim random_bits = BN_num_bits(priv_key); 964280297Sjkim } else { 965280297Sjkim priv_key = dh->priv_key; 966280297Sjkim } 967160814Ssimon 968280297Sjkim if (dh->pub_key == NULL) { 969280297Sjkim pub_key = BN_new(); 970280297Sjkim if (pub_key == NULL) 971280297Sjkim goto err; 972280297Sjkim pub_key_len = BN_num_bits(dh->p); 973280297Sjkim if (bn_wexpand(pub_key, dh->p->top) == NULL) 974280297Sjkim goto err; 975280297Sjkim } else { 976280297Sjkim pub_key = dh->pub_key; 977280297Sjkim } 978160814Ssimon 979280297Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 980280297Sjkim const DH_METHOD *meth; 981280297Sjkim UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE); 982280297Sjkim meth = DH_OpenSSL(); 983280297Sjkim ret = meth->generate_key(dh); 984280297Sjkim goto err; 985280297Sjkim } 986160814Ssimon 987280297Sjkim if (p_UBSEC_diffie_hellman_generate_ioctl(fd, 988280297Sjkim (unsigned char *)priv_key->d, 989280297Sjkim &priv_key_len, 990280297Sjkim (unsigned char *)pub_key->d, 991280297Sjkim &pub_key_len, 992280297Sjkim (unsigned char *)dh->g->d, 993280297Sjkim BN_num_bits(dh->g), 994280297Sjkim (unsigned char *)dh->p->d, 995280297Sjkim BN_num_bits(dh->p), 0, 0, 996280297Sjkim random_bits) != 0) { 997280297Sjkim /* Hardware's a no go, failover to software */ 998280297Sjkim const DH_METHOD *meth; 999160814Ssimon 1000280297Sjkim UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED); 1001160814Ssimon p_UBSEC_ubsec_close(fd); 1002160814Ssimon 1003280297Sjkim meth = DH_OpenSSL(); 1004280297Sjkim ret = meth->generate_key(dh); 1005160814Ssimon 1006280297Sjkim goto err; 1007280297Sjkim } 1008160814Ssimon 1009280297Sjkim p_UBSEC_ubsec_close(fd); 1010160814Ssimon 1011280297Sjkim dh->pub_key = pub_key; 1012280297Sjkim dh->pub_key->top = (pub_key_len + BN_BITS2 - 1) / BN_BITS2; 1013280297Sjkim dh->priv_key = priv_key; 1014280297Sjkim dh->priv_key->top = (priv_key_len + BN_BITS2 - 1) / BN_BITS2; 1015160814Ssimon 1016280297Sjkim ret = 1; 1017280297Sjkim err: 1018280297Sjkim return ret; 1019280297Sjkim} 1020280297Sjkim# endif 1021160814Ssimon 1022280297Sjkim# ifdef NOT_USED 1023280297Sjkimstatic int ubsec_rand_bytes(unsigned char *buf, int num) 1024280297Sjkim{ 1025280297Sjkim int ret = 0, fd; 1026160814Ssimon 1027280297Sjkim if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 1028280297Sjkim const RAND_METHOD *meth; 1029280297Sjkim UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE); 1030280297Sjkim num = p_UBSEC_ubsec_bits_to_bytes(num); 1031280297Sjkim meth = RAND_SSLeay(); 1032280297Sjkim meth->seed(buf, num); 1033280297Sjkim ret = meth->bytes(buf, num); 1034280297Sjkim goto err; 1035280297Sjkim } 1036160814Ssimon 1037280297Sjkim num *= 8; /* bytes to bits */ 1038160814Ssimon 1039280297Sjkim if (p_UBSEC_rng_ioctl(fd, UBSEC_RNG_DIRECT, buf, &num) != 0) { 1040280297Sjkim /* Hardware's a no go, failover to software */ 1041280297Sjkim const RAND_METHOD *meth; 1042160814Ssimon 1043280297Sjkim UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED); 1044160814Ssimon p_UBSEC_ubsec_close(fd); 1045160814Ssimon 1046280297Sjkim num = p_UBSEC_ubsec_bits_to_bytes(num); 1047280297Sjkim meth = RAND_SSLeay(); 1048280297Sjkim meth->seed(buf, num); 1049280297Sjkim ret = meth->bytes(buf, num); 1050160814Ssimon 1051280297Sjkim goto err; 1052280297Sjkim } 1053160814Ssimon 1054280297Sjkim p_UBSEC_ubsec_close(fd); 1055280297Sjkim 1056280297Sjkim ret = 1; 1057280297Sjkim err: 1058280297Sjkim return (ret); 1059280297Sjkim} 1060280297Sjkim 1061160814Ssimonstatic int ubsec_rand_status(void) 1062280297Sjkim{ 1063280297Sjkim return 0; 1064280297Sjkim} 1065280297Sjkim# endif 1066160814Ssimon 1067280297Sjkim/* 1068280297Sjkim * This stuff is needed if this ENGINE is being compiled into a 1069280297Sjkim * self-contained shared-library. 1070280297Sjkim */ 1071280297Sjkim# ifndef OPENSSL_NO_DYNAMIC_ENGINE 1072160814Ssimonstatic int bind_fn(ENGINE *e, const char *id) 1073280297Sjkim{ 1074280297Sjkim if (id && (strcmp(id, engine_ubsec_id) != 0)) 1075280297Sjkim return 0; 1076280297Sjkim if (!bind_helper(e)) 1077280297Sjkim return 0; 1078280297Sjkim return 1; 1079280297Sjkim} 1080280297Sjkim 1081160814SsimonIMPLEMENT_DYNAMIC_CHECK_FN() 1082280297Sjkim IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 1083280297Sjkim# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 1084280297Sjkim# endif /* !OPENSSL_NO_HW_UBSEC */ 1085280297Sjkim#endif /* !OPENSSL_NO_HW */ 1086