]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/symTest/symTest.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / symTest / symTest.c
1 /* Copyright (c) 1998,2003-2006,2008 Apple Inc.
2 *
3 * symTest.c - test CSP symmetric encrypt/decrypt.
4 *
5 * Revision History
6 * ----------------
7 * 4 May 2000 Doug Mitchell
8 * Ported to X/CDSA2.
9 * 20 May 1998 Doug Mitchell at Apple
10 * Ported to CDSA1.2, new Apple CSP
11 * 15 Aug 1997 Doug Mitchell at Apple
12 * Ported from CryptKit ObjC version
13 * 26 Aug 1996 Doug Mitchell at NeXT
14 * Created.
15 */
16 #include <string.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <time.h>
20 #include <Security/cssm.h>
21 #include <Security/cssmapple.h>
22 #include "cspwrap.h"
23 #include "common.h"
24 #include "cspdlTesting.h"
25
26 /*
27 * Defaults.
28 */
29 #define LOOPS_DEF 50
30 #define MIN_PTEXT_SIZE 8
31 #define MAX_PTEXT_SIZE 0x10000
32
33 /*
34 * Enumerate algs our own way to allow iteration.
35 */
36 typedef enum {
37 ALG_ASC = 1,
38 ALG_DES,
39 ALG_RC2,
40 ALG_RC4,
41 ALG_RC5,
42 ALG_3DES,
43 ALG_AES,
44 ALG_BFISH,
45 ALG_CAST,
46 ALG_NULL /* normally not used */
47 } SymAlg;
48 #define ALG_FIRST ALG_ASC
49 #define ALG_LAST ALG_CAST
50
51 #define PBE_ENABLE 0
52 #define PWD_LENGTH_MAX 64
53 #define MAX_DATA_SIZE (100000 + 100) /* bytes */
54 #define LOOP_NOTIFY 20
55
56 #define LOG_SIZE 0
57 #if LOG_SIZE
58 #define logSize(s) printf s
59 #else
60 #define logSize(s)
61 #endif
62
63 static void usage(char **argv)
64 {
65 printf("usage: %s [options]\n", argv[0]);
66 printf(" Options:\n");
67 printf(" a=algorithm (s=ASC; d=DES; 3=3DES; 2=RC2; 4=RC4; 5=RC5; a=AES;\n");
68 printf(" b=Blowfish; c=CAST; n=Null; default=all)\n");
69 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
70 printf(" n=minPtextSize (default=%d)\n", MIN_PTEXT_SIZE);
71 printf(" x=maxPtextSize (default=%d)\n", MAX_PTEXT_SIZE);
72 printf(" k=keySizeInBits\n");
73 printf(" r(eference keys only)\n");
74 printf(" e(xport)\n");
75 printf(" d (no DB open)\n");
76 printf(" p=pauseInterval (default=0, no pause)\n");
77 printf(" o (no padding, well-aligned plaintext)\n");
78 printf(" u (no multi-update ops)\n");
79 printf(" U (only multi-update ops)\n");
80 printf(" m (CSP mallocs out bufs)\n");
81 printf(" D (CSP/DL; default = bare CSP)\n");
82 printf(" K (key gen only)\n");
83 printf(" v(erbose)\n");
84 printf(" q(uiet)\n");
85 printf(" h(elp)\n");
86 exit(1);
87 }
88
89 /* constant seed data */
90 static CSSM_DATA seedData = {8, (uint8 *)"12345678"};
91
92 /* alternate between two derivation algs, with different digest sizes */
93 #define PBE_DERIVE_ALG_ODD CSSM_ALGID_PKCS5_PBKDF1_MD5
94 #define PBE_DERIVE_ALG_EVEN CSSM_ALGID_PKCS5_PBKDF1_SHA1
95
96 /*
97 * When expectEqualText is true, encrypt/decrypt in place.
98 */
99 #define EQUAL_TEXT_IN_PLACE 1
100
101 static int doTest(CSSM_CSP_HANDLE cspHand,
102 CSSM_DATA_PTR ptext,
103 uint32 keyAlg, // CSSM_ALGID_xxx of the key
104 uint32 encrAlg, // encrypt/decrypt
105 uint32 mode,
106 uint32 padding,
107 uint32 effectiveKeySizeInBits,
108 CSSM_BOOL refKey,
109 CSSM_DATA_PTR pwd, // password- NULL means use a random key data
110 CSSM_BOOL stagedEncr,
111 CSSM_BOOL stagedDecr,
112 CSSM_BOOL mallocPtext, // only meaningful if !stagedDecr
113 CSSM_BOOL mallocCtext, // only meaningful if !stagedEncr
114 CSSM_BOOL quiet,
115 CSSM_BOOL keyGenOnly,
116 CSSM_BOOL expectEqualText) // ptext size must == ctext size
117 {
118 CSSM_KEY_PTR symKey = NULL;
119 CSSM_DATA ctext = {0, NULL};
120 CSSM_DATA rptext = {0, NULL};
121 CSSM_RETURN crtn;
122 int rtn = 0;
123 uint32 keySizeInBits;
124 CSSM_DATA initVector;
125 uint32 rounds = 0;
126
127 /* generate keys with well aligned sizes; effectiveKeySize specified in encrypt
128 * only if not well aligned */
129 keySizeInBits = (effectiveKeySizeInBits + 7) & ~7;
130 if(keySizeInBits == effectiveKeySizeInBits) {
131 effectiveKeySizeInBits = 0;
132 }
133
134 if(encrAlg == CSSM_ALGID_RC5) {
135 /* roll the dice, pick one of three values for rounds */
136 unsigned die = genRand(1,3);
137 switch(die) {
138 case 1:
139 rounds = 8;
140 break;
141 case 2:
142 rounds = 12;
143 break;
144 case 3:
145 rounds = 16;
146 break;
147 }
148 }
149
150 if(pwd == NULL) {
151 /* random key */
152 symKey = cspGenSymKey(cspHand,
153 keyAlg,
154 "noLabel",
155 7,
156 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
157 keySizeInBits,
158 refKey);
159 }
160 else {
161 /* this code isn't tested */
162 uint32 pbeAlg;
163 initVector.Data = NULL; // we're going to ignore this
164 initVector.Length = 0;
165 /* one of two random PBE algs */
166 if(ptext->Data[0] & 1) {
167 pbeAlg = PBE_DERIVE_ALG_ODD;
168 }
169 else {
170 pbeAlg = PBE_DERIVE_ALG_EVEN;
171 }
172 symKey = cspDeriveKey(cspHand,
173 pbeAlg,
174 keyAlg,
175 "noLabel",
176 7,
177 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
178 keySizeInBits,
179 refKey,
180 pwd,
181 &seedData,
182 1, // iteration count
183 &initVector);
184 if(initVector.Data != NULL) {
185 CSSM_FREE(initVector.Data);
186 }
187 }
188 if(symKey == NULL) {
189 rtn = testError(quiet);
190 goto abort;
191 }
192 if(keyGenOnly) {
193 rtn = 0;
194 goto abort;
195 }
196
197 /* not all algs need this, pass it in anyway */
198 initVector.Data = (uint8 *)"someStrangeInitVect";
199 switch(encrAlg) {
200 case CSSM_ALGID_AES:
201 case CSSM_ALGID_NONE:
202 initVector.Length = 16;
203 break;
204 default:
205 initVector.Length = 8;
206 break;
207 }
208 if(stagedEncr) {
209 crtn = cspStagedEncrypt(cspHand,
210 encrAlg,
211 mode,
212 padding,
213 symKey,
214 NULL, // second key unused
215 effectiveKeySizeInBits,
216 0, // cipherBlockSize
217 rounds,
218 &initVector,
219 ptext,
220 &ctext,
221 CSSM_TRUE); // multi
222 }
223 else {
224 const CSSM_DATA *ptextPtr = ptext;
225 if(expectEqualText && mallocCtext && CSPDL_NOPAD_ENFORCE_SIZE) {
226 /*
227 * !pad test: ensure this works when ctextlen == ptextlen by
228 * mallocing ourself right now (instead of cspEncrypt doing it
229 * after doing a CSSM_QuerySize())
230 */
231 ctext.Data = (uint8 *)appMalloc(ptext->Length, NULL);
232 if(ctext.Data == NULL) {
233 printf("memmory failure\n");
234 rtn = testError(quiet);
235 goto abort;
236 }
237 ctext.Length = ptext->Length;
238 #if EQUAL_TEXT_IN_PLACE
239 /* encrypt in place */
240 memmove(ctext.Data, ptext->Data, ptext->Length);
241 ptextPtr = &ctext;
242 #endif
243 }
244 crtn = cspEncrypt(cspHand,
245 encrAlg,
246 mode,
247 padding,
248 symKey,
249 NULL, // second key unused
250 effectiveKeySizeInBits,
251 rounds,
252 &initVector,
253 ptextPtr,
254 &ctext,
255 mallocCtext);
256 }
257 if(crtn) {
258 rtn = testError(quiet);
259 goto abort;
260 }
261 if(expectEqualText && (ptext->Length != ctext.Length)) {
262 printf("***ctext/ptext length mismatch: ptextLen %lu ctextLen %lu\n",
263 ptext->Length, ctext.Length);
264 rtn = testError(quiet);
265 if(rtn) {
266 goto abort;
267 }
268 }
269 logSize(("###ctext len %lu\n", ctext.Length));
270 if(stagedDecr) {
271 crtn = cspStagedDecrypt(cspHand,
272 encrAlg,
273 mode,
274 padding,
275 symKey,
276 NULL, // second key unused
277 effectiveKeySizeInBits,
278 0, // cipherBlockSize
279 rounds,
280 &initVector,
281 &ctext,
282 &rptext,
283 CSSM_TRUE); // multi
284 }
285 else {
286 const CSSM_DATA *ctextPtr = &ctext;
287 if(expectEqualText && mallocPtext && CSPDL_NOPAD_ENFORCE_SIZE) {
288 /*
289 * !pad test: ensure this works when ctextlen == ptextlen by
290 * mallocing ourself right now (instead of cspDecrypt doing it
291 * after doing a CSSM_QuerySize())
292 */
293 rptext.Data = (uint8 *)appMalloc(ctext.Length, NULL);
294 if(rptext.Data == NULL) {
295 printf("memmory failure\n");
296 rtn = testError(quiet);
297 goto abort;
298 }
299 rptext.Length = ctext.Length;
300 #if EQUAL_TEXT_IN_PLACE
301 /* decrypt in place */
302 memmove(rptext.Data, ctext.Data, ctext.Length);
303 ctextPtr = &rptext;
304 #endif
305 }
306 crtn = cspDecrypt(cspHand,
307 encrAlg,
308 mode,
309 padding,
310 symKey,
311 NULL, // second key unused
312 effectiveKeySizeInBits,
313 rounds,
314 &initVector,
315 ctextPtr,
316 &rptext,
317 mallocPtext);
318 }
319 if(crtn) {
320 rtn = testError(quiet);
321 goto abort;
322 }
323 logSize(("###rptext len %lu\n", rptext.Length));
324 /* compare ptext, rptext */
325 if(ptext->Length != rptext.Length) {
326 printf("Ptext length mismatch: expect %lu, got %lu\n", ptext->Length, rptext.Length);
327 rtn = testError(quiet);
328 if(rtn) {
329 goto abort;
330 }
331 }
332 if(memcmp(ptext->Data, rptext.Data, ptext->Length)) {
333 printf("***data miscompare\n");
334 rtn = testError(quiet);
335 }
336 abort:
337 /* free key if we have it*/
338 if(symKey != NULL) {
339 if(cspFreeKey(cspHand, symKey)) {
340 printf("Error freeing privKey\n");
341 rtn = 1;
342 }
343 CSSM_FREE(symKey);
344 }
345 /* free rptext, ctext */
346 appFreeCssmData(&rptext, CSSM_FALSE);
347 appFreeCssmData(&ctext, CSSM_FALSE);
348 return rtn;
349 }
350
351 int main(int argc, char **argv)
352 {
353 int arg;
354 char *argp;
355 unsigned loop;
356 CSSM_DATA ptext;
357 CSSM_CSP_HANDLE cspHand;
358 CSSM_BOOL stagedEncr;
359 CSSM_BOOL stagedDecr;
360 CSSM_BOOL mallocCtext;
361 CSSM_BOOL mallocPtext;
362 CSSM_BOOL refKey;
363 const char *algStr;
364 uint32 keyAlg; // CSSM_ALGID_xxx of the key
365 uint32 encrAlg; // CSSM_ALGID_xxx of the encrypt/decrypt/sign
366 int i;
367 int currAlg; // ALG_xxx
368 CSSM_DATA_PTR pPwd;
369 CSSM_DATA pwd;
370 uint32 actKeySizeInBits;
371 int rtn = 0;
372 uint32 blockSize; // for noPadding case
373 CSSM_BOOL expectEqualText;
374
375 /*
376 * User-spec'd params
377 */
378 CSSM_BOOL keySizeSpec = CSSM_FALSE; // false: use rand key size
379 SymAlg minAlg = ALG_FIRST;
380 SymAlg maxAlg = ALG_LAST;
381 unsigned loops = LOOPS_DEF;
382 CSSM_BOOL verbose = CSSM_FALSE;
383 unsigned minPtextSize = MIN_PTEXT_SIZE;
384 unsigned maxPtextSize = MAX_PTEXT_SIZE;
385 CSSM_BOOL quiet = CSSM_FALSE;
386 unsigned pauseInterval = 0;
387 uint32 mode;
388 uint32 padding;
389 CSSM_BOOL noDbOpen = CSSM_FALSE;
390 CSSM_BOOL bareCsp = CSSM_TRUE;
391 CSSM_BOOL keyGenOnly = CSSM_FALSE;
392 CSSM_BOOL noPadding = CSSM_FALSE;
393 CSSM_BOOL multiEnable = CSSM_TRUE;
394 CSSM_BOOL multiOnly = CSSM_FALSE;
395 CSSM_BOOL refKeysOnly = CSSM_FALSE;
396 CSSM_BOOL cspMallocs = CSSM_FALSE;
397
398 #if macintosh
399 argc = ccommand(&argv);
400 #endif
401 for(arg=1; arg<argc; arg++) {
402 argp = argv[arg];
403 switch(argp[0]) {
404 case 'a':
405 if(argp[1] != '=') {
406 usage(argv);
407 }
408 switch(argp[2]) {
409 case 's':
410 minAlg = maxAlg = ALG_ASC;
411 break;
412 case 'd':
413 minAlg = maxAlg = ALG_DES;
414 break;
415 case '3':
416 minAlg = maxAlg = ALG_3DES;
417 break;
418 case '2':
419 minAlg = maxAlg = ALG_RC2;
420 break;
421 case '4':
422 minAlg = maxAlg = ALG_RC4;
423 break;
424 case '5':
425 minAlg = maxAlg = ALG_RC5;
426 break;
427 case 'a':
428 minAlg = maxAlg = ALG_AES;
429 break;
430 case 'b':
431 minAlg = maxAlg = ALG_BFISH;
432 break;
433 case 'c':
434 minAlg = maxAlg = ALG_CAST;
435 break;
436 case 'n':
437 minAlg = maxAlg = ALG_NULL;
438 break;
439 default:
440 usage(argv);
441 }
442 break;
443 case 'l':
444 loops = atoi(&argp[2]);
445 break;
446 case 'n':
447 minPtextSize = atoi(&argp[2]);
448 break;
449 case 'x':
450 maxPtextSize = atoi(&argp[2]);
451 break;
452 case 'r':
453 refKeysOnly = CSSM_TRUE;
454 break;
455 case 'k':
456 actKeySizeInBits = atoi(&argp[2]);
457 keySizeSpec = CSSM_TRUE;
458 break;
459 case 'v':
460 verbose = CSSM_TRUE;
461 break;
462 case 'D':
463 bareCsp = CSSM_FALSE;
464 #if CSPDL_ALL_KEYS_ARE_REF
465 refKeysOnly = CSSM_TRUE;
466 #endif
467 break;
468 case 'q':
469 quiet = CSSM_TRUE;
470 break;
471 case 'p':
472 pauseInterval = atoi(&argp[2]);;
473 break;
474 case 'o':
475 noPadding = CSSM_TRUE;
476 break;
477 case 'd':
478 noDbOpen = CSSM_TRUE;
479 break;
480 case 'K':
481 keyGenOnly = CSSM_TRUE;
482 break;
483 case 'u':
484 multiEnable = CSSM_FALSE;
485 break;
486 case 'U':
487 multiOnly = CSSM_TRUE;
488 break;
489 case 'm':
490 cspMallocs = CSSM_TRUE;
491 break;
492 case 'h':
493 default:
494 usage(argv);
495 }
496 }
497 if(multiOnly && !multiEnable) {
498 printf("***can't specify multi disable and multi only\n");
499 exit(1);
500 }
501 if(minPtextSize > maxPtextSize) {
502 printf("***minPtextSize must be <= maxPtextSize\n");
503 usage(argv);
504 }
505 pwd.Data = (uint8 *)CSSM_MALLOC(PWD_LENGTH_MAX);
506 ptext.Data = (uint8 *)CSSM_MALLOC(maxPtextSize);
507 if(ptext.Data == NULL) {
508 printf("Insufficient heap space\n");
509 exit(1);
510 }
511 /* ptext length set in test loop */
512 printf("Starting symTest; args: ");
513 for(i=1; i<argc; i++) {
514 printf("%s ", argv[i]);
515 }
516 printf("\n");
517 cspHand = cspDlDbStartup(bareCsp, NULL);
518 if(cspHand == 0) {
519 exit(1);
520 }
521 if(pauseInterval) {
522 fpurge(stdin);
523 printf("Top of test; hit CR to proceed: ");
524 getchar();
525 }
526 for(currAlg=minAlg; currAlg<=maxAlg; currAlg++) {
527 /* some default values... */
528 mode = CSSM_ALGMODE_NONE;
529 padding = CSSM_PADDING_NONE;
530 blockSize = 0; // i.e., don't align
531 expectEqualText = CSSM_FALSE;
532 switch(currAlg) {
533 case ALG_ASC:
534 encrAlg = keyAlg = CSSM_ALGID_ASC;
535 algStr = "ASC";
536 break;
537 case ALG_DES:
538 encrAlg = keyAlg = CSSM_ALGID_DES;
539 algStr = "DES";
540 if(noPadding) {
541 mode = CSSM_ALGMODE_CBC_IV8;
542 blockSize = 8;
543 expectEqualText = CSSM_TRUE;
544 }
545 else {
546 mode = CSSM_ALGMODE_CBCPadIV8;
547 padding = CSSM_PADDING_PKCS1;
548 }
549 break;
550 case ALG_3DES:
551 /* currently the only one with different key and encr algs */
552 /* Though actually these two consts are equivalent...for now... */
553 keyAlg = CSSM_ALGID_3DES_3KEY;
554 encrAlg = CSSM_ALGID_3DES_3KEY_EDE;
555 algStr = "3DES";
556 if(noPadding) {
557 mode = CSSM_ALGMODE_CBC_IV8;
558 blockSize = 8;
559 expectEqualText = CSSM_TRUE;
560 }
561 else {
562 mode = CSSM_ALGMODE_CBCPadIV8;
563 padding = CSSM_PADDING_PKCS1;
564 }
565 break;
566 case ALG_RC2:
567 encrAlg = keyAlg = CSSM_ALGID_RC2;
568 algStr = "RC2";
569 if(noPadding) {
570 mode = CSSM_ALGMODE_CBC_IV8;
571 blockSize = 8;
572 expectEqualText = CSSM_TRUE;
573 }
574 else {
575 mode = CSSM_ALGMODE_CBCPadIV8;
576 padding = CSSM_PADDING_PKCS1; // what does padding do here?
577 }
578 break;
579 case ALG_RC4:
580 encrAlg = keyAlg = CSSM_ALGID_RC4;
581 algStr = "RC4";
582 mode = CSSM_ALGMODE_NONE;
583 expectEqualText = CSSM_TRUE; // always for RC4
584 break;
585 case ALG_RC5:
586 encrAlg = keyAlg = CSSM_ALGID_RC5;
587 algStr = "RC5";
588 if(noPadding) {
589 mode = CSSM_ALGMODE_CBC_IV8;
590 blockSize = 8;
591 expectEqualText = CSSM_TRUE;
592 }
593 else {
594 mode = CSSM_ALGMODE_CBCPadIV8;
595 padding = CSSM_PADDING_PKCS1; // eh?
596 }
597 break;
598 case ALG_AES:
599 encrAlg = keyAlg = CSSM_ALGID_AES;
600 algStr = "AES";
601 if(noPadding) {
602 mode = CSSM_ALGMODE_CBC_IV8;
603 blockSize = 16;
604 expectEqualText = CSSM_TRUE;
605 }
606 else {
607 mode = CSSM_ALGMODE_CBCPadIV8;
608 padding = CSSM_PADDING_PKCS5;
609 }
610 break;
611 case ALG_BFISH:
612 encrAlg = keyAlg = CSSM_ALGID_BLOWFISH;
613 algStr = "Blowfish";
614 if(noPadding) {
615 mode = CSSM_ALGMODE_CBC_IV8;
616 blockSize = 8;
617 expectEqualText = CSSM_TRUE;
618 }
619 else {
620 mode = CSSM_ALGMODE_CBCPadIV8;
621 padding = CSSM_PADDING_PKCS5;
622 }
623 break;
624 case ALG_CAST:
625 encrAlg = keyAlg = CSSM_ALGID_CAST;
626 algStr = "CAST";
627 if(noPadding) {
628 mode = CSSM_ALGMODE_CBC_IV8;
629 blockSize = 8;
630 expectEqualText = CSSM_TRUE;
631 }
632 else {
633 mode = CSSM_ALGMODE_CBCPadIV8;
634 padding = CSSM_PADDING_PKCS5;
635 }
636 break;
637 case ALG_NULL:
638 encrAlg = keyAlg = CSSM_ALGID_NONE;
639 algStr = "NULL";
640 if(noPadding) {
641 mode = CSSM_ALGMODE_CBC_IV8;
642 blockSize = 16;
643 expectEqualText = CSSM_TRUE;
644 }
645 else {
646 mode = CSSM_ALGMODE_CBCPadIV8;
647 padding = CSSM_PADDING_PKCS5;
648 }
649 break;
650 }
651 if(!quiet || verbose) {
652 printf("Testing alg %s\n", algStr);
653 }
654 for(loop=1; ; loop++) {
655 simpleGenData(&ptext, minPtextSize, maxPtextSize);
656 if(blockSize) {
657 /* i.e., no padding --> align ptext */
658 ptext.Length = ((ptext.Length + blockSize - 1) / blockSize) * blockSize;
659 }
660 if(!keySizeSpec) {
661 actKeySizeInBits = randKeySizeBits(keyAlg, OT_Encrypt);
662 }
663 /* else constant, spec'd by user, may be 0 (default per alg) */
664 /* mix up some random and derived keys, as well as staging and "who does
665 * the malloc?" */
666 pPwd = (loop & 1) ? &pwd : NULL;
667 if(multiEnable) {
668 if(multiOnly) {
669 stagedEncr = stagedDecr = CSSM_TRUE;
670 }
671 else {
672 stagedEncr = (loop & 2) ? CSSM_TRUE : CSSM_FALSE;
673 stagedDecr = (loop & 4) ? CSSM_TRUE : CSSM_FALSE;
674 }
675 }
676 else {
677 stagedEncr = CSSM_FALSE;
678 stagedDecr = CSSM_FALSE;
679 }
680 if(!stagedEncr && !cspMallocs) {
681 mallocCtext = (ptext.Data[0] & 1) ? CSSM_TRUE : CSSM_FALSE;
682 }
683 else {
684 mallocCtext = CSSM_FALSE;
685 }
686 if(!stagedDecr && !cspMallocs) {
687 mallocPtext = (ptext.Data[0] & 2) ? CSSM_TRUE : CSSM_FALSE;
688 }
689 else {
690 mallocPtext = CSSM_FALSE;
691 }
692 if(refKeysOnly) {
693 refKey = CSSM_TRUE;
694 }
695 else {
696 refKey = (ptext.Data[0] & 4) ? CSSM_TRUE : CSSM_FALSE;
697 }
698 #if !PBE_ENABLE
699 pPwd = NULL;
700 #endif
701 if(!quiet) {
702 if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
703 printf("..loop %d text size %lu keySizeBits %u\n",
704 loop, (unsigned long)ptext.Length, (unsigned)actKeySizeInBits);
705 if(verbose) {
706 printf(" refKey %d derive %d stagedEncr %d stagedDecr %d mallocCtext %d "
707 "mallocPtext %d\n",
708 (int)refKey, (pPwd == NULL) ? 0 : 1, (int)stagedEncr, (int)stagedDecr,
709 (int)mallocCtext, (int)mallocPtext);
710 }
711 }
712 }
713 #if PBE_ENABLE
714 if(pPwd != NULL) {
715 /* PBE - cook up random password */
716 simpleGenData(pPwd, APPLE_PBE_MIN_PASSWORD, PWD_LENGTH_MAX);
717 }
718 #endif
719
720 if(doTest(cspHand,
721 &ptext,
722 keyAlg,
723 encrAlg,
724 mode,
725 padding,
726 actKeySizeInBits,
727 refKey,
728 pPwd,
729 stagedEncr,
730 stagedDecr,
731 mallocPtext,
732 mallocCtext,
733 quiet,
734 keyGenOnly,
735 expectEqualText)) {
736 rtn = 1;
737 break;
738 }
739 if(pauseInterval && ((loop % pauseInterval) == 0)) {
740 char c;
741 fpurge(stdin);
742 printf("Hit CR to proceed, q to abort: ");
743 c = getchar();
744 if(c == 'q') {
745 goto testDone;
746 }
747 }
748 if(loops && (loop == loops)) {
749 break;
750 }
751 } /* main loop */
752 if(rtn) {
753 break;
754 }
755
756 } /* for algs */
757
758 testDone:
759 cspShutdown(cspHand, bareCsp);
760 if(pauseInterval) {
761 fpurge(stdin);
762 printf("ModuleDetach/Unload complete; hit CR to exit: ");
763 getchar();
764 }
765 if((rtn == 0) && !quiet) {
766 printf("%s test complete\n", argv[0]);
767 }
768 CSSM_FREE(pwd.Data);
769 CSSM_FREE(ptext.Data);
770 return rtn;
771 }