1/* Copyright (c) 1998,2003-2005 Apple Computer, Inc. 2 * 3 * miniWrap.c - simple key wrap/unwrap exerciser. 4 * 5 * Revision History 6 * ---------------- 7 * 4 May 2000 Doug Mitchell 8 * Ported to X/CDSA2. 9 * 22 May 1998 Doug Mitchell at Apple 10 * Created. 11 */ 12 13#include <stdlib.h> 14#include <stdio.h> 15#include <time.h> 16#include <string.h> 17#include <Security/cssm.h> 18#include "cspwrap.h" 19#include "common.h" 20#include "cspdlTesting.h" 21 22/* 23 * Temporary hack to use CSSM_KEYBLOB_WRAPPED_FORMAT_{PKCS7,PKCS8}, which 24 * are no longer supported as of 7/28/00 25 */ 26#define PKCS8_FORMAT_ENABLE 1 27#define PKCS7_FORMAT_ENABLE 0 28 29#define ENCR_USAGE_NAME "noLabel" 30#define ENCR_USAGE_NAME_LEN (strlen(ENCR_USAGE_NAME)) 31#define WRAP_USAGE_NAME "noWrapLabel" 32#define WRAP_USAGE_NAME_LEN (strlen(WRAP_USAGE_NAME)) 33#define LOOPS_DEF 10 34#define MAX_PTEXT_SIZE 1000 35#define LOOP_PAUSE 10 36 37/* 38 * A new restriction for X: when wrapping using an RSA key, you can't 39 * wrap a key which is bigger than the RSA key itself because the 40 * wrap (Encrypt) is a one-shot deal, unlike the OS9 CSP which 41 * handled multiple chunks. This only effectively restricts the 42 * use of an RSA key to wrap symmetric keys, which doesn't seem like 43 * an unreasonable restriction. 44 */ 45#define RSA_WRAP_RESTRICTION 1 46 47/* 48 * Currently the CSP can use wrapping keys flagged exclusively for wrapping 49 * (CSSM_KEYUSE_{WRAP,UNWRAP} for the actual wrap since�the wrap/unwrap op is 50 * done with an encrypt/decrypt op. The WrapKey op doesn't even see the 51 * wrapping key - it's in the context we pass it. Thus for now wrap/unwrap 52 * keys have to be marked with CSSM_KEYUSE_ANY. 53 */ 54#define WRAP_USAGE_ANY 0 55 56static void usage(char **argv) 57{ 58 printf("usage: %s [options]\n", argv[0]); 59 printf(" Options:\n"); 60 printf(" f (only wrap RSA private key)\n"); 61 printf(" d (only wrap DES key)\n"); 62 printf(" S (do symmetric wrap only)\n"); 63 printf(" a (do asymmetric wrap only)\n"); 64 printf(" n (do null wrap only)\n"); 65 printf(" m (dump malloc info)\n"); 66 printf(" r (ref keys only)\n"); 67 printf(" w (wrap only)\n"); 68 printf(" e (export)\n"); 69 printf(" q (quiet)\n"); 70 printf(" k (force PKCS7/8)\n"); 71 #if PKCS7_FORMAT_ENABLE || PKCS8_FORMAT_ENABLE 72 printf(" K (skip PKCS7/8) (pkcs normally enable)\n"); 73 #else 74 printf(" K (allow PKCS7/8) (pkcs normally disabled)\n"); 75 #endif /* PKCS_FORMAT_ENABLE */ 76 printf(" D (CSP/DL; default = bare CSP)\n"); 77 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF); 78 printf(" p(ause every %d loops)\n", LOOP_PAUSE); 79 printf(" h(elp)\n"); 80 exit(1); 81} 82 83/* not all algs need this, pass it in anyway */ 84CSSM_DATA initVector = {8, (uint8 *)"someVect"}; 85 86/* 87 * local verbose wrap/unwrap functions. 88 */ 89/* wrap key function. */ 90static CSSM_RETURN wrapKey(CSSM_CSP_HANDLE cspHand, 91 const CSSM_KEY_PTR unwrappedKey, // must be ref 92 const CSSM_KEY_PTR wrappingKey, 93 CSSM_ALGORITHMS wrapAlg, 94 CSSM_ENCRYPT_MODE wrapMode, 95 CSSM_KEYBLOB_FORMAT wrapFormat, // NONE, PKCS7, PKCS8 96 CSSM_PADDING wrapPad, 97 CSSM_KEY_PTR wrappedKey) // RETURNED 98{ 99 CSSM_CC_HANDLE ccHand; 100 CSSM_RETURN crtn; 101 CSSM_RETURN crtn2; 102 #if WRAP_KEY_REQUIRES_CREDS 103 CSSM_ACCESS_CREDENTIALS creds; 104 #endif 105 106 #if 0 107 if(unwrappedKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) { 108 printf("Hey! you can only wrap a reference key!\n"); 109 return CSSM_ERRCODE_INTERNAL_ERROR; 110 } 111 #endif 112 memset(wrappedKey, 0, sizeof(CSSM_KEY)); 113 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); 114 /* special case for NULL wrap - no wrapping key */ 115 if((wrappingKey == NULL) || 116 (wrappingKey->KeyHeader.KeyClass == CSSM_KEYCLASS_SESSION_KEY)) { 117 crtn = CSSM_CSP_CreateSymmetricContext(cspHand, 118 wrapAlg, 119 wrapMode, 120 &creds, // accessCred 121 wrappingKey, 122 &initVector, 123 wrapPad, // Padding 124 NULL, // Reserved 125 &ccHand); 126 if(crtn) { 127 printError("cspWrapKey/CreateContext", crtn); 128 return CSSM_ERRCODE_INTERNAL_ERROR; 129 } 130 } 131 else { 132 crtn = CSSM_CSP_CreateAsymmetricContext(cspHand, 133 wrapAlg, 134 &creds, // passPhrase 135 wrappingKey, 136 wrapPad, // Padding 137 &ccHand); 138 if(crtn) { 139 printError("cspWrapKey/CreateContext", crtn); 140 return CSSM_ERRCODE_INTERNAL_ERROR; 141 } 142 /* CMS requires 8-byte IV */ 143 crtn = AddContextAttribute(ccHand, 144 CSSM_ATTRIBUTE_INIT_VECTOR, 145 sizeof(CSSM_DATA), 146 CAT_Ptr, 147 &initVector, 148 0); 149 if(crtn) { 150 printError("CSSM_UpdateContextAttributes", crtn); 151 return crtn; 152 } 153 } 154 if(wrapFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE) { 155 /* only add this attribute if it's not the default */ 156 CSSM_CONTEXT_ATTRIBUTE attr; 157 attr.AttributeType = CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT; 158 attr.AttributeLength = sizeof(uint32); 159 attr.Attribute.Uint32 = wrapFormat; 160 crtn = CSSM_UpdateContextAttributes( 161 ccHand, 162 1, 163 &attr); 164 if(crtn) { 165 printError("CSSM_UpdateContextAttributes", crtn); 166 return crtn; 167 } 168 } 169 crtn = CSSM_WrapKey(ccHand, 170 #if WRAP_KEY_REQUIRES_CREDS 171 &creds, 172 #else 173 NULL, // AccessCred 174 #endif 175 unwrappedKey, 176 NULL, // DescriptiveData 177 wrappedKey); 178 if(crtn != CSSM_OK) { 179 printError("CSSM_WrapKey", crtn); 180 } 181 if((crtn2 = CSSM_DeleteContext(ccHand))) { 182 printError("CSSM_DeleteContext", crtn2); 183 } 184 return crtn; 185} 186 187/* unwrap key function. */ 188static CSSM_RETURN unwrapKey(CSSM_CSP_HANDLE cspHand, 189 const CSSM_KEY_PTR wrappedKey, 190 const CSSM_KEY_PTR unwrappingKey, 191 CSSM_ALGORITHMS unwrapAlg, 192 CSSM_ENCRYPT_MODE unwrapMode, 193 CSSM_PADDING unwrapPad, 194 CSSM_KEY_PTR unwrappedKey, // RETURNED 195 const unsigned char *keyLabel, 196 unsigned keyLabelLen) 197{ 198 CSSM_CC_HANDLE ccHand; 199 CSSM_RETURN crtn; 200 CSSM_RETURN crtn2; 201 CSSM_DATA labelData; 202 uint32 keyAttr; 203 CSSM_DATA descData = { 0, NULL }; 204 CSSM_ACCESS_CREDENTIALS creds; 205 206 memset(unwrappedKey, 0, sizeof(CSSM_KEY)); 207 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); 208 if((unwrappingKey == NULL) || 209 (unwrappingKey->KeyHeader.KeyClass == CSSM_KEYCLASS_SESSION_KEY)) { 210 crtn = CSSM_CSP_CreateSymmetricContext(cspHand, 211 unwrapAlg, 212 unwrapMode, 213 &creds, // accessCreds 214 unwrappingKey, 215 &initVector, 216 unwrapPad, // Padding 217 0, // Reserved 218 &ccHand); 219 if(crtn) { 220 printError("cspUnwrapKey/CreateContext", crtn); 221 return CSSM_ERRCODE_INTERNAL_ERROR; 222 } 223 } 224 else { 225 crtn = CSSM_CSP_CreateAsymmetricContext(cspHand, 226 unwrapAlg, 227 &creds, // passPhrase, 228 unwrappingKey, 229 unwrapPad, // Padding 230 &ccHand); 231 if(crtn) { 232 printError("cspUnwrapKey/CreateContext", crtn); 233 return CSSM_ERRCODE_INTERNAL_ERROR; 234 } 235 /* CMS requires 8-byte IV */ 236 crtn = AddContextAttribute(ccHand, 237 CSSM_ATTRIBUTE_INIT_VECTOR, 238 sizeof(CSSM_DATA), 239 CAT_Ptr, 240 &initVector, 241 0); 242 if(crtn) { 243 printError("CSSM_UpdateContextAttributes", crtn); 244 return crtn; 245 } 246 } 247 labelData.Data = (uint8 *)keyLabel; 248 labelData.Length = keyLabelLen; 249 250 /* 251 * New keyAttr - clear some old bits, make sure we ask for ref key 252 */ 253 keyAttr = wrappedKey->KeyHeader.KeyAttr; 254 keyAttr &= ~(CSSM_KEYATTR_ALWAYS_SENSITIVE | CSSM_KEYATTR_NEVER_EXTRACTABLE); 255 keyAttr |= CSSM_KEYATTR_RETURN_REF; 256 crtn = CSSM_UnwrapKey(ccHand, 257 NULL, // PublicKey 258 wrappedKey, 259 CSSM_KEYUSE_ANY, // FIXME 260 keyAttr, 261 &labelData, 262 NULL, // CredAndAclEntry 263 unwrappedKey, 264 &descData); // required 265 if(crtn != CSSM_OK) { 266 printError("CSSM_UnwrapKey", crtn); 267 } 268 if((crtn2 = CSSM_DeleteContext(ccHand))) { 269 printError("CSSM_DeleteContext", crtn2); 270 } 271 return crtn; 272} 273 274#define UNWRAPPED_LABEL "unwrapped thing" 275#define NULL_TEST 0 276#if NULL_TEST 277 278static int doTest(CSSM_CSP_HANDLE cspHand, 279 CSSM_KEY_PTR encrKey, 280 CSSM_KEY_PTR decrKey, // we wrap this one 281 CSSM_KEY_PTR wrappingKey, // ...using this key, NULL for null wrap 282 CSSM_KEY_PTR unwrappingKey, 283 CSSM_ALGORITHMS wrapAlg, 284 CSSM_ENCRYPT_MODE wrapMode, 285 CSSM_PADDING wrapPad, 286 CSSM_ALGORITHMS encrAlg, 287 CSSM_ENCRYPT_MODE encrMode, 288 CSSM_PADDING encrPad, 289 CSSM_BOOL wrapOnly, 290 uint32 maxPtextSize, // max size to encrypt 291 CSSM_BOOL quiet) 292{ 293 return 0; 294} 295#else /* NULL_TEST */ 296/* 297 * NULL Wrapping decrKey - a private key - only works for DEBUG CSPs. 298 * We'll always wrap decrKey, except for NULL wrap when 299 * NULL_WRAP_DECR_KEY is false. 300 */ 301#define NULL_WRAP_DECR_KEY 1 302 303static int doTest(CSSM_CSP_HANDLE cspHand, 304 CSSM_KEY_PTR encrKey, // we wrap this one 305 CSSM_KEY_PTR decrKey, // ...or this one, depending on WRAP_DECR_KEY 306 CSSM_KEY_PTR wrappingKey, // ...using this key, NULL for null wrap 307 CSSM_KEY_PTR unwrappingKey, 308 CSSM_ALGORITHMS wrapAlg, 309 CSSM_ENCRYPT_MODE wrapMode, 310 CSSM_KEYBLOB_FORMAT wrapFormat, // NONE, PKCS7, PKCS8 311 CSSM_PADDING wrapPad, 312 CSSM_ALGORITHMS encrAlg, 313 CSSM_ENCRYPT_MODE encrMode, 314 CSSM_PADDING encrPad, 315 CSSM_BOOL wrapOnly, 316 uint32 maxPtextSize, // max size to encrypt 317 CSSM_BOOL quiet) 318{ 319 CSSM_DATA ptext; 320 CSSM_DATA ctext; 321 CSSM_DATA rptext; 322 CSSM_KEY wrappedKey; 323 CSSM_KEY unwrappedKey; 324 CSSM_RETURN crtn; 325 CSSM_KEY_PTR realEncrKey; // encrKey or &unwrappedKey 326 CSSM_KEY_PTR realDecrKey; // decrKey or &unwrappedKey 327 328 /* wrap decrKey or encrKey using wrappingKey ==> wrappedKey */ 329 if((wrappingKey == NULL) && !NULL_WRAP_DECR_KEY) { 330 /* NULL wrap of pub key */ 331 crtn = wrapKey(cspHand, 332 encrKey, 333 wrappingKey, 334 wrapAlg, 335 wrapMode, 336 wrapFormat, 337 wrapPad, 338 &wrappedKey); 339 realEncrKey = &unwrappedKey; 340 realDecrKey = decrKey; 341 } 342 else { 343 /* normal case, wrap priv key (may be NULL if NULL_WRAP_DECR_KEY) */ 344 crtn = wrapKey(cspHand, 345 decrKey, 346 wrappingKey, 347 wrapAlg, 348 wrapMode, 349 wrapFormat, 350 wrapPad, 351 &wrappedKey); 352 realEncrKey = encrKey; 353 realDecrKey = &unwrappedKey; 354 } 355 356 if(crtn) { 357 return testError(quiet); 358 } 359 if((wrappingKey != NULL) && // skip for NULL wrap 360 (wrapFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE)) { 361 /* don't want default, verify we got what we want */ 362 if(wrappedKey.KeyHeader.Format != wrapFormat) { 363 printf("wrapped key format mismatch: expect %u; got %u\n", 364 (unsigned)wrapFormat, (unsigned)wrappedKey.KeyHeader.Format); 365 if(testError(quiet)) { 366 return 1; 367 } 368 } 369 } 370 if(wrapOnly) { 371 cspFreeKey(cspHand, &wrappedKey); 372 goto done; 373 } 374 /* unwrap wrappedKey using unwrappingKey ==> unwrappedKey; */ 375 crtn = unwrapKey(cspHand, 376 &wrappedKey, 377 unwrappingKey, 378 wrapAlg, 379 wrapMode, 380 wrapPad, 381 &unwrappedKey, 382 (uint8 *)UNWRAPPED_LABEL, 383 15); 384 if(crtn) { 385 return testError(quiet); 386 } 387 388 /* cook up ptext */ 389 ptext.Data = (uint8 *)CSSM_MALLOC(maxPtextSize); 390 simpleGenData(&ptext, 1, maxPtextSize); 391 /* encrypt using realEncrKey ==> ctext */ 392 ctext.Data = NULL; 393 ctext.Length = 0; 394 crtn = cspEncrypt(cspHand, 395 encrAlg, 396 encrMode, 397 encrPad, 398 realEncrKey, 399 NULL, // no 2nd key 400 0, // effectiveKeySize 401 0, // rounds 402 &initVector, 403 &ptext, 404 &ctext, 405 CSSM_TRUE); // mallocCtext 406 if(crtn) { 407 return testError(quiet); 408 } 409 410 /* decrypt ctext with realDecrKey ==> rptext; */ 411 rptext.Data = NULL; 412 rptext.Length = 0; 413 crtn = cspDecrypt(cspHand, 414 encrAlg, 415 encrMode, 416 encrPad, 417 realDecrKey, 418 NULL, // no 2nd key 419 0, // effectiveKeySize 420 0, // rounds 421 &initVector, 422 &ctext, 423 &rptext, 424 CSSM_TRUE); 425 if(crtn) { 426 return testError(quiet); 427 } 428 429 /* compare ptext vs. rptext; */ 430 if(ptext.Length != rptext.Length) { 431 printf("ptext length mismatch\n"); 432 return testError(quiet); 433 } 434 if(memcmp(ptext.Data, rptext.Data, ptext.Length)) { 435 printf("***data miscompare\n"); 436 return testError(quiet); 437 } 438 /* free resources */ 439 cspFreeKey(cspHand, &wrappedKey); 440 cspFreeKey(cspHand, &unwrappedKey); 441 CSSM_FREE(ptext.Data); 442 CSSM_FREE(ctext.Data); 443 CSSM_FREE(rptext.Data); 444done: 445 return 0; 446} 447#endif /* NULL_TEST */ 448 449int main(int argc, char **argv) 450{ 451 int arg; 452 char *argp; 453 int i; 454 CSSM_CSP_HANDLE cspHand; 455 CSSM_RETURN crtn; 456 CSSM_KEY origPub; // we generate if !desSubj 457 CSSM_KEY origPriv; 458 CSSM_KEY_PTR origSess; // we generate if desSubj 459 CSSM_KEY_PTR origEncrKey; // pts to origPub or origSess 460 CSSM_KEY_PTR origDecrKey; // pts to origPriv or origSess 461 CSSM_ALGORITHMS encrAlg; 462 CSSM_ENCRYPT_MODE encrMode; 463 CSSM_PADDING encrPad; 464 int rtn = 0; 465 CSSM_BOOL genRsaKey; 466 uint32 maxPtextSize; 467 CSSM_BOOL encrIsRef = CSSM_TRUE; 468 CSSM_BOOL decrIsRef = CSSM_TRUE; 469 CSSM_KEYBLOB_FORMAT wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE; 470 unsigned loop; 471 472 /* user-specified vars */ 473 unsigned loops = LOOPS_DEF; 474 CSSM_BOOL pause = CSSM_FALSE; 475 CSSM_BOOL doSymmWrap = CSSM_TRUE; 476 CSSM_BOOL doAsymmWrap = CSSM_TRUE; 477 CSSM_BOOL doNullWrap = CSSM_TRUE; 478 CSSM_BOOL doSymmEncrOnly = CSSM_FALSE; 479 CSSM_BOOL doAsymmEncrOnly = CSSM_FALSE; 480 CSSM_BOOL wrapOnly = CSSM_FALSE; 481 CSSM_BOOL quiet = CSSM_FALSE; 482 CSSM_BOOL bareCsp = CSSM_TRUE; 483 CSSM_BOOL forcePkcs = CSSM_FALSE; 484 CSSM_BOOL refKeysOnly = CSSM_FALSE; 485 #if PKCS_FORMAT_ENABLE 486 CSSM_BOOL skipPkcs = CSSM_FALSE; 487 #else 488 CSSM_BOOL skipPkcs = CSSM_TRUE; 489 #endif 490 491 for(arg=1; arg<argc; arg++) { 492 argp = argv[arg]; 493 switch(argp[0]) { 494 case 'S': 495 doAsymmWrap = CSSM_FALSE; 496 doNullWrap = CSSM_FALSE; 497 break; 498 case 'a': 499 doSymmWrap = CSSM_FALSE; 500 doNullWrap = CSSM_FALSE; 501 break; 502 case 'n': 503 doSymmWrap = CSSM_FALSE; 504 doAsymmWrap = CSSM_FALSE; 505 break; 506 case 'f': 507 doAsymmEncrOnly = CSSM_TRUE; 508 break; 509 case 'd': // symmetric encrypt only option 510 case 'e': // export option - avoids asymetric encrypt/decrypt 511 doSymmEncrOnly = CSSM_TRUE; 512 break; 513 case 'l': 514 loops = atoi(&argp[2]); 515 break; 516 case 'w': 517 wrapOnly = CSSM_TRUE; 518 break; 519 case 'p': 520 pause = CSSM_TRUE; 521 break; 522 case 'D': 523 bareCsp = CSSM_FALSE; 524 #if CSPDL_ALL_KEYS_ARE_REF 525 refKeysOnly = CSSM_TRUE; 526 #endif 527 break; 528 case 'k': 529 forcePkcs = CSSM_TRUE; 530 break; 531 case 'K': 532 #if PKCS7_FORMAT_ENABLE || PKCS8_FORMAT_ENABLE 533 skipPkcs = CSSM_TRUE; 534 #else 535 skipPkcs = CSSM_FALSE; 536 #endif 537 break; 538 case 'r': 539 refKeysOnly = CSSM_TRUE; 540 break; 541 case 'q': 542 quiet = CSSM_TRUE; 543 break; 544 default: 545 usage(argv); 546 } 547 } 548 549 #if 0 550 #if !PKCS_FORMAT_ENABLE 551 if(skipPkcs) { 552 if(doAsymmEncrOnly) { 553 printf("Asymmetric keys can only be wrapped via PKCS; aborting\n"); 554 usage(argv); 555 } 556 else if(!doSymmWrap) { 557 printf("AsymmetricWrapping can only be done via PKCS; aborting\n"); 558 usage(argv); 559 } 560 doSymmEncrOnly = CSSM_TRUE; 561 doSymmWrap = CSSM_TRUE; 562 doAsymmWrap = CSSM_FALSE; 563 } 564 #endif /* !PKCS_FORMAT_ENABLE */ 565 #endif 566 567 cspHand = cspDlDbStartup(bareCsp, NULL); 568 if(cspHand == 0) { 569 exit(1); 570 } 571 572 printf("Starting miniWrap; args: "); 573 for(i=1; i<argc; i++) { 574 printf("%s ", argv[i]); 575 } 576 printf("\n"); 577 578 for(loop=1; ; loop++) { 579 if((loop % LOOP_PAUSE) == 0) { 580 if(!quiet) { 581 printf("...loop %d\n", loop); 582 } 583 if(pause) { 584 fpurge(stdin); 585 printf("Hit CR to proceed: "); 586 getchar(); 587 } 588 } 589 590 /* mix up ref and raw keys - with X, we can wrap a raw key */ 591 if(!refKeysOnly) { 592 encrIsRef = (loop & 2) ? CSSM_TRUE : CSSM_FALSE; 593 decrIsRef = (loop & 4) ? CSSM_TRUE : CSSM_FALSE; 594 } 595 596 /* first generate key to be wrapped */ 597 if(!doAsymmEncrOnly && (doSymmEncrOnly || ((loop & 1) == 0))) { 598 if(!quiet) { 599 printf("...wrapping DES key (%s)\n", 600 encrIsRef ? "ref" : "raw"); 601 } 602 origSess = cspGenSymKey(cspHand, 603 CSSM_ALGID_DES, 604 ENCR_USAGE_NAME, 605 ENCR_USAGE_NAME_LEN, 606 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT, 607 CSP_KEY_SIZE_DEFAULT, 608 encrIsRef); 609 if(origSess == NULL) { 610 rtn = 1; 611 goto testDone; 612 } 613 origDecrKey = origEncrKey = origSess; 614 encrAlg = CSSM_ALGID_DES; 615 encrMode = CSSM_ALGMODE_CBCPadIV8; 616 encrPad = CSSM_PADDING_PKCS5; 617 maxPtextSize = MAX_PTEXT_SIZE; // i.e., unlimited 618 } 619 else { 620 origSess = NULL; 621 } 622 if(!doSymmEncrOnly && (doAsymmEncrOnly || ((loop & 1) == 1))) { 623 if(!quiet) { 624 printf("...wrapping RSA key (pub %s priv %s)\n", 625 (encrIsRef ? "ref" : "raw"), 626 (decrIsRef ? "ref" : "raw")); 627 } 628 crtn = cspGenKeyPair(cspHand, 629 CSSM_ALGID_RSA, 630 ENCR_USAGE_NAME, 631 ENCR_USAGE_NAME_LEN, 632 CSP_KEY_SIZE_DEFAULT, 633 &origPub, 634 encrIsRef, // pubIsRef 635 CSSM_KEYUSE_ENCRYPT, 636 CSSM_KEYBLOB_RAW_FORMAT_NONE, 637 &origPriv, 638 decrIsRef, // privIsRef 639 CSSM_KEYUSE_DECRYPT, 640 CSSM_KEYBLOB_RAW_FORMAT_NONE, 641 CSSM_FALSE); // genSeed 642 if(crtn) { 643 rtn = 1; 644 goto testDone; 645 } 646 origDecrKey = &origPriv; 647 origEncrKey = &origPub; 648 encrAlg = CSSM_ALGID_RSA; 649 encrMode = CSSM_ALGMODE_NONE; 650 encrPad = CSSM_PADDING_PKCS1; 651 genRsaKey = CSSM_TRUE; 652 maxPtextSize = origPriv.KeyHeader.LogicalKeySizeInBits / 8; 653 // a weird BSAFE requirement which is not documented 654 maxPtextSize -= 11; 655 } 656 else { 657 genRsaKey = CSSM_FALSE; 658 } 659 660 /* now the tests, symmetric and/or asymmetric wrapping */ 661 if(doSymmWrap) { 662 CSSM_KEY_PTR wrapKey; 663 if(!quiet) { 664 printf(" ...Doing symmetric wrap\n"); 665 } 666 wrapKey = cspGenSymKey(cspHand, 667 CSSM_ALGID_DES, 668 WRAP_USAGE_NAME, 669 WRAP_USAGE_NAME_LEN, 670 /* for now, wrapping keys have to have keyuse_any */ 671 /* CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP, */ 672 WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : 673 CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP, 674 CSP_KEY_SIZE_DEFAULT, 675 CSSM_TRUE); // FIXME - try both 676 if(wrapKey == NULL) { 677 rtn = 1; 678 goto testDone; 679 } 680 if(forcePkcs) { 681 /* symmetric wrapping key ==> PKCS7 */ 682 wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7; 683 } 684 else { 685 /* default */ 686 wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE; 687 } 688 if(doTest(cspHand, 689 origEncrKey, 690 origDecrKey, 691 wrapKey, 692 wrapKey, 693 CSSM_ALGID_DES, // wrapAlg 694 CSSM_ALGMODE_CBCPadIV8, // wrapMode 695 wrapFormat, 696 CSSM_PADDING_PKCS5, // wrapPad 697 encrAlg, 698 encrMode, 699 encrPad, 700 wrapOnly, 701 maxPtextSize, 702 quiet)) { 703 rtn = 1; 704 goto testDone; 705 } 706 cspFreeKey(cspHand, wrapKey); 707 CSSM_FREE(wrapKey); // mallocd by cspGenSymKey 708 wrapKey = NULL; 709 } 710 if(doAsymmWrap && 711 !(RSA_WRAP_RESTRICTION && (origEncrKey != origDecrKey))) { 712 /* skip wrapping asymmetric key with asymmetric key */ 713 CSSM_KEY wrapPrivKey; 714 CSSM_KEY wrapPubKey; 715 716 if(!quiet) { 717 printf(" ...Doing asymmetric wrap\n"); 718 } 719 crtn = cspGenKeyPair(cspHand, 720 CSSM_ALGID_RSA, 721 WRAP_USAGE_NAME, 722 WRAP_USAGE_NAME_LEN, 723 CSP_RSA_KEY_SIZE_DEFAULT, 724 &wrapPubKey, 725 CSSM_TRUE, // both are ref 726 WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : CSSM_KEYUSE_WRAP, 727 CSSM_KEYBLOB_RAW_FORMAT_NONE, 728 &wrapPrivKey, 729 CSSM_TRUE, // FIXME privIsRef 730 WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : CSSM_KEYUSE_UNWRAP, 731 CSSM_KEYBLOB_RAW_FORMAT_NONE, 732 CSSM_FALSE); // genSeed 733 if(crtn) { 734 rtn = 1; 735 goto testDone; 736 } 737 if(forcePkcs) { 738 /* asymmetric wrapping key ==> PKCS8 */ 739 wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8; 740 } 741 else { 742 wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE; 743 } 744 if(doTest(cspHand, 745 origEncrKey, 746 origDecrKey, 747 &wrapPubKey, 748 &wrapPrivKey, 749 CSSM_ALGID_RSA, // wrapAlg 750 CSSM_ALGMODE_NONE, // wrapMode 751 wrapFormat, 752 CSSM_PADDING_PKCS1, // wrapPad 753 encrAlg, 754 encrMode, 755 encrPad, 756 wrapOnly, 757 maxPtextSize, 758 quiet)) { 759 rtn = 1; 760 goto testDone; 761 } 762 cspFreeKey(cspHand, &wrapPubKey); 763 cspFreeKey(cspHand, &wrapPrivKey); 764 } 765 //if(doNullWrap && (origDecrKey != origEncrKey)) { 766 if(doNullWrap) { 767 /* with X, we can do NULL wrap/unwrap of any key */ 768 if(!quiet) { 769 printf(" ...Doing NULL wrap\n"); 770 } 771 if(doTest(cspHand, 772 origEncrKey, 773 origDecrKey, 774 NULL, 775 NULL, 776 CSSM_ALGID_NONE, // wrapAlg 777 CSSM_ALGMODE_NONE, // wrapMode 778 CSSM_KEYBLOB_WRAPPED_FORMAT_NONE, 779 CSSM_PADDING_NONE, // wrapPad 780 encrAlg, 781 encrMode, 782 encrPad, 783 wrapOnly, 784 maxPtextSize, 785 quiet)) { 786 rtn = 1; 787 goto testDone; 788 } 789 } 790 791 if(origSess != NULL) { 792 cspFreeKey(cspHand, origSess); 793 CSSM_FREE(origSess); 794 } 795 if(genRsaKey) { 796 cspFreeKey(cspHand, &origPub); 797 cspFreeKey(cspHand, &origPriv); 798 } 799 if(loops && (loop == loops)) { 800 break; 801 } 802 } 803testDone: 804 CSSM_ModuleDetach(cspHand); 805 if((rtn == 0) && !quiet) { 806 printf("%s test complete\n", argv[0]); 807 } 808 return rtn; 809} 810