1160814Ssimon/* Written by Corinne Dive-Reclus(cdive@baltimore.com) 2160814Ssimon* 3160814Ssimon* 4160814Ssimon* Redistribution and use in source and binary forms, with or without 5160814Ssimon* modification, are permitted provided that the following conditions 6160814Ssimon* are met: 7160814Ssimon* 8160814Ssimon* 1. Redistributions of source code must retain the above copyright 9160814Ssimon* notice, this list of conditions and the following disclaimer. 10160814Ssimon* 11160814Ssimon* 2. Redistributions in binary form must reproduce the above copyright 12160814Ssimon* notice, this list of conditions and the following disclaimer in 13160814Ssimon* the documentation and/or other materials provided with the 14160814Ssimon* distribution. 15160814Ssimon* 16160814Ssimon* 3. All advertising materials mentioning features or use of this 17160814Ssimon* software must display the following acknowledgment: 18160814Ssimon* "This product includes software developed by the OpenSSL Project 19160814Ssimon* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 20160814Ssimon* 21160814Ssimon* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22160814Ssimon* endorse or promote products derived from this software without 23160814Ssimon* prior written permission. For written permission, please contact 24160814Ssimon* licensing@OpenSSL.org. 25160814Ssimon* 26160814Ssimon* 5. Products derived from this software may not be called "OpenSSL" 27160814Ssimon* nor may "OpenSSL" appear in their names without prior written 28160814Ssimon* permission of the OpenSSL Project. 29160814Ssimon* 30160814Ssimon* 6. Redistributions of any form whatsoever must retain the following 31160814Ssimon* acknowledgment: 32160814Ssimon* "This product includes software developed by the OpenSSL Project 33160814Ssimon* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 34160814Ssimon* 35160814Ssimon* Written by Corinne Dive-Reclus(cdive@baltimore.com) 36160814Ssimon* 37160814Ssimon* Copyright@2001 Baltimore Technologies Ltd. 38160814Ssimon* All right Reserved. 39160814Ssimon* * 40160814Ssimon* THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND * 41160814Ssimon* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * 42160814Ssimon* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * 43160814Ssimon* ARE DISCLAIMED. IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE * 44160814Ssimon* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * 45160814Ssimon* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 46160814Ssimon* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * 47160814Ssimon* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 48160814Ssimon* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 49160814Ssimon* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * 50160814Ssimon* SUCH DAMAGE. * 51160814Ssimon====================================================================*/ 52160814Ssimon 53160814Ssimon#include <stdio.h> 54160814Ssimon#include <string.h> 55160814Ssimon#include <openssl/crypto.h> 56160814Ssimon#include <openssl/pem.h> 57160814Ssimon#include <openssl/dso.h> 58160814Ssimon#include <openssl/engine.h> 59160814Ssimon#include <openssl/rand.h> 60160814Ssimon#ifndef OPENSSL_NO_RSA 61160814Ssimon#include <openssl/rsa.h> 62160814Ssimon#endif 63160814Ssimon#ifndef OPENSSL_NO_DSA 64160814Ssimon#include <openssl/dsa.h> 65160814Ssimon#endif 66160814Ssimon#ifndef OPENSSL_NO_DH 67160814Ssimon#include <openssl/dh.h> 68160814Ssimon#endif 69160814Ssimon#include <openssl/bn.h> 70160814Ssimon 71160814Ssimon#ifndef OPENSSL_NO_HW 72160814Ssimon#ifndef OPENSSL_NO_HW_SUREWARE 73160814Ssimon 74160814Ssimon#ifdef FLAT_INC 75160814Ssimon#include "sureware.h" 76160814Ssimon#else 77160814Ssimon#include "vendor_defns/sureware.h" 78160814Ssimon#endif 79160814Ssimon 80160814Ssimon#define SUREWARE_LIB_NAME "sureware engine" 81160814Ssimon#include "e_sureware_err.c" 82160814Ssimon 83160814Ssimonstatic int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 84160814Ssimonstatic int surewarehk_destroy(ENGINE *e); 85160814Ssimonstatic int surewarehk_init(ENGINE *e); 86160814Ssimonstatic int surewarehk_finish(ENGINE *e); 87160814Ssimonstatic int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 88160814Ssimon const BIGNUM *m, BN_CTX *ctx); 89160814Ssimon 90160814Ssimon/* RSA stuff */ 91160814Ssimon#ifndef OPENSSL_NO_RSA 92160814Ssimonstatic int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to, 93160814Ssimon RSA *rsa,int padding); 94160814Ssimonstatic int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to, 95160814Ssimon RSA *rsa,int padding); 96160814Ssimon#endif 97160814Ssimon 98160814Ssimon/* RAND stuff */ 99160814Ssimonstatic int surewarehk_rand_bytes(unsigned char *buf, int num); 100160814Ssimonstatic void surewarehk_rand_seed(const void *buf, int num); 101160814Ssimonstatic void surewarehk_rand_add(const void *buf, int num, double entropy); 102160814Ssimon 103160814Ssimon/* KM stuff */ 104160814Ssimonstatic EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id, 105160814Ssimon UI_METHOD *ui_method, void *callback_data); 106160814Ssimonstatic EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id, 107160814Ssimon UI_METHOD *ui_method, void *callback_data); 108160814Ssimonstatic void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 109160814Ssimon int idx,long argl, void *argp); 110160814Ssimon#if 0 111160814Ssimonstatic void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 112160814Ssimon int idx,long argl, void *argp); 113160814Ssimon#endif 114160814Ssimon 115160814Ssimon#ifndef OPENSSL_NO_RSA 116160814Ssimon/* This function is aliased to mod_exp (with the mont stuff dropped). */ 117160814Ssimonstatic int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 118160814Ssimon const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 119160814Ssimon{ 120160814Ssimon return surewarehk_modexp(r, a, p, m, ctx); 121160814Ssimon} 122160814Ssimon 123160814Ssimon/* Our internal RSA_METHOD that we provide pointers to */ 124160814Ssimonstatic RSA_METHOD surewarehk_rsa = 125160814Ssimon { 126160814Ssimon "SureWare RSA method", 127160814Ssimon NULL, /* pub_enc*/ 128160814Ssimon NULL, /* pub_dec*/ 129160814Ssimon surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc*/ 130160814Ssimon surewarehk_rsa_priv_dec, /* priv_dec*/ 131160814Ssimon NULL, /*mod_exp*/ 132160814Ssimon surewarehk_mod_exp_mont, /*mod_exp_mongomery*/ 133160814Ssimon NULL, /* init*/ 134160814Ssimon NULL, /* finish*/ 135160814Ssimon 0, /* RSA flag*/ 136160814Ssimon NULL, 137160814Ssimon NULL, /* OpenSSL sign*/ 138160814Ssimon NULL, /* OpenSSL verify*/ 139160814Ssimon NULL /* keygen */ 140160814Ssimon }; 141160814Ssimon#endif 142160814Ssimon 143160814Ssimon#ifndef OPENSSL_NO_DH 144160814Ssimon/* Our internal DH_METHOD that we provide pointers to */ 145160814Ssimon/* This function is aliased to mod_exp (with the dh and mont dropped). */ 146160814Ssimonstatic int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 147160814Ssimon const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 148160814Ssimon{ 149160814Ssimon return surewarehk_modexp(r, a, p, m, ctx); 150160814Ssimon} 151160814Ssimon 152160814Ssimonstatic DH_METHOD surewarehk_dh = 153160814Ssimon { 154160814Ssimon "SureWare DH method", 155160814Ssimon NULL,/*gen_key*/ 156160814Ssimon NULL,/*agree,*/ 157160814Ssimon surewarehk_modexp_dh, /*dh mod exp*/ 158160814Ssimon NULL, /* init*/ 159160814Ssimon NULL, /* finish*/ 160160814Ssimon 0, /* flags*/ 161160814Ssimon NULL, 162160814Ssimon NULL 163160814Ssimon }; 164160814Ssimon#endif 165160814Ssimon 166160814Ssimonstatic RAND_METHOD surewarehk_rand = 167160814Ssimon { 168160814Ssimon /* "SureWare RAND method", */ 169160814Ssimon surewarehk_rand_seed, 170160814Ssimon surewarehk_rand_bytes, 171160814Ssimon NULL,/*cleanup*/ 172160814Ssimon surewarehk_rand_add, 173160814Ssimon surewarehk_rand_bytes, 174160814Ssimon NULL,/*rand_status*/ 175160814Ssimon }; 176160814Ssimon 177160814Ssimon#ifndef OPENSSL_NO_DSA 178160814Ssimon/* DSA stuff */ 179160814Ssimonstatic DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); 180160814Ssimonstatic int surewarehk_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 181160814Ssimon BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 182160814Ssimon BN_CTX *ctx, BN_MONT_CTX *in_mont) 183160814Ssimon{ 184160814Ssimon BIGNUM t; 185160814Ssimon int to_return = 0; 186160814Ssimon BN_init(&t); 187160814Ssimon /* let rr = a1 ^ p1 mod m */ 188160814Ssimon if (!surewarehk_modexp(rr,a1,p1,m,ctx)) goto end; 189160814Ssimon /* let t = a2 ^ p2 mod m */ 190160814Ssimon if (!surewarehk_modexp(&t,a2,p2,m,ctx)) goto end; 191160814Ssimon /* let rr = rr * t mod m */ 192160814Ssimon if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end; 193160814Ssimon to_return = 1; 194160814Ssimonend: 195160814Ssimon BN_free(&t); 196160814Ssimon return to_return; 197160814Ssimon} 198160814Ssimon 199160814Ssimonstatic DSA_METHOD surewarehk_dsa = 200160814Ssimon { 201160814Ssimon "SureWare DSA method", 202160814Ssimon surewarehk_dsa_do_sign, 203160814Ssimon NULL,/*sign setup*/ 204160814Ssimon NULL,/*verify,*/ 205160814Ssimon surewarehk_dsa_mod_exp,/*mod exp*/ 206160814Ssimon NULL,/*bn mod exp*/ 207160814Ssimon NULL, /*init*/ 208160814Ssimon NULL,/*finish*/ 209160814Ssimon 0, 210160814Ssimon NULL, 211160814Ssimon NULL, 212160814Ssimon NULL 213160814Ssimon }; 214160814Ssimon#endif 215160814Ssimon 216160814Ssimonstatic const char *engine_sureware_id = "sureware"; 217160814Ssimonstatic const char *engine_sureware_name = "SureWare hardware engine support"; 218160814Ssimon 219160814Ssimon/* Now, to our own code */ 220160814Ssimon 221160814Ssimon/* As this is only ever called once, there's no need for locking 222160814Ssimon * (indeed - the lock will already be held by our caller!!!) */ 223160814Ssimonstatic int bind_sureware(ENGINE *e) 224160814Ssimon{ 225160814Ssimon#ifndef OPENSSL_NO_RSA 226160814Ssimon const RSA_METHOD *meth1; 227160814Ssimon#endif 228160814Ssimon#ifndef OPENSSL_NO_DSA 229160814Ssimon const DSA_METHOD *meth2; 230160814Ssimon#endif 231160814Ssimon#ifndef OPENSSL_NO_DH 232160814Ssimon const DH_METHOD *meth3; 233160814Ssimon#endif 234160814Ssimon 235160814Ssimon if(!ENGINE_set_id(e, engine_sureware_id) || 236160814Ssimon !ENGINE_set_name(e, engine_sureware_name) || 237160814Ssimon#ifndef OPENSSL_NO_RSA 238160814Ssimon !ENGINE_set_RSA(e, &surewarehk_rsa) || 239160814Ssimon#endif 240160814Ssimon#ifndef OPENSSL_NO_DSA 241160814Ssimon !ENGINE_set_DSA(e, &surewarehk_dsa) || 242160814Ssimon#endif 243160814Ssimon#ifndef OPENSSL_NO_DH 244160814Ssimon !ENGINE_set_DH(e, &surewarehk_dh) || 245160814Ssimon#endif 246160814Ssimon !ENGINE_set_RAND(e, &surewarehk_rand) || 247160814Ssimon !ENGINE_set_destroy_function(e, surewarehk_destroy) || 248160814Ssimon !ENGINE_set_init_function(e, surewarehk_init) || 249160814Ssimon !ENGINE_set_finish_function(e, surewarehk_finish) || 250160814Ssimon !ENGINE_set_ctrl_function(e, surewarehk_ctrl) || 251160814Ssimon !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) || 252160814Ssimon !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey)) 253160814Ssimon return 0; 254160814Ssimon 255160814Ssimon#ifndef OPENSSL_NO_RSA 256160814Ssimon /* We know that the "PKCS1_SSLeay()" functions hook properly 257160814Ssimon * to the cswift-specific mod_exp and mod_exp_crt so we use 258160814Ssimon * those functions. NB: We don't use ENGINE_openssl() or 259160814Ssimon * anything "more generic" because something like the RSAref 260160814Ssimon * code may not hook properly, and if you own one of these 261160814Ssimon * cards then you have the right to do RSA operations on it 262160814Ssimon * anyway! */ 263160814Ssimon meth1 = RSA_PKCS1_SSLeay(); 264160814Ssimon if (meth1) 265160814Ssimon { 266160814Ssimon surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; 267160814Ssimon surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 268160814Ssimon } 269160814Ssimon#endif 270160814Ssimon 271160814Ssimon#ifndef OPENSSL_NO_DSA 272160814Ssimon /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish 273160814Ssimon * bits. */ 274160814Ssimon meth2 = DSA_OpenSSL(); 275160814Ssimon if (meth2) 276160814Ssimon { 277160814Ssimon surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify; 278160814Ssimon } 279160814Ssimon#endif 280160814Ssimon 281160814Ssimon#ifndef OPENSSL_NO_DH 282160814Ssimon /* Much the same for Diffie-Hellman */ 283160814Ssimon meth3 = DH_OpenSSL(); 284160814Ssimon if (meth3) 285160814Ssimon { 286160814Ssimon surewarehk_dh.generate_key = meth3->generate_key; 287160814Ssimon surewarehk_dh.compute_key = meth3->compute_key; 288160814Ssimon } 289160814Ssimon#endif 290160814Ssimon 291160814Ssimon /* Ensure the sureware error handling is set up */ 292160814Ssimon ERR_load_SUREWARE_strings(); 293160814Ssimon return 1; 294160814Ssimon} 295160814Ssimon 296160814Ssimon#ifndef OPENSSL_NO_DYNAMIC_ENGINE 297160814Ssimonstatic int bind_helper(ENGINE *e, const char *id) 298160814Ssimon { 299160814Ssimon if(id && (strcmp(id, engine_sureware_id) != 0)) 300160814Ssimon return 0; 301160814Ssimon if(!bind_sureware(e)) 302160814Ssimon return 0; 303160814Ssimon return 1; 304160814Ssimon } 305160814SsimonIMPLEMENT_DYNAMIC_CHECK_FN() 306160814SsimonIMPLEMENT_DYNAMIC_BIND_FN(bind_helper) 307160814Ssimon#else 308160814Ssimonstatic ENGINE *engine_sureware(void) 309160814Ssimon { 310160814Ssimon ENGINE *ret = ENGINE_new(); 311160814Ssimon if(!ret) 312160814Ssimon return NULL; 313160814Ssimon if(!bind_sureware(ret)) 314160814Ssimon { 315160814Ssimon ENGINE_free(ret); 316160814Ssimon return NULL; 317160814Ssimon } 318160814Ssimon return ret; 319160814Ssimon } 320160814Ssimon 321160814Ssimonvoid ENGINE_load_sureware(void) 322160814Ssimon { 323160814Ssimon /* Copied from eng_[openssl|dyn].c */ 324160814Ssimon ENGINE *toadd = engine_sureware(); 325160814Ssimon if(!toadd) return; 326160814Ssimon ENGINE_add(toadd); 327160814Ssimon ENGINE_free(toadd); 328160814Ssimon ERR_clear_error(); 329160814Ssimon } 330160814Ssimon#endif 331160814Ssimon 332160814Ssimon/* This is a process-global DSO handle used for loading and unloading 333160814Ssimon * the SureWareHook library. NB: This is only set (or unset) during an 334160814Ssimon * init() or finish() call (reference counts permitting) and they're 335160814Ssimon * operating with global locks, so this should be thread-safe 336160814Ssimon * implicitly. */ 337160814Ssimonstatic DSO *surewarehk_dso = NULL; 338160814Ssimon#ifndef OPENSSL_NO_RSA 339160814Ssimonstatic int rsaHndidx = -1; /* Index for KM handle. Not really used yet. */ 340160814Ssimon#endif 341160814Ssimon#ifndef OPENSSL_NO_DSA 342160814Ssimonstatic int dsaHndidx = -1; /* Index for KM handle. Not really used yet. */ 343160814Ssimon#endif 344160814Ssimon 345160814Ssimon/* These are the function pointers that are (un)set when the library has 346160814Ssimon * successfully (un)loaded. */ 347160814Ssimonstatic SureWareHook_Init_t *p_surewarehk_Init = NULL; 348160814Ssimonstatic SureWareHook_Finish_t *p_surewarehk_Finish = NULL; 349160814Ssimonstatic SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL; 350160814Ssimonstatic SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL; 351160814Ssimonstatic SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL; 352160814Ssimonstatic SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL; 353160814Ssimonstatic SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL; 354160814Ssimonstatic SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL; 355160814Ssimonstatic SureWareHook_Free_t *p_surewarehk_Free=NULL; 356160814Ssimonstatic SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec=NULL; 357160814Ssimonstatic SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign=NULL; 358160814Ssimonstatic SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign=NULL; 359160814Ssimonstatic SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp=NULL; 360160814Ssimon 361160814Ssimon/* Used in the DSO operations. */ 362160814Ssimonstatic const char *surewarehk_LIBNAME = "SureWareHook"; 363160814Ssimonstatic const char *n_surewarehk_Init = "SureWareHook_Init"; 364160814Ssimonstatic const char *n_surewarehk_Finish = "SureWareHook_Finish"; 365160814Ssimonstatic const char *n_surewarehk_Rand_Bytes="SureWareHook_Rand_Bytes"; 366160814Ssimonstatic const char *n_surewarehk_Rand_Seed="SureWareHook_Rand_Seed"; 367160814Ssimonstatic const char *n_surewarehk_Load_Privkey="SureWareHook_Load_Privkey"; 368160814Ssimonstatic const char *n_surewarehk_Info_Pubkey="SureWareHook_Info_Pubkey"; 369160814Ssimonstatic const char *n_surewarehk_Load_Rsa_Pubkey="SureWareHook_Load_Rsa_Pubkey"; 370160814Ssimonstatic const char *n_surewarehk_Load_Dsa_Pubkey="SureWareHook_Load_Dsa_Pubkey"; 371160814Ssimonstatic const char *n_surewarehk_Free="SureWareHook_Free"; 372160814Ssimonstatic const char *n_surewarehk_Rsa_Priv_Dec="SureWareHook_Rsa_Priv_Dec"; 373160814Ssimonstatic const char *n_surewarehk_Rsa_Sign="SureWareHook_Rsa_Sign"; 374160814Ssimonstatic const char *n_surewarehk_Dsa_Sign="SureWareHook_Dsa_Sign"; 375160814Ssimonstatic const char *n_surewarehk_Mod_Exp="SureWareHook_Mod_Exp"; 376160814Ssimonstatic BIO *logstream = NULL; 377160814Ssimon 378160814Ssimon/* SureWareHook library functions and mechanics - these are used by the 379160814Ssimon * higher-level functions further down. NB: As and where there's no 380160814Ssimon * error checking, take a look lower down where these functions are 381160814Ssimon * called, the checking and error handling is probably down there. 382160814Ssimon*/ 383160814Ssimonstatic int threadsafe=1; 384160814Ssimonstatic int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) 385160814Ssimon{ 386160814Ssimon int to_return = 1; 387160814Ssimon 388160814Ssimon switch(cmd) 389160814Ssimon { 390160814Ssimon case ENGINE_CTRL_SET_LOGSTREAM: 391160814Ssimon { 392160814Ssimon BIO *bio = (BIO *)p; 393160814Ssimon CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 394160814Ssimon if (logstream) 395160814Ssimon { 396160814Ssimon BIO_free(logstream); 397160814Ssimon logstream = NULL; 398160814Ssimon } 399160814Ssimon if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) 400160814Ssimon logstream = bio; 401160814Ssimon else 402160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,SUREWARE_R_BIO_WAS_FREED); 403160814Ssimon } 404160814Ssimon CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 405160814Ssimon break; 406160814Ssimon /* This will prevent the initialisation function from "installing" 407160814Ssimon * the mutex-handling callbacks, even if they are available from 408160814Ssimon * within the library (or were provided to the library from the 409160814Ssimon * calling application). This is to remove any baggage for 410160814Ssimon * applications not using multithreading. */ 411160814Ssimon case ENGINE_CTRL_CHIL_NO_LOCKING: 412160814Ssimon CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 413160814Ssimon threadsafe = 0; 414160814Ssimon CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 415160814Ssimon break; 416160814Ssimon 417160814Ssimon /* The command isn't understood by this engine */ 418160814Ssimon default: 419160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL, 420160814Ssimon ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); 421160814Ssimon to_return = 0; 422160814Ssimon break; 423160814Ssimon } 424160814Ssimon 425160814Ssimon return to_return; 426160814Ssimon} 427160814Ssimon 428160814Ssimon/* Destructor (complements the "ENGINE_surewarehk()" constructor) */ 429160814Ssimonstatic int surewarehk_destroy(ENGINE *e) 430160814Ssimon{ 431160814Ssimon ERR_unload_SUREWARE_strings(); 432160814Ssimon return 1; 433160814Ssimon} 434160814Ssimon 435160814Ssimon/* (de)initialisation functions. */ 436160814Ssimonstatic int surewarehk_init(ENGINE *e) 437160814Ssimon{ 438160814Ssimon char msg[64]="ENGINE_init"; 439160814Ssimon SureWareHook_Init_t *p1=NULL; 440160814Ssimon SureWareHook_Finish_t *p2=NULL; 441160814Ssimon SureWareHook_Rand_Bytes_t *p3=NULL; 442160814Ssimon SureWareHook_Rand_Seed_t *p4=NULL; 443160814Ssimon SureWareHook_Load_Privkey_t *p5=NULL; 444160814Ssimon SureWareHook_Load_Rsa_Pubkey_t *p6=NULL; 445160814Ssimon SureWareHook_Free_t *p7=NULL; 446160814Ssimon SureWareHook_Rsa_Priv_Dec_t *p8=NULL; 447160814Ssimon SureWareHook_Rsa_Sign_t *p9=NULL; 448160814Ssimon SureWareHook_Dsa_Sign_t *p12=NULL; 449160814Ssimon SureWareHook_Info_Pubkey_t *p13=NULL; 450160814Ssimon SureWareHook_Load_Dsa_Pubkey_t *p14=NULL; 451160814Ssimon SureWareHook_Mod_Exp_t *p15=NULL; 452160814Ssimon 453160814Ssimon if(surewarehk_dso != NULL) 454160814Ssimon { 455160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_ALREADY_LOADED); 456160814Ssimon goto err; 457160814Ssimon } 458160814Ssimon /* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */ 459160814Ssimon surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0); 460160814Ssimon if(surewarehk_dso == NULL) 461160814Ssimon { 462160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE); 463160814Ssimon goto err; 464160814Ssimon } 465160814Ssimon if(!(p1=(SureWareHook_Init_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Init)) || 466160814Ssimon !(p2=(SureWareHook_Finish_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Finish)) || 467160814Ssimon !(p3=(SureWareHook_Rand_Bytes_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Bytes)) || 468160814Ssimon !(p4=(SureWareHook_Rand_Seed_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Seed)) || 469160814Ssimon !(p5=(SureWareHook_Load_Privkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Privkey)) || 470160814Ssimon !(p6=(SureWareHook_Load_Rsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Rsa_Pubkey)) || 471160814Ssimon !(p7=(SureWareHook_Free_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Free)) || 472160814Ssimon !(p8=(SureWareHook_Rsa_Priv_Dec_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Priv_Dec)) || 473160814Ssimon !(p9=(SureWareHook_Rsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Sign)) || 474160814Ssimon !(p12=(SureWareHook_Dsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Dsa_Sign)) || 475160814Ssimon !(p13=(SureWareHook_Info_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Info_Pubkey)) || 476160814Ssimon !(p14=(SureWareHook_Load_Dsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Dsa_Pubkey)) || 477160814Ssimon !(p15=(SureWareHook_Mod_Exp_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Mod_Exp))) 478160814Ssimon { 479160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE); 480160814Ssimon goto err; 481160814Ssimon } 482160814Ssimon /* Copy the pointers */ 483160814Ssimon p_surewarehk_Init = p1; 484160814Ssimon p_surewarehk_Finish = p2; 485160814Ssimon p_surewarehk_Rand_Bytes = p3; 486160814Ssimon p_surewarehk_Rand_Seed = p4; 487160814Ssimon p_surewarehk_Load_Privkey = p5; 488160814Ssimon p_surewarehk_Load_Rsa_Pubkey = p6; 489160814Ssimon p_surewarehk_Free = p7; 490160814Ssimon p_surewarehk_Rsa_Priv_Dec = p8; 491160814Ssimon p_surewarehk_Rsa_Sign = p9; 492160814Ssimon p_surewarehk_Dsa_Sign = p12; 493160814Ssimon p_surewarehk_Info_Pubkey = p13; 494160814Ssimon p_surewarehk_Load_Dsa_Pubkey = p14; 495160814Ssimon p_surewarehk_Mod_Exp = p15; 496160814Ssimon /* Contact the hardware and initialises it. */ 497160814Ssimon if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE) 498160814Ssimon { 499160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE); 500160814Ssimon goto err; 501160814Ssimon } 502160814Ssimon if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE) 503160814Ssimon { 504160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE); 505160814Ssimon goto err; 506160814Ssimon } 507160814Ssimon /* try to load the default private key, if failed does not return a failure but 508160814Ssimon wait for an explicit ENGINE_load_privakey */ 509160814Ssimon surewarehk_load_privkey(e,NULL,NULL,NULL); 510160814Ssimon 511160814Ssimon /* Everything's fine. */ 512160814Ssimon#ifndef OPENSSL_NO_RSA 513160814Ssimon if (rsaHndidx == -1) 514160814Ssimon rsaHndidx = RSA_get_ex_new_index(0, 515160814Ssimon "SureWareHook RSA key handle", 516160814Ssimon NULL, NULL, surewarehk_ex_free); 517160814Ssimon#endif 518160814Ssimon#ifndef OPENSSL_NO_DSA 519160814Ssimon if (dsaHndidx == -1) 520160814Ssimon dsaHndidx = DSA_get_ex_new_index(0, 521160814Ssimon "SureWareHook DSA key handle", 522160814Ssimon NULL, NULL, surewarehk_ex_free); 523160814Ssimon#endif 524160814Ssimon 525160814Ssimon return 1; 526160814Ssimonerr: 527160814Ssimon if(surewarehk_dso) 528160814Ssimon DSO_free(surewarehk_dso); 529160814Ssimon surewarehk_dso = NULL; 530160814Ssimon p_surewarehk_Init = NULL; 531160814Ssimon p_surewarehk_Finish = NULL; 532160814Ssimon p_surewarehk_Rand_Bytes = NULL; 533160814Ssimon p_surewarehk_Rand_Seed = NULL; 534160814Ssimon p_surewarehk_Load_Privkey = NULL; 535160814Ssimon p_surewarehk_Load_Rsa_Pubkey = NULL; 536160814Ssimon p_surewarehk_Free = NULL; 537160814Ssimon p_surewarehk_Rsa_Priv_Dec = NULL; 538160814Ssimon p_surewarehk_Rsa_Sign = NULL; 539160814Ssimon p_surewarehk_Dsa_Sign = NULL; 540160814Ssimon p_surewarehk_Info_Pubkey = NULL; 541160814Ssimon p_surewarehk_Load_Dsa_Pubkey = NULL; 542160814Ssimon p_surewarehk_Mod_Exp = NULL; 543160814Ssimon return 0; 544160814Ssimon} 545160814Ssimon 546160814Ssimonstatic int surewarehk_finish(ENGINE *e) 547160814Ssimon{ 548160814Ssimon int to_return = 1; 549160814Ssimon if(surewarehk_dso == NULL) 550160814Ssimon { 551160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_NOT_LOADED); 552160814Ssimon to_return = 0; 553160814Ssimon goto err; 554160814Ssimon } 555160814Ssimon p_surewarehk_Finish(); 556160814Ssimon if(!DSO_free(surewarehk_dso)) 557160814Ssimon { 558160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_DSO_FAILURE); 559160814Ssimon to_return = 0; 560160814Ssimon goto err; 561160814Ssimon } 562160814Ssimon err: 563160814Ssimon if (logstream) 564160814Ssimon BIO_free(logstream); 565160814Ssimon surewarehk_dso = NULL; 566160814Ssimon p_surewarehk_Init = NULL; 567160814Ssimon p_surewarehk_Finish = NULL; 568160814Ssimon p_surewarehk_Rand_Bytes = NULL; 569160814Ssimon p_surewarehk_Rand_Seed = NULL; 570160814Ssimon p_surewarehk_Load_Privkey = NULL; 571160814Ssimon p_surewarehk_Load_Rsa_Pubkey = NULL; 572160814Ssimon p_surewarehk_Free = NULL; 573160814Ssimon p_surewarehk_Rsa_Priv_Dec = NULL; 574160814Ssimon p_surewarehk_Rsa_Sign = NULL; 575160814Ssimon p_surewarehk_Dsa_Sign = NULL; 576160814Ssimon p_surewarehk_Info_Pubkey = NULL; 577160814Ssimon p_surewarehk_Load_Dsa_Pubkey = NULL; 578160814Ssimon p_surewarehk_Mod_Exp = NULL; 579160814Ssimon return to_return; 580160814Ssimon} 581160814Ssimon 582160814Ssimonstatic void surewarehk_error_handling(char *const msg,int func,int ret) 583160814Ssimon{ 584160814Ssimon switch (ret) 585160814Ssimon { 586160814Ssimon case SUREWAREHOOK_ERROR_UNIT_FAILURE: 587160814Ssimon ENGINEerr(func,SUREWARE_R_UNIT_FAILURE); 588160814Ssimon break; 589160814Ssimon case SUREWAREHOOK_ERROR_FALLBACK: 590160814Ssimon ENGINEerr(func,SUREWARE_R_REQUEST_FALLBACK); 591160814Ssimon break; 592160814Ssimon case SUREWAREHOOK_ERROR_DATA_SIZE: 593160814Ssimon ENGINEerr(func,SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 594160814Ssimon break; 595160814Ssimon case SUREWAREHOOK_ERROR_INVALID_PAD: 596160814Ssimon ENGINEerr(func,SUREWARE_R_PADDING_CHECK_FAILED); 597160814Ssimon break; 598160814Ssimon default: 599160814Ssimon ENGINEerr(func,SUREWARE_R_REQUEST_FAILED); 600160814Ssimon break; 601160814Ssimon case 1:/*nothing*/ 602160814Ssimon msg[0]='\0'; 603160814Ssimon } 604160814Ssimon if (*msg) 605160814Ssimon { 606160814Ssimon ERR_add_error_data(1,msg); 607160814Ssimon if (logstream) 608160814Ssimon { 609160814Ssimon CRYPTO_w_lock(CRYPTO_LOCK_BIO); 610160814Ssimon BIO_write(logstream, msg, strlen(msg)); 611160814Ssimon CRYPTO_w_unlock(CRYPTO_LOCK_BIO); 612160814Ssimon } 613160814Ssimon } 614160814Ssimon} 615160814Ssimon 616160814Ssimonstatic int surewarehk_rand_bytes(unsigned char *buf, int num) 617160814Ssimon{ 618160814Ssimon int ret=0; 619160814Ssimon char msg[64]="ENGINE_rand_bytes"; 620160814Ssimon if(!p_surewarehk_Rand_Bytes) 621160814Ssimon { 622160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED); 623160814Ssimon } 624160814Ssimon else 625160814Ssimon { 626160814Ssimon ret = p_surewarehk_Rand_Bytes(msg,buf, num); 627160814Ssimon surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_BYTES,ret); 628160814Ssimon } 629160814Ssimon return ret==1 ? 1 : 0; 630160814Ssimon} 631160814Ssimon 632160814Ssimonstatic void surewarehk_rand_seed(const void *buf, int num) 633160814Ssimon{ 634160814Ssimon int ret=0; 635160814Ssimon char msg[64]="ENGINE_rand_seed"; 636160814Ssimon if(!p_surewarehk_Rand_Seed) 637160814Ssimon { 638160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED,ENGINE_R_NOT_INITIALISED); 639160814Ssimon } 640160814Ssimon else 641160814Ssimon { 642160814Ssimon ret = p_surewarehk_Rand_Seed(msg,buf, num); 643160814Ssimon surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_SEED,ret); 644160814Ssimon } 645160814Ssimon} 646160814Ssimon 647160814Ssimonstatic void surewarehk_rand_add(const void *buf, int num, double entropy) 648160814Ssimon{ 649160814Ssimon surewarehk_rand_seed(buf,num); 650160814Ssimon} 651160814Ssimon 652160814Ssimonstatic EVP_PKEY* sureware_load_public(ENGINE *e,const char *key_id,char *hptr,unsigned long el,char keytype) 653160814Ssimon{ 654160814Ssimon EVP_PKEY *res = NULL; 655160814Ssimon#ifndef OPENSSL_NO_RSA 656160814Ssimon RSA *rsatmp = NULL; 657160814Ssimon#endif 658160814Ssimon#ifndef OPENSSL_NO_DSA 659160814Ssimon DSA *dsatmp=NULL; 660160814Ssimon#endif 661160814Ssimon char msg[64]="sureware_load_public"; 662160814Ssimon int ret=0; 663160814Ssimon if(!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey) 664160814Ssimon { 665160814Ssimon SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_NOT_INITIALISED); 666160814Ssimon goto err; 667160814Ssimon } 668160814Ssimon switch (keytype) 669160814Ssimon { 670160814Ssimon#ifndef OPENSSL_NO_RSA 671160814Ssimon case 1: /*RSA*/ 672160814Ssimon /* set private external reference */ 673160814Ssimon rsatmp = RSA_new_method(e); 674160814Ssimon RSA_set_ex_data(rsatmp,rsaHndidx,hptr); 675160814Ssimon rsatmp->flags |= RSA_FLAG_EXT_PKEY; 676160814Ssimon 677160814Ssimon /* set public big nums*/ 678160814Ssimon rsatmp->e = BN_new(); 679160814Ssimon rsatmp->n = BN_new(); 680160814Ssimon bn_expand2(rsatmp->e, el/sizeof(BN_ULONG)); 681160814Ssimon bn_expand2(rsatmp->n, el/sizeof(BN_ULONG)); 682160814Ssimon if (!rsatmp->e || rsatmp->e->dmax!=(int)(el/sizeof(BN_ULONG))|| 683160814Ssimon !rsatmp->n || rsatmp->n->dmax!=(int)(el/sizeof(BN_ULONG))) 684160814Ssimon goto err; 685160814Ssimon ret=p_surewarehk_Load_Rsa_Pubkey(msg,key_id,el, 686160814Ssimon (unsigned long *)rsatmp->n->d, 687160814Ssimon (unsigned long *)rsatmp->e->d); 688160814Ssimon surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret); 689160814Ssimon if (ret!=1) 690160814Ssimon { 691160814Ssimon SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY); 692160814Ssimon goto err; 693160814Ssimon } 694160814Ssimon /* normalise pub e and pub n */ 695160814Ssimon rsatmp->e->top=el/sizeof(BN_ULONG); 696160814Ssimon bn_fix_top(rsatmp->e); 697160814Ssimon rsatmp->n->top=el/sizeof(BN_ULONG); 698160814Ssimon bn_fix_top(rsatmp->n); 699160814Ssimon /* create an EVP object: engine + rsa key */ 700160814Ssimon res = EVP_PKEY_new(); 701160814Ssimon EVP_PKEY_assign_RSA(res, rsatmp); 702160814Ssimon break; 703160814Ssimon#endif 704160814Ssimon 705160814Ssimon#ifndef OPENSSL_NO_DSA 706160814Ssimon case 2:/*DSA*/ 707160814Ssimon /* set private/public external reference */ 708160814Ssimon dsatmp = DSA_new_method(e); 709160814Ssimon DSA_set_ex_data(dsatmp,dsaHndidx,hptr); 710160814Ssimon /*dsatmp->flags |= DSA_FLAG_EXT_PKEY;*/ 711160814Ssimon 712160814Ssimon /* set public key*/ 713160814Ssimon dsatmp->pub_key = BN_new(); 714160814Ssimon dsatmp->p = BN_new(); 715160814Ssimon dsatmp->q = BN_new(); 716160814Ssimon dsatmp->g = BN_new(); 717160814Ssimon bn_expand2(dsatmp->pub_key, el/sizeof(BN_ULONG)); 718160814Ssimon bn_expand2(dsatmp->p, el/sizeof(BN_ULONG)); 719160814Ssimon bn_expand2(dsatmp->q, 20/sizeof(BN_ULONG)); 720160814Ssimon bn_expand2(dsatmp->g, el/sizeof(BN_ULONG)); 721160814Ssimon if (!dsatmp->pub_key || dsatmp->pub_key->dmax!=(int)(el/sizeof(BN_ULONG))|| 722160814Ssimon !dsatmp->p || dsatmp->p->dmax!=(int)(el/sizeof(BN_ULONG)) || 723160814Ssimon !dsatmp->q || dsatmp->q->dmax!=20/sizeof(BN_ULONG) || 724160814Ssimon !dsatmp->g || dsatmp->g->dmax!=(int)(el/sizeof(BN_ULONG))) 725160814Ssimon goto err; 726160814Ssimon 727160814Ssimon ret=p_surewarehk_Load_Dsa_Pubkey(msg,key_id,el, 728160814Ssimon (unsigned long *)dsatmp->pub_key->d, 729160814Ssimon (unsigned long *)dsatmp->p->d, 730160814Ssimon (unsigned long *)dsatmp->q->d, 731160814Ssimon (unsigned long *)dsatmp->g->d); 732160814Ssimon surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret); 733160814Ssimon if (ret!=1) 734160814Ssimon { 735160814Ssimon SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY); 736160814Ssimon goto err; 737160814Ssimon } 738160814Ssimon /* set parameters */ 739160814Ssimon /* normalise pubkey and parameters in case of */ 740160814Ssimon dsatmp->pub_key->top=el/sizeof(BN_ULONG); 741160814Ssimon bn_fix_top(dsatmp->pub_key); 742160814Ssimon dsatmp->p->top=el/sizeof(BN_ULONG); 743160814Ssimon bn_fix_top(dsatmp->p); 744160814Ssimon dsatmp->q->top=20/sizeof(BN_ULONG); 745160814Ssimon bn_fix_top(dsatmp->q); 746160814Ssimon dsatmp->g->top=el/sizeof(BN_ULONG); 747160814Ssimon bn_fix_top(dsatmp->g); 748160814Ssimon 749160814Ssimon /* create an EVP object: engine + rsa key */ 750160814Ssimon res = EVP_PKEY_new(); 751160814Ssimon EVP_PKEY_assign_DSA(res, dsatmp); 752160814Ssimon break; 753160814Ssimon#endif 754160814Ssimon 755160814Ssimon default: 756160814Ssimon SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PRIVATE_KEY); 757160814Ssimon goto err; 758160814Ssimon } 759160814Ssimon return res; 760160814Ssimon err: 761160814Ssimon#ifndef OPENSSL_NO_RSA 762160814Ssimon if (rsatmp) 763160814Ssimon RSA_free(rsatmp); 764160814Ssimon#endif 765160814Ssimon#ifndef OPENSSL_NO_DSA 766160814Ssimon if (dsatmp) 767160814Ssimon DSA_free(dsatmp); 768160814Ssimon#endif 769160814Ssimon return NULL; 770160814Ssimon} 771160814Ssimon 772160814Ssimonstatic EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id, 773160814Ssimon UI_METHOD *ui_method, void *callback_data) 774160814Ssimon{ 775160814Ssimon EVP_PKEY *res = NULL; 776160814Ssimon int ret=0; 777160814Ssimon unsigned long el=0; 778160814Ssimon char *hptr=NULL; 779160814Ssimon char keytype=0; 780160814Ssimon char msg[64]="ENGINE_load_privkey"; 781160814Ssimon 782160814Ssimon if(!p_surewarehk_Load_Privkey) 783160814Ssimon { 784160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,ENGINE_R_NOT_INITIALISED); 785160814Ssimon } 786160814Ssimon else 787160814Ssimon { 788160814Ssimon ret=p_surewarehk_Load_Privkey(msg,key_id,&hptr,&el,&keytype); 789160814Ssimon if (ret!=1) 790160814Ssimon { 791160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY); 792160814Ssimon ERR_add_error_data(1,msg); 793160814Ssimon } 794160814Ssimon else 795160814Ssimon res=sureware_load_public(e,key_id,hptr,el,keytype); 796160814Ssimon } 797160814Ssimon return res; 798160814Ssimon} 799160814Ssimon 800160814Ssimonstatic EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id, 801160814Ssimon UI_METHOD *ui_method, void *callback_data) 802160814Ssimon{ 803160814Ssimon EVP_PKEY *res = NULL; 804160814Ssimon int ret=0; 805160814Ssimon unsigned long el=0; 806160814Ssimon char *hptr=NULL; 807160814Ssimon char keytype=0; 808160814Ssimon char msg[64]="ENGINE_load_pubkey"; 809160814Ssimon 810160814Ssimon if(!p_surewarehk_Info_Pubkey) 811160814Ssimon { 812160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,ENGINE_R_NOT_INITIALISED); 813160814Ssimon } 814160814Ssimon else 815160814Ssimon { 816160814Ssimon /* call once to identify if DSA or RSA */ 817160814Ssimon ret=p_surewarehk_Info_Pubkey(msg,key_id,&el,&keytype); 818160814Ssimon if (ret!=1) 819160814Ssimon { 820160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY); 821160814Ssimon ERR_add_error_data(1,msg); 822160814Ssimon } 823160814Ssimon else 824160814Ssimon res=sureware_load_public(e,key_id,hptr,el,keytype); 825160814Ssimon } 826160814Ssimon return res; 827160814Ssimon} 828160814Ssimon 829160814Ssimon/* This cleans up an RSA/DSA KM key(do not destroy the key into the hardware) 830160814Ssimon, called when ex_data is freed */ 831160814Ssimonstatic void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 832160814Ssimon int idx,long argl, void *argp) 833160814Ssimon{ 834160814Ssimon if(!p_surewarehk_Free) 835160814Ssimon { 836160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED); 837160814Ssimon } 838160814Ssimon else 839160814Ssimon p_surewarehk_Free((char *)item,0); 840160814Ssimon} 841160814Ssimon 842160814Ssimon#if 0 843160814Ssimon/* not currently used (bug?) */ 844160814Ssimon/* This cleans up an DH KM key (destroys the key into hardware), 845160814Ssimoncalled when ex_data is freed */ 846160814Ssimonstatic void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 847160814Ssimon int idx,long argl, void *argp) 848160814Ssimon{ 849160814Ssimon if(!p_surewarehk_Free) 850160814Ssimon { 851160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_DH_EX_FREE,ENGINE_R_NOT_INITIALISED); 852160814Ssimon } 853160814Ssimon else 854160814Ssimon p_surewarehk_Free((char *)item,1); 855160814Ssimon} 856160814Ssimon#endif 857160814Ssimon 858160814Ssimon/* 859160814Ssimon* return number of decrypted bytes 860160814Ssimon*/ 861160814Ssimon#ifndef OPENSSL_NO_RSA 862160814Ssimonstatic int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to, 863160814Ssimon RSA *rsa,int padding) 864160814Ssimon{ 865160814Ssimon int ret=0,tlen; 866160814Ssimon char *buf=NULL,*hptr=NULL; 867160814Ssimon char msg[64]="ENGINE_rsa_priv_dec"; 868160814Ssimon if (!p_surewarehk_Rsa_Priv_Dec) 869160814Ssimon { 870160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ENGINE_R_NOT_INITIALISED); 871160814Ssimon } 872160814Ssimon /* extract ref to private key */ 873160814Ssimon else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx))) 874160814Ssimon { 875160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_MISSING_KEY_COMPONENTS); 876160814Ssimon goto err; 877160814Ssimon } 878160814Ssimon /* analyse what padding we can do into the hardware */ 879160814Ssimon if (padding==RSA_PKCS1_PADDING) 880160814Ssimon { 881160814Ssimon /* do it one shot */ 882160814Ssimon ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD); 883160814Ssimon surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret); 884160814Ssimon if (ret!=1) 885160814Ssimon goto err; 886160814Ssimon ret=tlen; 887160814Ssimon } 888160814Ssimon else /* do with no padding into hardware */ 889160814Ssimon { 890160814Ssimon ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_NO_PAD); 891160814Ssimon surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret); 892160814Ssimon if (ret!=1) 893160814Ssimon goto err; 894160814Ssimon /* intermediate buffer for padding */ 895160814Ssimon if ((buf=OPENSSL_malloc(tlen)) == NULL) 896160814Ssimon { 897160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ERR_R_MALLOC_FAILURE); 898160814Ssimon goto err; 899160814Ssimon } 900160814Ssimon memcpy(buf,to,tlen);/* transfert to into buf */ 901160814Ssimon switch (padding) /* check padding in software */ 902160814Ssimon { 903160814Ssimon#ifndef OPENSSL_NO_SHA 904160814Ssimon case RSA_PKCS1_OAEP_PADDING: 905160814Ssimon ret=RSA_padding_check_PKCS1_OAEP(to,tlen,(unsigned char *)buf,tlen,tlen,NULL,0); 906160814Ssimon break; 907160814Ssimon#endif 908160814Ssimon case RSA_SSLV23_PADDING: 909160814Ssimon ret=RSA_padding_check_SSLv23(to,tlen,(unsigned char *)buf,flen,tlen); 910160814Ssimon break; 911160814Ssimon case RSA_NO_PADDING: 912160814Ssimon ret=RSA_padding_check_none(to,tlen,(unsigned char *)buf,flen,tlen); 913160814Ssimon break; 914160814Ssimon default: 915160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_UNKNOWN_PADDING_TYPE); 916160814Ssimon goto err; 917160814Ssimon } 918160814Ssimon if (ret < 0) 919160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_PADDING_CHECK_FAILED); 920160814Ssimon } 921160814Ssimonerr: 922160814Ssimon if (buf) 923160814Ssimon { 924160814Ssimon OPENSSL_cleanse(buf,tlen); 925160814Ssimon OPENSSL_free(buf); 926160814Ssimon } 927160814Ssimon return ret; 928160814Ssimon} 929160814Ssimon 930160814Ssimon/* 931160814Ssimon* Does what OpenSSL rsa_priv_enc does. 932160814Ssimon*/ 933160814Ssimonstatic int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to, 934160814Ssimon RSA *rsa,int padding) 935160814Ssimon{ 936160814Ssimon int ret=0,tlen; 937160814Ssimon char *hptr=NULL; 938160814Ssimon char msg[64]="ENGINE_rsa_sign"; 939160814Ssimon if (!p_surewarehk_Rsa_Sign) 940160814Ssimon { 941160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,ENGINE_R_NOT_INITIALISED); 942160814Ssimon } 943160814Ssimon /* extract ref to private key */ 944160814Ssimon else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx))) 945160814Ssimon { 946160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS); 947160814Ssimon } 948160814Ssimon else 949160814Ssimon { 950160814Ssimon switch (padding) 951160814Ssimon { 952160814Ssimon case RSA_PKCS1_PADDING: /* do it in one shot */ 953160814Ssimon ret=p_surewarehk_Rsa_Sign(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD); 954160814Ssimon surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_SIGN,ret); 955160814Ssimon break; 956160814Ssimon case RSA_NO_PADDING: 957160814Ssimon default: 958160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,SUREWARE_R_UNKNOWN_PADDING_TYPE); 959160814Ssimon } 960160814Ssimon } 961160814Ssimon return ret==1 ? tlen : ret; 962160814Ssimon} 963160814Ssimon 964160814Ssimon#endif 965160814Ssimon 966160814Ssimon#ifndef OPENSSL_NO_DSA 967160814Ssimon/* DSA sign and verify */ 968160814Ssimonstatic DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *from, int flen, DSA *dsa) 969160814Ssimon{ 970160814Ssimon int ret=0; 971160814Ssimon char *hptr=NULL; 972160814Ssimon DSA_SIG *psign=NULL; 973160814Ssimon char msg[64]="ENGINE_dsa_do_sign"; 974160814Ssimon if (!p_surewarehk_Dsa_Sign) 975160814Ssimon { 976160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ENGINE_R_NOT_INITIALISED); 977160814Ssimon goto err; 978160814Ssimon } 979160814Ssimon /* extract ref to private key */ 980160814Ssimon else if (!(hptr=DSA_get_ex_data(dsa, dsaHndidx))) 981160814Ssimon { 982160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS); 983160814Ssimon goto err; 984160814Ssimon } 985160814Ssimon else 986160814Ssimon { 987160814Ssimon if((psign = DSA_SIG_new()) == NULL) 988160814Ssimon { 989160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ERR_R_MALLOC_FAILURE); 990160814Ssimon goto err; 991160814Ssimon } 992160814Ssimon psign->r=BN_new(); 993160814Ssimon psign->s=BN_new(); 994160814Ssimon bn_expand2(psign->r, 20/sizeof(BN_ULONG)); 995160814Ssimon bn_expand2(psign->s, 20/sizeof(BN_ULONG)); 996160814Ssimon if (!psign->r || psign->r->dmax!=20/sizeof(BN_ULONG) || 997160814Ssimon !psign->s || psign->s->dmax!=20/sizeof(BN_ULONG)) 998160814Ssimon goto err; 999160814Ssimon ret=p_surewarehk_Dsa_Sign(msg,flen,from, 1000160814Ssimon (unsigned long *)psign->r->d, 1001160814Ssimon (unsigned long *)psign->s->d, 1002160814Ssimon hptr); 1003160814Ssimon surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ret); 1004160814Ssimon } 1005160814Ssimon psign->r->top=20/sizeof(BN_ULONG); 1006160814Ssimon bn_fix_top(psign->r); 1007160814Ssimon psign->s->top=20/sizeof(BN_ULONG); 1008160814Ssimon bn_fix_top(psign->s); 1009160814Ssimon 1010160814Ssimonerr: 1011160814Ssimon if (psign) 1012160814Ssimon { 1013160814Ssimon DSA_SIG_free(psign); 1014160814Ssimon psign=NULL; 1015160814Ssimon } 1016160814Ssimon return psign; 1017160814Ssimon} 1018160814Ssimon#endif 1019160814Ssimon 1020160814Ssimonstatic int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 1021160814Ssimon const BIGNUM *m, BN_CTX *ctx) 1022160814Ssimon{ 1023160814Ssimon int ret=0; 1024160814Ssimon char msg[64]="ENGINE_modexp"; 1025160814Ssimon if (!p_surewarehk_Mod_Exp) 1026160814Ssimon { 1027160814Ssimon SUREWAREerr(SUREWARE_F_SUREWAREHK_MODEXP,ENGINE_R_NOT_INITIALISED); 1028160814Ssimon } 1029160814Ssimon else 1030160814Ssimon { 1031160814Ssimon bn_expand2(r,m->top); 1032160814Ssimon if (r && r->dmax==m->top) 1033160814Ssimon { 1034160814Ssimon /* do it*/ 1035160814Ssimon ret=p_surewarehk_Mod_Exp(msg, 1036160814Ssimon m->top*sizeof(BN_ULONG), 1037160814Ssimon (unsigned long *)m->d, 1038160814Ssimon p->top*sizeof(BN_ULONG), 1039160814Ssimon (unsigned long *)p->d, 1040160814Ssimon a->top*sizeof(BN_ULONG), 1041160814Ssimon (unsigned long *)a->d, 1042160814Ssimon (unsigned long *)r->d); 1043160814Ssimon surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_MODEXP,ret); 1044160814Ssimon if (ret==1) 1045160814Ssimon { 1046160814Ssimon /* normalise result */ 1047160814Ssimon r->top=m->top; 1048160814Ssimon bn_fix_top(r); 1049160814Ssimon } 1050160814Ssimon } 1051160814Ssimon } 1052160814Ssimon return ret; 1053160814Ssimon} 1054160814Ssimon#endif /* !OPENSSL_NO_HW_SureWare */ 1055160814Ssimon#endif /* !OPENSSL_NO_HW */ 1056