]> git.saurik.com Git - apple/security.git/blob - libsecurity_cryptkit/ckutils/cfileTest/cfileTest.c
Security-55178.0.1.tar.gz
[apple/security.git] / libsecurity_cryptkit / ckutils / cfileTest / cfileTest.c
1 /* Copyright 1997 Apple Computer, Inc.
2 *
3 * cfileTest.c - General standalone CipherFile test
4 *
5 * Revision History
6 * ----------------
7 * 28 May 98 Doug Mitchell at Apple
8 * Checged to use fmalloc(), ffree(), ccommand()
9 * 24 Jun 97 Doug Mitchell at Apple
10 * Mods for Mac CodeWarrior build - standalone; no feeLib
11 * 7 Mar 97 Doug Mitchell at Apple
12 * Created.
13 */
14
15 #include "ckutilsPlatform.h"
16 #include "Crypt.h"
17 #include "feeCipherFile.h"
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <time.h>
21
22 static unsigned char *dataPool; /* plaintext comes from here */
23
24 #undef BOOL
25 #undef YES
26 #undef NO
27 #define BOOL int
28 #define YES 1
29 #define NO 0
30
31 #define LOOPS_DEF 100
32 #define MIN_EXP 2 /* for data size 10**exp */
33 #define MAX_EXP 3 /* FEED is very slow with ptext larger than this... */
34 #define DEPTH_DEFAULT FEE_DEPTH_DEFAULT
35 #define MIN_OFFSET 0
36 #define MAX_OFFSET 99
37
38 #define PASSWD_LENGTH 10
39
40 static void usage(char **argv)
41 {
42 printf("usage: %s [options]\n", argv[0]);
43 printf("Options:\n");
44 printf(" l==loops (default=%d)\n", LOOPS_DEF);
45 printf(" n=minExp (default=%d)\n", MIN_EXP);
46 printf(" x=maxExp (default=max=%d)\n", MAX_EXP);
47 printf(" D=depth (default=%d)\n", DEPTH_DEFAULT);
48 printf(" N=minOffset (default=%d)\n", MIN_OFFSET);
49 printf(" q(uiet) v(erbose)\n");
50 printf(" h(elp) I(ncrementing offset)\n");
51 exit(1);
52 }
53
54 /*
55 * ...min <= return <= max
56 */
57 static int genRand(int min, int max)
58 {
59
60 /* note random() only yields a 31-bit number... */
61
62 if(max == min) /* avoid % 1 ! */
63 return(max);
64 else
65 return(min + (RAND() % (max-min+1)));
66 }
67
68 /* end of feeLib routines */
69
70 #define MIN_ASCII ' '
71 #define MAX_ASCII '~'
72
73 static void genPasswd(unsigned char *passwd,
74 unsigned passwdLen, BOOL ascii)
75 {
76 unsigned *ip = (unsigned *)passwd;
77 unsigned intCount = passwdLen / 4;
78 int i;
79 unsigned char *cp;
80 unsigned residue = passwdLen & 0x3;
81 char ac;
82
83 if(ascii) {
84 cp = passwd;
85 ac = MIN_ASCII;
86 for(i=0; i<passwdLen; i++) {
87 *cp++ = ac++;
88 if(ac > MAX_ASCII) {
89 ac = MIN_ASCII;
90 }
91 }
92 }
93 else {
94 for (i=0; i<intCount; i++) {
95 *ip++ = RAND();
96 }
97 cp = (unsigned char *)ip;
98 for(i=0; i<residue; i++) {
99 *cp = (unsigned char)RAND();
100 }
101 }
102 }
103
104 /*
105 * Calculate random data size, fill dataPool with that many random bytes.
106 */
107 typedef enum {
108 DT_Random,
109 DT_Zero,
110 DT_ASCII,
111 DT_None /* data irrelevant; use existing pool */
112 } dataType;
113
114 static void fillDataPool(unsigned size, dataType type)
115 {
116 #ifdef __LITTLE_ENDIAN__
117 unsigned *ip;
118 unsigned intCount;
119 unsigned residue;
120 #endif
121 unsigned char *cp;
122 int i;
123 unsigned char ac;
124
125 switch(type) {
126 case DT_Zero:
127 bzero(dataPool, size);
128 break;
129 case DT_ASCII:
130 ac = MIN_ASCII;
131 cp = dataPool;
132 for(i=0; i<size; i++) {
133 *cp++ = ac++;
134 if(ac > MAX_ASCII) {
135 ac = MIN_ASCII;
136 }
137 }
138 break;
139 case DT_Random:
140 #ifdef __LITTLE_ENDIAN__
141 intCount = size >> 2;
142 ip = (unsigned *)dataPool;
143 for(i=0; i<intCount; i++) {
144 *ip++ = RAND();
145 }
146
147 residue = size & 0x3;
148 cp = (unsigned char *)ip;
149 for(i=0; i<residue; i++) {
150 *cp++ = (unsigned char)RAND();
151 }
152 #else __LITTLE_ENDIAN__
153 cp = dataPool;
154 for(i=0; i<size; i++) {
155 *cp++ = (char)RAND();
156 }
157 #endif __LITTLE_ENDIAN__
158 break;
159 case DT_None:
160 printf("fillDataPool(DT_None)\n");
161 exit(1);
162 }
163 }
164
165 static unsigned dataSizeFromExp(unsigned maxExp)
166 {
167 int size = 1;
168 while(maxExp--) { // size = 10 ** exp
169 size *= 10;
170 }
171 return size;
172 }
173
174 static int sizeOffset = MIN_OFFSET;
175
176 static unsigned char *genData(unsigned minExp,
177 unsigned maxExp,
178 dataType type,
179 BOOL incrOffset,
180 unsigned minOffset,
181 unsigned *dataLen) // RETURNED
182 {
183 int exp;
184 int offset;
185 int size;
186
187 /*
188 * Calculate "random" size : (10 ** (random exponent)) + random offset
189 */
190 exp = genRand(minExp, maxExp);
191 if(incrOffset) {
192 offset = sizeOffset++;
193 if(sizeOffset == MAX_OFFSET) {
194 sizeOffset = minOffset;
195 }
196 }
197 else {
198 offset = genRand(minOffset, MAX_OFFSET);
199 }
200 size = dataSizeFromExp(exp) + offset;
201 if(type != DT_None) {
202 fillDataPool(size, type);
203 }
204 *dataLen = size;
205 return dataPool;
206 }
207
208 static feePubKey genPrivKey(const unsigned char *privKeyData,
209 unsigned privDataLen,
210 int depth)
211 {
212 feePubKey privKey; // generic key object
213 feeReturn frtn;
214
215 privKey = feePubKeyAlloc();
216 frtn = feePubKeyInitFromPrivDataDepth(privKey,
217 (unsigned char *)privKeyData,
218 privDataLen,
219 depth,
220 1);
221 if(frtn) {
222 printf("pubKeyFromPrivDataDepth: Can't create new key (%s)\n",
223 feeReturnString(frtn));
224 exit(1);
225 }
226 return privKey;
227 }
228
229 static feePubKey genPubKey(feePubKey privKey)
230 {
231 feePubKey pubKey; // generic key object
232 feeReturn frtn;
233 char *pubString;
234 unsigned pubStringLen;
235
236 frtn = feePubKeyCreateKeyString(privKey, &pubString, &pubStringLen);
237 if(frtn) {
238 printf("feePubKeyCreateKeyString: Can't get key string (%s)\n",
239 feeReturnString(frtn));
240 exit(1);
241 }
242 pubKey = feePubKeyAlloc();
243 frtn = feePubKeyInitFromKeyString(pubKey, pubString, pubStringLen);
244 if(frtn) {
245 printf("feePubKeyInitFromKeyString: Can't create new key "
246 "(%s)\n",
247 feeReturnString(frtn));
248 feePubKeyFree(pubKey);
249 exit(1);
250 }
251 ffree(pubString);
252 return pubKey;
253 }
254
255 static char *stringFromEncrType(cipherFileEncrType encrType)
256 {
257 switch(encrType) {
258 case CFE_PublicDES: return "CFE_PublicDES";
259 case CFE_RandDES: return "CFE_RandDES";
260 case CFE_FEED: return "CFE_FEED";
261 case CFE_FEEDExp: return "CFE_FEEDExp";
262 default: return "Bogus encrType";
263 }
264 }
265
266 #define SIG_NO 0
267 #define SIG_YES 1
268 #define EXPLICIT_NO 0
269 #define EXPLICIT_YES 1
270 #define EXPLICIT_ERR 2
271
272 static void doTest(unsigned char *ptext,
273 unsigned ptextLen,
274 feePubKey myPrivKey,
275 feePubKey myPubKey,
276 feePubKey theirPrivKey,
277 feePubKey theirPubKey,
278 cipherFileEncrType encrType,
279 int doEnc64,
280 int doSig,
281 int doExplicitKey) /* EXPLICIT_ERR means do one with
282 * bad verify key */
283 {
284 feeReturn frtn;
285 unsigned char *ctext;
286 unsigned ctextLen;
287 unsigned char *dectext;
288 unsigned dectextLen;
289 unsigned outUserData = 0x1234567;
290 unsigned inUserData;
291 cipherFileEncrType inEncrType;
292 feeSigStatus sigStatus;
293 int abort = 0;
294 char instr[100];
295 feeSigStatus expSigStatus = SS_PresentValid;
296 int valid64;
297
298 /*
299 * These are tailored to specific encrTypes and doExplicitKeys
300 */
301 feePubKey sendPrivKey = myPrivKey;
302 feePubKey sendPubKey = myPubKey;
303 feePubKey recvPrivKey = theirPrivKey;
304 feePubKey recvPubKey = theirPubKey;
305
306 switch(encrType) {
307 case CFE_RandDES:
308 case CFE_FEEDExp:
309 if(!doSig) {
310 sendPrivKey = NULL; // not needed
311 }
312 break;
313 case CFE_PublicDES:
314 case CFE_FEED:
315 break;
316 default:
317 printf("Hey bozo! Give me a real encrType!\n");
318 exit(1);
319 }
320 if(!doSig) {
321 sendPubKey = NULL; // never needed
322 expSigStatus = SS_NotPresent;
323 }
324 else switch(doExplicitKey) {
325 case EXPLICIT_NO:
326 sendPubKey = NULL; // get it from cipherfile
327 break;
328 case EXPLICIT_YES:
329 break; // use myPubKey
330 case EXPLICIT_ERR:
331 if(feePubKeyIsEqual(myPubKey, theirPubKey)) {
332 printf("myPubKey = theirPubKey!\n");
333 goto errOut;
334 }
335 sendPubKey = theirPubKey; // hopefully != myPubKey!
336 expSigStatus = SS_PresentInvalid;
337 break;
338 default:
339 printf("BOGUS doExplicitKey\n");
340 exit(1);
341 }
342
343 frtn = createCipherFile(sendPrivKey,
344 recvPubKey,
345 encrType,
346 ptext,
347 ptextLen,
348 doSig,
349 doEnc64,
350 outUserData,
351 &ctext,
352 &ctextLen);
353 if(frtn) {
354 printf("createCipherFile: %s\n", feeReturnString(frtn));
355 goto errOut;
356 }
357
358 valid64 = isValidEnc64(ctext, ctextLen);
359 if(valid64 != doEnc64) {
360 printf("valid64 mismatch! exp %d got %d\n", doEnc64, valid64);
361 abort = 1;
362 }
363 frtn = parseCipherFile(recvPrivKey,
364 sendPubKey,
365 ctext,
366 ctextLen,
367 doEnc64,
368 &inEncrType,
369 &dectext,
370 &dectextLen,
371 &sigStatus,
372 &inUserData);
373 if(frtn) {
374 printf("parseCipherFile: %s\n", feeReturnString(frtn));
375 goto errOut;
376 }
377 if(inEncrType != encrType) {
378 printf("encrType mismatch exp %d got %d\n",
379 encrType, inEncrType);
380 abort = 1;
381 }
382 if(inUserData != outUserData) {
383 printf("userData mismatch exp %d got %d\n",
384 outUserData, inUserData);
385 abort = 1;
386 }
387 if(sigStatus != expSigStatus) {
388 printf("Bad sigStatus exp %d got %d\n",
389 expSigStatus, sigStatus);
390 abort = 1;
391 }
392 if(ptextLen != dectextLen) {
393 printf("ptextLen mismatch exp %d got %d\n",
394 ptextLen, dectextLen);
395 abort = 1;
396 }
397 if(bcmp(ptext, dectext, ptextLen)) {
398 printf("Data Miscompare\n");
399 abort = 1;
400 }
401 ffree(dectext);
402 ffree(ctext);
403 if(!abort) {
404 return;
405 }
406 errOut:
407 /* dump params */
408 printf("attach with debugger for more info; enter CR to quit: ");
409 gets(instr);
410 exit(1);
411
412 }
413
414 int main(int argc, char **argv)
415 {
416 int arg;
417 char *argp;
418 int loop;
419 unsigned char *ptext;
420 unsigned ptextLen;
421 unsigned char passwd1[PASSWD_LENGTH];
422 unsigned char passwd2[PASSWD_LENGTH];
423 int encrType;
424 int doEnc64;
425 feePubKey myPrivKey;
426 feePubKey theirPrivKey;
427 feePubKey myPubKey;
428 feePubKey theirPubKey;
429 unsigned maxSize;
430
431 /*
432 * User-spec'd params
433 */
434 unsigned loops = LOOPS_DEF;
435 BOOL seedSpec = NO;
436 unsigned seed;
437 BOOL quiet = NO;
438 BOOL verbose = NO;
439 unsigned minExp = MIN_EXP;
440 unsigned maxExp = MAX_EXP;
441 BOOL incrOffset = NO;
442 unsigned depth = DEPTH_DEFAULT;
443 unsigned minOffset = MIN_OFFSET;
444
445 #if macintosh
446 argc = ccommand(&argv);
447 #endif
448
449 for(arg=1; arg<argc; arg++) {
450 argp = argv[arg];
451 switch(argp[0]) {
452 case 'l':
453 loops = atoi(&argp[2]);
454 break;
455 case 'n':
456 minExp = atoi(&argp[2]);
457 break;
458 case 'D':
459 depth = atoi(&argp[2]);
460 break;
461 case 'N':
462 minOffset = atoi(&argp[2]);
463 if(minOffset > MAX_OFFSET) {
464 minOffset = MIN_OFFSET;
465 }
466 sizeOffset = minOffset;
467 break;
468 case 'x':
469 maxExp = atoi(&argp[2]);
470 if(maxExp > MAX_EXP) {
471 usage(argv);
472 }
473 break;
474 case 's':
475 seed = atoi(&argp[2]);
476 seedSpec = YES;
477 break;
478 case 'I':
479 incrOffset = YES;
480 break;
481 case 'q':
482 quiet = YES;
483 break;
484 case 'v':
485 verbose = YES;
486 break;
487 case 'h':
488 default:
489 usage(argv);
490 }
491 }
492
493 if(seedSpec == NO) {
494 time((unsigned long *)(&seed));
495 }
496 SRAND(seed);
497 maxSize = dataSizeFromExp(maxExp) + MAX_OFFSET + 8;
498 dataPool = fmalloc(maxSize);
499
500 printf("Starting cfileTest: loops %d seed %d depth %d\n",
501 loops, seed, depth);
502
503 for(loop=1; ; loop++) {
504
505 ptext = genData(minExp, maxExp, DT_Random, incrOffset,
506 minOffset, &ptextLen);
507 if(!quiet) {
508 printf("..loop %d plaintext size %d\n", loop, ptextLen);
509 }
510
511 /*
512 * Generate a whole bunch of keys
513 */
514 genPasswd(passwd1, PASSWD_LENGTH, NO); // not ascii!
515 genPasswd(passwd2, PASSWD_LENGTH, NO);
516 myPrivKey = genPrivKey(passwd1, PASSWD_LENGTH, depth);
517 theirPrivKey = genPrivKey(passwd2, PASSWD_LENGTH, depth);
518 myPubKey = genPubKey(myPrivKey);
519 theirPubKey = genPubKey(theirPrivKey);
520
521 for(encrType=CFE_PublicDES;
522 encrType<=CFE_FEEDExp;
523 encrType++) {
524
525 if(verbose) {
526 printf(" ..%s\n", stringFromEncrType(encrType));
527 }
528 for(doEnc64=0; doEnc64<2; doEnc64++) {
529 if(verbose) {
530 printf(" ..doEnc64 %d\n", doEnc64);
531 }
532
533 if(verbose) {
534 printf(" ..no sig\n");
535 }
536 doTest(ptext, ptextLen, myPrivKey, myPubKey,
537 theirPrivKey, theirPubKey,
538 encrType, doEnc64, SIG_NO, EXPLICIT_NO);
539
540 if(verbose) {
541 printf(" ..sig, implicit sendPubKey\n");
542 }
543 doTest(ptext, ptextLen, myPrivKey, myPubKey,
544 theirPrivKey, theirPubKey,
545 encrType, doEnc64, SIG_YES, EXPLICIT_NO);
546
547 if(verbose) {
548 printf(" ..sig, explicit sendPubKey\n");
549 }
550 doTest(ptext, ptextLen, myPrivKey, myPubKey,
551 theirPrivKey, theirPubKey,
552 encrType, doEnc64, SIG_YES, EXPLICIT_YES);
553
554 if(verbose) {
555 printf(" ..sig, force error\n");
556 }
557 doTest(ptext, ptextLen, myPrivKey, myPubKey,
558 theirPrivKey, theirPubKey,
559 encrType, doEnc64, SIG_YES, EXPLICIT_ERR);
560
561 } /* for doEnc64 */
562 } /* for encrType */
563
564 feePubKeyFree(myPrivKey);
565 feePubKeyFree(myPubKey);
566 feePubKeyFree(theirPrivKey);
567 feePubKeyFree(theirPubKey);
568 if(loops) {
569 if(loop == loops) {
570 break;
571 }
572 }
573 } /* main loop */
574
575 if(!quiet) {
576 printf("cfile test complete\n");
577 }
578 return 0;
579 }