1/* Author: Maurice Gittens <maurice@gittens.nl> */ 2/* ==================================================================== 3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * licensing@OpenSSL.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This product includes cryptographic software written by Eric Young 51 * (eay@cryptsoft.com). This product includes software written by Tim 52 * Hudson (tjh@cryptsoft.com). 53 * 54 */ 55 56#include <stdio.h> 57#include <string.h> 58#include <openssl/crypto.h> 59#include <openssl/dso.h> 60#include <openssl/x509.h> 61#include <openssl/objects.h> 62#include <openssl/engine.h> 63#include <openssl/rand.h> 64#ifndef OPENSSL_NO_RSA 65#include <openssl/rsa.h> 66#endif 67#include <openssl/bn.h> 68 69#ifndef OPENSSL_NO_HW 70#ifndef OPENSSL_NO_HW_4758_CCA 71 72#ifdef FLAT_INC 73#include "hw_4758_cca.h" 74#else 75#include "vendor_defns/hw_4758_cca.h" 76#endif 77 78#include "e_4758cca_err.c" 79 80static int ibm_4758_cca_destroy(ENGINE *e); 81static int ibm_4758_cca_init(ENGINE *e); 82static int ibm_4758_cca_finish(ENGINE *e); 83static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 84 85/* rsa functions */ 86/*---------------*/ 87#ifndef OPENSSL_NO_RSA 88static int cca_rsa_pub_enc(int flen, const unsigned char *from, 89 unsigned char *to, RSA *rsa,int padding); 90static int cca_rsa_priv_dec(int flen, const unsigned char *from, 91 unsigned char *to, RSA *rsa,int padding); 92static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 93 unsigned char *sigret, unsigned int *siglen, const RSA *rsa); 94static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, 95 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa); 96 97/* utility functions */ 98/*-----------------------*/ 99static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*, 100 UI_METHOD *ui_method, void *callback_data); 101static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*, 102 UI_METHOD *ui_method, void *callback_data); 103 104static int getModulusAndExponent(const unsigned char *token, long *exponentLength, 105 unsigned char *exponent, long *modulusLength, 106 long *modulusFieldLength, unsigned char *modulus); 107#endif 108 109/* RAND number functions */ 110/*-----------------------*/ 111static int cca_get_random_bytes(unsigned char*, int ); 112static int cca_random_status(void); 113 114#ifndef OPENSSL_NO_RSA 115static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 116 int idx,long argl, void *argp); 117#endif 118 119/* Function pointers for CCA verbs */ 120/*---------------------------------*/ 121#ifndef OPENSSL_NO_RSA 122static F_KEYRECORDREAD keyRecordRead; 123static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate; 124static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify; 125static F_PUBLICKEYEXTRACT publicKeyExtract; 126static F_PKAENCRYPT pkaEncrypt; 127static F_PKADECRYPT pkaDecrypt; 128#endif 129static F_RANDOMNUMBERGENERATE randomNumberGenerate; 130 131/* static variables */ 132/*------------------*/ 133static const char *CCA4758_LIB_NAME = NULL; 134static const char *get_CCA4758_LIB_NAME(void) 135 { 136 if(CCA4758_LIB_NAME) 137 return CCA4758_LIB_NAME; 138 return CCA_LIB_NAME; 139 } 140static void free_CCA4758_LIB_NAME(void) 141 { 142 if(CCA4758_LIB_NAME) 143 OPENSSL_free((void*)CCA4758_LIB_NAME); 144 CCA4758_LIB_NAME = NULL; 145 } 146static long set_CCA4758_LIB_NAME(const char *name) 147 { 148 free_CCA4758_LIB_NAME(); 149 return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0); 150 } 151#ifndef OPENSSL_NO_RSA 152static const char* n_keyRecordRead = CSNDKRR; 153static const char* n_digitalSignatureGenerate = CSNDDSG; 154static const char* n_digitalSignatureVerify = CSNDDSV; 155static const char* n_publicKeyExtract = CSNDPKX; 156static const char* n_pkaEncrypt = CSNDPKE; 157static const char* n_pkaDecrypt = CSNDPKD; 158#endif 159static const char* n_randomNumberGenerate = CSNBRNG; 160 161#ifndef OPENSSL_NO_RSA 162static int hndidx = -1; 163#endif 164static DSO *dso = NULL; 165 166/* openssl engine initialization structures */ 167/*------------------------------------------*/ 168 169#define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE 170static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = { 171 {CCA4758_CMD_SO_PATH, 172 "SO_PATH", 173 "Specifies the path to the '4758cca' shared library", 174 ENGINE_CMD_FLAG_STRING}, 175 {0, NULL, NULL, 0} 176 }; 177 178#ifndef OPENSSL_NO_RSA 179static RSA_METHOD ibm_4758_cca_rsa = 180 { 181 "IBM 4758 CCA RSA method", 182 cca_rsa_pub_enc, 183 NULL, 184 NULL, 185 cca_rsa_priv_dec, 186 NULL, /*rsa_mod_exp,*/ 187 NULL, /*mod_exp_mont,*/ 188 NULL, /* init */ 189 NULL, /* finish */ 190 RSA_FLAG_SIGN_VER, /* flags */ 191 NULL, /* app_data */ 192 cca_rsa_sign, /* rsa_sign */ 193 cca_rsa_verify, /* rsa_verify */ 194 NULL /* rsa_keygen */ 195 }; 196#endif 197 198static RAND_METHOD ibm_4758_cca_rand = 199 { 200 /* "IBM 4758 RAND method", */ 201 NULL, /* seed */ 202 cca_get_random_bytes, /* get random bytes from the card */ 203 NULL, /* cleanup */ 204 NULL, /* add */ 205 cca_get_random_bytes, /* pseudo rand */ 206 cca_random_status, /* status */ 207 }; 208 209static const char *engine_4758_cca_id = "4758cca"; 210static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support"; 211#ifndef OPENSSL_NO_DYNAMIC_ENGINE 212/* Compatibility hack, the dynamic library uses this form in the path */ 213static const char *engine_4758_cca_id_alt = "4758_cca"; 214#endif 215 216/* engine implementation */ 217/*-----------------------*/ 218static int bind_helper(ENGINE *e) 219 { 220 if(!ENGINE_set_id(e, engine_4758_cca_id) || 221 !ENGINE_set_name(e, engine_4758_cca_name) || 222#ifndef OPENSSL_NO_RSA 223 !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) || 224#endif 225 !ENGINE_set_RAND(e, &ibm_4758_cca_rand) || 226 !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) || 227 !ENGINE_set_init_function(e, ibm_4758_cca_init) || 228 !ENGINE_set_finish_function(e, ibm_4758_cca_finish) || 229 !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) || 230#ifndef OPENSSL_NO_RSA 231 !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) || 232 !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) || 233#endif 234 !ENGINE_set_cmd_defns(e, cca4758_cmd_defns)) 235 return 0; 236 /* Ensure the error handling is set up */ 237 ERR_load_CCA4758_strings(); 238 return 1; 239 } 240 241#ifdef OPENSSL_NO_DYNAMIC_ENGINE 242static ENGINE *engine_4758_cca(void) 243 { 244 ENGINE *ret = ENGINE_new(); 245 if(!ret) 246 return NULL; 247 if(!bind_helper(ret)) 248 { 249 ENGINE_free(ret); 250 return NULL; 251 } 252 return ret; 253 } 254 255void ENGINE_load_4758cca(void) 256 { 257 ENGINE *e_4758 = engine_4758_cca(); 258 if (!e_4758) return; 259 ENGINE_add(e_4758); 260 ENGINE_free(e_4758); 261 ERR_clear_error(); 262 } 263#endif 264 265static int ibm_4758_cca_destroy(ENGINE *e) 266 { 267 ERR_unload_CCA4758_strings(); 268 free_CCA4758_LIB_NAME(); 269 return 1; 270 } 271 272static int ibm_4758_cca_init(ENGINE *e) 273 { 274 if(dso) 275 { 276 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED); 277 goto err; 278 } 279 280 dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0); 281 if(!dso) 282 { 283 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE); 284 goto err; 285 } 286 287#ifndef OPENSSL_NO_RSA 288 if(!(keyRecordRead = (F_KEYRECORDREAD) 289 DSO_bind_func(dso, n_keyRecordRead)) || 290 !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 291 DSO_bind_func(dso, n_randomNumberGenerate)) || 292 !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 293 DSO_bind_func(dso, n_digitalSignatureGenerate)) || 294 !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY) 295 DSO_bind_func(dso, n_digitalSignatureVerify)) || 296 !(publicKeyExtract = (F_PUBLICKEYEXTRACT) 297 DSO_bind_func(dso, n_publicKeyExtract)) || 298 !(pkaEncrypt = (F_PKAENCRYPT) 299 DSO_bind_func(dso, n_pkaEncrypt)) || 300 !(pkaDecrypt = (F_PKADECRYPT) 301 DSO_bind_func(dso, n_pkaDecrypt))) 302 { 303 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE); 304 goto err; 305 } 306#else 307 if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 308 DSO_bind_func(dso, n_randomNumberGenerate))) 309 { 310 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE); 311 goto err; 312 } 313#endif 314 315#ifndef OPENSSL_NO_RSA 316 hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", 317 NULL, NULL, cca_ex_free); 318#endif 319 320 return 1; 321err: 322 if(dso) 323 DSO_free(dso); 324 dso = NULL; 325 326#ifndef OPENSSL_NO_RSA 327 keyRecordRead = (F_KEYRECORDREAD)0; 328 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0; 329 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 330 publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 331 pkaEncrypt = (F_PKAENCRYPT)0; 332 pkaDecrypt = (F_PKADECRYPT)0; 333#endif 334 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0; 335 return 0; 336 } 337 338static int ibm_4758_cca_finish(ENGINE *e) 339 { 340 free_CCA4758_LIB_NAME(); 341 if(!dso) 342 { 343 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, 344 CCA4758_R_NOT_LOADED); 345 return 0; 346 } 347 if(!DSO_free(dso)) 348 { 349 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, 350 CCA4758_R_UNIT_FAILURE); 351 return 0; 352 } 353 dso = NULL; 354#ifndef OPENSSL_NO_RSA 355 keyRecordRead = (F_KEYRECORDREAD)0; 356 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0; 357 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0; 358 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 359 publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 360 pkaEncrypt = (F_PKAENCRYPT)0; 361 pkaDecrypt = (F_PKADECRYPT)0; 362#endif 363 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0; 364 return 1; 365 } 366 367static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) 368 { 369 int initialised = ((dso == NULL) ? 0 : 1); 370 switch(cmd) 371 { 372 case CCA4758_CMD_SO_PATH: 373 if(p == NULL) 374 { 375 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 376 ERR_R_PASSED_NULL_PARAMETER); 377 return 0; 378 } 379 if(initialised) 380 { 381 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 382 CCA4758_R_ALREADY_LOADED); 383 return 0; 384 } 385 return set_CCA4758_LIB_NAME((const char *)p); 386 default: 387 break; 388 } 389 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 390 CCA4758_R_COMMAND_NOT_IMPLEMENTED); 391 return 0; 392 } 393 394#ifndef OPENSSL_NO_RSA 395 396#define MAX_CCA_PKA_TOKEN_SIZE 2500 397 398static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id, 399 UI_METHOD *ui_method, void *callback_data) 400 { 401 RSA *rtmp = NULL; 402 EVP_PKEY *res = NULL; 403 unsigned char* keyToken = NULL; 404 unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE]; 405 long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 406 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 407 long returnCode; 408 long reasonCode; 409 long exitDataLength = 0; 410 long ruleArrayLength = 0; 411 unsigned char exitData[8]; 412 unsigned char ruleArray[8]; 413 unsigned char keyLabel[64]; 414 unsigned long keyLabelLength = strlen(key_id); 415 unsigned char modulus[256]; 416 long modulusFieldLength = sizeof(modulus); 417 long modulusLength = 0; 418 unsigned char exponent[256]; 419 long exponentLength = sizeof(exponent); 420 421 if (keyLabelLength > sizeof(keyLabel)) 422 { 423 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 424 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 425 return NULL; 426 } 427 428 memset(keyLabel,' ', sizeof(keyLabel)); 429 memcpy(keyLabel, key_id, keyLabelLength); 430 431 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 432 if (!keyToken) 433 { 434 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 435 ERR_R_MALLOC_FAILURE); 436 goto err; 437 } 438 439 keyRecordRead(&returnCode, &reasonCode, &exitDataLength, 440 exitData, &ruleArrayLength, ruleArray, keyLabel, 441 &keyTokenLength, keyToken+sizeof(long)); 442 443 if (returnCode) 444 { 445 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 446 CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 447 goto err; 448 } 449 450 publicKeyExtract(&returnCode, &reasonCode, &exitDataLength, 451 exitData, &ruleArrayLength, ruleArray, &keyTokenLength, 452 keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken); 453 454 if (returnCode) 455 { 456 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 457 CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 458 goto err; 459 } 460 461 if (!getModulusAndExponent(pubKeyToken, &exponentLength, 462 exponent, &modulusLength, &modulusFieldLength, 463 modulus)) 464 { 465 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 466 CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 467 goto err; 468 } 469 470 (*(long*)keyToken) = keyTokenLength; 471 rtmp = RSA_new_method(e); 472 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 473 474 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 475 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 476 rtmp->flags |= RSA_FLAG_EXT_PKEY; 477 478 res = EVP_PKEY_new(); 479 EVP_PKEY_assign_RSA(res, rtmp); 480 481 return res; 482err: 483 if (keyToken) 484 OPENSSL_free(keyToken); 485 if (res) 486 EVP_PKEY_free(res); 487 if (rtmp) 488 RSA_free(rtmp); 489 return NULL; 490 } 491 492static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id, 493 UI_METHOD *ui_method, void *callback_data) 494 { 495 RSA *rtmp = NULL; 496 EVP_PKEY *res = NULL; 497 unsigned char* keyToken = NULL; 498 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 499 long returnCode; 500 long reasonCode; 501 long exitDataLength = 0; 502 long ruleArrayLength = 0; 503 unsigned char exitData[8]; 504 unsigned char ruleArray[8]; 505 unsigned char keyLabel[64]; 506 unsigned long keyLabelLength = strlen(key_id); 507 unsigned char modulus[512]; 508 long modulusFieldLength = sizeof(modulus); 509 long modulusLength = 0; 510 unsigned char exponent[512]; 511 long exponentLength = sizeof(exponent); 512 513 if (keyLabelLength > sizeof(keyLabel)) 514 { 515 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 516 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 517 return NULL; 518 } 519 520 memset(keyLabel,' ', sizeof(keyLabel)); 521 memcpy(keyLabel, key_id, keyLabelLength); 522 523 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 524 if (!keyToken) 525 { 526 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 527 ERR_R_MALLOC_FAILURE); 528 goto err; 529 } 530 531 keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData, 532 &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength, 533 keyToken+sizeof(long)); 534 535 if (returnCode) 536 { 537 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 538 ERR_R_MALLOC_FAILURE); 539 goto err; 540 } 541 542 if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength, 543 exponent, &modulusLength, &modulusFieldLength, modulus)) 544 { 545 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 546 CCA4758_R_FAILED_LOADING_PUBLIC_KEY); 547 goto err; 548 } 549 550 (*(long*)keyToken) = keyTokenLength; 551 rtmp = RSA_new_method(e); 552 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 553 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 554 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 555 rtmp->flags |= RSA_FLAG_EXT_PKEY; 556 res = EVP_PKEY_new(); 557 EVP_PKEY_assign_RSA(res, rtmp); 558 559 return res; 560err: 561 if (keyToken) 562 OPENSSL_free(keyToken); 563 if (res) 564 EVP_PKEY_free(res); 565 if (rtmp) 566 RSA_free(rtmp); 567 return NULL; 568 } 569 570static int cca_rsa_pub_enc(int flen, const unsigned char *from, 571 unsigned char *to, RSA *rsa,int padding) 572 { 573 long returnCode; 574 long reasonCode; 575 long lflen = flen; 576 long exitDataLength = 0; 577 unsigned char exitData[8]; 578 long ruleArrayLength = 1; 579 unsigned char ruleArray[8] = "PKCS-1.2"; 580 long dataStructureLength = 0; 581 unsigned char dataStructure[8]; 582 long outputLength = RSA_size(rsa); 583 long keyTokenLength; 584 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx); 585 586 keyTokenLength = *(long*)keyToken; 587 keyToken+=sizeof(long); 588 589 pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 590 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from, 591 &dataStructureLength, dataStructure, &keyTokenLength, 592 keyToken, &outputLength, to); 593 594 if (returnCode || reasonCode) 595 return -(returnCode << 16 | reasonCode); 596 return outputLength; 597 } 598 599static int cca_rsa_priv_dec(int flen, const unsigned char *from, 600 unsigned char *to, RSA *rsa,int padding) 601 { 602 long returnCode; 603 long reasonCode; 604 long lflen = flen; 605 long exitDataLength = 0; 606 unsigned char exitData[8]; 607 long ruleArrayLength = 1; 608 unsigned char ruleArray[8] = "PKCS-1.2"; 609 long dataStructureLength = 0; 610 unsigned char dataStructure[8]; 611 long outputLength = RSA_size(rsa); 612 long keyTokenLength; 613 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx); 614 615 keyTokenLength = *(long*)keyToken; 616 keyToken+=sizeof(long); 617 618 pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 619 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from, 620 &dataStructureLength, dataStructure, &keyTokenLength, 621 keyToken, &outputLength, to); 622 623 return (returnCode | reasonCode) ? 0 : 1; 624 } 625 626#define SSL_SIG_LEN 36 627 628static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len, 629 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa) 630 { 631 long returnCode; 632 long reasonCode; 633 long lsiglen = siglen; 634 long exitDataLength = 0; 635 unsigned char exitData[8]; 636 long ruleArrayLength = 1; 637 unsigned char ruleArray[8] = "PKCS-1.1"; 638 long keyTokenLength; 639 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx); 640 long length = SSL_SIG_LEN; 641 long keyLength ; 642 unsigned char *hashBuffer = NULL; 643 X509_SIG sig; 644 ASN1_TYPE parameter; 645 X509_ALGOR algorithm; 646 ASN1_OCTET_STRING digest; 647 648 keyTokenLength = *(long*)keyToken; 649 keyToken+=sizeof(long); 650 651 if (type == NID_md5 || type == NID_sha1) 652 { 653 sig.algor = &algorithm; 654 algorithm.algorithm = OBJ_nid2obj(type); 655 656 if (!algorithm.algorithm) 657 { 658 CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 659 CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 660 return 0; 661 } 662 663 if (!algorithm.algorithm->length) 664 { 665 CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 666 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 667 return 0; 668 } 669 670 parameter.type = V_ASN1_NULL; 671 parameter.value.ptr = NULL; 672 algorithm.parameter = ¶meter; 673 674 sig.digest = &digest; 675 sig.digest->data = (unsigned char*)m; 676 sig.digest->length = m_len; 677 678 length = i2d_X509_SIG(&sig, NULL); 679 } 680 681 keyLength = RSA_size(rsa); 682 683 if (length - RSA_PKCS1_PADDING > keyLength) 684 { 685 CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 686 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 687 return 0; 688 } 689 690 switch (type) 691 { 692 case NID_md5_sha1 : 693 if (m_len != SSL_SIG_LEN) 694 { 695 CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 696 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 697 return 0; 698 } 699 700 hashBuffer = (unsigned char *)m; 701 length = m_len; 702 break; 703 case NID_md5 : 704 { 705 unsigned char *ptr; 706 ptr = hashBuffer = OPENSSL_malloc( 707 (unsigned int)keyLength+1); 708 if (!hashBuffer) 709 { 710 CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 711 ERR_R_MALLOC_FAILURE); 712 return 0; 713 } 714 715 i2d_X509_SIG(&sig, &ptr); 716 } 717 break; 718 case NID_sha1 : 719 { 720 unsigned char *ptr; 721 ptr = hashBuffer = OPENSSL_malloc( 722 (unsigned int)keyLength+1); 723 if (!hashBuffer) 724 { 725 CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 726 ERR_R_MALLOC_FAILURE); 727 return 0; 728 } 729 i2d_X509_SIG(&sig, &ptr); 730 } 731 break; 732 default: 733 return 0; 734 } 735 736 digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength, 737 exitData, &ruleArrayLength, ruleArray, &keyTokenLength, 738 keyToken, &length, hashBuffer, &lsiglen, sigbuf); 739 740 if (type == NID_sha1 || type == NID_md5) 741 { 742 OPENSSL_cleanse(hashBuffer, keyLength+1); 743 OPENSSL_free(hashBuffer); 744 } 745 746 return ((returnCode || reasonCode) ? 0 : 1); 747 } 748 749#define SSL_SIG_LEN 36 750 751static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 752 unsigned char *sigret, unsigned int *siglen, const RSA *rsa) 753 { 754 long returnCode; 755 long reasonCode; 756 long exitDataLength = 0; 757 unsigned char exitData[8]; 758 long ruleArrayLength = 1; 759 unsigned char ruleArray[8] = "PKCS-1.1"; 760 long outputLength=256; 761 long outputBitLength; 762 long keyTokenLength; 763 unsigned char *hashBuffer = NULL; 764 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx); 765 long length = SSL_SIG_LEN; 766 long keyLength ; 767 X509_SIG sig; 768 ASN1_TYPE parameter; 769 X509_ALGOR algorithm; 770 ASN1_OCTET_STRING digest; 771 772 keyTokenLength = *(long*)keyToken; 773 keyToken+=sizeof(long); 774 775 if (type == NID_md5 || type == NID_sha1) 776 { 777 sig.algor = &algorithm; 778 algorithm.algorithm = OBJ_nid2obj(type); 779 780 if (!algorithm.algorithm) 781 { 782 CCA4758err(CCA4758_F_CCA_RSA_SIGN, 783 CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 784 return 0; 785 } 786 787 if (!algorithm.algorithm->length) 788 { 789 CCA4758err(CCA4758_F_CCA_RSA_SIGN, 790 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 791 return 0; 792 } 793 794 parameter.type = V_ASN1_NULL; 795 parameter.value.ptr = NULL; 796 algorithm.parameter = ¶meter; 797 798 sig.digest = &digest; 799 sig.digest->data = (unsigned char*)m; 800 sig.digest->length = m_len; 801 802 length = i2d_X509_SIG(&sig, NULL); 803 } 804 805 keyLength = RSA_size(rsa); 806 807 if (length - RSA_PKCS1_PADDING > keyLength) 808 { 809 CCA4758err(CCA4758_F_CCA_RSA_SIGN, 810 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 811 return 0; 812 } 813 814 switch (type) 815 { 816 case NID_md5_sha1 : 817 if (m_len != SSL_SIG_LEN) 818 { 819 CCA4758err(CCA4758_F_CCA_RSA_SIGN, 820 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 821 return 0; 822 } 823 hashBuffer = (unsigned char*)m; 824 length = m_len; 825 break; 826 case NID_md5 : 827 { 828 unsigned char *ptr; 829 ptr = hashBuffer = OPENSSL_malloc( 830 (unsigned int)keyLength+1); 831 if (!hashBuffer) 832 { 833 CCA4758err(CCA4758_F_CCA_RSA_SIGN, 834 ERR_R_MALLOC_FAILURE); 835 return 0; 836 } 837 i2d_X509_SIG(&sig, &ptr); 838 } 839 break; 840 case NID_sha1 : 841 { 842 unsigned char *ptr; 843 ptr = hashBuffer = OPENSSL_malloc( 844 (unsigned int)keyLength+1); 845 if (!hashBuffer) 846 { 847 CCA4758err(CCA4758_F_CCA_RSA_SIGN, 848 ERR_R_MALLOC_FAILURE); 849 return 0; 850 } 851 i2d_X509_SIG(&sig, &ptr); 852 } 853 break; 854 default: 855 return 0; 856 } 857 858 digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength, 859 exitData, &ruleArrayLength, ruleArray, &keyTokenLength, 860 keyToken, &length, hashBuffer, &outputLength, &outputBitLength, 861 sigret); 862 863 if (type == NID_sha1 || type == NID_md5) 864 { 865 OPENSSL_cleanse(hashBuffer, keyLength+1); 866 OPENSSL_free(hashBuffer); 867 } 868 869 *siglen = outputLength; 870 871 return ((returnCode || reasonCode) ? 0 : 1); 872 } 873 874static int getModulusAndExponent(const unsigned char*token, long *exponentLength, 875 unsigned char *exponent, long *modulusLength, long *modulusFieldLength, 876 unsigned char *modulus) 877 { 878 unsigned long len; 879 880 if (*token++ != (char)0x1E) /* internal PKA token? */ 881 return 0; 882 883 if (*token++) /* token version must be zero */ 884 return 0; 885 886 len = *token++; 887 len = len << 8; 888 len |= (unsigned char)*token++; 889 890 token += 4; /* skip reserved bytes */ 891 892 if (*token++ == (char)0x04) 893 { 894 if (*token++) /* token version must be zero */ 895 return 0; 896 897 len = *token++; 898 len = len << 8; 899 len |= (unsigned char)*token++; 900 901 token+=2; /* skip reserved section */ 902 903 len = *token++; 904 len = len << 8; 905 len |= (unsigned char)*token++; 906 907 *exponentLength = len; 908 909 len = *token++; 910 len = len << 8; 911 len |= (unsigned char)*token++; 912 913 *modulusLength = len; 914 915 len = *token++; 916 len = len << 8; 917 len |= (unsigned char)*token++; 918 919 *modulusFieldLength = len; 920 921 memcpy(exponent, token, *exponentLength); 922 token+= *exponentLength; 923 924 memcpy(modulus, token, *modulusFieldLength); 925 return 1; 926 } 927 return 0; 928 } 929 930#endif /* OPENSSL_NO_RSA */ 931 932static int cca_random_status(void) 933 { 934 return 1; 935 } 936 937static int cca_get_random_bytes(unsigned char* buf, int num) 938 { 939 long ret_code; 940 long reason_code; 941 long exit_data_length; 942 unsigned char exit_data[4]; 943 unsigned char form[] = "RANDOM "; 944 unsigned char rand_buf[8]; 945 946 while(num >= (int)sizeof(rand_buf)) 947 { 948 randomNumberGenerate(&ret_code, &reason_code, &exit_data_length, 949 exit_data, form, rand_buf); 950 if (ret_code) 951 return 0; 952 num -= sizeof(rand_buf); 953 memcpy(buf, rand_buf, sizeof(rand_buf)); 954 buf += sizeof(rand_buf); 955 } 956 957 if (num) 958 { 959 randomNumberGenerate(&ret_code, &reason_code, NULL, NULL, 960 form, rand_buf); 961 if (ret_code) 962 return 0; 963 memcpy(buf, rand_buf, num); 964 } 965 966 return 1; 967 } 968 969#ifndef OPENSSL_NO_RSA 970static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx, 971 long argl, void *argp) 972 { 973 if (item) 974 OPENSSL_free(item); 975 } 976#endif 977 978/* Goo to handle building as a dynamic engine */ 979#ifndef OPENSSL_NO_DYNAMIC_ENGINE 980static int bind_fn(ENGINE *e, const char *id) 981 { 982 if(id && (strcmp(id, engine_4758_cca_id) != 0) && 983 (strcmp(id, engine_4758_cca_id_alt) != 0)) 984 return 0; 985 if(!bind_helper(e)) 986 return 0; 987 return 1; 988 } 989IMPLEMENT_DYNAMIC_CHECK_FN() 990IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 991#endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 992 993#endif /* !OPENSSL_NO_HW_4758_CCA */ 994#endif /* !OPENSSL_NO_HW */ 995