1160814Ssimon/* crypto/engine/hw_ubsec.c */ 2296465Sdelphij/* 3296465Sdelphij * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project 4296465Sdelphij * 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 14296465Sdelphij * 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 67296465Sdelphij# include <openssl/rsa.h> 68160814Ssimon#endif 69160814Ssimon#ifndef OPENSSL_NO_DSA 70296465Sdelphij# include <openssl/dsa.h> 71160814Ssimon#endif 72160814Ssimon#ifndef OPENSSL_NO_DH 73296465Sdelphij# include <openssl/dh.h> 74160814Ssimon#endif 75160814Ssimon#include <openssl/bn.h> 76160814Ssimon 77160814Ssimon#ifndef OPENSSL_NO_HW 78296465Sdelphij# ifndef OPENSSL_NO_HW_UBSEC 79160814Ssimon 80296465Sdelphij# ifdef FLAT_INC 81296465Sdelphij# include "hw_ubsec.h" 82296465Sdelphij# else 83296465Sdelphij# include "vendor_defns/hw_ubsec.h" 84296465Sdelphij# endif 85160814Ssimon 86296465Sdelphij# define UBSEC_LIB_NAME "ubsec engine" 87296465Sdelphij# include "e_ubsec_err.c" 88160814Ssimon 89296465Sdelphij# define FAIL_TO_SOFTWARE -15 90160814Ssimon 91160814Ssimonstatic int ubsec_destroy(ENGINE *e); 92160814Ssimonstatic int ubsec_init(ENGINE *e); 93160814Ssimonstatic int ubsec_finish(ENGINE *e); 94296465Sdelphijstatic 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, 96296465Sdelphij const BIGNUM *m, BN_CTX *ctx); 97160814Ssimonstatic int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 98296465Sdelphij const BIGNUM *q, const BIGNUM *dp, 99296465Sdelphij const BIGNUM *dq, const BIGNUM *qinv, 100296465Sdelphij BN_CTX *ctx); 101296465Sdelphij# ifndef OPENSSL_NO_RSA 102296465Sdelphijstatic int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, 103296465Sdelphij BN_CTX *ctx); 104296465Sdelphij# endif 105160814Ssimonstatic int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 106296465Sdelphij const BIGNUM *m, BN_CTX *ctx, 107296465Sdelphij BN_MONT_CTX *m_ctx); 108296465Sdelphij# ifndef OPENSSL_NO_DSA 109296465Sdelphij# ifdef NOT_USED 110160814Ssimonstatic int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 111296465Sdelphij BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 112296465Sdelphij BN_CTX *ctx, BN_MONT_CTX *in_mont); 113160814Ssimonstatic int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 114296465Sdelphij const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 115296465Sdelphij BN_MONT_CTX *m_ctx); 116296465Sdelphij# endif 117296465Sdelphijstatic DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, 118296465Sdelphij DSA *dsa); 119160814Ssimonstatic int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, 120296465Sdelphij DSA_SIG *sig, DSA *dsa); 121296465Sdelphij# endif 122296465Sdelphij# ifndef OPENSSL_NO_DH 123160814Ssimonstatic int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 124296465Sdelphij const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 125296465Sdelphij BN_MONT_CTX *m_ctx); 126296465Sdelphijstatic int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, 127296465Sdelphij DH *dh); 128160814Ssimonstatic int ubsec_dh_generate_key(DH *dh); 129296465Sdelphij# endif 130160814Ssimon 131296465Sdelphij# ifdef NOT_USED 132160814Ssimonstatic int ubsec_rand_bytes(unsigned char *buf, int num); 133160814Ssimonstatic int ubsec_rand_status(void); 134296465Sdelphij# endif 135160814Ssimon 136296465Sdelphij# define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE 137160814Ssimonstatic const ENGINE_CMD_DEFN ubsec_cmd_defns[] = { 138296465Sdelphij {UBSEC_CMD_SO_PATH, 139296465Sdelphij "SO_PATH", 140296465Sdelphij "Specifies the path to the 'ubsec' shared library", 141296465Sdelphij ENGINE_CMD_FLAG_STRING}, 142296465Sdelphij {0, NULL, NULL, 0} 143296465Sdelphij}; 144160814Ssimon 145296465Sdelphij# ifndef OPENSSL_NO_RSA 146160814Ssimon/* Our internal RSA_METHOD that we provide pointers to */ 147296465Sdelphijstatic RSA_METHOD ubsec_rsa = { 148296465Sdelphij "UBSEC RSA method", 149296465Sdelphij NULL, 150296465Sdelphij NULL, 151296465Sdelphij NULL, 152296465Sdelphij NULL, 153296465Sdelphij ubsec_rsa_mod_exp, 154296465Sdelphij ubsec_mod_exp_mont, 155296465Sdelphij NULL, 156296465Sdelphij NULL, 157296465Sdelphij 0, 158296465Sdelphij NULL, 159296465Sdelphij NULL, 160296465Sdelphij NULL, 161296465Sdelphij NULL 162296465Sdelphij}; 163296465Sdelphij# endif 164160814Ssimon 165296465Sdelphij# ifndef OPENSSL_NO_DSA 166160814Ssimon/* Our internal DSA_METHOD that we provide pointers to */ 167296465Sdelphijstatic DSA_METHOD ubsec_dsa = { 168296465Sdelphij "UBSEC DSA method", 169296465Sdelphij ubsec_dsa_do_sign, /* dsa_do_sign */ 170296465Sdelphij NULL, /* dsa_sign_setup */ 171296465Sdelphij ubsec_dsa_verify, /* dsa_do_verify */ 172296465Sdelphij NULL, /* ubsec_dsa_mod_exp *//* dsa_mod_exp */ 173296465Sdelphij NULL, /* ubsec_mod_exp_dsa *//* bn_mod_exp */ 174296465Sdelphij NULL, /* init */ 175296465Sdelphij NULL, /* finish */ 176296465Sdelphij 0, /* flags */ 177296465Sdelphij NULL, /* app_data */ 178296465Sdelphij NULL, /* dsa_paramgen */ 179296465Sdelphij NULL /* dsa_keygen */ 180296465Sdelphij}; 181296465Sdelphij# endif 182160814Ssimon 183296465Sdelphij# ifndef OPENSSL_NO_DH 184160814Ssimon/* Our internal DH_METHOD that we provide pointers to */ 185296465Sdelphijstatic DH_METHOD ubsec_dh = { 186296465Sdelphij "UBSEC DH method", 187296465Sdelphij ubsec_dh_generate_key, 188296465Sdelphij ubsec_dh_compute_key, 189296465Sdelphij ubsec_mod_exp_dh, 190296465Sdelphij NULL, 191296465Sdelphij NULL, 192296465Sdelphij 0, 193296465Sdelphij NULL, 194296465Sdelphij NULL 195296465Sdelphij}; 196296465Sdelphij# 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 202296465Sdelphij/* 203296465Sdelphij * This internal function is used by ENGINE_ubsec() and possibly by the 204296465Sdelphij * "dynamic" ENGINE support too 205296465Sdelphij */ 206160814Ssimonstatic int bind_helper(ENGINE *e) 207296465Sdelphij{ 208296465Sdelphij# ifndef OPENSSL_NO_RSA 209296465Sdelphij const RSA_METHOD *meth1; 210296465Sdelphij# endif 211296465Sdelphij# ifndef OPENSSL_NO_DH 212296465Sdelphij# ifndef HAVE_UBSEC_DH 213296465Sdelphij const DH_METHOD *meth3; 214296465Sdelphij# endif /* HAVE_UBSEC_DH */ 215296465Sdelphij# endif 216296465Sdelphij if (!ENGINE_set_id(e, engine_ubsec_id) || 217296465Sdelphij !ENGINE_set_name(e, engine_ubsec_name) || 218296465Sdelphij# ifndef OPENSSL_NO_RSA 219296465Sdelphij !ENGINE_set_RSA(e, &ubsec_rsa) || 220296465Sdelphij# endif 221296465Sdelphij# ifndef OPENSSL_NO_DSA 222296465Sdelphij !ENGINE_set_DSA(e, &ubsec_dsa) || 223296465Sdelphij# endif 224296465Sdelphij# ifndef OPENSSL_NO_DH 225296465Sdelphij !ENGINE_set_DH(e, &ubsec_dh) || 226296465Sdelphij# endif 227296465Sdelphij !ENGINE_set_destroy_function(e, ubsec_destroy) || 228296465Sdelphij !ENGINE_set_init_function(e, ubsec_init) || 229296465Sdelphij !ENGINE_set_finish_function(e, ubsec_finish) || 230296465Sdelphij !ENGINE_set_ctrl_function(e, ubsec_ctrl) || 231296465Sdelphij !ENGINE_set_cmd_defns(e, ubsec_cmd_defns)) 232296465Sdelphij return 0; 233160814Ssimon 234296465Sdelphij# ifndef OPENSSL_NO_RSA 235296465Sdelphij /* 236296465Sdelphij * We know that the "PKCS1_SSLeay()" functions hook properly to the 237296465Sdelphij * Broadcom-specific mod_exp and mod_exp_crt so we use those functions. 238296465Sdelphij * NB: We don't use ENGINE_openssl() or anything "more generic" because 239296465Sdelphij * something like the RSAref code may not hook properly, and if you own 240296465Sdelphij * one of these cards then you have the right to do RSA operations on it 241296465Sdelphij * anyway! 242296465Sdelphij */ 243296465Sdelphij meth1 = RSA_PKCS1_SSLeay(); 244296465Sdelphij ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc; 245296465Sdelphij ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 246296465Sdelphij ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc; 247296465Sdelphij ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec; 248296465Sdelphij# endif 249160814Ssimon 250296465Sdelphij# ifndef OPENSSL_NO_DH 251296465Sdelphij# ifndef HAVE_UBSEC_DH 252296465Sdelphij /* Much the same for Diffie-Hellman */ 253296465Sdelphij meth3 = DH_OpenSSL(); 254296465Sdelphij ubsec_dh.generate_key = meth3->generate_key; 255296465Sdelphij ubsec_dh.compute_key = meth3->compute_key; 256296465Sdelphij# endif /* HAVE_UBSEC_DH */ 257296465Sdelphij# endif 258160814Ssimon 259296465Sdelphij /* Ensure the ubsec error handling is set up */ 260296465Sdelphij ERR_load_UBSEC_strings(); 261296465Sdelphij return 1; 262296465Sdelphij} 263160814Ssimon 264296465Sdelphij# ifdef OPENSSL_NO_DYNAMIC_ENGINE 265160814Ssimonstatic ENGINE *engine_ubsec(void) 266296465Sdelphij{ 267296465Sdelphij ENGINE *ret = ENGINE_new(); 268296465Sdelphij if (!ret) 269296465Sdelphij return NULL; 270296465Sdelphij if (!bind_helper(ret)) { 271296465Sdelphij ENGINE_free(ret); 272296465Sdelphij return NULL; 273296465Sdelphij } 274296465Sdelphij return ret; 275296465Sdelphij} 276160814Ssimon 277160814Ssimonvoid ENGINE_load_ubsec(void) 278296465Sdelphij{ 279296465Sdelphij /* Copied from eng_[openssl|dyn].c */ 280296465Sdelphij ENGINE *toadd = engine_ubsec(); 281296465Sdelphij if (!toadd) 282296465Sdelphij return; 283296465Sdelphij ENGINE_add(toadd); 284296465Sdelphij ENGINE_free(toadd); 285296465Sdelphij ERR_clear_error(); 286296465Sdelphij} 287296465Sdelphij# endif 288160814Ssimon 289296465Sdelphij/* 290296465Sdelphij * This is a process-global DSO handle used for loading and unloading the 291296465Sdelphij * UBSEC library. NB: This is only set (or unset) during an init() or 292296465Sdelphij * finish() call (reference counts permitting) and they're operating with 293296465Sdelphij * global locks, so this should be thread-safe implicitly. 294296465Sdelphij */ 295160814Ssimon 296160814Ssimonstatic DSO *ubsec_dso = NULL; 297160814Ssimon 298296465Sdelphij/* 299296465Sdelphij * These are the function pointers that are (un)set when the library has 300296465Sdelphij * successfully (un)loaded. 301296465Sdelphij */ 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; 307296465Sdelphij# ifndef OPENSSL_NO_DH 308296465Sdelphijstatic t_UBSEC_diffie_hellman_generate_ioctl 309296465Sdelphij * p_UBSEC_diffie_hellman_generate_ioctl = NULL; 310296465Sdelphijstatic t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl 311296465Sdelphij = NULL; 312296465Sdelphij# endif 313160814Ssimon/* #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; 316160814Ssimon/* #endif */ 317296465Sdelphij# 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; 320296465Sdelphij# 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 327296465Sdelphij/* 328160814Ssimon * These are the static string constants for the DSO file name and the function 329296465Sdelphij * symbol names to bind to. 330160814Ssimon */ 331160814Ssimon 332160814Ssimonstatic const char *UBSEC_LIBNAME = NULL; 333160814Ssimonstatic const char *get_UBSEC_LIBNAME(void) 334296465Sdelphij{ 335296465Sdelphij if (UBSEC_LIBNAME) 336296465Sdelphij return UBSEC_LIBNAME; 337296465Sdelphij return "ubsec"; 338296465Sdelphij} 339296465Sdelphij 340160814Ssimonstatic void free_UBSEC_LIBNAME(void) 341296465Sdelphij{ 342296465Sdelphij if (UBSEC_LIBNAME) 343296465Sdelphij OPENSSL_free((void *)UBSEC_LIBNAME); 344296465Sdelphij UBSEC_LIBNAME = NULL; 345296465Sdelphij} 346296465Sdelphij 347160814Ssimonstatic long set_UBSEC_LIBNAME(const char *name) 348296465Sdelphij{ 349296465Sdelphij free_UBSEC_LIBNAME(); 350296465Sdelphij return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); 351296465Sdelphij} 352296465Sdelphij 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"; 357296465Sdelphij# ifndef OPENSSL_NO_DH 358160814Ssimonstatic const char *UBSEC_F5 = "diffie_hellman_generate_ioctl"; 359160814Ssimonstatic const char *UBSEC_F6 = "diffie_hellman_agree_ioctl"; 360296465Sdelphij# 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 */ 365296465Sdelphij# ifndef OPENSSL_NO_DSA 366160814Ssimonstatic const char *UBSEC_F9 = "dsa_sign_ioctl"; 367160814Ssimonstatic const char *UBSEC_F10 = "dsa_verify_ioctl"; 368296465Sdelphij# 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) 375296465Sdelphij{ 376296465Sdelphij free_UBSEC_LIBNAME(); 377296465Sdelphij ERR_unload_UBSEC_strings(); 378296465Sdelphij return 1; 379296465Sdelphij} 380160814Ssimon 381160814Ssimon/* (de)initialisation functions. */ 382160814Ssimonstatic int ubsec_init(ENGINE *e) 383296465Sdelphij{ 384296465Sdelphij t_UBSEC_ubsec_bytes_to_bits *p1; 385296465Sdelphij t_UBSEC_ubsec_bits_to_bytes *p2; 386296465Sdelphij t_UBSEC_ubsec_open *p3; 387296465Sdelphij t_UBSEC_ubsec_close *p4; 388296465Sdelphij# ifndef OPENSSL_NO_DH 389296465Sdelphij t_UBSEC_diffie_hellman_generate_ioctl *p5; 390296465Sdelphij t_UBSEC_diffie_hellman_agree_ioctl *p6; 391296465Sdelphij# endif 392160814Ssimon/* #ifndef OPENSSL_NO_RSA */ 393296465Sdelphij t_UBSEC_rsa_mod_exp_ioctl *p7; 394296465Sdelphij t_UBSEC_rsa_mod_exp_crt_ioctl *p8; 395160814Ssimon/* #endif */ 396296465Sdelphij# ifndef OPENSSL_NO_DSA 397296465Sdelphij t_UBSEC_dsa_sign_ioctl *p9; 398296465Sdelphij t_UBSEC_dsa_verify_ioctl *p10; 399296465Sdelphij# endif 400296465Sdelphij t_UBSEC_math_accelerate_ioctl *p11; 401296465Sdelphij t_UBSEC_rng_ioctl *p12; 402296465Sdelphij t_UBSEC_max_key_len_ioctl *p13; 403296465Sdelphij int fd = 0; 404160814Ssimon 405296465Sdelphij if (ubsec_dso != NULL) { 406296465Sdelphij UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED); 407296465Sdelphij goto err; 408296465Sdelphij } 409296465Sdelphij /* 410296465Sdelphij * Attempt to load libubsec.so/ubsec.dll/whatever. 411296465Sdelphij */ 412296465Sdelphij ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0); 413296465Sdelphij if (ubsec_dso == NULL) { 414296465Sdelphij UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); 415296465Sdelphij goto err; 416296465Sdelphij } 417160814Ssimon 418296465Sdelphij if (!(p1 = (t_UBSEC_ubsec_bytes_to_bits *) 419296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F1)) 420296465Sdelphij || !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) 421296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F2)) 422296465Sdelphij || !(p3 = (t_UBSEC_ubsec_open *) 423296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F3)) 424296465Sdelphij || !(p4 = (t_UBSEC_ubsec_close *) 425296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F4)) 426296465Sdelphij# ifndef OPENSSL_NO_DH 427296465Sdelphij || !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *) 428296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F5)) 429296465Sdelphij || !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *) 430296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F6)) 431296465Sdelphij# endif 432160814Ssimon/* #ifndef OPENSSL_NO_RSA */ 433296465Sdelphij || !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) 434296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F7)) 435296465Sdelphij || !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) 436296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F8)) 437160814Ssimon/* #endif */ 438296465Sdelphij# ifndef OPENSSL_NO_DSA 439296465Sdelphij || !(p9 = (t_UBSEC_dsa_sign_ioctl *) 440296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F9)) 441296465Sdelphij || !(p10 = (t_UBSEC_dsa_verify_ioctl *) 442296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F10)) 443296465Sdelphij# endif 444296465Sdelphij || !(p11 = (t_UBSEC_math_accelerate_ioctl *) 445296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F11)) 446296465Sdelphij || !(p12 = (t_UBSEC_rng_ioctl *) 447296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F12)) 448296465Sdelphij || !(p13 = (t_UBSEC_max_key_len_ioctl *) 449296465Sdelphij DSO_bind_func(ubsec_dso, UBSEC_F13))) { 450296465Sdelphij UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); 451296465Sdelphij goto err; 452296465Sdelphij } 453160814Ssimon 454296465Sdelphij /* Copy the pointers */ 455296465Sdelphij p_UBSEC_ubsec_bytes_to_bits = p1; 456296465Sdelphij p_UBSEC_ubsec_bits_to_bytes = p2; 457296465Sdelphij p_UBSEC_ubsec_open = p3; 458296465Sdelphij p_UBSEC_ubsec_close = p4; 459296465Sdelphij# ifndef OPENSSL_NO_DH 460296465Sdelphij p_UBSEC_diffie_hellman_generate_ioctl = p5; 461296465Sdelphij p_UBSEC_diffie_hellman_agree_ioctl = p6; 462296465Sdelphij# endif 463296465Sdelphij# ifndef OPENSSL_NO_RSA 464296465Sdelphij p_UBSEC_rsa_mod_exp_ioctl = p7; 465296465Sdelphij p_UBSEC_rsa_mod_exp_crt_ioctl = p8; 466296465Sdelphij# endif 467296465Sdelphij# ifndef OPENSSL_NO_DSA 468296465Sdelphij p_UBSEC_dsa_sign_ioctl = p9; 469296465Sdelphij p_UBSEC_dsa_verify_ioctl = p10; 470296465Sdelphij# endif 471296465Sdelphij p_UBSEC_math_accelerate_ioctl = p11; 472296465Sdelphij p_UBSEC_rng_ioctl = p12; 473296465Sdelphij p_UBSEC_max_key_len_ioctl = p13; 474160814Ssimon 475296465Sdelphij /* Perform an open to see if there's actually any unit running. */ 476296465Sdelphij if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) 477296465Sdelphij && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0)) { 478296465Sdelphij p_UBSEC_ubsec_close(fd); 479296465Sdelphij return 1; 480296465Sdelphij } else { 481296465Sdelphij UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); 482296465Sdelphij } 483160814Ssimon 484296465Sdelphij err: 485296465Sdelphij if (ubsec_dso) 486296465Sdelphij DSO_free(ubsec_dso); 487296465Sdelphij ubsec_dso = NULL; 488296465Sdelphij p_UBSEC_ubsec_bytes_to_bits = NULL; 489296465Sdelphij p_UBSEC_ubsec_bits_to_bytes = NULL; 490296465Sdelphij p_UBSEC_ubsec_open = NULL; 491296465Sdelphij p_UBSEC_ubsec_close = NULL; 492296465Sdelphij# ifndef OPENSSL_NO_DH 493296465Sdelphij p_UBSEC_diffie_hellman_generate_ioctl = NULL; 494296465Sdelphij p_UBSEC_diffie_hellman_agree_ioctl = NULL; 495296465Sdelphij# endif 496296465Sdelphij# ifndef OPENSSL_NO_RSA 497296465Sdelphij p_UBSEC_rsa_mod_exp_ioctl = NULL; 498296465Sdelphij p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 499296465Sdelphij# endif 500296465Sdelphij# ifndef OPENSSL_NO_DSA 501296465Sdelphij p_UBSEC_dsa_sign_ioctl = NULL; 502296465Sdelphij p_UBSEC_dsa_verify_ioctl = NULL; 503296465Sdelphij# endif 504296465Sdelphij p_UBSEC_math_accelerate_ioctl = NULL; 505296465Sdelphij p_UBSEC_rng_ioctl = NULL; 506296465Sdelphij p_UBSEC_max_key_len_ioctl = NULL; 507160814Ssimon 508296465Sdelphij return 0; 509296465Sdelphij} 510160814Ssimon 511160814Ssimonstatic int ubsec_finish(ENGINE *e) 512296465Sdelphij{ 513296465Sdelphij free_UBSEC_LIBNAME(); 514296465Sdelphij if (ubsec_dso == NULL) { 515296465Sdelphij UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED); 516296465Sdelphij return 0; 517296465Sdelphij } 518296465Sdelphij if (!DSO_free(ubsec_dso)) { 519296465Sdelphij UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE); 520296465Sdelphij return 0; 521296465Sdelphij } 522296465Sdelphij ubsec_dso = NULL; 523296465Sdelphij p_UBSEC_ubsec_bytes_to_bits = NULL; 524296465Sdelphij p_UBSEC_ubsec_bits_to_bytes = NULL; 525296465Sdelphij p_UBSEC_ubsec_open = NULL; 526296465Sdelphij p_UBSEC_ubsec_close = NULL; 527296465Sdelphij# ifndef OPENSSL_NO_DH 528296465Sdelphij p_UBSEC_diffie_hellman_generate_ioctl = NULL; 529296465Sdelphij p_UBSEC_diffie_hellman_agree_ioctl = NULL; 530296465Sdelphij# endif 531296465Sdelphij# ifndef OPENSSL_NO_RSA 532296465Sdelphij p_UBSEC_rsa_mod_exp_ioctl = NULL; 533296465Sdelphij p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; 534296465Sdelphij# endif 535296465Sdelphij# ifndef OPENSSL_NO_DSA 536296465Sdelphij p_UBSEC_dsa_sign_ioctl = NULL; 537296465Sdelphij p_UBSEC_dsa_verify_ioctl = NULL; 538296465Sdelphij# endif 539296465Sdelphij p_UBSEC_math_accelerate_ioctl = NULL; 540296465Sdelphij p_UBSEC_rng_ioctl = NULL; 541296465Sdelphij p_UBSEC_max_key_len_ioctl = NULL; 542296465Sdelphij return 1; 543296465Sdelphij} 544160814Ssimon 545296465Sdelphijstatic int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 546296465Sdelphij{ 547296465Sdelphij int initialised = ((ubsec_dso == NULL) ? 0 : 1); 548296465Sdelphij switch (cmd) { 549296465Sdelphij case UBSEC_CMD_SO_PATH: 550296465Sdelphij if (p == NULL) { 551296465Sdelphij UBSECerr(UBSEC_F_UBSEC_CTRL, ERR_R_PASSED_NULL_PARAMETER); 552296465Sdelphij return 0; 553296465Sdelphij } 554296465Sdelphij if (initialised) { 555296465Sdelphij UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_ALREADY_LOADED); 556296465Sdelphij return 0; 557296465Sdelphij } 558296465Sdelphij return set_UBSEC_LIBNAME((const char *)p); 559296465Sdelphij default: 560296465Sdelphij break; 561296465Sdelphij } 562296465Sdelphij UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED); 563296465Sdelphij return 0; 564296465Sdelphij} 565160814Ssimon 566160814Ssimonstatic int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 567296465Sdelphij const BIGNUM *m, BN_CTX *ctx) 568296465Sdelphij{ 569296465Sdelphij int y_len = 0; 570296465Sdelphij int fd; 571160814Ssimon 572296465Sdelphij if (ubsec_dso == NULL) { 573296465Sdelphij UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED); 574296465Sdelphij return 0; 575296465Sdelphij } 576160814Ssimon 577296465Sdelphij /* Check if hardware can't handle this argument. */ 578296465Sdelphij y_len = BN_num_bits(m); 579296465Sdelphij if (y_len > max_key_len) { 580296465Sdelphij UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 581296465Sdelphij return BN_mod_exp(r, a, p, m, ctx); 582296465Sdelphij } 583160814Ssimon 584296465Sdelphij if (!bn_wexpand(r, m->top)) { 585296465Sdelphij UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL); 586296465Sdelphij return 0; 587296465Sdelphij } 588160814Ssimon 589296465Sdelphij if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 590296465Sdelphij fd = 0; 591296465Sdelphij UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE); 592296465Sdelphij return BN_mod_exp(r, a, p, m, ctx); 593296465Sdelphij } 594160814Ssimon 595296465Sdelphij if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a), 596296465Sdelphij (unsigned char *)m->d, BN_num_bits(m), 597296465Sdelphij (unsigned char *)p->d, BN_num_bits(p), 598296465Sdelphij (unsigned char *)r->d, &y_len) != 0) { 599296465Sdelphij UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED); 600296465Sdelphij p_UBSEC_ubsec_close(fd); 601160814Ssimon 602296465Sdelphij return BN_mod_exp(r, a, p, m, ctx); 603296465Sdelphij } 604160814Ssimon 605296465Sdelphij p_UBSEC_ubsec_close(fd); 606160814Ssimon 607296465Sdelphij r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2; 608296465Sdelphij return 1; 609296465Sdelphij} 610160814Ssimon 611296465Sdelphij# ifndef OPENSSL_NO_RSA 612296465Sdelphijstatic int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, 613296465Sdelphij BN_CTX *ctx) 614296465Sdelphij{ 615296465Sdelphij int to_return = 0; 616160814Ssimon 617296465Sdelphij if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { 618296465Sdelphij UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS); 619296465Sdelphij goto err; 620296465Sdelphij } 621160814Ssimon 622296465Sdelphij to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, 623296465Sdelphij rsa->dmq1, rsa->iqmp, ctx); 624296465Sdelphij if (to_return == FAIL_TO_SOFTWARE) { 625296465Sdelphij /* 626296465Sdelphij * Do in software as hardware failed. 627296465Sdelphij */ 628296465Sdelphij const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 629296465Sdelphij to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); 630296465Sdelphij } 631296465Sdelphij err: 632296465Sdelphij return to_return; 633296465Sdelphij} 634296465Sdelphij# endif 635160814Ssimon 636160814Ssimonstatic int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 637296465Sdelphij const BIGNUM *q, const BIGNUM *dp, 638296465Sdelphij const BIGNUM *dq, const BIGNUM *qinv, 639296465Sdelphij BN_CTX *ctx) 640296465Sdelphij{ 641296465Sdelphij int y_len, fd; 642160814Ssimon 643296465Sdelphij y_len = BN_num_bits(p) + BN_num_bits(q); 644160814Ssimon 645296465Sdelphij /* Check if hardware can't handle this argument. */ 646296465Sdelphij if (y_len > max_key_len) { 647296465Sdelphij UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, 648296465Sdelphij UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 649296465Sdelphij return FAIL_TO_SOFTWARE; 650296465Sdelphij } 651160814Ssimon 652296465Sdelphij if (!bn_wexpand(r, p->top + q->top + 1)) { 653296465Sdelphij UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL); 654296465Sdelphij return 0; 655296465Sdelphij } 656160814Ssimon 657296465Sdelphij if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 658296465Sdelphij fd = 0; 659296465Sdelphij UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE); 660296465Sdelphij return FAIL_TO_SOFTWARE; 661296465Sdelphij } 662160814Ssimon 663296465Sdelphij if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd, 664296465Sdelphij (unsigned char *)a->d, BN_num_bits(a), 665296465Sdelphij (unsigned char *)qinv->d, 666296465Sdelphij BN_num_bits(qinv), 667296465Sdelphij (unsigned char *)dp->d, BN_num_bits(dp), 668296465Sdelphij (unsigned char *)p->d, BN_num_bits(p), 669296465Sdelphij (unsigned char *)dq->d, BN_num_bits(dq), 670296465Sdelphij (unsigned char *)q->d, BN_num_bits(q), 671296465Sdelphij (unsigned char *)r->d, &y_len) != 0) { 672296465Sdelphij UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED); 673296465Sdelphij p_UBSEC_ubsec_close(fd); 674296465Sdelphij return FAIL_TO_SOFTWARE; 675296465Sdelphij } 676160814Ssimon 677296465Sdelphij p_UBSEC_ubsec_close(fd); 678160814Ssimon 679296465Sdelphij r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1) / BN_BITS2; 680296465Sdelphij return 1; 681160814Ssimon} 682160814Ssimon 683296465Sdelphij# ifndef OPENSSL_NO_DSA 684296465Sdelphij# ifdef NOT_USED 685160814Ssimonstatic int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 686296465Sdelphij BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 687296465Sdelphij BN_CTX *ctx, BN_MONT_CTX *in_mont) 688296465Sdelphij{ 689296465Sdelphij BIGNUM t; 690296465Sdelphij int to_return = 0; 691160814Ssimon 692296465Sdelphij BN_init(&t); 693296465Sdelphij /* let rr = a1 ^ p1 mod m */ 694296465Sdelphij if (!ubsec_mod_exp(rr, a1, p1, m, ctx)) 695296465Sdelphij goto end; 696296465Sdelphij /* let t = a2 ^ p2 mod m */ 697296465Sdelphij if (!ubsec_mod_exp(&t, a2, p2, m, ctx)) 698296465Sdelphij goto end; 699296465Sdelphij /* let rr = rr * t mod m */ 700296465Sdelphij if (!BN_mod_mul(rr, rr, &t, m, ctx)) 701296465Sdelphij goto end; 702296465Sdelphij to_return = 1; 703296465Sdelphij end: 704296465Sdelphij BN_free(&t); 705296465Sdelphij return to_return; 706296465Sdelphij} 707296465Sdelphij 708160814Ssimonstatic int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 709296465Sdelphij const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 710296465Sdelphij BN_MONT_CTX *m_ctx) 711296465Sdelphij{ 712296465Sdelphij return ubsec_mod_exp(r, a, p, m, ctx); 713296465Sdelphij} 714296465Sdelphij# endif 715296465Sdelphij# endif 716160814Ssimon 717160814Ssimon/* 718160814Ssimon * This function is aliased to mod_exp (with the mont stuff dropped). 719160814Ssimon */ 720160814Ssimonstatic int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 721296465Sdelphij const BIGNUM *m, BN_CTX *ctx, 722296465Sdelphij BN_MONT_CTX *m_ctx) 723296465Sdelphij{ 724296465Sdelphij int ret = 0; 725160814Ssimon 726296465Sdelphij# ifndef OPENSSL_NO_RSA 727296465Sdelphij /* Do in software if the key is too large for the hardware. */ 728296465Sdelphij if (BN_num_bits(m) > max_key_len) { 729296465Sdelphij const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 730296465Sdelphij ret = (*meth->bn_mod_exp) (r, a, p, m, ctx, m_ctx); 731296465Sdelphij } else 732296465Sdelphij# endif 733296465Sdelphij { 734296465Sdelphij ret = ubsec_mod_exp(r, a, p, m, ctx); 735296465Sdelphij } 736160814Ssimon 737296465Sdelphij return ret; 738296465Sdelphij} 739296465Sdelphij 740296465Sdelphij# 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, 743296465Sdelphij const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 744296465Sdelphij BN_MONT_CTX *m_ctx) 745296465Sdelphij{ 746296465Sdelphij return ubsec_mod_exp(r, a, p, m, ctx); 747296465Sdelphij} 748296465Sdelphij# endif 749160814Ssimon 750296465Sdelphij# ifndef OPENSSL_NO_DSA 751296465Sdelphijstatic DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, 752296465Sdelphij DSA *dsa) 753296465Sdelphij{ 754296465Sdelphij DSA_SIG *to_return = NULL; 755296465Sdelphij int s_len = 160, r_len = 160, d_len, fd; 756296465Sdelphij BIGNUM m, *r = NULL, *s = NULL; 757160814Ssimon 758296465Sdelphij BN_init(&m); 759160814Ssimon 760296465Sdelphij s = BN_new(); 761296465Sdelphij r = BN_new(); 762296465Sdelphij if ((s == NULL) || (r == NULL)) 763296465Sdelphij goto err; 764160814Ssimon 765296465Sdelphij d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen); 766160814Ssimon 767296465Sdelphij if (!bn_wexpand(r, (160 + BN_BITS2 - 1) / BN_BITS2) || 768296465Sdelphij (!bn_wexpand(s, (160 + BN_BITS2 - 1) / BN_BITS2))) { 769296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 770296465Sdelphij goto err; 771296465Sdelphij } 772160814Ssimon 773296465Sdelphij if (BN_bin2bn(dgst, dlen, &m) == NULL) { 774296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 775296465Sdelphij goto err; 776296465Sdelphij } 777160814Ssimon 778296465Sdelphij if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 779296465Sdelphij const DSA_METHOD *meth; 780296465Sdelphij fd = 0; 781296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE); 782296465Sdelphij meth = DSA_OpenSSL(); 783296465Sdelphij to_return = meth->dsa_do_sign(dgst, dlen, dsa); 784296465Sdelphij goto err; 785296465Sdelphij } 786160814Ssimon 787296465Sdelphij if (p_UBSEC_dsa_sign_ioctl(fd, 788296465Sdelphij /* compute hash before signing */ 789296465Sdelphij 0, (unsigned char *)dgst, d_len, NULL, 790296465Sdelphij /* compute random value */ 791296465Sdelphij 0, 792296465Sdelphij (unsigned char *)dsa->p->d, 793296465Sdelphij BN_num_bits(dsa->p), 794296465Sdelphij (unsigned char *)dsa->q->d, 795296465Sdelphij BN_num_bits(dsa->q), 796296465Sdelphij (unsigned char *)dsa->g->d, 797296465Sdelphij BN_num_bits(dsa->g), 798296465Sdelphij (unsigned char *)dsa->priv_key->d, 799296465Sdelphij BN_num_bits(dsa->priv_key), 800296465Sdelphij (unsigned char *)r->d, &r_len, 801296465Sdelphij (unsigned char *)s->d, &s_len) != 0) { 802296465Sdelphij const DSA_METHOD *meth; 803160814Ssimon 804296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED); 805296465Sdelphij p_UBSEC_ubsec_close(fd); 806296465Sdelphij meth = DSA_OpenSSL(); 807296465Sdelphij to_return = meth->dsa_do_sign(dgst, dlen, dsa); 808160814Ssimon 809296465Sdelphij goto err; 810296465Sdelphij } 811160814Ssimon 812296465Sdelphij p_UBSEC_ubsec_close(fd); 813160814Ssimon 814296465Sdelphij r->top = (160 + BN_BITS2 - 1) / BN_BITS2; 815296465Sdelphij s->top = (160 + BN_BITS2 - 1) / BN_BITS2; 816160814Ssimon 817296465Sdelphij to_return = DSA_SIG_new(); 818296465Sdelphij if (to_return == NULL) { 819296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); 820296465Sdelphij goto err; 821296465Sdelphij } 822160814Ssimon 823296465Sdelphij to_return->r = r; 824296465Sdelphij to_return->s = s; 825160814Ssimon 826296465Sdelphij err: 827296465Sdelphij if (!to_return) { 828296465Sdelphij if (r) 829296465Sdelphij BN_free(r); 830296465Sdelphij if (s) 831296465Sdelphij BN_free(s); 832296465Sdelphij } 833296465Sdelphij BN_clear_free(&m); 834296465Sdelphij return to_return; 835160814Ssimon} 836160814Ssimon 837160814Ssimonstatic int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, 838296465Sdelphij DSA_SIG *sig, DSA *dsa) 839296465Sdelphij{ 840296465Sdelphij int v_len, d_len; 841296465Sdelphij int to_return = 0; 842296465Sdelphij int fd; 843296465Sdelphij BIGNUM v, *pv = &v; 844160814Ssimon 845296465Sdelphij BN_init(&v); 846160814Ssimon 847296465Sdelphij if (!bn_wexpand(pv, dsa->p->top)) { 848296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL); 849296465Sdelphij goto err; 850296465Sdelphij } 851160814Ssimon 852296465Sdelphij v_len = BN_num_bits(dsa->p); 853160814Ssimon 854296465Sdelphij d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len); 855160814Ssimon 856296465Sdelphij if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 857296465Sdelphij const DSA_METHOD *meth; 858296465Sdelphij fd = 0; 859296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE); 860296465Sdelphij meth = DSA_OpenSSL(); 861296465Sdelphij to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); 862296465Sdelphij goto err; 863296465Sdelphij } 864160814Ssimon 865296465Sdelphij if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */ 866296465Sdelphij (unsigned char *)dgst, d_len, 867296465Sdelphij (unsigned char *)dsa->p->d, 868296465Sdelphij BN_num_bits(dsa->p), 869296465Sdelphij (unsigned char *)dsa->q->d, 870296465Sdelphij BN_num_bits(dsa->q), 871296465Sdelphij (unsigned char *)dsa->g->d, 872296465Sdelphij BN_num_bits(dsa->g), 873296465Sdelphij (unsigned char *)dsa->pub_key->d, 874296465Sdelphij BN_num_bits(dsa->pub_key), 875296465Sdelphij (unsigned char *)sig->r->d, 876296465Sdelphij BN_num_bits(sig->r), 877296465Sdelphij (unsigned char *)sig->s->d, 878296465Sdelphij BN_num_bits(sig->s), (unsigned char *)v.d, 879296465Sdelphij &v_len) != 0) { 880296465Sdelphij const DSA_METHOD *meth; 881296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED); 882296465Sdelphij p_UBSEC_ubsec_close(fd); 883160814Ssimon 884296465Sdelphij meth = DSA_OpenSSL(); 885296465Sdelphij to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); 886160814Ssimon 887296465Sdelphij goto err; 888296465Sdelphij } 889160814Ssimon 890296465Sdelphij p_UBSEC_ubsec_close(fd); 891160814Ssimon 892296465Sdelphij to_return = 1; 893296465Sdelphij err: 894296465Sdelphij BN_clear_free(&v); 895296465Sdelphij return to_return; 896296465Sdelphij} 897296465Sdelphij# endif 898160814Ssimon 899296465Sdelphij# ifndef OPENSSL_NO_DH 900296465Sdelphijstatic int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, 901296465Sdelphij DH *dh) 902296465Sdelphij{ 903296465Sdelphij int ret = -1, k_len, fd; 904160814Ssimon 905296465Sdelphij k_len = BN_num_bits(dh->p); 906160814Ssimon 907296465Sdelphij if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 908296465Sdelphij const DH_METHOD *meth; 909296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE); 910296465Sdelphij meth = DH_OpenSSL(); 911296465Sdelphij ret = meth->compute_key(key, pub_key, dh); 912296465Sdelphij goto err; 913296465Sdelphij } 914160814Ssimon 915296465Sdelphij if (p_UBSEC_diffie_hellman_agree_ioctl(fd, 916296465Sdelphij (unsigned char *)dh->priv_key->d, 917296465Sdelphij BN_num_bits(dh->priv_key), 918296465Sdelphij (unsigned char *)pub_key->d, 919296465Sdelphij BN_num_bits(pub_key), 920296465Sdelphij (unsigned char *)dh->p->d, 921296465Sdelphij BN_num_bits(dh->p), key, 922296465Sdelphij &k_len) != 0) { 923296465Sdelphij /* Hardware's a no go, failover to software */ 924296465Sdelphij const DH_METHOD *meth; 925296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED); 926296465Sdelphij p_UBSEC_ubsec_close(fd); 927160814Ssimon 928296465Sdelphij meth = DH_OpenSSL(); 929296465Sdelphij ret = meth->compute_key(key, pub_key, dh); 930160814Ssimon 931296465Sdelphij goto err; 932296465Sdelphij } 933160814Ssimon 934296465Sdelphij p_UBSEC_ubsec_close(fd); 935160814Ssimon 936296465Sdelphij ret = p_UBSEC_ubsec_bits_to_bytes(k_len); 937296465Sdelphij err: 938296465Sdelphij return ret; 939296465Sdelphij} 940160814Ssimon 941160814Ssimonstatic int ubsec_dh_generate_key(DH *dh) 942296465Sdelphij{ 943296465Sdelphij int ret = 0, random_bits = 0, pub_key_len = 0, priv_key_len = 0, fd; 944296465Sdelphij BIGNUM *pub_key = NULL; 945296465Sdelphij BIGNUM *priv_key = NULL; 946160814Ssimon 947296465Sdelphij /* 948296465Sdelphij * How many bits should Random x be? dh_key.c 949296465Sdelphij * sets the range from 0 to num_bits(modulus) ??? 950296465Sdelphij */ 951160814Ssimon 952296465Sdelphij if (dh->priv_key == NULL) { 953296465Sdelphij priv_key = BN_new(); 954296465Sdelphij if (priv_key == NULL) 955296465Sdelphij goto err; 956296465Sdelphij priv_key_len = BN_num_bits(dh->p); 957296465Sdelphij if (bn_wexpand(priv_key, dh->p->top) == NULL) 958296465Sdelphij goto err; 959296465Sdelphij do 960296465Sdelphij if (!BN_rand_range(priv_key, dh->p)) 961160814Ssimon goto err; 962296465Sdelphij while (BN_is_zero(priv_key)) ; 963296465Sdelphij random_bits = BN_num_bits(priv_key); 964296465Sdelphij } else { 965296465Sdelphij priv_key = dh->priv_key; 966296465Sdelphij } 967160814Ssimon 968296465Sdelphij if (dh->pub_key == NULL) { 969296465Sdelphij pub_key = BN_new(); 970296465Sdelphij pub_key_len = BN_num_bits(dh->p); 971296465Sdelphij if (bn_wexpand(pub_key, dh->p->top) == NULL) 972296465Sdelphij goto err; 973296465Sdelphij if (pub_key == NULL) 974296465Sdelphij goto err; 975296465Sdelphij } else { 976296465Sdelphij pub_key = dh->pub_key; 977296465Sdelphij } 978160814Ssimon 979296465Sdelphij if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 980296465Sdelphij const DH_METHOD *meth; 981296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE); 982296465Sdelphij meth = DH_OpenSSL(); 983296465Sdelphij ret = meth->generate_key(dh); 984296465Sdelphij goto err; 985296465Sdelphij } 986160814Ssimon 987296465Sdelphij if (p_UBSEC_diffie_hellman_generate_ioctl(fd, 988296465Sdelphij (unsigned char *)priv_key->d, 989296465Sdelphij &priv_key_len, 990296465Sdelphij (unsigned char *)pub_key->d, 991296465Sdelphij &pub_key_len, 992296465Sdelphij (unsigned char *)dh->g->d, 993296465Sdelphij BN_num_bits(dh->g), 994296465Sdelphij (unsigned char *)dh->p->d, 995296465Sdelphij BN_num_bits(dh->p), 0, 0, 996296465Sdelphij random_bits) != 0) { 997296465Sdelphij /* Hardware's a no go, failover to software */ 998296465Sdelphij const DH_METHOD *meth; 999160814Ssimon 1000296465Sdelphij UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED); 1001160814Ssimon p_UBSEC_ubsec_close(fd); 1002160814Ssimon 1003296465Sdelphij meth = DH_OpenSSL(); 1004296465Sdelphij ret = meth->generate_key(dh); 1005160814Ssimon 1006296465Sdelphij goto err; 1007296465Sdelphij } 1008160814Ssimon 1009296465Sdelphij p_UBSEC_ubsec_close(fd); 1010160814Ssimon 1011296465Sdelphij dh->pub_key = pub_key; 1012296465Sdelphij dh->pub_key->top = (pub_key_len + BN_BITS2 - 1) / BN_BITS2; 1013296465Sdelphij dh->priv_key = priv_key; 1014296465Sdelphij dh->priv_key->top = (priv_key_len + BN_BITS2 - 1) / BN_BITS2; 1015160814Ssimon 1016296465Sdelphij ret = 1; 1017296465Sdelphij err: 1018296465Sdelphij return ret; 1019296465Sdelphij} 1020296465Sdelphij# endif 1021160814Ssimon 1022296465Sdelphij# ifdef NOT_USED 1023296465Sdelphijstatic int ubsec_rand_bytes(unsigned char *buf, int num) 1024296465Sdelphij{ 1025296465Sdelphij int ret = 0, fd; 1026160814Ssimon 1027296465Sdelphij if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { 1028296465Sdelphij const RAND_METHOD *meth; 1029296465Sdelphij UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE); 1030296465Sdelphij num = p_UBSEC_ubsec_bits_to_bytes(num); 1031296465Sdelphij meth = RAND_SSLeay(); 1032296465Sdelphij meth->seed(buf, num); 1033296465Sdelphij ret = meth->bytes(buf, num); 1034296465Sdelphij goto err; 1035296465Sdelphij } 1036160814Ssimon 1037296465Sdelphij num *= 8; /* bytes to bits */ 1038160814Ssimon 1039296465Sdelphij if (p_UBSEC_rng_ioctl(fd, UBSEC_RNG_DIRECT, buf, &num) != 0) { 1040296465Sdelphij /* Hardware's a no go, failover to software */ 1041296465Sdelphij const RAND_METHOD *meth; 1042160814Ssimon 1043296465Sdelphij UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED); 1044160814Ssimon p_UBSEC_ubsec_close(fd); 1045160814Ssimon 1046296465Sdelphij num = p_UBSEC_ubsec_bits_to_bytes(num); 1047296465Sdelphij meth = RAND_SSLeay(); 1048296465Sdelphij meth->seed(buf, num); 1049296465Sdelphij ret = meth->bytes(buf, num); 1050160814Ssimon 1051296465Sdelphij goto err; 1052296465Sdelphij } 1053160814Ssimon 1054296465Sdelphij p_UBSEC_ubsec_close(fd); 1055296465Sdelphij 1056296465Sdelphij ret = 1; 1057296465Sdelphij err: 1058296465Sdelphij return (ret); 1059296465Sdelphij} 1060296465Sdelphij 1061160814Ssimonstatic int ubsec_rand_status(void) 1062296465Sdelphij{ 1063296465Sdelphij return 0; 1064296465Sdelphij} 1065296465Sdelphij# endif 1066160814Ssimon 1067296465Sdelphij/* 1068296465Sdelphij * This stuff is needed if this ENGINE is being compiled into a 1069296465Sdelphij * self-contained shared-library. 1070296465Sdelphij */ 1071296465Sdelphij# ifndef OPENSSL_NO_DYNAMIC_ENGINE 1072160814Ssimonstatic int bind_fn(ENGINE *e, const char *id) 1073296465Sdelphij{ 1074296465Sdelphij if (id && (strcmp(id, engine_ubsec_id) != 0)) 1075296465Sdelphij return 0; 1076296465Sdelphij if (!bind_helper(e)) 1077296465Sdelphij return 0; 1078296465Sdelphij return 1; 1079296465Sdelphij} 1080296465Sdelphij 1081160814SsimonIMPLEMENT_DYNAMIC_CHECK_FN() 1082296465Sdelphij IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 1083296465Sdelphij# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 1084296465Sdelphij# endif /* !OPENSSL_NO_HW_UBSEC */ 1085296465Sdelphij#endif /* !OPENSSL_NO_HW */ 1086