]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/ccSymTest/ccSymTest.cpp
Security-57740.31.2.tar.gz
[apple/security.git] / SecurityTests / cspxutils / ccSymTest / ccSymTest.cpp
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 */
25 typedef 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
51 static 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
75 static 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 */
109 CCCryptorStatus 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
313 errOut:
314 if(crtn) {
315 if(outBuf) {
316 free(outBuf);
317 }
318 }
319 if(cryptor) {
320 CCCryptorRelease(cryptor);
321 }
322 return crtn;
323 }
324
325 static 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 }
419 abort:
420 if(ctext) {
421 free(ctext);
422 }
423 if(rptext) {
424 free(rptext);
425 }
426 return rtn;
427 }
428
429 bool 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
439 int 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
766 testDone:
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 }