1/* Copyright (c) 1998,2003-2005,2008 Apple Inc. 2 * 3 * symDelta.c - Ensure that varying each parameter in a symmetric 4 * encryption op does in fact change the ciphertext. 5 * 6 * Revision History 7 * ---------------- 8 * July 18 2000 Doug Mitchell at Apple 9 * Created. 10 */ 11#include <string.h> 12#include <stdlib.h> 13#include <stdio.h> 14#include <time.h> 15#include <Security/cssm.h> 16#include <Security/cssmapple.h> 17#include "cspwrap.h" 18#include "common.h" 19#include "cspdlTesting.h" 20 21/* we need to know a little bit about AES for this test.... */ 22#define AES_BLOCK_SIZE 16 /* bytes */ 23 24/* 25 * Defaults. 26 */ 27#define LOOPS_DEF 10 28#define MIN_PTEXT_SIZE AES_BLOCK_SIZE /* for non-padding tests */ 29#define MAX_PTEXT_SIZE 1000 30#define MAX_IV_SIZE AES_BLOCK_SIZE 31 32/* 33 * Enumerate algs our own way to allow iteration. 34 */ 35typedef unsigned privAlg; 36enum { 37 pka_ASC, 38 pka_RC4, 39 pka_DES, 40 pka_RC2, 41 pka_RC5, 42 pka_3DES, 43 pka_AES 44}; 45 46/* 47 * Ditto for modes. ALGMODE_NONE not iterated, it's a special case for 48 * RC4 and ASC. 49 */ 50typedef unsigned privMode; 51enum { 52 pma_CBC_PadIV8, 53 pma_CBC_IV8, // no pad - requires well-aligned ptext 54 pma_ECB, // no IV, no pad - requires well-aligned ptext 55}; 56 57#define ENCR_ALG_FIRST pka_ASC 58#define ENCR_ALG_LAST pka_AES 59 60#define ENCR_MODE_FIRST pma_CBC_PadIV8 61#define ENCR_MODE_LAST pma_ECB 62 63/* 64 * Args passed to each test and to testCommon; these completely define 65 * the paramters for one encryption op. 66 */ 67typedef struct { 68 CSSM_CSP_HANDLE cspHand; 69 CSSM_ALGORITHMS keyAlg; 70 CSSM_ALGORITHMS encrAlg; 71 uint32 keySizeInBits; 72 uint32 effectiveKeySizeInBits; // 0 means not used 73 uint32 rounds; // ditto 74 const char *keyAlgStr; 75 CSSM_ENCRYPT_MODE encrMode; 76 const char *encrModeStr; 77 CSSM_PADDING encrPad; 78 CSSM_DATA_PTR ptext; 79 CSSM_BOOL useInitVector; // encrypt needs an IV 80 CSSM_BOOL useRefKey; 81 CSSM_DATA initVector; // Data mallocd and init in main() 82 CSSM_KEY_PTR key; // gen'd in main 83 CSSM_BOOL verbose; 84 CSSM_BOOL quiet; 85} testArgs; 86 87static void usage(char **argv) 88{ 89 printf("usage: %s [options]\n", argv[0]); 90 printf(" Options:\n"); 91 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF); 92 printf(" e(xport)\n"); 93 printf(" r(epeatOnly)\n"); 94 printf(" p(ause after each loop)\n"); 95 printf(" D (CSP/DL; default = bare CSP)\n"); 96 printf(" q(uiet)\n"); 97 printf(" h(elp)\n"); 98 exit(1); 99} 100 101/* 102 * Given a privAlg value, return various associated stuff. 103 */ 104static void algInfo(privAlg alg, // pka_DES, etc. 105 CSSM_ALGORITHMS *keyAlg, // CSSM_ALGID_DES, etc. RETURNED 106 // key alg for key gen algs 107 CSSM_ALGORITHMS *encrAlg, // encrypt/decrypt alg for key 108 // gen algs 109 const char **algStr, // RETURNED 110 CSSM_SIZE *ivSize) // RETURNED 111{ 112 *ivSize = 8; 113 switch(alg) { 114 case pka_DES: 115 *keyAlg = *encrAlg = CSSM_ALGID_DES; 116 *algStr = "DES"; 117 return; 118 case pka_3DES: 119 *keyAlg = CSSM_ALGID_3DES_3KEY; 120 *encrAlg = CSSM_ALGID_3DES_3KEY_EDE; 121 *algStr = "3DES"; 122 return; 123 case pka_RC2: 124 *keyAlg = *encrAlg = CSSM_ALGID_RC2; 125 *algStr = "RC2"; 126 return; 127 case pka_RC4: 128 *keyAlg = *encrAlg = CSSM_ALGID_RC4; 129 /* initVector false */ 130 *ivSize = 0; 131 *algStr = "RC4"; 132 return; 133 case pka_RC5: 134 *keyAlg = *encrAlg = CSSM_ALGID_RC5; 135 *algStr = "RC5"; 136 return; 137 case pka_AES: 138 *keyAlg = *encrAlg = CSSM_ALGID_AES; 139 *algStr = "AES"; 140 *ivSize = AES_BLOCK_SIZE; 141 return; 142 case pka_ASC: 143 *keyAlg = *encrAlg = CSSM_ALGID_ASC; 144 /* initVector false */ 145 *ivSize = 0; 146 *algStr = "ASC"; 147 return; 148 default: 149 printf("BRRZZZT! Update algInfo()!\n"); 150 testError(CSSM_TRUE); 151 } 152} 153 154/* given a privMode, return related info */ 155static void modeInfo( 156 CSSM_ALGORITHMS alg, 157 privMode mode, 158 CSSM_ENCRYPT_MODE *cdsaMode, 159 const char **modeStr, 160 CSSM_PADDING *pad, // PKCS5 or NONE 161 CSSM_BOOL *useInitVector) // RETURNED, for encrypt/decrypt 162{ 163 *useInitVector = CSSM_FALSE; 164 165 /* first deal with modeless algorithms */ 166 switch(alg) { 167 case CSSM_ALGID_RC4: 168 case CSSM_ALGID_ASC: 169 *cdsaMode = CSSM_ALGMODE_NONE; 170 *modeStr = "NONE"; 171 *pad = CSSM_PADDING_NONE; 172 return; 173 default: 174 break; 175 } 176 177 switch(mode) { 178 case pma_CBC_PadIV8: 179 *cdsaMode = CSSM_ALGMODE_CBCPadIV8; 180 *modeStr = "CBCPadIV8"; 181 *useInitVector = CSSM_TRUE; 182 *pad = CSSM_PADDING_PKCS5; 183 return; 184 case pma_CBC_IV8: 185 *cdsaMode = CSSM_ALGMODE_CBC_IV8; 186 *modeStr = "CBC_IV8"; 187 *useInitVector = CSSM_TRUE; 188 *pad = CSSM_PADDING_NONE; 189 return; 190 case pma_ECB: 191 *cdsaMode = CSSM_ALGMODE_ECB; 192 *modeStr = "ECB"; 193 *pad = CSSM_PADDING_NONE; 194 return; 195 default: 196 printf("BRRZZZT! Update modeInfo()!\n"); 197 testError(CSSM_TRUE); 198 } 199} 200 201/* 202 * Given alg and mode, determine alignment of ptext size. 0 means no 203 * alignment necessary. 204 */ 205uint32 alignInfo( 206 CSSM_ALGORITHMS alg, 207 CSSM_ENCRYPT_MODE mode) 208{ 209 switch(alg) { 210 case CSSM_ALGID_RC4: 211 case CSSM_ALGID_ASC: 212 return 0; 213 default: 214 break; 215 } 216 217 switch(mode) { 218 case CSSM_ALGMODE_CBC_IV8: 219 case CSSM_ALGMODE_ECB: 220 if(alg == CSSM_ALGID_AES) { 221 return AES_BLOCK_SIZE; 222 } 223 else { 224 return 8; 225 } 226 default: 227 return 0; 228 } 229} 230 231/* a handy "compare two CSSM_DATAs" ditty */ 232static CSSM_BOOL compareData(const CSSM_DATA_PTR d1, 233 const CSSM_DATA_PTR d2) 234{ 235 if(d1->Length != d2->Length) { 236 return CSSM_FALSE; 237 } 238 if(memcmp(d1->Data, d2->Data, d1->Length)) { 239 return CSSM_FALSE; 240 } 241 return CSSM_TRUE; 242} 243 244/* generate random one-bit byte */ 245static uint8 randBit() 246{ 247 return 1 << genRand(0, 7); 248} 249 250/* 251 * Copy a key. 252 */ 253static void copyCssmKey( 254 const CSSM_KEY_PTR key1, 255 CSSM_KEY_PTR key2) 256{ 257 key2->KeyHeader = key1->KeyHeader; 258 key2->KeyData.Data = NULL; 259 key2->KeyData.Length = 0; 260 appCopyCssmData(&key1->KeyData, &key2->KeyData); 261} 262 263/* 264 * Encrypt ptext using specified parameters 265 */ 266static int encryptCom(CSSM_CSP_HANDLE cspHand, 267 const char *testName, 268 CSSM_DATA_PTR ptext, 269 CSSM_KEY_PTR key, 270 CSSM_ALGORITHMS alg, 271 CSSM_ENCRYPT_MODE mode, 272 CSSM_PADDING padding, // CSSM_PADDING_PKCS1, etc. 273 CSSM_DATA_PTR iv, // may be NULL 274 uint32 effectiveKeySizeInBits, // may be 0 275 uint32 rounds, // ditto 276 CSSM_DATA_PTR ctext, // RETURNED 277 CSSM_BOOL quiet) 278{ 279 CSSM_CC_HANDLE cryptHand; 280 CSSM_RETURN crtn; 281 CSSM_SIZE bytesEncrypted; 282 CSSM_DATA remData; 283 int rtn; 284 285 cryptHand = genCryptHandle(cspHand, 286 alg, 287 mode, 288 padding, 289 key, 290 NULL, // no 2nd key 291 iv, // InitVector 292 effectiveKeySizeInBits, 293 rounds); 294 if(cryptHand == 0) { 295 return testError(quiet); 296 } 297 298 remData.Data = NULL; 299 remData.Length = 0; 300 crtn = CSSM_EncryptData(cryptHand, 301 ptext, 302 1, 303 ctext, 304 1, 305 &bytesEncrypted, 306 &remData); 307 308 if(crtn) { 309 printError("CSSM_EncryptData", crtn); 310 rtn = testError(quiet); 311 goto done; 312 } 313 if(remData.Length != 0) { 314 ctext->Data = (uint8 *)appRealloc(ctext->Data, bytesEncrypted, NULL); 315 memmove(ctext->Data + ctext->Length, 316 remData.Data, 317 bytesEncrypted - ctext->Length); 318 appFreeCssmData(&remData, CSSM_FALSE); 319 } 320 ctext->Length = bytesEncrypted; 321 rtn = 0; 322done: 323 if(CSSM_DeleteContext(cryptHand)) { 324 printError("CSSM_DeleteContext", 0); 325 rtn = 1; 326 } 327 return rtn; 328} 329 330/* 331 * Common test portion 332 * encrypt ptext with args in targ1; 333 * encrypt ptext with args in targ2; 334 * compare 2 ctexts; expect failure; 335 */ 336static int testCommon(const char *testName, 337 testArgs *targs1, 338 testArgs *targs2) 339{ 340 CSSM_DATA ctext1 = {0, NULL}; 341 CSSM_DATA ctext2 = {0, NULL}; 342 343 if(encryptCom(targs1->cspHand, 344 testName, 345 targs1->ptext, 346 targs1->key, 347 targs1->encrAlg, 348 targs1->encrMode, 349 targs1->encrPad, 350 &targs1->initVector, 351 targs1->effectiveKeySizeInBits, 352 targs1->rounds, 353 &ctext1, 354 targs1->quiet)) { 355 return 1; 356 } 357 if(encryptCom(targs2->cspHand, 358 testName, 359 targs2->ptext, 360 targs2->key, 361 targs2->encrAlg, 362 targs2->encrMode, 363 targs2->encrPad, 364 &targs2->initVector, 365 targs2->effectiveKeySizeInBits, 366 targs2->rounds, 367 &ctext2, 368 targs2->quiet)) { 369 return 1; 370 } 371 if(compareData(&ctext1, &ctext2)) { 372 printf("***%s: Unexpected Data compare!\n", testName); 373 return testError(targs1->quiet); 374 } 375 appFreeCssmData(&ctext1, CSSM_FALSE); 376 appFreeCssmData(&ctext2, CSSM_FALSE); 377 return 0; 378} 379 380/** 381 ** inidividual tests. 382 **/ 383#define KEY_LABEL1 "noLabel1" 384#define KEY_LABEL2 "noLabel2" 385#define KEY_LABEL_LEN strlen(KEY_LABEL1) 386#define REPEAT_ON_ERROR 1 387 388/* 389 * Ensure initVector alters ctext. 390 */ 391static int initVectTest(testArgs *targs) 392{ 393 uint32 mungeDex; 394 uint32 mungeBits; 395 testArgs mungeArgs = *targs; 396 CSSM_DATA mungeIV; 397 398 if(targs->verbose) { 399 printf(" ...modifying init vector\n"); 400 } 401 402 /* get munged copy of iv */ 403 mungeIV.Length = targs->initVector.Length; 404 mungeIV.Data = (uint8 *)CSSM_MALLOC(mungeIV.Length); 405 memmove(mungeIV.Data, targs->initVector.Data, mungeIV.Length); 406 mungeArgs.initVector = mungeIV; 407 mungeDex = genRand(0, mungeIV.Length - 1); 408 mungeBits = randBit(); 409 mungeIV.Data[mungeDex] ^= mungeBits; 410 if(testCommon("initVectTest", targs, &mungeArgs)) { 411 return 1; 412 } 413 appFreeCssmData(&mungeIV, CSSM_FALSE); 414 return 0; 415} 416 417/* 418 * Ensure effectiveKeySizeInBits alters ctext. RC2 only. 419 */ 420static int effectSizeTest(testArgs *targs) 421{ 422 testArgs mungeArgs = *targs; 423 424 if(targs->verbose) { 425 printf(" ...modifying effective key size\n"); 426 } 427 mungeArgs.effectiveKeySizeInBits -= 8; 428 return testCommon("effectSizeTest", targs, &mungeArgs); 429} 430 431/* 432 * Ensure rounds alters ctext. RC5 only. 433 */ 434static int roundsTest(testArgs *targs) 435{ 436 testArgs mungeArgs = *targs; 437 438 if(targs->verbose) { 439 printf(" ...modifying rounds\n"); 440 } 441 switch(targs->rounds) { 442 case 8: 443 mungeArgs.rounds = 12; 444 break; 445 case 12: 446 mungeArgs.rounds = 16; 447 break; 448 case 16: 449 mungeArgs.rounds = 8; 450 break; 451 default: 452 printf("***ACK! roundsTest needs work!\n"); 453 return 1; 454 } 455 return testCommon("roundsTest", targs, &mungeArgs); 456} 457 458 459/* 460 * ensure encryption algorithm alters ctext. 461 */ 462static int encrAlgTest(testArgs *targs) 463{ 464 testArgs mungeArgs = *targs; 465 CSSM_KEY mungeKey = *targs->key; 466 467 /* come up with different encrypt alg - not all work */ 468 switch(targs->encrAlg) { 469 case CSSM_ALGID_DES: // fixed size key 470 case CSSM_ALGID_3DES_3KEY_EDE: 471 default: 472 return 0; 473 case CSSM_ALGID_RC4: // no IV 474 mungeArgs.encrAlg = CSSM_ALGID_ASC; 475 break; 476 case CSSM_ALGID_ASC: // no IV 477 mungeArgs.encrAlg = CSSM_ALGID_RC4; 478 break; 479 case CSSM_ALGID_RC2: 480 mungeArgs.encrAlg = CSSM_ALGID_RC5; 481 break; 482 case CSSM_ALGID_RC5: 483 mungeArgs.encrAlg = CSSM_ALGID_RC2; 484 break; 485 case CSSM_ALGID_AES: 486 mungeArgs.encrAlg = CSSM_ALGID_RC5; 487 mungeArgs.initVector.Length = 8; 488 break; 489 } 490 491 /* we're assuming this is legal - a shallow copy of a key, followed by a blind 492 * reassignment of its algorithm... */ 493 mungeKey.KeyHeader.AlgorithmId = mungeArgs.encrAlg; 494 mungeArgs.key = &mungeKey; 495 496 if(targs->verbose) { 497 printf(" ...modifying encryption alg\n"); 498 } 499 500 return testCommon("encrAlgTest", targs, &mungeArgs); 501} 502 503/* 504 * ensure encryption mode alters ctext. 505 */ 506static int encrModeTest(testArgs *targs) 507{ 508 testArgs mungeArgs = *targs; 509 510 /* come up with different encrypt mode - not all work */ 511 switch(targs->encrMode) { 512 case CSSM_ALGMODE_NONE: // i.e., RC4, ASC 513 case CSSM_ALGMODE_CBCPadIV8: // others, only one which does 514 // padding 515 return 0; 516 case CSSM_ALGMODE_CBC_IV8: 517 mungeArgs.encrMode = CSSM_ALGMODE_ECB; 518 mungeArgs.useInitVector = CSSM_FALSE; 519 break; 520 case CSSM_ALGMODE_ECB: 521 mungeArgs.encrMode = CSSM_ALGMODE_CBC_IV8; 522 mungeArgs.useInitVector = CSSM_TRUE; 523 break; 524 default: 525 printf("Update encrModeTest\n"); 526 return 1; 527 } 528 if(targs->verbose) { 529 printf(" ...modifying encryption mode\n"); 530 } 531 532 return testCommon("encrModeTest", targs, &mungeArgs); 533} 534 535/* 536 * Ensure ptext alters ctext. 537 */ 538static int ptextTest(testArgs *targs) 539{ 540 uint32 mungeDex; 541 uint32 mungeBits; 542 testArgs mungeArgs = *targs; 543 CSSM_DATA mungePtext; 544 545 if(targs->verbose) { 546 printf(" ...modifying plaintext\n"); 547 } 548 549 /* get munged copy of ptext */ 550 mungePtext.Length = targs->ptext->Length; 551 mungePtext.Data = (uint8 *)CSSM_MALLOC(mungePtext.Length); 552 memmove(mungePtext.Data, targs->ptext->Data, mungePtext.Length); 553 mungeArgs.ptext = &mungePtext; 554 mungeDex = genRand(0, mungePtext.Length - 1); 555 mungeBits = randBit(); 556 mungePtext.Data[mungeDex] ^= mungeBits; 557 if(testCommon("ptextTest", targs, &mungeArgs)) { 558 return 1; 559 } 560 appFreeCssmData(&mungePtext, CSSM_FALSE); 561 return 0; 562} 563 564/* 565 * Ensure key alters ctext. Requires raw key, of course. 566 */ 567static int keyTest(testArgs *targs) 568{ 569 uint32 mungeDex; 570 uint32 mungeBits; 571 testArgs mungeArgs = *targs; 572 CSSM_KEY mungeKey; 573 unsigned minBit; 574 unsigned maxByte; 575 576 if(targs->verbose) { 577 printf(" ...modifying key\n"); 578 } 579 580 /* get munged copy of key */ 581 copyCssmKey(targs->key, &mungeKey); 582 mungeArgs.key = &mungeKey; 583 584 maxByte = mungeKey.KeyData.Length - 1; 585 if(targs->effectiveKeySizeInBits) { 586 /* skip MS byte - partially used */ 587 maxByte--; 588 } 589 mungeDex = genRand(0, maxByte); 590 591 minBit = 0; 592 switch(targs->keyAlg) { 593 case CSSM_ALGID_DES: 594 case CSSM_ALGID_DESX: 595 case CSSM_ALGID_3DES_3KEY: 596 /* skip lsb - DES parity bit */ 597 minBit++; 598 break; 599 default: 600 break; 601 } 602 mungeBits = 1 << genRand(minBit, 7); 603 mungeKey.KeyData.Data[mungeDex] ^= mungeBits; 604 if(testCommon("keyTest", targs, &mungeArgs)) { 605 return 1; 606 } 607 appFreeCssmData(&mungeKey.KeyData, CSSM_FALSE); 608 return 0; 609} 610 611int main(int argc, char **argv) 612{ 613 int arg; 614 char *argp; 615 unsigned loop; 616 CSSM_DATA ptext; 617 CSSM_DATA initVector; 618 testArgs targs; 619 privAlg encrAlg; 620 int rtn = 0; 621 privMode pmode; 622 uint32 origLen; 623 uint32 alignRequired; 624 CSSM_BOOL refKeys = CSSM_FALSE; 625 int i; 626 627 /* 628 * User-spec'd params 629 */ 630 unsigned loops = LOOPS_DEF; 631 CSSM_BOOL quiet = CSSM_FALSE; 632 CSSM_BOOL doPause = CSSM_FALSE; 633 CSSM_BOOL verbose = CSSM_FALSE; 634 CSSM_BOOL repeatOnly = CSSM_FALSE; 635 CSSM_BOOL bareCsp = CSSM_TRUE; 636 637 for(arg=1; arg<argc; arg++) { 638 argp = argv[arg]; 639 switch(argp[0]) { 640 case 'l': 641 loops = atoi(&argp[2]); 642 break; 643 case 'q': 644 quiet = CSSM_TRUE; 645 break; 646 case 'v': 647 verbose = CSSM_TRUE; 648 break; 649 case 'D': 650 bareCsp = CSSM_FALSE; 651 #if CSPDL_ALL_KEYS_ARE_REF 652 refKeys = CSSM_TRUE; 653 #endif 654 break; 655 case 'p': 656 doPause = CSSM_TRUE; 657 break; 658 case 'r': 659 repeatOnly = CSSM_TRUE; 660 break; 661 case 'h': 662 default: 663 usage(argv); 664 } 665 } 666 667 /* statically allocate ptext and initVector; data and length 668 * change in test loop */ 669 ptext.Data = (uint8 *)CSSM_MALLOC(MAX_PTEXT_SIZE); 670 initVector.Data = (uint8 *)CSSM_MALLOC(MAX_IV_SIZE); 671 targs.ptext = &ptext; 672 targs.initVector = initVector; 673 targs.verbose = verbose; 674 targs.quiet = quiet; 675 676 printf("Starting symDelta; args: "); 677 for(i=1; i<argc; i++) { 678 printf("%s ", argv[i]); 679 } 680 printf("\n"); 681 targs.cspHand = cspDlDbStartup(bareCsp, NULL); 682 if(targs.cspHand == 0) { 683 exit(1); 684 } 685 686 for(loop=1; ; loop++) { 687 if(!quiet) { 688 printf("...loop %d\n", loop); 689 } 690 /* change once per outer loop */ 691 simpleGenData(&ptext, MIN_PTEXT_SIZE, MAX_PTEXT_SIZE); 692 origLen = ptext.Length; 693 simpleGenData(&initVector, MAX_IV_SIZE, MAX_IV_SIZE); 694 targs.useRefKey = refKeys; 695 696 for(encrAlg=ENCR_ALG_FIRST; encrAlg<=ENCR_ALG_LAST; encrAlg++) { 697 /* Cook up encryption-related args */ 698 algInfo(encrAlg, 699 &targs.keyAlg, 700 &targs.encrAlg, 701 &targs.keyAlgStr, 702 &targs.initVector.Length); 703 704 /* random key size */ 705 targs.effectiveKeySizeInBits = randKeySizeBits(targs.keyAlg, OT_Encrypt); 706 targs.keySizeInBits = (targs.effectiveKeySizeInBits + 7) & ~7; 707 if(targs.keySizeInBits == targs.effectiveKeySizeInBits) { 708 /* same size, ignore effective */ 709 targs.effectiveKeySizeInBits = 0; 710 } 711 if(!quiet) { 712 printf(" ...Encrypt alg %s keySizeInBits %u effectKeySize %u\n", 713 targs.keyAlgStr, (unsigned)targs.keySizeInBits, 714 (unsigned)targs.effectiveKeySizeInBits); 715 } 716 717 /* generate raw key for this keyAlg */ 718 targs.key = cspGenSymKey(targs.cspHand, 719 targs.keyAlg, 720 KEY_LABEL1, 721 KEY_LABEL_LEN, 722 CSSM_KEYUSE_ENCRYPT, 723 targs.keySizeInBits, 724 targs.useRefKey); 725 if(targs.key == NULL) { 726 if(testError(quiet)) { 727 goto testDone; // abort 728 } 729 else { 730 continue; // next key alg 731 } 732 } 733 734 /* 735 * Inner loop: iterate thru modes for algorithms which 736 * support them 737 */ 738 for(pmode=ENCR_MODE_FIRST; 739 pmode<=ENCR_MODE_LAST; 740 pmode++) { 741 742 /* Cook up mode-related args */ 743 modeInfo(targs.keyAlg, 744 pmode, 745 &targs.encrMode, 746 &targs.encrModeStr, 747 &targs.encrPad, 748 &targs.useInitVector); 749 750 if(targs.keyAlg == CSSM_ALGID_RC5) { 751 /* roll the dice, pick one of three values for rounds */ 752 unsigned die = genRand(1,3); 753 switch(die) { 754 case 1: 755 targs.rounds = 8; 756 break; 757 case 2: 758 targs.rounds = 12; 759 break; 760 case 3: 761 targs.rounds = 16; 762 break; 763 } 764 } 765 else { 766 targs.rounds = 0; 767 } 768 if(!quiet) { 769 printf(" ...mode %s\n", targs.encrModeStr); 770 } 771 772 alignRequired = alignInfo(targs.encrAlg, targs.encrMode); 773 if(alignRequired) { 774 /* truncate ptext - we'll restore it at end of loop */ 775 ptext.Length &= (~(alignRequired - 1)); 776 } 777 if(targs.useInitVector) { 778 if(initVectTest(&targs)) { 779 rtn = 1; 780 goto testDone; 781 } 782 } 783 784 if(targs.effectiveKeySizeInBits != 0) { 785 if(effectSizeTest(&targs)) { 786 rtn = 1; 787 goto testDone; 788 } 789 } 790 791 if(targs.rounds != 0) { 792 if(roundsTest(&targs)) { 793 rtn = 1; 794 goto testDone; 795 } 796 } 797 798 if(!targs.useRefKey) { 799 /* can't do this with ref keys due to key/encr alg mismatch */ 800 if(encrAlgTest(&targs)) { 801 rtn = 1; 802 goto testDone; 803 } 804 } 805 806 if(encrModeTest(&targs)) { 807 rtn = 1; 808 goto testDone; 809 } 810 if(ptextTest(&targs)) { 811 rtn = 1; 812 goto testDone; 813 } 814 if(!targs.useRefKey) { 815 if(keyTest(&targs)) { 816 rtn = 1; 817 goto testDone; 818 } 819 } 820 821 822 /* restore possible rounded ptext length */ 823 ptext.Length = origLen; 824 825 if(targs.encrMode == CSSM_ALGMODE_NONE) { 826 /* one mode, we're done */ 827 break; 828 } 829 830 } /* for mode */ 831 832 /* free key */ 833 cspFreeKey(targs.cspHand, targs.key); 834 CSSM_FREE(targs.key); 835 836 } /* for encrAlg */ 837 if(doPause) { 838 if(testError(quiet)) { 839 break; 840 } 841 } 842 if(loops && (loop == loops)) { 843 break; 844 } 845 } /* for loop */ 846 847testDone: 848 CSSM_ModuleDetach(targs.cspHand); 849 if(!quiet && (rtn == 0)) { 850 printf("%s test complete\n", argv[0]); 851 } 852 return rtn; 853} 854