1/* Copyright (c) 2006,2008 Apple Inc. 2 * 3 * ccSymTest.c - test CommonCrypto symmetric encrypt/decrypt. 4 */ 5#include <string.h> 6#include <stdlib.h> 7#include <stdio.h> 8#include <CommonCrypto/CommonCryptor.h> 9#include "common.h" 10#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h> 11 12/* 13 * Defaults. 14 */ 15#define LOOPS_DEF 500 16#define MIN_DATA_SIZE 8 17#define MAX_DATA_SIZE 10000 /* bytes */ 18#define MAX_KEY_SIZE kCCKeySizeMaxRC4 /* bytes */ 19#define MAX_BLOCK_SIZE kCCBlockSizeAES128 /* bytes */ 20#define LOOP_NOTIFY 250 21 22/* 23 * Enumerate algs our own way to allow iteration. 24 */ 25typedef enum { 26 ALG_AES_128 = 1, /* 128 bit block, 128 bit key */ 27 ALG_AES_192, /* 128 bit block, 192 bit key */ 28 ALG_AES_256, /* 128 bit block, 256 bit key */ 29 ALG_DES, 30 ALG_3DES, 31 ALG_CAST, 32 ALG_RC4, 33 /* these aren't in CommonCrypto (yet?) */ 34 ALG_RC2, 35 ALG_RC5, 36 ALG_BFISH, 37 ALG_ASC, 38 ALG_NULL /* normally not used */ 39} SymAlg; 40#define ALG_FIRST ALG_AES_128 41#define ALG_LAST ALG_RC4 42 43 44#define LOG_SIZE 0 45#if LOG_SIZE 46#define logSize(s) printf s 47#else 48#define logSize(s) 49#endif 50 51static void usage(char **argv) 52{ 53 printf("usage: %s [options]\n", argv[0]); 54 printf(" Options:\n"); 55 printf(" a=algorithm (d=DES; 3=3DES; a=AES128; n=AES192; A=AES256; \n"); 56 printf(" c=CAST; 4=RC4; default=all)\n"); 57 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF); 58 printf(" m=maxPtextSize (default=%d)\n", MAX_DATA_SIZE); 59 printf(" n=minPtextSize (default=%d)\n", MIN_DATA_SIZE); 60 printf(" k=keySizeInBytes\n"); 61 printf(" p=pauseInterval (default=0, no pause)\n"); 62 printf(" o (no padding, well-aligned plaintext)\n"); 63 printf(" e (ECB only)\n"); 64 printf(" E (CBC only, no ECB)\n"); 65 printf(" u (no multi-update ops)\n"); 66 printf(" U (only multi-update ops)\n"); 67 printf(" x (always allocate context)\n"); 68 printf(" X (never allocate context)\n"); 69 printf(" v(erbose)\n"); 70 printf(" q(uiet)\n"); 71 printf(" h(elp)\n"); 72 exit(1); 73} 74 75static void printCCError(const char *str, CCCryptorStatus crtn) 76{ 77 const char *errStr; 78 char unknownStr[200]; 79 80 switch(crtn) { 81 case kCCSuccess: errStr = "kCCSuccess"; break; 82 case kCCParamError: errStr = "kCCParamError"; break; 83 case kCCBufferTooSmall: errStr = "kCCBufferTooSmall"; break; 84 case kCCMemoryFailure: errStr = "kCCMemoryFailure"; break; 85 case kCCAlignmentError: errStr = "kCCAlignmentError"; break; 86 case kCCDecodeError: errStr = "kCCDecodeError"; break; 87 case kCCUnimplemented: errStr = "kCCUnimplemented"; break; 88 default: 89 sprintf(unknownStr, "Unknown(%ld)\n", (long)crtn); 90 errStr = unknownStr; 91 break; 92 } 93 printf("***%s returned %s\n", str, errStr); 94} 95 96/* max context size */ 97#define CC_MAX_CTX_SIZE kCCContextSizeRC4 98 99/* 100 * We write a marker at end of expected output and at end of caller-allocated 101 * CCCryptorRef, and check at the end to make sure they weren't written 102 */ 103#define MARKER_LENGTH 8 104#define MARKER_BYTE 0x7e 105 106/* 107 * Test harness for CCCryptor with lots of options. 108 */ 109CCCryptorStatus doCCCrypt( 110 bool forEncrypt, 111 CCAlgorithm encrAlg, 112 bool doCbc, 113 bool doPadding, 114 const void *keyBytes, size_t keyLen, 115 const void *iv, 116 bool randUpdates, 117 bool inPlace, /* !doPadding only */ 118 size_t ctxSize, /* if nonzero, we allocate ctx */ 119 bool askOutSize, 120 const uint8_t *inText, size_t inTextLen, 121 uint8_t **outText, size_t *outTextLen) /* both returned, WE malloc */ 122{ 123 CCCryptorRef cryptor = NULL; 124 CCCryptorStatus crtn; 125 CCOperation op = forEncrypt ? kCCEncrypt : kCCDecrypt; 126 CCOptions options = 0; 127 uint8_t *outBuf = NULL; /* mallocd output buffer */ 128 uint8_t *outp; /* running ptr into outBuf */ 129 const uint8 *inp; /* running ptr into inText */ 130 size_t outLen; /* bytes remaining in outBuf */ 131 size_t toMove; /* bytes remaining in inText */ 132 size_t thisMoveOut; /* output from CCCryptUpdate()/CCCryptFinal() */ 133 size_t outBytes; /* total bytes actually produced in outBuf */ 134 char ctx[CC_MAX_CTX_SIZE]; /* for CCCryptorCreateFromData() */ 135 uint8_t *textMarker = NULL; /* 8 bytes of marker here after expected end of 136 * output */ 137 char *ctxMarker = NULL; /* ditto for caller-provided context */ 138 unsigned dex; 139 size_t askedOutSize; /* from the lib */ 140 size_t thisOutLen; /* dataOutAvailable we use */ 141 142 if(ctxSize > CC_MAX_CTX_SIZE) { 143 printf("***HEY! Adjust CC_MAX_CTX_SIZE!\n"); 144 exit(1); 145 } 146 if(!doCbc) { 147 options |= kCCOptionECBMode; 148 } 149 if(doPadding) { 150 options |= kCCOptionPKCS7Padding; 151 } 152 153 /* just hack this one */ 154 outLen = inTextLen; 155 if(forEncrypt) { 156 outLen += MAX_BLOCK_SIZE; 157 } 158 159 outBuf = (uint8_t *)malloc(outLen + MARKER_LENGTH); 160 161 /* library should not touch this memory */ 162 textMarker = outBuf + outLen; 163 memset(textMarker, MARKER_BYTE, MARKER_LENGTH); 164 165 /* subsequent errors to errOut: */ 166 167 if(inPlace) { 168 memmove(outBuf, inText, inTextLen); 169 inp = outBuf; 170 } 171 else { 172 inp = inText; 173 } 174 175 if(!randUpdates) { 176 /* one shot */ 177 if(askOutSize) { 178 crtn = CCCrypt(op, encrAlg, options, 179 keyBytes, keyLen, iv, 180 inp, inTextLen, 181 outBuf, 0, &askedOutSize); 182 if(crtn != kCCBufferTooSmall) { 183 printf("***Did not get kCCBufferTooSmall as expected\n"); 184 printf(" alg %d inTextLen %lu cbc %d padding %d keyLen %lu\n", 185 (int)encrAlg, (unsigned long)inTextLen, (int)doCbc, (int)doPadding, 186 (unsigned long)keyLen); 187 printCCError("CCCrypt", crtn); 188 crtn = -1; 189 goto errOut; 190 } 191 outLen = askedOutSize; 192 } 193 crtn = CCCrypt(op, encrAlg, options, 194 keyBytes, keyLen, iv, 195 inp, inTextLen, 196 outBuf, outLen, &outLen); 197 if(crtn) { 198 printCCError("CCCrypt", crtn); 199 goto errOut; 200 } 201 *outText = outBuf; 202 *outTextLen = outLen; 203 goto errOut; 204 } 205 206 /* random multi updates */ 207 if(ctxSize) { 208 size_t ctxSizeCreated; 209 210 if(askOutSize) { 211 crtn = CCCryptorCreateFromData(op, encrAlg, options, 212 keyBytes, keyLen, iv, 213 ctx, 0 /* ctxSize */, 214 &cryptor, &askedOutSize); 215 if(crtn != kCCBufferTooSmall) { 216 printf("***Did not get kCCBufferTooSmall as expected\n"); 217 printCCError("CCCryptorCreateFromData", crtn); 218 crtn = -1; 219 goto errOut; 220 } 221 ctxSize = askedOutSize; 222 } 223 crtn = CCCryptorCreateFromData(op, encrAlg, options, 224 keyBytes, keyLen, iv, 225 ctx, ctxSize, &cryptor, &ctxSizeCreated); 226 if(crtn) { 227 printCCError("CCCryptorCreateFromData", crtn); 228 return crtn; 229 } 230 ctxMarker = ctx + ctxSizeCreated; 231 memset(ctxMarker, MARKER_BYTE, MARKER_LENGTH); 232 } 233 else { 234 crtn = CCCryptorCreate(op, encrAlg, options, 235 keyBytes, keyLen, iv, 236 &cryptor); 237 if(crtn) { 238 printCCError("CCCryptorCreate", crtn); 239 return crtn; 240 } 241 } 242 243 toMove = inTextLen; /* total to go */ 244 outp = outBuf; 245 outBytes = 0; /* bytes actually produced in outBuf */ 246 247 while(toMove) { 248 uint32 thisMoveIn; /* input to CCryptUpdate() */ 249 250 thisMoveIn = genRand(1, toMove); 251 logSize(("###ptext segment len %lu\n", (unsigned long)thisMoveIn)); 252 if(askOutSize) { 253 thisOutLen = CCCryptorGetOutputLength(cryptor, thisMoveIn, false); 254 } 255 else { 256 thisOutLen = outLen; 257 } 258 crtn = CCCryptorUpdate(cryptor, inp, thisMoveIn, 259 outp, thisOutLen, &thisMoveOut); 260 if(crtn) { 261 printCCError("CCCryptorUpdate", crtn); 262 goto errOut; 263 } 264 inp += thisMoveIn; 265 toMove -= thisMoveIn; 266 outp += thisMoveOut; 267 outLen -= thisMoveOut; 268 outBytes += thisMoveOut; 269 } 270 271 if(doPadding) { 272 /* Final is not needed if padding is disabled */ 273 if(askOutSize) { 274 thisOutLen = CCCryptorGetOutputLength(cryptor, 0, true); 275 } 276 else { 277 thisOutLen = outLen; 278 } 279 crtn = CCCryptorFinal(cryptor, outp, thisOutLen, &thisMoveOut); 280 } 281 else { 282 thisMoveOut = 0; 283 crtn = kCCSuccess; 284 } 285 286 if(crtn) { 287 printCCError("CCCryptorFinal", crtn); 288 goto errOut; 289 } 290 291 outBytes += thisMoveOut; 292 *outText = outBuf; 293 *outTextLen = outBytes; 294 crtn = kCCSuccess; 295 296 for(dex=0; dex<MARKER_LENGTH; dex++) { 297 if(textMarker[dex] != MARKER_BYTE) { 298 printf("***lib scribbled on our textMarker memory (op=%s)!\n", 299 forEncrypt ? "encrypt" : "decrypt"); 300 crtn = (CCCryptorStatus)-1; 301 } 302 } 303 if(ctxSize) { 304 for(dex=0; dex<MARKER_LENGTH; dex++) { 305 if(ctxMarker[dex] != MARKER_BYTE) { 306 printf("***lib scribbled on our ctxMarker memory (op=%s)!\n", 307 forEncrypt ? "encrypt" : "decrypt"); 308 crtn = (CCCryptorStatus)-1; 309 } 310 } 311 } 312 313errOut: 314 if(crtn) { 315 if(outBuf) { 316 free(outBuf); 317 } 318 } 319 if(cryptor) { 320 CCCryptorRelease(cryptor); 321 } 322 return crtn; 323} 324 325static int doTest(const uint8_t *ptext, 326 size_t ptextLen, 327 CCAlgorithm encrAlg, 328 bool doCbc, 329 bool doPadding, 330 bool nullIV, /* if CBC, use NULL IV */ 331 uint32 keySizeInBytes, 332 bool stagedEncr, 333 bool stagedDecr, 334 bool inPlace, 335 size_t ctxSize, 336 bool askOutSize, 337 bool quiet) 338{ 339 uint8_t keyBytes[MAX_KEY_SIZE]; 340 uint8_t iv[MAX_BLOCK_SIZE]; 341 uint8_t *ivPtrEncrypt; 342 uint8_t *ivPtrDecrypt; 343 uint8_t *ctext = NULL; /* mallocd by doCCCrypt */ 344 size_t ctextLen = 0; 345 uint8_t *rptext = NULL; /* mallocd by doCCCrypt */ 346 size_t rptextLen; 347 CCCryptorStatus crtn; 348 int rtn = 0; 349 350 /* random key */ 351 appGetRandomBytes(keyBytes, keySizeInBytes); 352 353 /* random IV if needed */ 354 if(doCbc) { 355 if(nullIV) { 356 memset(iv, 0, MAX_BLOCK_SIZE); 357 358 /* flip a coin, give one side NULL, the other size zeroes */ 359 if(genRand(1,2) == 1) { 360 ivPtrEncrypt = NULL; 361 ivPtrDecrypt = iv; 362 } 363 else { 364 ivPtrEncrypt = iv; 365 ivPtrDecrypt = NULL; 366 } 367 } 368 else { 369 appGetRandomBytes(iv, MAX_BLOCK_SIZE); 370 ivPtrEncrypt = iv; 371 ivPtrDecrypt = iv; 372 } 373 } 374 else { 375 ivPtrEncrypt = NULL; 376 ivPtrDecrypt = NULL; 377 } 378 379 crtn = doCCCrypt(true, encrAlg, doCbc, doPadding, 380 keyBytes, keySizeInBytes, ivPtrEncrypt, 381 stagedEncr, inPlace, ctxSize, askOutSize, 382 ptext, ptextLen, 383 &ctext, &ctextLen); 384 if(crtn) { 385 rtn = testError(quiet); 386 if(rtn) { 387 goto abort; 388 } 389 } 390 391 logSize(("###ctext len %lu\n", ctextLen)); 392 393 crtn = doCCCrypt(false, encrAlg, doCbc, doPadding, 394 keyBytes, keySizeInBytes, ivPtrDecrypt, 395 stagedDecr, inPlace, ctxSize, askOutSize, 396 ctext, ctextLen, 397 &rptext, &rptextLen); 398 if(crtn) { 399 rtn = testError(quiet); 400 if(rtn) { 401 goto abort; 402 } 403 } 404 405 logSize(("###rptext len %lu\n", rptextLen)); 406 407 /* compare ptext, rptext */ 408 if(ptextLen != rptextLen) { 409 printf("Ptext length mismatch: expect %lu, got %lu\n", ptextLen, rptextLen); 410 rtn = testError(quiet); 411 if(rtn) { 412 goto abort; 413 } 414 } 415 if(memcmp(ptext, rptext, ptextLen)) { 416 printf("***data miscompare\n"); 417 rtn = testError(quiet); 418 } 419abort: 420 if(ctext) { 421 free(ctext); 422 } 423 if(rptext) { 424 free(rptext); 425 } 426 return rtn; 427} 428 429bool isBitSet(unsigned bit, unsigned word) 430{ 431 if(bit > 31) { 432 printf("We don't have that many bits\n"); 433 exit(1); 434 } 435 unsigned mask = 1 << bit; 436 return (word & mask) ? true : false; 437} 438 439int main(int argc, char **argv) 440{ 441 int arg; 442 char *argp; 443 unsigned loop; 444 uint8 *ptext; 445 size_t ptextLen; 446 bool stagedEncr; 447 bool stagedDecr; 448 bool doPadding; 449 bool doCbc; 450 bool nullIV; 451 const char *algStr; 452 CCAlgorithm encrAlg; 453 int i; 454 int currAlg; // ALG_xxx 455 uint32 minKeySizeInBytes; 456 uint32 maxKeySizeInBytes; 457 uint32 keySizeInBytes; 458 int rtn = 0; 459 uint32 blockSize; // for noPadding case 460 size_t ctxSize; // always set per alg 461 size_t ctxSizeUsed; // passed to doTest 462 bool askOutSize; // inquire output size each op 463 464 /* 465 * User-spec'd params 466 */ 467 bool keySizeSpec = false; // false: use rand key size 468 SymAlg minAlg = ALG_FIRST; 469 SymAlg maxAlg = ALG_LAST; 470 unsigned loops = LOOPS_DEF; 471 bool verbose = false; 472 size_t minPtextSize = MIN_DATA_SIZE; 473 size_t maxPtextSize = MAX_DATA_SIZE; 474 bool quiet = false; 475 unsigned pauseInterval = 0; 476 bool paddingSpec = false; // true: user calls doPadding, const 477 bool cbcSpec = false; // ditto for doCbc 478 bool stagedSpec = false; // ditto for stagedEncr and stagedDecr 479 bool inPlace = false; // en/decrypt in place for ECB 480 bool allocCtxSpec = false; // use allocCtx 481 bool allocCtx = false; // allocate context ourself 482 483 for(arg=1; arg<argc; arg++) { 484 argp = argv[arg]; 485 switch(argp[0]) { 486 case 'a': 487 if(argp[1] != '=') { 488 usage(argv); 489 } 490 switch(argp[2]) { 491 case 's': 492 minAlg = maxAlg = ALG_ASC; 493 break; 494 case 'd': 495 minAlg = maxAlg = ALG_DES; 496 break; 497 case '3': 498 minAlg = maxAlg = ALG_3DES; 499 break; 500 case '2': 501 minAlg = maxAlg = ALG_RC2; 502 break; 503 case '4': 504 minAlg = maxAlg = ALG_RC4; 505 break; 506 case '5': 507 minAlg = maxAlg = ALG_RC5; 508 break; 509 case 'a': 510 minAlg = maxAlg = ALG_AES_128; 511 break; 512 case 'n': 513 minAlg = maxAlg = ALG_AES_192; 514 break; 515 case 'A': 516 minAlg = maxAlg = ALG_AES_256; 517 break; 518 case 'b': 519 minAlg = maxAlg = ALG_BFISH; 520 break; 521 case 'c': 522 minAlg = maxAlg = ALG_CAST; 523 break; 524 default: 525 usage(argv); 526 } 527 if(maxAlg > ALG_LAST) { 528 /* we left them in the switch but we can't use them */ 529 usage(argv); 530 } 531 break; 532 case 'l': 533 loops = atoi(&argp[2]); 534 break; 535 case 'n': 536 minPtextSize = atoi(&argp[2]); 537 break; 538 case 'm': 539 maxPtextSize = atoi(&argp[2]); 540 break; 541 case 'k': 542 minKeySizeInBytes = maxKeySizeInBytes = atoi(&argp[2]); 543 keySizeSpec = true; 544 break; 545 case 'x': 546 allocCtxSpec = true; 547 allocCtx = true; 548 break; 549 case 'X': 550 allocCtxSpec = true; 551 allocCtx = false; 552 break; 553 case 'v': 554 verbose = true; 555 break; 556 case 'q': 557 quiet = true; 558 break; 559 case 'p': 560 pauseInterval = atoi(&argp[2]);; 561 break; 562 case 'o': 563 doPadding = false; 564 paddingSpec = true; 565 break; 566 case 'e': 567 doCbc = false; 568 cbcSpec = true; 569 break; 570 case 'E': 571 doCbc = true; 572 cbcSpec = true; 573 break; 574 case 'u': 575 stagedEncr = false; 576 stagedDecr = false; 577 stagedSpec = true; 578 break; 579 case 'U': 580 stagedEncr = true; 581 stagedDecr = true; 582 stagedSpec = true; 583 break; 584 case 'h': 585 default: 586 usage(argv); 587 } 588 } 589 ptext = (uint8 *)malloc(maxPtextSize); 590 if(ptext == NULL) { 591 printf("Insufficient heap space\n"); 592 exit(1); 593 } 594 /* ptext length set in test loop */ 595 596 printf("Starting ccSymTest; args: "); 597 for(i=1; i<argc; i++) { 598 printf("%s ", argv[i]); 599 } 600 printf("\n"); 601 602 if(pauseInterval) { 603 fpurge(stdin); 604 printf("Top of test; hit CR to proceed: "); 605 getchar(); 606 } 607 608 for(currAlg=minAlg; currAlg<=maxAlg; currAlg++) { 609 switch(currAlg) { 610 case ALG_DES: 611 encrAlg = kCCAlgorithmDES; 612 blockSize = kCCBlockSizeDES; 613 minKeySizeInBytes = kCCKeySizeDES; 614 maxKeySizeInBytes = minKeySizeInBytes; 615 ctxSize = kCCContextSizeDES; 616 algStr = "DES"; 617 break; 618 case ALG_3DES: 619 encrAlg = kCCAlgorithm3DES; 620 blockSize = kCCBlockSize3DES; 621 minKeySizeInBytes = kCCKeySize3DES; 622 maxKeySizeInBytes = minKeySizeInBytes; 623 ctxSize = kCCContextSize3DES; 624 algStr = "3DES"; 625 break; 626 case ALG_AES_128: 627 encrAlg = kCCAlgorithmAES128; 628 blockSize = kCCBlockSizeAES128; 629 minKeySizeInBytes = kCCKeySizeAES128; 630 maxKeySizeInBytes = minKeySizeInBytes; 631 ctxSize = kCCContextSizeAES128; 632 algStr = "AES128"; 633 break; 634 case ALG_AES_192: 635 encrAlg = kCCAlgorithmAES128; 636 blockSize = kCCBlockSizeAES128; 637 minKeySizeInBytes = kCCKeySizeAES192; 638 maxKeySizeInBytes = minKeySizeInBytes; 639 ctxSize = kCCContextSizeAES128; 640 algStr = "AES192"; 641 break; 642 case ALG_AES_256: 643 encrAlg = kCCAlgorithmAES128; 644 blockSize = kCCBlockSizeAES128; 645 minKeySizeInBytes = kCCKeySizeAES256; 646 maxKeySizeInBytes = minKeySizeInBytes; 647 ctxSize = kCCContextSizeAES128; 648 algStr = "AES256"; 649 break; 650 case ALG_CAST: 651 encrAlg = kCCAlgorithmCAST; 652 blockSize = kCCBlockSizeCAST; 653 minKeySizeInBytes = kCCKeySizeMinCAST; 654 maxKeySizeInBytes = kCCKeySizeMaxCAST; 655 ctxSize = kCCContextSizeCAST; 656 algStr = "CAST"; 657 break; 658 case ALG_RC4: 659 encrAlg = kCCAlgorithmRC4; 660 blockSize = 0; 661 minKeySizeInBytes = kCCKeySizeMinRC4; 662 maxKeySizeInBytes = kCCKeySizeMaxRC4; 663 ctxSize = kCCContextSizeRC4; 664 algStr = "RC4"; 665 break; 666 default: 667 printf("***BRRZAP!\n"); 668 exit(1); 669 } 670 if(!quiet || verbose) { 671 printf("Testing alg %s\n", algStr); 672 } 673 for(loop=1; ; loop++) { 674 ptextLen = genRand(minPtextSize, maxPtextSize); 675 appGetRandomBytes(ptext, ptextLen); 676 677 /* per-loop settings */ 678 if(!keySizeSpec) { 679 if(minKeySizeInBytes == maxKeySizeInBytes) { 680 keySizeInBytes = minKeySizeInBytes; 681 } 682 else { 683 keySizeInBytes = genRand(minKeySizeInBytes, maxKeySizeInBytes); 684 } 685 } 686 if(blockSize == 0) { 687 /* stream cipher */ 688 doCbc = false; 689 doPadding = false; 690 } 691 else { 692 if(!cbcSpec) { 693 doCbc = isBitSet(0, loop); 694 } 695 if(!paddingSpec) { 696 doPadding = isBitSet(1, loop); 697 } 698 } 699 if(!doPadding && (blockSize != 0)) { 700 /* align plaintext */ 701 ptextLen = (ptextLen / blockSize) * blockSize; 702 if(ptextLen == 0) { 703 ptextLen = blockSize; 704 } 705 } 706 if(!stagedSpec) { 707 stagedEncr = isBitSet(2, loop); 708 stagedDecr = isBitSet(3, loop); 709 } 710 if(doCbc) { 711 nullIV = isBitSet(4, loop); 712 } 713 else { 714 nullIV = false; 715 } 716 inPlace = isBitSet(5, loop); 717 if(allocCtxSpec) { 718 ctxSizeUsed = allocCtx ? ctxSize : 0; 719 } 720 else if(isBitSet(6, loop)) { 721 ctxSizeUsed = ctxSize; 722 } 723 else { 724 ctxSizeUsed = 0; 725 } 726 askOutSize = isBitSet(7, loop); 727 if(!quiet) { 728 if(verbose || ((loop % LOOP_NOTIFY) == 0)) { 729 printf("..loop %3d ptextLen %lu keyLen %d cbc=%d padding=%d stagedEncr=%d " 730 "stagedDecr=%d\n", 731 loop, (unsigned long)ptextLen, (int)keySizeInBytes, 732 (int)doCbc, (int)doPadding, 733 (int)stagedEncr, (int)stagedDecr); 734 printf(" nullIV %d inPlace %d ctxSize %d askOutSize %d\n", 735 (int)nullIV, (int)inPlace, (int)ctxSizeUsed, (int)askOutSize); 736 } 737 } 738 739 if(doTest(ptext, ptextLen, 740 encrAlg, doCbc, doPadding, nullIV, 741 keySizeInBytes, 742 stagedEncr, stagedDecr, inPlace, ctxSizeUsed, askOutSize, 743 quiet)) { 744 rtn = 1; 745 break; 746 } 747 if(pauseInterval && ((loop % pauseInterval) == 0)) { 748 char c; 749 fpurge(stdin); 750 printf("Hit CR to proceed, q to abort: "); 751 c = getchar(); 752 if(c == 'q') { 753 goto testDone; 754 } 755 } 756 if(loops && (loop == loops)) { 757 break; 758 } 759 } /* main loop */ 760 if(rtn) { 761 break; 762 } 763 764 } /* for algs */ 765 766testDone: 767 if(pauseInterval) { 768 fpurge(stdin); 769 printf("ModuleDetach/Unload complete; hit CR to exit: "); 770 getchar(); 771 } 772 if((rtn == 0) && !quiet) { 773 printf("%s test complete\n", argv[0]); 774 } 775 free(ptext); 776 return rtn; 777} 778