1/* 2 * bsafeUtils.c - common routines for CDSA/BSAFE compatibility testing 3 */ 4 5 6#include <stdlib.h> 7#include <stdio.h> 8#include <time.h> 9#include <string.h> 10//#include <security_bsafe/bsafe.h> 11//#include <security_bsafe/aglobal.h> 12#include "bsafeUtils.h" 13#include <Security/cssmerr.h> 14#include "common.h" 15 16/* 17 * Convert between BSAFE ITEM and CSSM_DATA 18 */ 19#if 0 20static inline void buItemToCssmData( 21 const ITEM *item, 22 CSSM_DATA_PTR cdata) 23{ 24 cdata->Data = item->data; 25 cdata->Length = item->len; 26} 27 28static inline void buCssmDataToItem( 29 const CSSM_DATA *cdata, 30 ITEM *item) 31{ 32 item->data = cdata->Data; 33 item->len = cdata->Length; 34} 35 36/* 37 * BSafe's Chooser table - all we'll ever need. 38 */ 39/*static*/ B_ALGORITHM_METHOD *BSAFE_ALGORITHM_CHOOSER[] = { 40 // digests 41 &AM_SHA, 42 &AM_MD5, 43 &AM_MD2, 44 45 // organizational 46 &AM_CBC_ENCRYPT, 47 &AM_CBC_DECRYPT, 48 &AM_ECB_ENCRYPT, 49 &AM_ECB_DECRYPT, 50 &AM_OFB_ENCRYPT, 51 &AM_OFB_DECRYPT, 52 53 // DES & variants 54 &AM_DES_ENCRYPT, 55 &AM_DES_DECRYPT, 56 &AM_DESX_ENCRYPT, 57 &AM_DESX_DECRYPT, 58 &AM_DES_EDE_ENCRYPT, 59 &AM_DES_EDE_DECRYPT, 60 61 // RCn stuff 62 &AM_RC2_CBC_ENCRYPT, 63 &AM_RC2_CBC_DECRYPT, 64 &AM_RC2_ENCRYPT, 65 &AM_RC2_DECRYPT, 66 &AM_RC4_ENCRYPT, 67 &AM_RC4_DECRYPT, 68 &AM_RC5_ENCRYPT, 69 &AM_RC5_DECRYPT, 70 &AM_RC5_CBC_ENCRYPT, 71 &AM_RC5_CBC_DECRYPT, 72 73 // RSA 74 &AM_RSA_STRONG_KEY_GEN, 75 &AM_RSA_KEY_GEN, 76 &AM_RSA_CRT_ENCRYPT_BLIND, 77 &AM_RSA_CRT_DECRYPT_BLIND, 78 &AM_RSA_ENCRYPT, 79 &AM_RSA_DECRYPT, 80 81 // DSA 82 &AM_DSA_PARAM_GEN, 83 &AM_DSA_KEY_GEN, 84 85 // signatures 86 &AM_DSA_SIGN, 87 &AM_DSA_VERIFY, 88 89 // random number generation 90 &AM_MD5_RANDOM, 91 &AM_SHA_RANDOM, 92 93 // sentinel 94 (B_ALGORITHM_METHOD *)NULL_PTR 95}; 96 97/* 98 * Convert a BSAFE return to a CSSM error and optionally print the error msg with 99 * the op in which the error occurred. 100 */ 101static CSSM_RETURN buBsafeErrToCssm( 102 int brtn, 103 const char *op) 104{ 105 const char *errStr = NULL; 106 CSSM_RETURN crtn; 107 108 switch (brtn) { 109 case 0: 110 return CSSM_OK; 111 case BE_ALLOC: 112 crtn = CSSMERR_CSSM_MEMORY_ERROR; 113 errStr = "BE_ALLOC"; 114 break; 115 case BE_SIGNATURE: 116 crtn = CSSMERR_CSP_VERIFY_FAILED; 117 errStr = "BE_SIGNATURE"; 118 break; 119 case BE_OUTPUT_LEN: 120 crtn = CSSMERR_CSP_OUTPUT_LENGTH_ERROR; 121 errStr = "BE_OUTPUT_LEN"; 122 break; 123 case BE_INPUT_LEN: 124 crtn = CSSMERR_CSP_INPUT_LENGTH_ERROR; 125 errStr = "BE_INPUT_LEN"; 126 break; 127 case BE_EXPONENT_EVEN: 128 crtn = CSSMERR_CSP_INVALID_KEY; 129 errStr = "BE_EXPONENT_EVEN"; 130 break; 131 case BE_EXPONENT_LEN: 132 crtn = CSSMERR_CSP_INVALID_KEY; 133 errStr = "BE_EXPONENT_LEN"; 134 break; 135 case BE_EXPONENT_ONE: 136 crtn = CSSMERR_CSP_INVALID_KEY; 137 errStr = "BE_EXPONENT_ONE"; 138 break; 139 case BE_DATA: 140 crtn = CSSMERR_CSP_INVALID_DATA; 141 errStr = "BE_DATA"; 142 break; 143 case BE_INPUT_DATA: 144 crtn = CSSMERR_CSP_INVALID_DATA; 145 errStr = "BE_INPUT_DATA"; 146 break; 147 case BE_WRONG_KEY_INFO: 148 crtn = CSSMERR_CSP_INVALID_KEY; 149 errStr = "BE_WRONG_KEY_INFO"; 150 break; 151 default: 152 //@@@ translate BSafe errors intelligently 153 crtn = CSSM_ERRCODE_INTERNAL_ERROR; 154 errStr = "Other BSAFE error"; 155 break; 156 } 157 if(op != NULL) { 158 printf("%s: BSAFE error %d (%s)\n", op, brtn, errStr); 159 } 160 return crtn; 161} 162 163/* 164 * Non-thread-safe global random B_ALGORITHM_OBJ and a reusable init for it. 165 */ 166static B_ALGORITHM_OBJ bsafeRng = NULL; 167#define BSAFE_RANDSIZE 64 168 169static B_ALGORITHM_OBJ buGetRng() 170{ 171 int brtn; 172 uint8 seed[BSAFE_RANDSIZE]; 173 174 if(bsafeRng != NULL) { 175 return bsafeRng; 176 } 177 brtn = B_CreateAlgorithmObject(&bsafeRng); 178 if(brtn) { 179 buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject(&bsafeRng)"); 180 return NULL; 181 } 182 brtn = B_SetAlgorithmInfo(bsafeRng, AI_X962Random_V0, NULL_PTR); 183 if(brtn) { 184 buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo(bsafeRng)"); 185 return NULL; 186 } 187 brtn = B_RandomInit(bsafeRng, BSAFE_ALGORITHM_CHOOSER, NULL); 188 if(brtn) { 189 buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo(bsafeRng)"); 190 return NULL; 191 } 192 appGetRandomBytes(seed, BSAFE_RANDSIZE); 193 brtn = B_RandomUpdate(bsafeRng, seed, BSAFE_RANDSIZE, NULL); 194 if(brtn) { 195 buBsafeErrToCssm(brtn, "B_RandomUpdate"); 196 return NULL; 197 } 198 return bsafeRng; 199} 200#endif 201 202/* 203 * Create a symmetric key. 204 */ 205CSSM_RETURN buGenSymKey( 206 uint32 keySizeInBits, 207 const CSSM_DATA *keyData, 208 BU_KEY *key) // RETURNED 209{ 210#if 0 211 int brtn; 212 B_KEY_OBJ bkey = NULL; 213 ITEM item; 214 unsigned keyBytes = (keySizeInBits + 7) / 8; 215 216 if(keyBytes > keyData->Length) { 217 /* note it's OK to give us too much key data */ 218 printf("***buGenSymKey: Insufficient keyData\n"); 219 return CSSM_ERRCODE_INTERNAL_ERROR; 220 } 221 222 /* create a BSAFE key */ 223 brtn = B_CreateKeyObject(&bkey); 224 if(brtn) { 225 return buBsafeErrToCssm(brtn, "B_CreateKeyObject"); 226 } 227 228 /* assign data to the key */ 229 item.data = keyData->Data; 230 item.len = keyBytes; 231 brtn = B_SetKeyInfo(bkey, KI_Item, (POINTER)&item); 232 if(brtn) { 233 return buBsafeErrToCssm(brtn, "B_SetKeyInfo"); 234 } 235 else { 236 *key = bkey; 237 return CSSM_OK; 238 } 239#endif 240 return 0; 241} 242 243/* 244 * Create asymmetric key pair. 245 * FIXME - additional params (e.g. DSA params, RSA exponent)? 246 */ 247CSSM_RETURN buGenKeyPair( 248 uint32 keySizeInBits, 249 CSSM_ALGORITHMS keyAlg, // CSSM_ALGID_{RSA,DSA} 250 BU_KEY *pubKey, // RETURNED 251 BU_KEY *privKey) // RETURNED 252{ 253#if 0 // NO MORE BSAFE 254 int brtn; 255 B_KEY_OBJ bPubkey = NULL; 256 B_KEY_OBJ bPrivkey = NULL; 257 B_ALGORITHM_OBJ keypairGen = NULL; 258 const char *op = NULL; 259 A_RSA_KEY_GEN_PARAMS params; 260 unsigned char exp[1] = { 3 }; 261 B_ALGORITHM_OBJ genDsaAlg = NULL; 262 B_ALGORITHM_OBJ dsaResult = NULL; 263 B_DSA_PARAM_GEN_PARAMS dsaParams; 264 A_DSA_PARAMS *kParams = NULL; 265 266 /* create algorithm object */ 267 brtn = B_CreateAlgorithmObject(&keypairGen); 268 if(brtn) { 269 return CSSMERR_CSSM_MEMORY_ERROR; 270 } 271 272 /* create two BSAFE keys */ 273 brtn = B_CreateKeyObject(&bPubkey); 274 if(brtn) { 275 op ="B_CreateKeyObject"; 276 goto abort; 277 } 278 brtn = B_CreateKeyObject(&bPrivkey); 279 if(brtn) { 280 op ="B_CreateKeyObject"; 281 goto abort; 282 } 283 switch(keyAlg) { 284 case CSSM_ALGID_RSA: 285 { 286 /* set RSA-specific params */ 287 params.modulusBits = keySizeInBits; 288 /* hack - parameterize? */ 289 params.publicExponent.data = exp; 290 params.publicExponent.len = 1; 291 brtn = B_SetAlgorithmInfo(keypairGen, AI_RSAKeyGen, 292 (POINTER)¶ms); 293 if(brtn) { 294 op ="B_SetAlgorithmInfo(AI_RSAKeyGen)"; 295 } 296 break; 297 } 298 case CSSM_ALGID_DSA: 299 { 300 /* jump through hoops generating parameters */ 301 brtn = B_CreateAlgorithmObject(&genDsaAlg); 302 if(brtn) { 303 op ="B_CreateAlgorithmObject"; 304 break; 305 } 306 dsaParams.primeBits = keySizeInBits; 307 brtn = B_SetAlgorithmInfo(genDsaAlg, AI_DSAParamGen, (POINTER)&dsaParams); 308 if(brtn) { 309 op = "B_SetAlgorithmInfo(AI_DSAParamGen)"; 310 break; 311 } 312 brtn = B_GenerateInit(genDsaAlg, BSAFE_ALGORITHM_CHOOSER, NULL); 313 if(brtn) { 314 op = "B_GenerateInit(AI_DSAParamGen)"; 315 break; 316 } 317 brtn = B_CreateAlgorithmObject(&dsaResult); 318 if(brtn) { 319 op = "B_CreateAlgorithmObject"; 320 break; 321 } 322 brtn = B_GenerateParameters(genDsaAlg, dsaResult, buGetRng(), NULL); 323 if(brtn) { 324 op = "B_GenerateParameters"; 325 break; 326 } 327 328 /* dsaResult now has the parameters, which we must extract and then 329 * apply to the keypairGen object. Cool, huh? */ 330 brtn = B_GetAlgorithmInfo((POINTER *)&kParams, dsaResult, AI_DSAKeyGen); 331 if(brtn) { 332 op = "B_GetAlgorithmInfo(AI_DSAKeyGen)"; 333 break; 334 } 335 brtn = B_SetAlgorithmInfo(keypairGen, AI_DSAKeyGen, (POINTER)kParams); 336 if(brtn) { 337 op ="B_SetAlgorithmInfo(AI_DSAKeyGen)"; 338 } 339 break; 340 } 341 default: 342 printf("buGenKeyPair: algorithm not supported\n"); 343 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED; 344 } 345 if(brtn) { 346 goto abort; 347 } 348 349 /* keypairGen all set to go. */ 350 brtn = B_GenerateInit(keypairGen, 351 BSAFE_ALGORITHM_CHOOSER, 352 (A_SURRENDER_CTX *)NULL); 353 if(brtn) { 354 op = "B_GenerateInit"; 355 goto abort; 356 } 357 brtn = B_GenerateKeypair(keypairGen, 358 bPubkey, 359 bPrivkey, 360 buGetRng(), 361 NULL); 362 if(brtn) { 363 op = "B_GenerateInit"; 364 } 365abort: 366 B_DestroyAlgorithmObject(&keypairGen); 367 B_DestroyAlgorithmObject(&genDsaAlg); 368 B_DestroyAlgorithmObject(&dsaResult); 369 if(brtn) { 370 B_DestroyKeyObject(&bPubkey); 371 B_DestroyKeyObject(&bPrivkey); 372 return buBsafeErrToCssm(brtn, op); 373 } 374 else { 375 *pubKey = bPubkey; 376 *privKey = bPrivkey; 377 return CSSM_OK; 378 } 379#endif 380 return CSSM_OK; 381} 382 383/* 384 * Free a key created in buGenSymKey or buGenKeyPair 385 */ 386CSSM_RETURN buFreeKey( 387 BU_KEY key) 388{ 389#if 0 // NO MORE BSAFE 390 B_KEY_OBJ bkey = (B_KEY_OBJ)key; 391 B_DestroyKeyObject(&bkey); 392#endif 393 return CSSM_OK; 394} 395 396/* 397 * encrypt/decrypt 398 */ 399CSSM_RETURN buEncryptDecrypt( 400 BU_KEY key, 401 CSSM_BOOL forEncrypt, 402 CSSM_ALGORITHMS encrAlg, 403 CSSM_ENCRYPT_MODE mode, // CSSM_ALGMODE_CBC, etc. 404 const CSSM_DATA *iv, //�optional per mode 405 uint32 effectiveKeyBits, // optional per key alg (actually just RC2) 406 // for RSA, key size in bits 407 uint32 rounds, // optional, RC5 only 408 const CSSM_DATA *inData, 409 CSSM_DATA_PTR outData) // mallocd and RETURNED 410{ 411#if 0 // NO MORE BSAFE 412 B_ALGORITHM_OBJ alg; 413 int brtn; 414 char fbCipher = 1; 415 uint32 blockSize = 0; 416 unsigned outBufLen; 417 unsigned bytesMoved; 418 CSSM_RETURN crtn; 419 char useIv; 420 421 // these variables are used in the switch below and need to 422 // live until after setAlgorithm() 423 ITEM bsIv; 424 B_BLK_CIPHER_W_FEEDBACK_PARAMS spec; 425 A_RC5_PARAMS rc5Params; 426 A_RC2_PARAMS rc2Params; 427 428 brtn = B_CreateAlgorithmObject(&alg); 429 if(brtn) { 430 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject"); 431 } 432 433 /* per-alg setup */ 434 switch(encrAlg) { 435 case CSSM_ALGID_RC4: 436 /* the easy one */ 437 brtn = B_SetAlgorithmInfo(alg, AI_RC4, NULL); 438 if(brtn) { 439 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo"); 440 goto abort; 441 } 442 fbCipher = 0; 443 break; 444 445 case CSSM_ALGID_RSA: 446 /* assume encrypt via publicm decrypt via private */ 447 if(forEncrypt) { 448 brtn = B_SetAlgorithmInfo(alg, AI_PKCS_RSAPublic, NULL); 449 } 450 else { 451 brtn = B_SetAlgorithmInfo(alg, AI_PKCS_RSAPrivate, NULL); 452 } 453 if(brtn) { 454 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo(RSA)"); 455 goto abort; 456 } 457 blockSize = (effectiveKeyBits + 7) / 8; 458 fbCipher = 0; 459 break; 460 461 /* common code using AI_FeebackCipher */ 462 case CSSM_ALGID_DES: 463 spec.encryptionMethodName = (POINTER)"des"; 464 blockSize = 8; 465 break; 466 case CSSM_ALGID_DESX: 467 spec.encryptionMethodName = (POINTER)"desx"; 468 blockSize = 8; 469 break; 470 case CSSM_ALGID_3DES_3KEY_EDE: 471 spec.encryptionMethodName = (POINTER)"des_ede"; 472 blockSize = 8; 473 break; 474 case CSSM_ALGID_RC5: 475 spec.encryptionMethodName = (POINTER)"rc5"; 476 spec.encryptionParams = (POINTER)&rc5Params; 477 rc5Params.version = 0x10; 478 rc5Params.rounds = rounds; 479 rc5Params.wordSizeInBits = 32; 480 blockSize = 8; 481 break; 482 case CSSM_ALGID_RC2: 483 spec.encryptionMethodName = (POINTER)"rc2"; 484 spec.encryptionParams = (POINTER)&rc2Params; 485 rc2Params.effectiveKeyBits = effectiveKeyBits; 486 blockSize = 8; 487 break; 488 /* add other non-AI_FeebackCipher algorithms here */ 489 default: 490 printf("buEncryptDecrypt: unknown algorithm\n"); 491 return CSSM_ERRCODE_INTERNAL_ERROR; 492 } 493 if(fbCipher) { 494 useIv = 1; // default, except for ECB 495 switch(mode) { 496 case CSSM_ALGMODE_CBCPadIV8: 497 spec.feedbackMethodName = (POINTER)"cbc"; 498 spec.paddingMethodName = (POINTER)"pad"; 499 break; 500 case CSSM_ALGMODE_CBC_IV8: 501 spec.feedbackMethodName = (POINTER)"cbc"; 502 spec.paddingMethodName = (POINTER)"nopad"; 503 break; 504 case CSSM_ALGMODE_OFB_IV8: 505 spec.feedbackMethodName = (POINTER)"cbc"; 506 spec.paddingMethodName = (POINTER)"nopad"; 507 break; 508 case CSSM_ALGMODE_ECB: 509 /* this does not seem to work yet - need info from 510 * RSA. Specify block size as the feedbackParams (per manual) 511 * and get a memmove error trying to copy from address 8; specify 512 * an IV and get BSAFE error 524 (BE_INPUT_DATA) error on the 513 * EncryptInit. 514 */ 515 spec.feedbackMethodName = (POINTER)"ecb"; 516 spec.paddingMethodName = (POINTER)"nopad"; 517 //useIv = 0; 518 //spec.feedbackParams = (POINTER)8; 519 break; 520 default: 521 printf("buEncryptDecrypt: unknown mode\n"); 522 return CSSM_ERRCODE_INTERNAL_ERROR; 523 } 524 if(useIv && (iv != NULL)) { 525 buCssmDataToItem(iv, &bsIv); 526 spec.feedbackParams = (POINTER)&bsIv; 527 } 528 529 brtn = B_SetAlgorithmInfo(alg, AI_FeedbackCipher, (POINTER)&spec); 530 if(brtn) { 531 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo"); 532 goto abort; 533 } 534 } 535 536 /* 537 * OK, one way or another we have an algorithm object. Set up 538 * output buffer. 539 */ 540 if(forEncrypt) { 541 outBufLen = inData->Length + blockSize; 542 } 543 else { 544 outBufLen = inData->Length; 545 } 546 outData->Length = 0; 547 outData->Data = NULL; 548 crtn = appSetupCssmData(outData, outBufLen); 549 if(crtn) { 550 goto abort; 551 } 552 if(forEncrypt) { 553 brtn = B_EncryptInit(alg, 554 (B_KEY_OBJ)key, 555 BSAFE_ALGORITHM_CHOOSER, 556 (A_SURRENDER_CTX *)NULL); 557 if(brtn) { 558 crtn = buBsafeErrToCssm(brtn, "B_EncryptInit"); 559 goto abort; 560 } 561 brtn = B_EncryptUpdate(alg, 562 outData->Data, 563 &bytesMoved, 564 outBufLen, 565 inData->Data, 566 inData->Length, 567 buGetRng(), // randAlg 568 NULL); // surrender 569 if(brtn) { 570 crtn = buBsafeErrToCssm(brtn, "B_EncryptInit"); 571 goto abort; 572 } 573 outData->Length = bytesMoved; 574 brtn = B_EncryptFinal(alg, 575 outData->Data + bytesMoved, 576 &bytesMoved, 577 outBufLen - outData->Length, 578 buGetRng(), // randAlg 579 NULL); // surrender 580 if(brtn) { 581 crtn = buBsafeErrToCssm(brtn, "B_EncryptFinal"); 582 goto abort; 583 } 584 outData->Length += bytesMoved; 585 crtn = CSSM_OK; 586 } 587 else { 588 brtn = B_DecryptInit(alg, 589 (B_KEY_OBJ)key, 590 BSAFE_ALGORITHM_CHOOSER, 591 (A_SURRENDER_CTX *)NULL); 592 if(brtn) { 593 crtn = buBsafeErrToCssm(brtn, "B_DecryptInit"); 594 goto abort; 595 } 596 brtn = B_DecryptUpdate(alg, 597 outData->Data, 598 &bytesMoved, 599 outBufLen, 600 inData->Data, 601 inData->Length, 602 NULL, // randAlg 603 NULL); // surrender 604 if(brtn) { 605 crtn = buBsafeErrToCssm(brtn, "B_DecryptUpdate"); 606 goto abort; 607 } 608 outData->Length = bytesMoved; 609 brtn = B_DecryptFinal(alg, 610 outData->Data + bytesMoved, 611 &bytesMoved, 612 outBufLen - outData->Length, 613 NULL, // randAlg 614 NULL); // surrender 615 if(brtn) { 616 crtn = buBsafeErrToCssm(brtn, "B_DecryptFinal"); 617 goto abort; 618 } 619 outData->Length += bytesMoved; 620 crtn = CSSM_OK; 621 } 622abort: 623 B_DestroyAlgorithmObject(&alg); 624#endif 625 return 0; //crtn; 626} 627 628#if 0 629/* CSSM sig alg --> B_INFO_TYPE */ 630static CSSM_RETURN cssmSigAlgToInfoType( 631 CSSM_ALGORITHMS cssmAlg, 632 B_INFO_TYPE *infoType) 633{ 634 switch(cssmAlg) { 635 case CSSM_ALGID_SHA1WithRSA: 636 *infoType = AI_SHA1WithRSAEncryption; 637 break; 638 case CSSM_ALGID_MD5WithRSA: 639 *infoType = AI_MD5WithRSAEncryption; 640 break; 641 case CSSM_ALGID_SHA1WithDSA: 642 *infoType = AI_DSAWithSHA1; 643 break; 644 default: 645 printf("cssmSigAlgToInfoType: unknown algorithm\n"); 646 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED; 647 } 648 return CSSM_OK; 649} 650#endif 651 652/* 653 * Sign/verify 654 */ 655CSSM_RETURN buSign( 656 BU_KEY key, 657 CSSM_ALGORITHMS sigAlg, 658 const CSSM_DATA *ptext, 659 uint32 keySizeInBits, // to set up sig 660 CSSM_DATA_PTR sig) // mallocd and RETURNED 661{ 662#if 0 // NO MORE BSAFE 663 B_ALGORITHM_OBJ alg = NULL; 664 int brtn; 665 B_INFO_TYPE infoType; 666 CSSM_RETURN crtn; 667 unsigned sigBytes; 668 669 brtn = B_CreateAlgorithmObject(&alg); 670 if(brtn) { 671 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject"); 672 } 673 crtn = cssmSigAlgToInfoType(sigAlg, &infoType); 674 if(crtn) { 675 return crtn; 676 } 677 brtn = B_SetAlgorithmInfo(alg, infoType, NULL); 678 if(brtn) { 679 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo"); 680 goto abort; 681 } 682 brtn = B_SignInit(alg, (B_KEY_OBJ)key, BSAFE_ALGORITHM_CHOOSER, NULL); 683 if(brtn) { 684 crtn = buBsafeErrToCssm(brtn, "B_SignInit"); 685 goto abort; 686 } 687 brtn = B_SignUpdate(alg, ptext->Data, ptext->Length, NULL); 688 if(brtn) { 689 crtn = buBsafeErrToCssm(brtn, "B_SignUpdate"); 690 goto abort; 691 } 692 693 /* prepare for sig, size of key */ 694 sigBytes = (keySizeInBits + 7) / 8; 695 sig->Data = (uint8 *)CSSM_MALLOC(sigBytes); 696 sig->Length = sigBytes; 697 698 brtn = B_SignFinal(alg, sig->Data, &sigBytes, sigBytes, buGetRng(), NULL); 699 if(brtn) { 700 crtn = buBsafeErrToCssm(brtn, "B_SignFinal"); 701 goto abort; 702 } 703 sig->Length = sigBytes; 704 crtn = CSSM_OK; 705abort: 706 B_DestroyAlgorithmObject(&alg); 707#endif 708 return 0;//; 709} 710 711CSSM_RETURN buVerify( 712 BU_KEY key, 713 CSSM_ALGORITHMS sigAlg, 714 const CSSM_DATA *ptext, 715 const CSSM_DATA *sig) // mallocd and RETURNED 716{ 717#if 0 // NO MORE BSAFE 718 B_ALGORITHM_OBJ alg = NULL; 719 int brtn; 720 B_INFO_TYPE infoType; 721 CSSM_RETURN crtn; 722 723 brtn = B_CreateAlgorithmObject(&alg); 724 if(brtn) { 725 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject"); 726 } 727 crtn = cssmSigAlgToInfoType(sigAlg, &infoType); 728 if(crtn) { 729 return crtn; 730 } 731 brtn = B_SetAlgorithmInfo(alg, infoType, NULL); 732 if(brtn) { 733 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo"); 734 goto abort; 735 } 736 brtn = B_VerifyInit(alg, (B_KEY_OBJ)key, BSAFE_ALGORITHM_CHOOSER, NULL); 737 if(brtn) { 738 crtn = buBsafeErrToCssm(brtn, "B_VerifyInit"); 739 goto abort; 740 } 741 brtn = B_VerifyUpdate(alg, ptext->Data, ptext->Length, NULL); 742 if(brtn) { 743 crtn = buBsafeErrToCssm(brtn, "B_VerifyUpdate"); 744 goto abort; 745 } 746 brtn = B_VerifyFinal(alg, sig->Data, sig->Length, buGetRng(), NULL); 747 if(brtn) { 748 crtn = buBsafeErrToCssm(brtn, "B_VerifyFinal"); 749 goto abort; 750 } 751 crtn = CSSM_OK; 752abort: 753 B_DestroyAlgorithmObject(&alg); 754 return crtn; 755#endif 756 return 0; 757} 758 759/* 760 * generate MAC either one update (updateSizes == NULL) or 761 * specified set of update sizes. 762 */ 763#define MAX_MAC_SIZE 20 764 765CSSM_RETURN buGenMac( 766 BU_KEY key, // any key, any size 767 CSSM_ALGORITHMS macAlg, // only CSSM_ALGID_SHA1HMAC for now 768 const CSSM_DATA *ptext, 769 unsigned *updateSizes, // NULL --> random updates 770 // else null-terminated list of sizes 771 CSSM_DATA_PTR mac) // mallocd and RETURNED 772{ 773#if 0 // NO MORE BSAFE 774 B_ALGORITHM_OBJ alg = NULL; 775 int brtn; 776 CSSM_RETURN crtn; 777 B_DIGEST_SPECIFIER digestInfo; 778 B_INFO_TYPE infoType; 779 unsigned macBytes; 780 781 brtn = B_CreateAlgorithmObject(&alg); 782 if(brtn) { 783 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject"); 784 } 785 switch(macAlg) { 786 case CSSM_ALGID_SHA1HMAC: 787 case CSSM_ALGID_SHA1HMAC_LEGACY: 788 digestInfo.digestInfoType = AI_SHA1; 789 infoType = AI_HMAC; 790 break; 791 default: 792 printf("buGenMac: alg not supported\n"); 793 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED; 794 } 795 digestInfo.digestInfoParams = NULL; 796 brtn = B_SetAlgorithmInfo(alg, infoType, (POINTER)&digestInfo); 797 if(brtn) { 798 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo"); 799 goto abort; 800 } 801 brtn = B_DigestInit(alg, (B_KEY_OBJ)key, BSAFE_ALGORITHM_CHOOSER, NULL); 802 if(brtn) { 803 crtn = buBsafeErrToCssm(brtn, "B_DigestInit"); 804 goto abort; 805 } 806 if(updateSizes) { 807 uint8 *currData = ptext->Data; 808 while(*updateSizes) { 809 brtn = B_DigestUpdate(alg, currData, *updateSizes, NULL); 810 if(brtn) { 811 crtn = buBsafeErrToCssm(brtn, "B_DigestUpdate"); 812 goto abort; 813 } 814 currData += *updateSizes; 815 updateSizes++; 816 } 817 } 818 else { 819 /* one-shot */ 820 brtn = B_DigestUpdate(alg, ptext->Data, ptext->Length, NULL); 821 if(brtn) { 822 crtn = buBsafeErrToCssm(brtn, "B_DigestUpdate"); 823 goto abort; 824 } 825 } 826 /* prepare for mac, magically gleaned max size */ 827 macBytes = MAX_MAC_SIZE; 828 mac->Data = (uint8 *)CSSM_MALLOC(macBytes); 829 mac->Length = macBytes; 830 831 brtn = B_DigestFinal(alg, mac->Data, &macBytes, macBytes, NULL); 832 if(brtn) { 833 crtn = buBsafeErrToCssm(brtn, "B_DigestFinal"); 834 goto abort; 835 } 836 mac->Length = macBytes; 837 crtn = CSSM_OK; 838abort: 839 B_DestroyAlgorithmObject(&alg); 840 return crtn; 841#endif 842 return 0; 843} 844 845/* generate digest */ 846#define MAX_DIGEST_SIZE 20 847 848CSSM_RETURN buGenDigest( 849 CSSM_ALGORITHMS macAlg, // CSSM_ALGID_SHA1, etc. */ 850 const CSSM_DATA *ptext, 851 CSSM_DATA_PTR digest) // mallocd and RETURNED 852{ 853#if 0 // NO MORE BSAFE 854 B_ALGORITHM_OBJ alg = NULL; 855 int brtn; 856 CSSM_RETURN crtn; 857 B_INFO_TYPE infoType; 858 unsigned hashBytes; 859 860 brtn = B_CreateAlgorithmObject(&alg); 861 if(brtn) { 862 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject"); 863 } 864 switch(macAlg) { 865 case CSSM_ALGID_SHA1: 866 infoType = AI_SHA1; 867 break; 868 case CSSM_ALGID_MD5: 869 infoType = AI_MD5; 870 break; 871 case CSSM_ALGID_MD2: 872 infoType = AI_MD2; 873 break; 874 default: 875 printf("buGenDigest: alg not supported\n"); 876 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED; 877 } 878 brtn = B_SetAlgorithmInfo(alg, infoType, NULL); 879 if(brtn) { 880 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo"); 881 goto abort; 882 } 883 brtn = B_DigestInit(alg, NULL, BSAFE_ALGORITHM_CHOOSER, NULL); 884 if(brtn) { 885 crtn = buBsafeErrToCssm(brtn, "B_DigestInit"); 886 goto abort; 887 } 888 brtn = B_DigestUpdate(alg, ptext->Data, ptext->Length, NULL); 889 if(brtn) { 890 crtn = buBsafeErrToCssm(brtn, "B_DigestUpdate"); 891 goto abort; 892 } 893 894 /* prepare for digest, magically gleaned max size */ 895 hashBytes = MAX_DIGEST_SIZE; 896 digest->Data = (uint8 *)CSSM_MALLOC(hashBytes); 897 digest->Length = hashBytes; 898 899 brtn = B_DigestFinal(alg, digest->Data, &hashBytes, hashBytes, NULL); 900 if(brtn) { 901 crtn = buBsafeErrToCssm(brtn, "B_DigestFinal"); 902 goto abort; 903 } 904 digest->Length = hashBytes; 905 crtn = CSSM_OK; 906abort: 907 B_DestroyAlgorithmObject(&alg); 908 return crtn; 909#else 910 return 0; 911#endif 912} 913 914/* 915 * Convert between BSAFE and CDSA private keys 916 */ 917CSSM_RETURN buBsafePrivKeyToCdsa( 918 CSSM_ALGORITHMS keyAlg, 919 uint32 keySizeInBits, 920 BU_KEY bsafePrivKey, 921 CSSM_KEY_PTR cdsaPrivKey) 922{ 923#if 0 // NO MORE BSAFE 924 B_INFO_TYPE infoType; 925 ITEM *keyBlob; 926 int brtn; 927 CSSM_KEYBLOB_FORMAT format; 928 CSSM_KEYHEADER_PTR hdr = &cdsaPrivKey->KeyHeader; 929 930 /* what kind of info? */ 931 switch(keyAlg) { 932 case CSSM_ALGID_RSA: 933 infoType = KI_PKCS_RSAPrivateBER; 934 format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; 935 break; 936 case CSSM_ALGID_DSA: 937 infoType = KI_DSAPrivateBER; 938 format = CSSM_KEYBLOB_RAW_FORMAT_FIPS186; 939 break; 940 default: 941 printf("***buBsafePrivKeyToCdsa: bogus keyAlg\n"); 942 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED; 943 } 944 945 /* get the blob */ 946 brtn = B_GetKeyInfo((POINTER *)&keyBlob, 947 (B_KEY_OBJ)bsafePrivKey, 948 infoType); 949 if(brtn) { 950 return buBsafeErrToCssm(brtn, "B_GetKeyInfo"); 951 } 952 953 /* copy blob to CDSA key */ 954 cdsaPrivKey->KeyData.Data = (uint8 *)CSSM_MALLOC(keyBlob->len); 955 cdsaPrivKey->KeyData.Length = keyBlob->len; 956 memmove(cdsaPrivKey->KeyData.Data, keyBlob->data, keyBlob->len); 957 958 /* set up CSSM key header */ 959 memset(hdr, 0, sizeof(CSSM_KEYHEADER)); 960 hdr->HeaderVersion = CSSM_KEYHEADER_VERSION; 961 hdr->BlobType = CSSM_KEYBLOB_RAW; 962 hdr->Format = format; 963 hdr->AlgorithmId = keyAlg; 964 hdr->KeyClass = CSSM_KEYCLASS_PRIVATE_KEY; 965 hdr->LogicalKeySizeInBits = keySizeInBits; 966 hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE; 967 hdr->KeyUsage = CSSM_KEYUSE_ANY; 968#endif 969 return CSSM_OK; 970} 971 972CSSM_RETURN buCdsaPrivKeyToBsafe( 973 CSSM_KEY_PTR cdsaPrivKey, 974 BU_KEY *bsafePrivKey) 975{ 976#if 0 // NO MORE BSAFE 977 int brtn; 978 B_KEY_OBJ privKey = NULL; 979 ITEM keyBlob; 980 B_INFO_TYPE infoType; 981 982 /* what kind of info? */ 983 switch(cdsaPrivKey->KeyHeader.AlgorithmId) { 984 case CSSM_ALGID_RSA: 985 infoType = KI_PKCS_RSAPrivateBER; 986 break; 987 case CSSM_ALGID_DSA: 988 infoType = KI_DSAPrivateBER; 989 break; 990 default: 991 printf("***buCdsaPrivKeyToCssm: bogus keyAlg\n"); 992 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED; 993 } 994 995 /* create caller's key, assign blob to it */ 996 brtn = B_CreateKeyObject(&privKey); 997 if(brtn) { 998 return buBsafeErrToCssm(brtn, "B_CreateKeyObject"); 999 } 1000 buCssmDataToItem(&cdsaPrivKey->KeyData, &keyBlob); 1001 brtn = B_SetKeyInfo(privKey, infoType, (POINTER)&keyBlob); 1002 if(brtn) { 1003 return buBsafeErrToCssm(brtn, "B_SetKeyInfo"); 1004 } 1005 *bsafePrivKey = privKey; 1006#endif 1007 return CSSM_OK; 1008} 1009 1010