]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/contextReuse/contextReuse.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / contextReuse / contextReuse.cpp
1 /*
2 * contextReuse.cpp
3 *
4 * Verify proper operation of symmetric CSP algorithms when CSSM_CC_HANDLE
5 * (crypto context) is reused. Tests specifically for Radar 4551700, which
6 * dealt with a problem with the Gladman AES implementation handling the
7 * same context for an encrypt followed by a decrypt; other situations
8 * are tested here (e.g. encrypt followed by another encrypt including CBC)
9 * as well as all CSP symmetric algorithms.
10 */
11
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 <string.h>
20 #include "cspdlTesting.h"
21
22 /*
23 * Defaults.
24 */
25 #define LOOPS_DEF 200
26
27 #define MIN_DATA_SIZE 8
28 #define MAX_DATA_SIZE 10000 /* bytes */
29 #define MAX_KEY_SIZE MAX_KEY_SIZE_RC245_BYTES /* bytes */
30 #define LOOP_NOTIFY 20
31
32 #define RAW_MODE CSSM_ALGMODE_ECB /* doesn't work for BSAFE */
33 #define RAW_MODE_STREAM CSSM_ALGMODE_NONE
34 #define COOKED_MODE CSSM_ALGMODE_CBCPadIV8
35
36 #define RAW_MODE_STR "ECB"
37 #define RAW_MODE_STREAM_STR "None"
38 #define COOKED_MODE_STR "CBC/Pad"
39
40 /*
41 * Enumerate algs our own way to allow iteration.
42 */
43 typedef enum {
44 ALG_ASC = 1, // not tested - no reference available
45 ALG_DES = 1,
46 ALG_RC2,
47 ALG_RC4,
48 ALG_RC5,
49 ALG_3DES,
50 ALG_AES,
51 ALG_AES192, /* 192 bit block */
52 ALG_AES256, /* 256 bit block */
53 ALG_BFISH,
54 ALG_CAST
55 } SymAlg;
56 #define ALG_FIRST ALG_ASC
57 #define ALG_LAST ALG_CAST
58
59 static void usage(char **argv)
60 {
61 printf("usage: %s [options]\n", argv[0]);
62 printf(" Options:\n");
63 printf(" a=algorithm (d=DES; 3=3DES3; 2=RC2; 4=RC4; 5=RC5; a=AES; A=AES192; \n");
64 printf(" 6=AES256; b=Blowfish; c=CAST; s=ASC; default=all)\n");
65 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
66 printf(" k=keySizeInBits\n");
67 printf(" m=maxPtextSize (default=%d)\n", MAX_DATA_SIZE);
68 printf(" n=minPtextSize (default=%d)\n", MIN_DATA_SIZE);
69 printf(" p=pauseInterval (default=0, no pause)\n");
70 printf(" D (CSP/DL; default = bare CSP)\n");
71 printf(" v(erbose)\n");
72 printf(" q(uiet)\n");
73 printf(" h(elp)\n");
74 exit(1);
75 }
76
77 #define LOG_STAGED_OPS 0
78 #if LOG_STAGED_OPS
79 #define soprintf(s) printf s
80 #else
81 #define soprintf(s)
82 #endif
83
84 /*
85 * Multipurpose encrypt. Like cspStagedEncrypt(), but it takes a
86 * context handle and doesn't have as many options.
87 */
88 static CSSM_RETURN stagedEncrypt(
89 CSSM_CSP_HANDLE cspHand,
90 CSSM_CC_HANDLE cryptHand,
91 uint32 algorithm, // CSSM_ALGID_FEED, etc.
92 uint32 cipherBlockSizeBytes,// optional
93 const CSSM_DATA *iv, // init vector, optional
94 const CSSM_DATA *ptext,
95 CSSM_DATA_PTR ctext, // mallocd by caller, must be big enough!
96 CSSM_BOOL multiUpdates) // false:single update, true:multi updates
97 {
98 CSSM_RETURN crtn;
99 CSSM_SIZE bytesEncrypted; // per update
100 CSSM_SIZE bytesEncryptedTotal = 0;
101 CSSM_RETURN ocrtn = CSSM_OK; // 'our' crtn
102 unsigned toMove; // remaining
103 unsigned thisMove; // bytes to encrypt on this update
104 CSSM_DATA thisPtext; // running ptr into ptext
105 CSSM_DATA thisCtext; // running ptr into ctext
106 CSSM_BOOL restoreErr = CSSM_FALSE;
107 CSSM_RETURN savedErr = CSSM_OK;
108 CSSM_SIZE ctextLen;
109
110 if(cipherBlockSizeBytes) {
111 crtn = AddContextAttribute(cryptHand,
112 CSSM_ATTRIBUTE_BLOCK_SIZE,
113 sizeof(uint32),
114 CAT_Uint32,
115 NULL,
116 cipherBlockSizeBytes);
117 if(crtn) {
118 printError("CSSM_UpdateContextAttributes", crtn);
119 ocrtn = crtn;
120 goto abort;
121 }
122 }
123
124 thisPtext = *ptext;
125 thisCtext = *ctext;
126 memset(ctext->Data, 0, ctext->Length);
127 ctextLen = ctext->Length;
128
129 crtn = CSSM_EncryptDataInit(cryptHand);
130 if(crtn) {
131 printError("CSSM_EncryptDataInit", crtn);
132 ocrtn = crtn;
133 goto abort;
134 }
135
136 toMove = ptext->Length;
137 while(toMove) {
138 if(multiUpdates) {
139 thisMove = genRand(1, toMove);
140 }
141 else {
142 /* just do one pass thru this loop */
143 thisMove = toMove;
144 }
145 thisPtext.Length = thisMove;
146 crtn = CSSM_EncryptDataUpdate(cryptHand,
147 &thisPtext,
148 1,
149 &thisCtext,
150 1,
151 &bytesEncrypted);
152 if(crtn) {
153 printError("CSSM_EncryptDataUpdate", crtn);
154 ocrtn = crtn;
155 goto abort;
156 }
157 soprintf(("*** EncryptDataUpdate: ptextLen 0x%x bytesEncrypted 0x%x\n",
158 (unsigned)thisMove, (unsigned)bytesEncrypted));
159
160 // NOTE: We return the proper length in ctext....
161 ctextLen -= bytesEncrypted; // bump out ptr
162 thisCtext.Length = ctextLen;
163 thisCtext.Data += bytesEncrypted;
164 bytesEncryptedTotal += bytesEncrypted;
165 thisPtext.Data += thisMove; // bump in ptr
166 toMove -= thisMove;
167 }
168 /* OK, one more */
169 crtn = CSSM_EncryptDataFinal(cryptHand, &thisCtext);
170 if(crtn) {
171 printError("CSSM_EncryptDataFinal", crtn);
172 savedErr = crtn;
173 restoreErr = CSSM_TRUE;
174 goto abort;
175 }
176 soprintf(("*** EncryptDataFinal: bytesEncrypted 0x%x\n",
177 (unsigned)thisCtext.Length));
178 bytesEncryptedTotal += thisCtext.Length;
179 ctext->Length = bytesEncryptedTotal;
180 abort:
181 if(restoreErr) {
182 /* give caller the error from the encrypt */
183 ocrtn = savedErr;
184 }
185 return ocrtn;
186 }
187
188 /*
189 * Multipurpose decrypt. Like cspStagedDecrypt(), but it takes a
190 * context handle and doesn't have as many options.
191 */
192 CSSM_RETURN stagedDecrypt(
193 CSSM_CSP_HANDLE cspHand,
194 CSSM_CC_HANDLE cryptHand,
195 uint32 algorithm, // CSSM_ALGID_FEED, etc.
196 uint32 cipherBlockSizeBytes,// optional
197 const CSSM_DATA *iv, // init vector, optional
198 const CSSM_DATA *ctext,
199 CSSM_DATA_PTR ptext, // mallocd by caller, must be big enough!
200 CSSM_BOOL multiUpdates) // false:single update, true:multi updates
201 {
202 CSSM_RETURN crtn;
203 CSSM_SIZE bytesDecrypted; // per update
204 CSSM_SIZE bytesDecryptedTotal = 0;
205 CSSM_RETURN ocrtn = CSSM_OK; // 'our' crtn
206 unsigned toMove; // remaining
207 unsigned thisMove; // bytes to decrypt on this update
208 CSSM_DATA thisCtext; // running ptr into ptext
209 CSSM_DATA thisPtext; // running ptr into ctext
210 CSSM_SIZE ptextLen;
211
212 if(cipherBlockSizeBytes) {
213 crtn = AddContextAttribute(cryptHand,
214 CSSM_ATTRIBUTE_BLOCK_SIZE,
215 sizeof(uint32),
216 CAT_Uint32,
217 NULL,
218 cipherBlockSizeBytes);
219 if(crtn) {
220 printError("CSSM_UpdateContextAttributes", crtn);
221 ocrtn = crtn;
222 goto abort;
223 }
224 }
225
226 thisCtext = *ctext;
227 thisPtext = *ptext;
228 memset(ptext->Data, 0, ptext->Length);
229 ptextLen = ptext->Length;
230
231 crtn = CSSM_DecryptDataInit(cryptHand);
232 if(crtn) {
233 printError("CSSM_DecryptDataInit", crtn);
234 ocrtn = crtn;
235 goto abort;
236 }
237
238 toMove = ctext->Length;
239 while(toMove) {
240 if(multiUpdates) {
241 thisMove = genRand(1, toMove);
242 }
243 else {
244 /* just do one pass thru this loop */
245 thisMove = toMove;
246 }
247 thisCtext.Length = thisMove;
248 crtn = CSSM_DecryptDataUpdate(cryptHand,
249 &thisCtext,
250 1,
251 &thisPtext,
252 1,
253 &bytesDecrypted);
254 if(crtn) {
255 printError("CSSM_DecryptDataUpdate", crtn);
256 ocrtn = crtn;
257 goto abort;
258 }
259 soprintf(("*** DecryptDataUpdate: ctextLen 0x%x bytesDecrypted 0x%x\n",
260 (unsigned)thisMove, (unsigned)bytesDecrypted));
261
262 // NOTE: We return the proper length in ptext....
263 ptextLen -= bytesDecrypted; // bump out ptr
264 thisPtext.Length = ptextLen;
265 thisPtext.Data += bytesDecrypted;
266 bytesDecryptedTotal += bytesDecrypted;
267 thisCtext.Data += thisMove; // bump in ptr
268 toMove -= thisMove;
269 }
270 /* OK, one more */
271 crtn = CSSM_DecryptDataFinal(cryptHand, &thisPtext);
272 if(crtn) {
273 printError("CSSM_DecryptDataFinal", crtn);
274 ocrtn = crtn;
275 goto abort;
276 }
277 soprintf(("*** DecryptDataFinal: bytesEncrypted 0x%x\n",
278 (unsigned)thisPtext.Length));
279 bytesDecryptedTotal += thisPtext.Length;
280 ptext->Length = bytesDecryptedTotal;
281 abort:
282 return ocrtn;
283 }
284
285 static int doTest(
286 CSSM_CSP_HANDLE cspHand,
287 const CSSM_DATA *ptext,
288 const CSSM_DATA *ctext1,
289 const CSSM_DATA *ctext2,
290 const CSSM_DATA *rptext,
291 const CSSM_DATA *keyData,
292 const CSSM_DATA *iv,
293 uint32 keyAlg, // CSSM_ALGID_xxx of the key
294 uint32 encrAlg, // encrypt/decrypt
295 uint32 encrMode,
296 uint32 padding,
297 uint32 keySizeInBits,
298 uint32 cipherBlockSizeBytes,
299 CSSM_BOOL quiet)
300 {
301 CSSM_DATA lctext1;
302 CSSM_DATA lctext2;
303 CSSM_DATA lrptext;
304 int rtn = 0;
305 CSSM_RETURN crtn;
306 CSSM_CC_HANDLE ccHand1 = 0;
307 CSSM_CC_HANDLE ccHand2 = 0;
308 CSSM_KEY key1;
309 CSSM_KEY key2;
310 uint8 dummy[cipherBlockSizeBytes];
311 CSSM_DATA dummyData = {cipherBlockSizeBytes, dummy};
312
313 /*
314 * generate two equivalent keys key1 and key2;
315 * generate two CC handles ccHand1, ccHand2;
316 * encrypt dummy data with ccHand1 to get it cooked;
317 * encrypt ptext with ccHand1 ==> ctext1;
318 * encrypt ptext with ccHand2 ==> ctext2;
319 * Compare ctext1 and ctext2;
320 * decrypt ctext1 with ccHand1, compare with ptext;
321 */
322 crtn = cspGenSymKeyWithBits(cspHand, keyAlg, CSSM_KEYUSE_ANY,
323 keyData, keySizeInBits / 8, &key1);
324 if(crtn) {
325 return crtn;
326 }
327 crtn = cspGenSymKeyWithBits(cspHand, keyAlg, CSSM_KEYUSE_ANY,
328 keyData, keySizeInBits / 8, &key2);
329 if(crtn) {
330 return crtn;
331 }
332 ccHand1 = genCryptHandle(cspHand,
333 encrAlg,
334 encrMode,
335 padding,
336 &key1,
337 NULL, // pubKey
338 iv,
339 0, // effectiveKeySizeInBits
340 0); // rounds
341 if(ccHand1 == 0) {
342 return CSSMERR_CSP_INTERNAL_ERROR;
343 }
344 ccHand2 = genCryptHandle(cspHand,
345 encrAlg,
346 encrMode,
347 padding,
348 &key2,
349 NULL, // pubKey
350 iv,
351 0, // effectiveKeySizeInBits
352 0); // rounds
353 if(ccHand2 == 0) {
354 return CSSMERR_CSP_INTERNAL_ERROR;
355 }
356
357 /* dummy encrypt to heat up ccHand1 */
358 appGetRandomBytes(dummy, sizeof(dummy));
359 lctext1 = *ctext1;
360 crtn = stagedEncrypt(cspHand, ccHand1, encrAlg, cipherBlockSizeBytes,
361 iv, &dummyData, &lctext1, CSSM_FALSE);
362 if(crtn) {
363 return crtn;
364 }
365
366 /* encrypt ptext with ccHand1 and ccHand2, compare ctext */
367 lctext1 = *ctext1;
368 crtn = stagedEncrypt(cspHand, ccHand1, encrAlg, cipherBlockSizeBytes,
369 iv, ptext, &lctext1, CSSM_TRUE);
370 if(crtn) {
371 return crtn;
372 }
373 lctext2 = *ctext2;
374 crtn = stagedEncrypt(cspHand, ccHand2, encrAlg, cipherBlockSizeBytes,
375 iv, ptext, &lctext2, CSSM_TRUE);
376 if(crtn) {
377 return crtn;
378 }
379 if(!appCompareCssmData(&lctext1, &lctext2)) {
380 printf("***Ciphertext miscompare\n");
381 if(testError(quiet)) {
382 return 1;
383 }
384 }
385
386 /* decrypt with ccHand1, compare with ptext */
387 lrptext = *rptext;
388 crtn = stagedDecrypt(cspHand, ccHand1, encrAlg, cipherBlockSizeBytes,
389 iv, &lctext1, &lrptext, CSSM_TRUE);
390 if(crtn) {
391 return crtn;
392 }
393 if(!appCompareCssmData(&lctext1, &lctext2)) {
394 printf("***Plaintext miscompare\n");
395 if(testError(quiet)) {
396 return 1;
397 }
398 }
399
400 if(ccHand1) {
401 CSSM_DeleteContext(ccHand1);
402 }
403 if(ccHand2) {
404 CSSM_DeleteContext(ccHand2);
405 }
406 return rtn;
407 }
408
409
410 int main(int argc, char **argv)
411 {
412 int arg;
413 char *argp;
414 unsigned loop;
415 CSSM_DATA ptext;
416 CSSM_DATA ctext1;
417 CSSM_DATA ctext2;
418 CSSM_DATA rptext;
419 CSSM_CSP_HANDLE cspHand;
420 const char *algStr;
421 uint32 keyAlg; // CSSM_ALGID_xxx of the key
422 uint32 encrAlg; // CSSM_ALGID_xxx of encr/decr
423 unsigned currAlg; // ALG_xxx
424 uint32 keySizeInBits;
425 int rtn = 0;
426 CSSM_DATA keyData;
427 CSSM_DATA initVector;
428 uint32 minTextSize;
429 uint32 rawMode;
430 uint32 cookedMode;
431 const char *rawModeStr;
432 const char *cookedModeStr;
433 uint32 algBlockSizeBytes;
434
435 /*
436 * User-spec'd params
437 */
438 CSSM_BOOL keySizeSpec = CSSM_FALSE; // false: use rand key size
439 unsigned minAlg = ALG_FIRST;
440 unsigned maxAlg = ALG_LAST;
441 unsigned loops = LOOPS_DEF;
442 CSSM_BOOL verbose = CSSM_FALSE;
443 CSSM_BOOL quiet = CSSM_FALSE;
444 unsigned pauseInterval = 0;
445 uint32 padding;
446 CSSM_BOOL bareCsp = CSSM_TRUE;
447 unsigned maxPtextSize = MAX_DATA_SIZE;
448 unsigned minPtextSize = MIN_DATA_SIZE;
449
450 for(arg=1; arg<argc; arg++) {
451 argp = argv[arg];
452 switch(argp[0]) {
453 case 'a':
454 if(argp[1] != '=') {
455 usage(argv);
456 }
457 switch(argp[2]) {
458 case 'd':
459 minAlg = maxAlg = ALG_DES;
460 break;
461 case '3':
462 minAlg = maxAlg = ALG_3DES;
463 break;
464 case '2':
465 minAlg = maxAlg = ALG_RC2;
466 break;
467 case '4':
468 minAlg = maxAlg = ALG_RC4;
469 break;
470 case '5':
471 minAlg = maxAlg = ALG_RC5;
472 break;
473 case 'a':
474 minAlg = maxAlg = ALG_AES;
475 break;
476 case 'A':
477 minAlg = maxAlg = ALG_AES192;
478 break;
479 case '6':
480 minAlg = maxAlg = ALG_AES256;
481 break;
482 case 'b':
483 minAlg = maxAlg = ALG_BFISH;
484 break;
485 case 'c':
486 minAlg = maxAlg = ALG_CAST;
487 break;
488 case 's':
489 minAlg = maxAlg = ALG_ASC;
490 break;
491 default:
492 usage(argv);
493 }
494 break;
495 case 'l':
496 loops = atoi(&argp[2]);
497 break;
498 case 'k':
499 keySizeInBits = atoi(&argp[2]);
500 keySizeSpec = CSSM_TRUE;
501 break;
502 case 'v':
503 verbose = CSSM_TRUE;
504 break;
505 case 'D':
506 bareCsp = CSSM_FALSE;
507 break;
508 case 'm':
509 maxPtextSize = atoi(&argp[2]);
510 break;
511 case 'n':
512 minPtextSize = atoi(&argp[2]);
513 break;
514 case 'q':
515 quiet = CSSM_TRUE;
516 break;
517 case 'p':
518 pauseInterval = atoi(&argp[2]);;
519 break;
520 case 'h':
521 default:
522 usage(argv);
523 }
524 }
525 ptext.Data = (uint8 *)CSSM_MALLOC(maxPtextSize);
526 if(ptext.Data == NULL) {
527 printf("Insufficient heap space\n");
528 exit(1);
529 }
530 /* ptext length set in test loop */
531 appSetupCssmData(&ctext1, 2 * maxPtextSize);
532 appSetupCssmData(&ctext2, 2 * maxPtextSize);
533 appSetupCssmData(&rptext, 2 * maxPtextSize);
534
535 keyData.Data = (uint8 *)CSSM_MALLOC(MAX_KEY_SIZE);
536 if(keyData.Data == NULL) {
537 printf("Insufficient heap space\n");
538 exit(1);
539 }
540 keyData.Length = MAX_KEY_SIZE;
541
542 initVector.Data = (uint8 *)"someStrangeInitVect";
543
544 testStartBanner("contextReuse", argc, argv);
545
546 cspHand = cspDlDbStartup(bareCsp, NULL);
547 if(cspHand == 0) {
548 exit(1);
549 }
550 if(pauseInterval) {
551 fpurge(stdin);
552 printf("Top of test; hit CR to proceed: ");
553 getchar();
554 }
555 for(currAlg=minAlg; currAlg<=maxAlg; currAlg++) {
556 /* some default values... */
557 padding = CSSM_PADDING_PKCS5;
558 rawMode = RAW_MODE;
559 cookedMode = COOKED_MODE;
560 rawModeStr = RAW_MODE_STR;
561 cookedModeStr = COOKED_MODE_STR;
562 padding = CSSM_PADDING_PKCS5;
563
564 switch(currAlg) {
565 case ALG_DES:
566 encrAlg = keyAlg = CSSM_ALGID_DES;
567 algStr = "DES";
568 algBlockSizeBytes = 8;
569 break;
570 case ALG_3DES:
571 /* currently the only one with different key and encr algs */
572 keyAlg = CSSM_ALGID_3DES_3KEY;
573 encrAlg = CSSM_ALGID_3DES_3KEY_EDE;
574 algStr = "3DES";
575 algBlockSizeBytes = 8;
576 break;
577 case ALG_RC2:
578 encrAlg = keyAlg = CSSM_ALGID_RC2;
579 algStr = "RC2";
580 algBlockSizeBytes = 8;
581 break;
582 case ALG_RC4:
583 encrAlg = keyAlg = CSSM_ALGID_RC4;
584 algStr = "RC4";
585 algBlockSizeBytes = 0;
586 rawMode = RAW_MODE_STREAM;
587 cookedMode = RAW_MODE_STREAM;
588 rawModeStr = RAW_MODE_STREAM_STR;
589 cookedModeStr = RAW_MODE_STREAM_STR;
590 break;
591 case ALG_RC5:
592 encrAlg = keyAlg = CSSM_ALGID_RC5;
593 algStr = "RC5";
594 algBlockSizeBytes = 8;
595 break;
596 case ALG_AES:
597 encrAlg = keyAlg = CSSM_ALGID_AES;
598 algStr = "AES";
599 algBlockSizeBytes = 16;
600 break;
601 case ALG_AES192:
602 encrAlg = keyAlg = CSSM_ALGID_AES;
603 algStr = "AES192";
604 algBlockSizeBytes = 24;
605 break;
606 case ALG_AES256:
607 encrAlg = keyAlg = CSSM_ALGID_AES;
608 algStr = "AES256";
609 algBlockSizeBytes = 32;
610 break;
611 case ALG_BFISH:
612 encrAlg = keyAlg = CSSM_ALGID_BLOWFISH;
613 algStr = "Blowfish";
614 algBlockSizeBytes = 8;
615 break;
616 case ALG_CAST:
617 encrAlg = keyAlg = CSSM_ALGID_CAST;
618 algStr = "CAST";
619 algBlockSizeBytes = 8;
620 break;
621 }
622
623 /* assume for now all algs require IV */
624 initVector.Length = algBlockSizeBytes ? algBlockSizeBytes : 8;
625
626 if(!quiet || verbose) {
627 printf("Testing alg %s\n", algStr);
628 }
629 for(loop=1; ; loop++) {
630 /* mix up raw/cooked */
631 uint32 mode;
632 const char *modeStr;
633 CSSM_BOOL paddingEnabled;
634
635 if(loop & 1) {
636 mode = rawMode;
637 modeStr = rawModeStr;
638 }
639 else {
640 mode = cookedMode;
641 modeStr = cookedModeStr;
642 }
643 switch(mode) {
644 case CSSM_ALGMODE_CBCPadIV8:
645 paddingEnabled = CSSM_TRUE;
646 break;
647 default:
648 /* all others - right? */
649 paddingEnabled = CSSM_FALSE;
650 break;
651 }
652 minTextSize = minPtextSize; // default
653 if(!paddingEnabled && algBlockSizeBytes && (minTextSize < algBlockSizeBytes)) {
654 /* i.e., no padding, adjust min ptext size */
655 minTextSize = algBlockSizeBytes;
656 }
657 simpleGenData(&ptext, minTextSize, maxPtextSize);
658 if(!paddingEnabled && algBlockSizeBytes) {
659 /* align ptext */
660 ptext.Length = (ptext.Length / algBlockSizeBytes) * algBlockSizeBytes;
661 }
662
663 simpleGenData(&keyData, MAX_KEY_SIZE, MAX_KEY_SIZE);
664
665 if(!keySizeSpec) {
666 /* random but byte-aligned */
667 keySizeInBits = randKeySizeBits(keyAlg, OT_Encrypt);
668 keySizeInBits = (keySizeInBits + 7) & ~7;
669 }
670 /* else constant, spec'd by user, may be 0 (default per alg) */
671 if(!quiet) {
672 if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
673 if(algBlockSizeBytes) {
674 printf("..loop %d text size %lu keySizeBits %u"
675 " blockSize %u mode %s\n",
676 loop, (unsigned long)ptext.Length, (unsigned)keySizeInBits,
677 (unsigned)algBlockSizeBytes, modeStr);
678 }
679 else {
680 printf("..loop %d text size %lu keySizeBits %u"
681 " mode %s\n",
682 loop, (unsigned long)ptext.Length, (unsigned)keySizeInBits,
683 modeStr);
684 }
685 }
686 }
687
688 if(doTest(cspHand,
689 &ptext,
690 &ctext1,
691 &ctext2,
692 &rptext,
693 &keyData,
694 &initVector,
695 keyAlg,
696 encrAlg,
697 mode,
698 padding,
699 keySizeInBits,
700 algBlockSizeBytes,
701 quiet)) {
702 rtn = 1;
703 break;
704 }
705 if(pauseInterval && ((loop % pauseInterval) == 0)) {
706 char c;
707 fpurge(stdin);
708 printf("Hit CR to proceed, q to abort: ");
709 c = getchar();
710 if(c == 'q') {
711 goto testDone;
712 }
713 }
714 if(loops && (loop == loops)) {
715 break;
716 }
717 } /* main loop */
718 if(rtn) {
719 break;
720 }
721
722 } /* for algs */
723
724 testDone:
725 cspShutdown(cspHand, bareCsp);
726 if(pauseInterval) {
727 fpurge(stdin);
728 printf("ModuleDetach/Unload complete; hit CR to exit: ");
729 getchar();
730 }
731 if((rtn == 0) && !quiet) {
732 printf("%s test complete\n", argv[0]);
733 }
734 CSSM_FREE(ptext.Data);
735 CSSM_FREE(keyData.Data);
736 return rtn;
737 }
738
739