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