1/* Written by Corinne Dive-Reclus(cdive@baltimore.com) 2* 3* 4* Redistribution and use in source and binary forms, with or without 5* modification, are permitted provided that the following conditions 6* are met: 7* 8* 1. Redistributions of source code must retain the above copyright 9* notice, this list of conditions and the following disclaimer. 10* 11* 2. Redistributions in binary form must reproduce the above copyright 12* notice, this list of conditions and the following disclaimer in 13* the documentation and/or other materials provided with the 14* distribution. 15* 16* 3. All advertising materials mentioning features or use of this 17* software must display the following acknowledgment: 18* "This product includes software developed by the OpenSSL Project 19* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 20* 21* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22* endorse or promote products derived from this software without 23* prior written permission. For written permission, please contact 24* licensing@OpenSSL.org. 25* 26* 5. Products derived from this software may not be called "OpenSSL" 27* nor may "OpenSSL" appear in their names without prior written 28* permission of the OpenSSL Project. 29* 30* 6. Redistributions of any form whatsoever must retain the following 31* acknowledgment: 32* "This product includes software developed by the OpenSSL Project 33* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 34* 35* Written by Corinne Dive-Reclus(cdive@baltimore.com) 36* 37* Copyright@2001 Baltimore Technologies Ltd. 38* All right Reserved. 39* * 40* THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND * 41* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * 42* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * 43* ARE DISCLAIMED. IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE * 44* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * 45* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 46* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * 47* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 48* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 49* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * 50* SUCH DAMAGE. * 51====================================================================*/ 52 53#include <stdio.h> 54#include "cryptlib.h" 55#include <openssl/crypto.h> 56#include <openssl/pem.h> 57#include <openssl/dso.h> 58#include "eng_int.h" 59#include "engine.h" 60#include <openssl/engine.h> 61 62#ifndef OPENSSL_NO_HW 63#ifndef OPENSSL_NO_HW_SUREWARE 64 65#ifdef FLAT_INC 66#include "sureware.h" 67#else 68#include "vendor_defns/sureware.h" 69#endif 70 71#define SUREWARE_LIB_NAME "sureware engine" 72#include "hw_sureware_err.c" 73 74static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 75static int surewarehk_destroy(ENGINE *e); 76static int surewarehk_init(ENGINE *e); 77static int surewarehk_finish(ENGINE *e); 78static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 79 const BIGNUM *m, BN_CTX *ctx); 80 81/* RSA stuff */ 82static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to, 83 RSA *rsa,int padding); 84static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to, 85 RSA *rsa,int padding); 86 87/* RAND stuff */ 88static int surewarehk_rand_bytes(unsigned char *buf, int num); 89static void surewarehk_rand_seed(const void *buf, int num); 90static void surewarehk_rand_add(const void *buf, int num, double entropy); 91 92/* KM stuff */ 93static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id, 94 UI_METHOD *ui_method, void *callback_data); 95static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id, 96 UI_METHOD *ui_method, void *callback_data); 97static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 98 int idx,long argl, void *argp); 99#if 0 100static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 101 int idx,long argl, void *argp); 102#endif 103 104#ifndef OPENSSL_NO_RSA 105/* This function is aliased to mod_exp (with the mont stuff dropped). */ 106static int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 107 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 108{ 109 return surewarehk_modexp(r, a, p, m, ctx); 110} 111 112/* Our internal RSA_METHOD that we provide pointers to */ 113static RSA_METHOD surewarehk_rsa = 114 { 115 "SureWare RSA method", 116 NULL, /* pub_enc*/ 117 NULL, /* pub_dec*/ 118 surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc*/ 119 surewarehk_rsa_priv_dec, /* priv_dec*/ 120 NULL, /*mod_exp*/ 121 surewarehk_mod_exp_mont, /*mod_exp_mongomery*/ 122 NULL, /* init*/ 123 NULL, /* finish*/ 124 0, /* RSA flag*/ 125 NULL, 126 NULL, /* OpenSSL sign*/ 127 NULL /* OpenSSL verify*/ 128 }; 129#endif 130 131#ifndef OPENSSL_NO_DH 132/* Our internal DH_METHOD that we provide pointers to */ 133/* This function is aliased to mod_exp (with the dh and mont dropped). */ 134static int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 135 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 136{ 137 return surewarehk_modexp(r, a, p, m, ctx); 138} 139 140static DH_METHOD surewarehk_dh = 141 { 142 "SureWare DH method", 143 NULL,/*gen_key*/ 144 NULL,/*agree,*/ 145 surewarehk_modexp_dh, /*dh mod exp*/ 146 NULL, /* init*/ 147 NULL, /* finish*/ 148 0, /* flags*/ 149 NULL 150 }; 151#endif 152 153static RAND_METHOD surewarehk_rand = 154 { 155 /* "SureWare RAND method", */ 156 surewarehk_rand_seed, 157 surewarehk_rand_bytes, 158 NULL,/*cleanup*/ 159 surewarehk_rand_add, 160 surewarehk_rand_bytes, 161 NULL,/*rand_status*/ 162 }; 163 164#ifndef OPENSSL_NO_DSA 165/* DSA stuff */ 166static DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); 167static int surewarehk_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 168 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 169 BN_CTX *ctx, BN_MONT_CTX *in_mont) 170{ 171 BIGNUM t; 172 int to_return = 0; 173 BN_init(&t); 174 /* let rr = a1 ^ p1 mod m */ 175 if (!surewarehk_modexp(rr,a1,p1,m,ctx)) goto end; 176 /* let t = a2 ^ p2 mod m */ 177 if (!surewarehk_modexp(&t,a2,p2,m,ctx)) goto end; 178 /* let rr = rr * t mod m */ 179 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end; 180 to_return = 1; 181end: 182 BN_free(&t); 183 return to_return; 184} 185 186static DSA_METHOD surewarehk_dsa = 187 { 188 "SureWare DSA method", 189 surewarehk_dsa_do_sign, 190 NULL,/*sign setup*/ 191 NULL,/*verify,*/ 192 surewarehk_dsa_mod_exp,/*mod exp*/ 193 NULL,/*bn mod exp*/ 194 NULL, /*init*/ 195 NULL,/*finish*/ 196 0, 197 NULL, 198 }; 199#endif 200 201static const char *engine_sureware_id = "sureware"; 202static const char *engine_sureware_name = "SureWare hardware engine support"; 203 204/* Now, to our own code */ 205 206/* As this is only ever called once, there's no need for locking 207 * (indeed - the lock will already be held by our caller!!!) */ 208static int bind_sureware(ENGINE *e) 209{ 210#ifndef OPENSSL_NO_RSA 211 const RSA_METHOD *meth1; 212#endif 213#ifndef OPENSSL_NO_DSA 214 const DSA_METHOD *meth2; 215#endif 216#ifndef OPENSSL_NO_DH 217 const DH_METHOD *meth3; 218#endif 219 220 if(!ENGINE_set_id(e, engine_sureware_id) || 221 !ENGINE_set_name(e, engine_sureware_name) || 222#ifndef OPENSSL_NO_RSA 223 !ENGINE_set_RSA(e, &surewarehk_rsa) || 224#endif 225#ifndef OPENSSL_NO_DSA 226 !ENGINE_set_DSA(e, &surewarehk_dsa) || 227#endif 228#ifndef OPENSSL_NO_DH 229 !ENGINE_set_DH(e, &surewarehk_dh) || 230#endif 231 !ENGINE_set_RAND(e, &surewarehk_rand) || 232 !ENGINE_set_destroy_function(e, surewarehk_destroy) || 233 !ENGINE_set_init_function(e, surewarehk_init) || 234 !ENGINE_set_finish_function(e, surewarehk_finish) || 235 !ENGINE_set_ctrl_function(e, surewarehk_ctrl) || 236 !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) || 237 !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey)) 238 return 0; 239 240#ifndef OPENSSL_NO_RSA 241 /* We know that the "PKCS1_SSLeay()" functions hook properly 242 * to the cswift-specific mod_exp and mod_exp_crt so we use 243 * those functions. NB: We don't use ENGINE_openssl() or 244 * anything "more generic" because something like the RSAref 245 * code may not hook properly, and if you own one of these 246 * cards then you have the right to do RSA operations on it 247 * anyway! */ 248 meth1 = RSA_PKCS1_SSLeay(); 249 if (meth1) 250 { 251 surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; 252 surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 253 } 254#endif 255 256#ifndef OPENSSL_NO_DSA 257 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish 258 * bits. */ 259 meth2 = DSA_OpenSSL(); 260 if (meth2) 261 { 262 surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify; 263 } 264#endif 265 266#ifndef OPENSSL_NO_DH 267 /* Much the same for Diffie-Hellman */ 268 meth3 = DH_OpenSSL(); 269 if (meth3) 270 { 271 surewarehk_dh.generate_key = meth3->generate_key; 272 surewarehk_dh.compute_key = meth3->compute_key; 273 } 274#endif 275 276 /* Ensure the sureware error handling is set up */ 277 ERR_load_SUREWARE_strings(); 278 return 1; 279} 280 281#ifdef ENGINE_DYNAMIC_SUPPORT 282static int bind_helper(ENGINE *e, const char *id) 283 { 284 if(id && (strcmp(id, engine_sureware_id) != 0)) 285 return 0; 286 if(!bind_sureware(e)) 287 return 0; 288 return 1; 289 } 290IMPLEMENT_DYNAMIC_CHECK_FN() 291IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) 292#else 293static ENGINE *engine_sureware(void) 294 { 295 ENGINE *ret = ENGINE_new(); 296 if(!ret) 297 return NULL; 298 if(!bind_sureware(ret)) 299 { 300 ENGINE_free(ret); 301 return NULL; 302 } 303 return ret; 304 } 305 306void ENGINE_load_sureware(void) 307 { 308 /* Copied from eng_[openssl|dyn].c */ 309 ENGINE *toadd = engine_sureware(); 310 if(!toadd) return; 311 ENGINE_add(toadd); 312 ENGINE_free(toadd); 313 ERR_clear_error(); 314 } 315#endif 316 317/* This is a process-global DSO handle used for loading and unloading 318 * the SureWareHook library. NB: This is only set (or unset) during an 319 * init() or finish() call (reference counts permitting) and they're 320 * operating with global locks, so this should be thread-safe 321 * implicitly. */ 322static DSO *surewarehk_dso = NULL; 323#ifndef OPENSSL_NO_RSA 324static int rsaHndidx = -1; /* Index for KM handle. Not really used yet. */ 325#endif 326#ifndef OPENSSL_NO_DSA 327static int dsaHndidx = -1; /* Index for KM handle. Not really used yet. */ 328#endif 329 330/* These are the function pointers that are (un)set when the library has 331 * successfully (un)loaded. */ 332static SureWareHook_Init_t *p_surewarehk_Init = NULL; 333static SureWareHook_Finish_t *p_surewarehk_Finish = NULL; 334static SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL; 335static SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL; 336static SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL; 337static SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL; 338static SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL; 339static SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL; 340static SureWareHook_Free_t *p_surewarehk_Free=NULL; 341static SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec=NULL; 342static SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign=NULL; 343static SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign=NULL; 344static SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp=NULL; 345 346/* Used in the DSO operations. */ 347static const char *surewarehk_LIBNAME = "SureWareHook"; 348static const char *n_surewarehk_Init = "SureWareHook_Init"; 349static const char *n_surewarehk_Finish = "SureWareHook_Finish"; 350static const char *n_surewarehk_Rand_Bytes="SureWareHook_Rand_Bytes"; 351static const char *n_surewarehk_Rand_Seed="SureWareHook_Rand_Seed"; 352static const char *n_surewarehk_Load_Privkey="SureWareHook_Load_Privkey"; 353static const char *n_surewarehk_Info_Pubkey="SureWareHook_Info_Pubkey"; 354static const char *n_surewarehk_Load_Rsa_Pubkey="SureWareHook_Load_Rsa_Pubkey"; 355static const char *n_surewarehk_Load_Dsa_Pubkey="SureWareHook_Load_Dsa_Pubkey"; 356static const char *n_surewarehk_Free="SureWareHook_Free"; 357static const char *n_surewarehk_Rsa_Priv_Dec="SureWareHook_Rsa_Priv_Dec"; 358static const char *n_surewarehk_Rsa_Sign="SureWareHook_Rsa_Sign"; 359static const char *n_surewarehk_Dsa_Sign="SureWareHook_Dsa_Sign"; 360static const char *n_surewarehk_Mod_Exp="SureWareHook_Mod_Exp"; 361static BIO *logstream = NULL; 362 363/* SureWareHook library functions and mechanics - these are used by the 364 * higher-level functions further down. NB: As and where there's no 365 * error checking, take a look lower down where these functions are 366 * called, the checking and error handling is probably down there. 367*/ 368static int threadsafe=1; 369static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) 370{ 371 int to_return = 1; 372 373 switch(cmd) 374 { 375 case ENGINE_CTRL_SET_LOGSTREAM: 376 { 377 BIO *bio = (BIO *)p; 378 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 379 if (logstream) 380 { 381 BIO_free(logstream); 382 logstream = NULL; 383 } 384 if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) 385 logstream = bio; 386 else 387 SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,SUREWARE_R_BIO_WAS_FREED); 388 } 389 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 390 break; 391 /* This will prevent the initialisation function from "installing" 392 * the mutex-handling callbacks, even if they are available from 393 * within the library (or were provided to the library from the 394 * calling application). This is to remove any baggage for 395 * applications not using multithreading. */ 396 case ENGINE_CTRL_CHIL_NO_LOCKING: 397 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 398 threadsafe = 0; 399 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 400 break; 401 402 /* The command isn't understood by this engine */ 403 default: 404 SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL, 405 ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); 406 to_return = 0; 407 break; 408 } 409 410 return to_return; 411} 412 413/* Destructor (complements the "ENGINE_surewarehk()" constructor) */ 414static int surewarehk_destroy(ENGINE *e) 415{ 416 ERR_unload_SUREWARE_strings(); 417 return 1; 418} 419 420/* (de)initialisation functions. */ 421static int surewarehk_init(ENGINE *e) 422{ 423 char msg[64]="ENGINE_init"; 424 SureWareHook_Init_t *p1=NULL; 425 SureWareHook_Finish_t *p2=NULL; 426 SureWareHook_Rand_Bytes_t *p3=NULL; 427 SureWareHook_Rand_Seed_t *p4=NULL; 428 SureWareHook_Load_Privkey_t *p5=NULL; 429 SureWareHook_Load_Rsa_Pubkey_t *p6=NULL; 430 SureWareHook_Free_t *p7=NULL; 431 SureWareHook_Rsa_Priv_Dec_t *p8=NULL; 432 SureWareHook_Rsa_Sign_t *p9=NULL; 433 SureWareHook_Dsa_Sign_t *p12=NULL; 434 SureWareHook_Info_Pubkey_t *p13=NULL; 435 SureWareHook_Load_Dsa_Pubkey_t *p14=NULL; 436 SureWareHook_Mod_Exp_t *p15=NULL; 437 438 if(surewarehk_dso != NULL) 439 { 440 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_ALREADY_LOADED); 441 goto err; 442 } 443 /* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */ 444 surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0); 445 if(surewarehk_dso == NULL) 446 { 447 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE); 448 goto err; 449 } 450 if(!(p1=(SureWareHook_Init_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Init)) || 451 !(p2=(SureWareHook_Finish_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Finish)) || 452 !(p3=(SureWareHook_Rand_Bytes_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Bytes)) || 453 !(p4=(SureWareHook_Rand_Seed_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Seed)) || 454 !(p5=(SureWareHook_Load_Privkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Privkey)) || 455 !(p6=(SureWareHook_Load_Rsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Rsa_Pubkey)) || 456 !(p7=(SureWareHook_Free_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Free)) || 457 !(p8=(SureWareHook_Rsa_Priv_Dec_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Priv_Dec)) || 458 !(p9=(SureWareHook_Rsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Sign)) || 459 !(p12=(SureWareHook_Dsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Dsa_Sign)) || 460 !(p13=(SureWareHook_Info_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Info_Pubkey)) || 461 !(p14=(SureWareHook_Load_Dsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Dsa_Pubkey)) || 462 !(p15=(SureWareHook_Mod_Exp_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Mod_Exp))) 463 { 464 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE); 465 goto err; 466 } 467 /* Copy the pointers */ 468 p_surewarehk_Init = p1; 469 p_surewarehk_Finish = p2; 470 p_surewarehk_Rand_Bytes = p3; 471 p_surewarehk_Rand_Seed = p4; 472 p_surewarehk_Load_Privkey = p5; 473 p_surewarehk_Load_Rsa_Pubkey = p6; 474 p_surewarehk_Free = p7; 475 p_surewarehk_Rsa_Priv_Dec = p8; 476 p_surewarehk_Rsa_Sign = p9; 477 p_surewarehk_Dsa_Sign = p12; 478 p_surewarehk_Info_Pubkey = p13; 479 p_surewarehk_Load_Dsa_Pubkey = p14; 480 p_surewarehk_Mod_Exp = p15; 481 /* Contact the hardware and initialises it. */ 482 if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE) 483 { 484 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE); 485 goto err; 486 } 487 if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE) 488 { 489 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE); 490 goto err; 491 } 492 /* try to load the default private key, if failed does not return a failure but 493 wait for an explicit ENGINE_load_privakey */ 494 surewarehk_load_privkey(e,NULL,NULL,NULL); 495 496 /* Everything's fine. */ 497#ifndef OPENSSL_NO_RSA 498 if (rsaHndidx == -1) 499 rsaHndidx = RSA_get_ex_new_index(0, 500 "SureWareHook RSA key handle", 501 NULL, NULL, surewarehk_ex_free); 502#endif 503#ifndef OPENSSL_NO_DSA 504 if (dsaHndidx == -1) 505 dsaHndidx = DSA_get_ex_new_index(0, 506 "SureWareHook DSA key handle", 507 NULL, NULL, surewarehk_ex_free); 508#endif 509 510 return 1; 511err: 512 if(surewarehk_dso) 513 DSO_free(surewarehk_dso); 514 surewarehk_dso = NULL; 515 p_surewarehk_Init = NULL; 516 p_surewarehk_Finish = NULL; 517 p_surewarehk_Rand_Bytes = NULL; 518 p_surewarehk_Rand_Seed = NULL; 519 p_surewarehk_Load_Privkey = NULL; 520 p_surewarehk_Load_Rsa_Pubkey = NULL; 521 p_surewarehk_Free = NULL; 522 p_surewarehk_Rsa_Priv_Dec = NULL; 523 p_surewarehk_Rsa_Sign = NULL; 524 p_surewarehk_Dsa_Sign = NULL; 525 p_surewarehk_Info_Pubkey = NULL; 526 p_surewarehk_Load_Dsa_Pubkey = NULL; 527 p_surewarehk_Mod_Exp = NULL; 528 return 0; 529} 530 531static int surewarehk_finish(ENGINE *e) 532{ 533 int to_return = 1; 534 if(surewarehk_dso == NULL) 535 { 536 SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_NOT_LOADED); 537 to_return = 0; 538 goto err; 539 } 540 p_surewarehk_Finish(); 541 if(!DSO_free(surewarehk_dso)) 542 { 543 SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_DSO_FAILURE); 544 to_return = 0; 545 goto err; 546 } 547 err: 548 if (logstream) 549 BIO_free(logstream); 550 surewarehk_dso = NULL; 551 p_surewarehk_Init = NULL; 552 p_surewarehk_Finish = NULL; 553 p_surewarehk_Rand_Bytes = NULL; 554 p_surewarehk_Rand_Seed = NULL; 555 p_surewarehk_Load_Privkey = NULL; 556 p_surewarehk_Load_Rsa_Pubkey = NULL; 557 p_surewarehk_Free = NULL; 558 p_surewarehk_Rsa_Priv_Dec = NULL; 559 p_surewarehk_Rsa_Sign = NULL; 560 p_surewarehk_Dsa_Sign = NULL; 561 p_surewarehk_Info_Pubkey = NULL; 562 p_surewarehk_Load_Dsa_Pubkey = NULL; 563 p_surewarehk_Mod_Exp = NULL; 564 return to_return; 565} 566 567static void surewarehk_error_handling(char *const msg,int func,int ret) 568{ 569 switch (ret) 570 { 571 case SUREWAREHOOK_ERROR_UNIT_FAILURE: 572 ENGINEerr(func,SUREWARE_R_UNIT_FAILURE); 573 break; 574 case SUREWAREHOOK_ERROR_FALLBACK: 575 ENGINEerr(func,SUREWARE_R_REQUEST_FALLBACK); 576 break; 577 case SUREWAREHOOK_ERROR_DATA_SIZE: 578 ENGINEerr(func,SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 579 break; 580 case SUREWAREHOOK_ERROR_INVALID_PAD: 581 ENGINEerr(func,RSA_R_PADDING_CHECK_FAILED); 582 break; 583 default: 584 ENGINEerr(func,SUREWARE_R_REQUEST_FAILED); 585 break; 586 case 1:/*nothing*/ 587 msg[0]='\0'; 588 } 589 if (*msg) 590 { 591 ERR_add_error_data(1,msg); 592 if (logstream) 593 { 594 CRYPTO_w_lock(CRYPTO_LOCK_BIO); 595 BIO_write(logstream, msg, strlen(msg)); 596 CRYPTO_w_unlock(CRYPTO_LOCK_BIO); 597 } 598 } 599} 600 601static int surewarehk_rand_bytes(unsigned char *buf, int num) 602{ 603 int ret=0; 604 char msg[64]="ENGINE_rand_bytes"; 605 if(!p_surewarehk_Rand_Bytes) 606 { 607 SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED); 608 } 609 else 610 { 611 ret = p_surewarehk_Rand_Bytes(msg,buf, num); 612 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_BYTES,ret); 613 } 614 return ret==1 ? 1 : 0; 615} 616 617static void surewarehk_rand_seed(const void *buf, int num) 618{ 619 int ret=0; 620 char msg[64]="ENGINE_rand_seed"; 621 if(!p_surewarehk_Rand_Seed) 622 { 623 SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED,ENGINE_R_NOT_INITIALISED); 624 } 625 else 626 { 627 ret = p_surewarehk_Rand_Seed(msg,buf, num); 628 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_SEED,ret); 629 } 630} 631 632static void surewarehk_rand_add(const void *buf, int num, double entropy) 633{ 634 surewarehk_rand_seed(buf,num); 635} 636 637static EVP_PKEY* sureware_load_public(ENGINE *e,const char *key_id,char *hptr,unsigned long el,char keytype) 638{ 639 EVP_PKEY *res = NULL; 640#ifndef OPENSSL_NO_RSA 641 RSA *rsatmp = NULL; 642#endif 643#ifndef OPENSSL_NO_DSA 644 DSA *dsatmp=NULL; 645#endif 646 char msg[64]="sureware_load_public"; 647 int ret=0; 648 if(!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey) 649 { 650 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ENGINE_R_NOT_INITIALISED); 651 goto err; 652 } 653 switch (keytype) 654 { 655#ifndef OPENSSL_NO_RSA 656 case 1: /*RSA*/ 657 /* set private external reference */ 658 rsatmp = RSA_new_method(e); 659 RSA_set_ex_data(rsatmp,rsaHndidx,hptr); 660 rsatmp->flags |= RSA_FLAG_EXT_PKEY; 661 662 /* set public big nums*/ 663 rsatmp->e = BN_new(); 664 rsatmp->n = BN_new(); 665 bn_expand2(rsatmp->e, el/sizeof(BN_ULONG)); 666 bn_expand2(rsatmp->n, el/sizeof(BN_ULONG)); 667 if (!rsatmp->e || rsatmp->e->dmax!=(int)(el/sizeof(BN_ULONG))|| 668 !rsatmp->n || rsatmp->n->dmax!=(int)(el/sizeof(BN_ULONG))) 669 goto err; 670 ret=p_surewarehk_Load_Rsa_Pubkey(msg,key_id,el, 671 (unsigned long *)rsatmp->n->d, 672 (unsigned long *)rsatmp->e->d); 673 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ret); 674 if (ret!=1) 675 { 676 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY); 677 goto err; 678 } 679 /* normalise pub e and pub n */ 680 rsatmp->e->top=el/sizeof(BN_ULONG); 681 bn_fix_top(rsatmp->e); 682 rsatmp->n->top=el/sizeof(BN_ULONG); 683 bn_fix_top(rsatmp->n); 684 /* create an EVP object: engine + rsa key */ 685 res = EVP_PKEY_new(); 686 EVP_PKEY_assign_RSA(res, rsatmp); 687 break; 688#endif 689 690#ifndef OPENSSL_NO_DSA 691 case 2:/*DSA*/ 692 /* set private/public external reference */ 693 dsatmp = DSA_new_method(e); 694 DSA_set_ex_data(dsatmp,dsaHndidx,hptr); 695 /*dsatmp->flags |= DSA_FLAG_EXT_PKEY;*/ 696 697 /* set public key*/ 698 dsatmp->pub_key = BN_new(); 699 dsatmp->p = BN_new(); 700 dsatmp->q = BN_new(); 701 dsatmp->g = BN_new(); 702 bn_expand2(dsatmp->pub_key, el/sizeof(BN_ULONG)); 703 bn_expand2(dsatmp->p, el/sizeof(BN_ULONG)); 704 bn_expand2(dsatmp->q, 20/sizeof(BN_ULONG)); 705 bn_expand2(dsatmp->g, el/sizeof(BN_ULONG)); 706 if (!dsatmp->pub_key || dsatmp->pub_key->dmax!=(int)(el/sizeof(BN_ULONG))|| 707 !dsatmp->p || dsatmp->p->dmax!=(int)(el/sizeof(BN_ULONG)) || 708 !dsatmp->q || dsatmp->q->dmax!=20/sizeof(BN_ULONG) || 709 !dsatmp->g || dsatmp->g->dmax!=(int)(el/sizeof(BN_ULONG))) 710 goto err; 711 712 ret=p_surewarehk_Load_Dsa_Pubkey(msg,key_id,el, 713 (unsigned long *)dsatmp->pub_key->d, 714 (unsigned long *)dsatmp->p->d, 715 (unsigned long *)dsatmp->q->d, 716 (unsigned long *)dsatmp->g->d); 717 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ret); 718 if (ret!=1) 719 { 720 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY); 721 goto err; 722 } 723 /* set parameters */ 724 /* normalise pubkey and parameters in case of */ 725 dsatmp->pub_key->top=el/sizeof(BN_ULONG); 726 bn_fix_top(dsatmp->pub_key); 727 dsatmp->p->top=el/sizeof(BN_ULONG); 728 bn_fix_top(dsatmp->p); 729 dsatmp->q->top=20/sizeof(BN_ULONG); 730 bn_fix_top(dsatmp->q); 731 dsatmp->g->top=el/sizeof(BN_ULONG); 732 bn_fix_top(dsatmp->g); 733 734 /* create an EVP object: engine + rsa key */ 735 res = EVP_PKEY_new(); 736 EVP_PKEY_assign_DSA(res, dsatmp); 737 break; 738#endif 739 740 default: 741 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY); 742 goto err; 743 } 744 return res; 745 err: 746 if (res) 747 EVP_PKEY_free(res); 748#ifndef OPENSSL_NO_RSA 749 if (rsatmp) 750 RSA_free(rsatmp); 751#endif 752#ifndef OPENSSL_NO_DSA 753 if (dsatmp) 754 DSA_free(dsatmp); 755#endif 756 return NULL; 757} 758 759static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id, 760 UI_METHOD *ui_method, void *callback_data) 761{ 762 EVP_PKEY *res = NULL; 763 int ret=0; 764 unsigned long el=0; 765 char *hptr=NULL; 766 char keytype=0; 767 char msg[64]="ENGINE_load_privkey"; 768 769 if(!p_surewarehk_Load_Privkey) 770 { 771 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_NOT_INITIALISED); 772 } 773 else 774 { 775 ret=p_surewarehk_Load_Privkey(msg,key_id,&hptr,&el,&keytype); 776 if (ret!=1) 777 { 778 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY); 779 ERR_add_error_data(1,msg); 780 } 781 else 782 res=sureware_load_public(e,key_id,hptr,el,keytype); 783 } 784 return res; 785} 786 787static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id, 788 UI_METHOD *ui_method, void *callback_data) 789{ 790 EVP_PKEY *res = NULL; 791 int ret=0; 792 unsigned long el=0; 793 char *hptr=NULL; 794 char keytype=0; 795 char msg[64]="ENGINE_load_pubkey"; 796 797 if(!p_surewarehk_Info_Pubkey) 798 { 799 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ENGINE_R_NOT_INITIALISED); 800 } 801 else 802 { 803 /* call once to identify if DSA or RSA */ 804 ret=p_surewarehk_Info_Pubkey(msg,key_id,&el,&keytype); 805 if (ret!=1) 806 { 807 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY); 808 ERR_add_error_data(1,msg); 809 } 810 else 811 res=sureware_load_public(e,key_id,hptr,el,keytype); 812 } 813 return res; 814} 815 816/* This cleans up an RSA/DSA KM key(do not destroy the key into the hardware) 817, called when ex_data is freed */ 818static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 819 int idx,long argl, void *argp) 820{ 821 if(!p_surewarehk_Free) 822 { 823 SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED); 824 } 825 else 826 p_surewarehk_Free((char *)item,0); 827} 828 829#if 0 830/* This cleans up an DH KM key (destroys the key into hardware), 831called when ex_data is freed */ 832static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 833 int idx,long argl, void *argp) 834{ 835 if(!p_surewarehk_Free) 836 { 837 SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED); 838 } 839 else 840 p_surewarehk_Free((char *)item,1); 841} 842#endif 843 844/* 845* return number of decrypted bytes 846*/ 847#ifndef OPENSSL_NO_RSA 848static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to, 849 RSA *rsa,int padding) 850{ 851 int ret=0,tlen; 852 char *buf=NULL,*hptr=NULL; 853 char msg[64]="ENGINE_rsa_priv_dec"; 854 if (!p_surewarehk_Rsa_Priv_Dec) 855 { 856 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ENGINE_R_NOT_INITIALISED); 857 } 858 /* extract ref to private key */ 859 else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx))) 860 { 861 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_MISSING_KEY_COMPONENTS); 862 goto err; 863 } 864 /* analyse what padding we can do into the hardware */ 865 if (padding==RSA_PKCS1_PADDING) 866 { 867 /* do it one shot */ 868 ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD); 869 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret); 870 if (ret!=1) 871 goto err; 872 ret=tlen; 873 } 874 else /* do with no padding into hardware */ 875 { 876 ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_NO_PAD); 877 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret); 878 if (ret!=1) 879 goto err; 880 /* intermediate buffer for padding */ 881 if ((buf=OPENSSL_malloc(tlen)) == NULL) 882 { 883 RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ERR_R_MALLOC_FAILURE); 884 goto err; 885 } 886 memcpy(buf,to,tlen);/* transfert to into buf */ 887 switch (padding) /* check padding in software */ 888 { 889#ifndef OPENSSL_NO_SHA 890 case RSA_PKCS1_OAEP_PADDING: 891 ret=RSA_padding_check_PKCS1_OAEP(to,tlen,(unsigned char *)buf,tlen,tlen,NULL,0); 892 break; 893#endif 894 case RSA_SSLV23_PADDING: 895 ret=RSA_padding_check_SSLv23(to,tlen,(unsigned char *)buf,flen,tlen); 896 break; 897 case RSA_NO_PADDING: 898 ret=RSA_padding_check_none(to,tlen,(unsigned char *)buf,flen,tlen); 899 break; 900 default: 901 RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,RSA_R_UNKNOWN_PADDING_TYPE); 902 goto err; 903 } 904 if (ret < 0) 905 RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,RSA_R_PADDING_CHECK_FAILED); 906 } 907err: 908 if (buf) 909 { 910 OPENSSL_cleanse(buf,tlen); 911 OPENSSL_free(buf); 912 } 913 return ret; 914} 915 916/* 917* Does what OpenSSL rsa_priv_enc does. 918*/ 919static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to, 920 RSA *rsa,int padding) 921{ 922 int ret=0,tlen; 923 char *hptr=NULL; 924 char msg[64]="ENGINE_rsa_sign"; 925 if (!p_surewarehk_Rsa_Sign) 926 { 927 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,ENGINE_R_NOT_INITIALISED); 928 } 929 /* extract ref to private key */ 930 else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx))) 931 { 932 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,SUREWARE_R_MISSING_KEY_COMPONENTS); 933 } 934 else 935 { 936 switch (padding) 937 { 938 case RSA_PKCS1_PADDING: /* do it in one shot */ 939 ret=p_surewarehk_Rsa_Sign(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD); 940 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,ret); 941 break; 942 case RSA_NO_PADDING: 943 default: 944 RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,RSA_R_UNKNOWN_PADDING_TYPE); 945 } 946 } 947 return ret==1 ? tlen : ret; 948} 949 950#endif 951 952#ifndef OPENSSL_NO_DSA 953/* DSA sign and verify */ 954static DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *from, int flen, DSA *dsa) 955{ 956 int ret=0; 957 char *hptr=NULL; 958 DSA_SIG *psign=NULL; 959 char msg[64]="ENGINE_dsa_do_sign"; 960 if (!p_surewarehk_Dsa_Sign) 961 { 962 SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ENGINE_R_NOT_INITIALISED); 963 } 964 /* extract ref to private key */ 965 else if (!(hptr=DSA_get_ex_data(dsa, dsaHndidx))) 966 { 967 SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS); 968 } 969 else 970 { 971 if((psign = DSA_SIG_new()) == NULL) 972 { 973 SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ERR_R_MALLOC_FAILURE); 974 goto err; 975 } 976 psign->r=BN_new(); 977 psign->s=BN_new(); 978 bn_expand2(psign->r, 20/sizeof(BN_ULONG)); 979 bn_expand2(psign->s, 20/sizeof(BN_ULONG)); 980 if (!psign->r || psign->r->dmax!=20/sizeof(BN_ULONG) || 981 !psign->s || psign->s->dmax!=20/sizeof(BN_ULONG)) 982 goto err; 983 ret=p_surewarehk_Dsa_Sign(msg,flen,from, 984 (unsigned long *)psign->r->d, 985 (unsigned long *)psign->s->d, 986 hptr); 987 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ret); 988 } 989 psign->r->top=20/sizeof(BN_ULONG); 990 bn_fix_top(psign->r); 991 psign->s->top=20/sizeof(BN_ULONG); 992 bn_fix_top(psign->s); 993 994err: 995 if (psign) 996 { 997 DSA_SIG_free(psign); 998 psign=NULL; 999 } 1000 return psign; 1001} 1002#endif 1003 1004static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 1005 const BIGNUM *m, BN_CTX *ctx) 1006{ 1007 int ret=0; 1008 char msg[64]="ENGINE_modexp"; 1009 if (!p_surewarehk_Mod_Exp) 1010 { 1011 SUREWAREerr(SUREWARE_F_SUREWAREHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); 1012 } 1013 else 1014 { 1015 bn_expand2(r,m->top); 1016 if (r && r->dmax==m->top) 1017 { 1018 /* do it*/ 1019 ret=p_surewarehk_Mod_Exp(msg, 1020 m->top*sizeof(BN_ULONG), 1021 (unsigned long *)m->d, 1022 p->top*sizeof(BN_ULONG), 1023 (unsigned long *)p->d, 1024 a->top*sizeof(BN_ULONG), 1025 (unsigned long *)a->d, 1026 (unsigned long *)r->d); 1027 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_MOD_EXP,ret); 1028 if (ret==1) 1029 { 1030 /* normalise result */ 1031 r->top=m->top; 1032 bn_fix_top(r); 1033 } 1034 } 1035 } 1036 return ret; 1037} 1038#endif /* !OPENSSL_NO_HW_SureWare */ 1039#endif /* !OPENSSL_NO_HW */ 1040