]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/symDelta/symDelta.c
Security-57031.10.10.tar.gz
[apple/security.git] / SecurityTests / cspxutils / symDelta / symDelta.c
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 */
35 typedef unsigned privAlg;
36 enum {
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 */
50 typedef unsigned privMode;
51 enum {
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 */
67 typedef 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
87 static 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 */
104 static 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 */
155 static 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 */
205 uint32 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 */
232 static 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 */
245 static uint8 randBit()
246 {
247 return 1 << genRand(0, 7);
248 }
249
250 /*
251 * Copy a key.
252 */
253 static 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 */
266 static 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;
322 done:
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 */
336 static 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 */
391 static 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 */
420 static 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 */
434 static 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 */
462 static 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 */
506 static 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 */
538 static 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 */
567 static 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
611 int 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
847 testDone:
848 CSSM_ModuleDetach(targs.cspHand);
849 if(!quiet && (rtn == 0)) {
850 printf("%s test complete\n", argv[0]);
851 }
852 return rtn;
853 }