]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
1 | /* |
2 | * asymCompat.c - test compatibilty of two different implementations of a | |
3 | * RSA and DSA - one in the standard AppleCSP, one in BSAFE. | |
4 | */ | |
5 | ||
6 | #include <stdlib.h> | |
7 | #include <stdio.h> | |
8 | #include <time.h> | |
9 | #include <Security/cssm.h> | |
10 | #include <Security/cssmapple.h> | |
11 | #include "cspwrap.h" | |
12 | #include "common.h" | |
13 | #include "bsafeUtils.h" | |
14 | #include <string.h> | |
15 | #include "cspdlTesting.h" | |
16 | ||
17 | /* | |
18 | * Defaults. | |
19 | */ | |
20 | #define OLOOPS_DEF 10 /* outer loops, one set of keys per loop */ | |
21 | #define SIG_LOOPS_DEF 100 /* sig loops */ | |
22 | #define ENC_LOOPS_DEF 100 /* encrypt/decrypt loops */ | |
23 | #define MAX_TEXT_SIZE 1025 | |
24 | ||
25 | #define LOOP_NOTIFY 20 | |
26 | ||
27 | static void usage(char **argv) | |
28 | { | |
29 | printf("usage: %s [options]\n", argv[0]); | |
30 | printf(" Options:\n"); | |
31 | printf(" a=algorithm (r=RSA; d=DSA; default=both)\n"); | |
32 | printf(" l=outerloops (default=%d; 0=forever)\n", OLOOPS_DEF); | |
33 | printf(" s=sigLoops (default=%d)\n", SIG_LOOPS_DEF); | |
34 | printf(" e=encryptLoops (default=%d)\n", ENC_LOOPS_DEF); | |
35 | printf(" k=keySizeInBits; default is random\n"); | |
36 | printf(" S (sign/verify only)\n"); | |
37 | printf(" E (encrypt/decrypt only)\n"); | |
38 | printf(" r (generate ref keys)\n"); | |
39 | printf(" R (generate public ref keys)\n"); | |
40 | printf(" p=pauseInterval (default=0, no pause)\n"); | |
41 | printf(" D (CSP/DL; default = bare CSP)\n"); | |
42 | printf(" v(erbose)\n"); | |
43 | printf(" q(uiet)\n"); | |
44 | printf(" h(elp)\n"); | |
45 | exit(1); | |
46 | } | |
47 | ||
48 | static const char *algToStr(CSSM_ALGORITHMS sigAlg) | |
49 | { | |
50 | switch(sigAlg) { | |
51 | case CSSM_ALGID_RSA: return "RSA"; | |
52 | case CSSM_ALGID_DSA: return "DSA"; | |
53 | case CSSM_ALGID_SHA1WithRSA: return "SHA1WithRSA"; | |
54 | case CSSM_ALGID_MD5WithRSA: return "MD5WithRSA"; | |
55 | case CSSM_ALGID_SHA1WithDSA: return "SHA1WithDSA"; | |
56 | default: | |
57 | printf("***Unknown sigAlg\n"); | |
58 | exit(1); | |
59 | } | |
60 | /* NOT REACHED */ | |
61 | return ""; | |
62 | } | |
63 | ||
64 | /* | |
65 | * CDSA private key decrypt with blinding option. | |
66 | */ | |
67 | static CSSM_RETURN _cspDecrypt(CSSM_CSP_HANDLE cspHand, | |
68 | uint32 algorithm, // CSSM_ALGID_FEED, etc. | |
69 | uint32 mode, // CSSM_ALGMODE_CBC, etc. - only for symmetric algs | |
70 | CSSM_PADDING padding, // CSSM_PADDING_PKCS1, etc. | |
71 | CSSM_BOOL blinding, | |
72 | const CSSM_KEY *key, // public or session key | |
73 | const CSSM_DATA *ctext, | |
74 | CSSM_DATA_PTR ptext) // RETURNED | |
75 | { | |
76 | CSSM_CC_HANDLE cryptHand; | |
77 | CSSM_RETURN crtn; | |
78 | CSSM_RETURN ocrtn = CSSM_OK; | |
79 | CSSM_SIZE bytesDecrypted; | |
80 | CSSM_DATA remData = {0, NULL}; | |
81 | ||
82 | cryptHand = genCryptHandle(cspHand, | |
83 | algorithm, | |
84 | mode, | |
85 | padding, | |
86 | key, | |
87 | NULL, // pubKey, | |
88 | NULL, // iv, | |
89 | 0, // effectiveKeySizeInBits, | |
90 | 0); // rounds | |
91 | if(cryptHand == 0) { | |
92 | return CSSMERR_CSP_INTERNAL_ERROR; | |
93 | } | |
94 | if(blinding) { | |
95 | CSSM_CONTEXT_ATTRIBUTE newAttr; | |
96 | newAttr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING; | |
97 | newAttr.AttributeLength = sizeof(uint32); | |
98 | newAttr.Attribute.Uint32 = 1; | |
99 | crtn = CSSM_UpdateContextAttributes(cryptHand, 1, &newAttr); | |
100 | if(crtn) { | |
101 | printError("CSSM_UpdateContextAttributes", crtn); | |
102 | return crtn; | |
103 | } | |
104 | } | |
105 | ||
106 | crtn = CSSM_DecryptData(cryptHand, | |
107 | ctext, | |
108 | 1, | |
109 | ptext, | |
110 | 1, | |
111 | &bytesDecrypted, | |
112 | &remData); | |
113 | if(crtn == CSSM_OK) { | |
114 | // NOTE: We return the proper length in ptext.... | |
115 | ptext->Length = bytesDecrypted; | |
116 | ||
117 | // FIXME - sometimes get mallocd RemData here, but never any valid data | |
118 | // there...side effect of CSPFullPluginSession's buffer handling logic; | |
119 | // but will we ever actually see valid data in RemData? So far we never | |
120 | // have.... | |
121 | if(remData.Data != NULL) { | |
122 | appFree(remData.Data, NULL); | |
123 | } | |
124 | } | |
125 | else { | |
126 | printError("CSSM_DecryptData", crtn); | |
127 | ocrtn = crtn; | |
128 | } | |
129 | crtn = CSSM_DeleteContext(cryptHand); | |
130 | if(crtn) { | |
131 | printError("CSSM_DeleteContext", crtn); | |
132 | ocrtn = crtn; | |
133 | } | |
134 | return ocrtn; | |
135 | } | |
136 | ||
137 | /* sign with RSA blinging option */ | |
138 | static CSSM_RETURN _cspSign(CSSM_CSP_HANDLE cspHand, | |
139 | uint32 algorithm, // CSSM_ALGID_FEE_MD5, etc. | |
140 | CSSM_KEY_PTR key, // private key | |
141 | const CSSM_DATA *text, | |
142 | CSSM_BOOL rsaBlinding, | |
143 | CSSM_DATA_PTR sig) // RETURNED | |
144 | { | |
145 | CSSM_CC_HANDLE sigHand; | |
146 | CSSM_RETURN crtn; | |
147 | CSSM_RETURN ocrtn = CSSM_OK; | |
148 | const CSSM_DATA *ptext; | |
149 | CSSM_DATA digest = {0, NULL}; | |
150 | CSSM_ALGORITHMS digestAlg = CSSM_ALGID_NONE; | |
151 | ||
152 | /* handle special cases for raw sign */ | |
153 | switch(algorithm) { | |
154 | case CSSM_ALGID_SHA1: | |
155 | digestAlg = CSSM_ALGID_SHA1; | |
156 | algorithm = CSSM_ALGID_RSA; | |
157 | break; | |
158 | case CSSM_ALGID_MD5: | |
159 | digestAlg = CSSM_ALGID_MD5; | |
160 | algorithm = CSSM_ALGID_RSA; | |
161 | break; | |
162 | case CSSM_ALGID_DSA: | |
163 | digestAlg = CSSM_ALGID_SHA1; | |
164 | algorithm = CSSM_ALGID_DSA; | |
165 | break; | |
166 | default: | |
167 | break; | |
168 | } | |
169 | if(digestAlg != CSSM_ALGID_NONE) { | |
170 | crtn = cspDigest(cspHand, | |
171 | digestAlg, | |
172 | CSSM_FALSE, // mallocDigest | |
173 | text, | |
174 | &digest); | |
175 | if(crtn) { | |
176 | return crtn; | |
177 | } | |
178 | /* sign digest with raw RSA/DSA */ | |
179 | ptext = &digest; | |
180 | } | |
181 | else { | |
182 | ptext = text; | |
183 | } | |
184 | crtn = CSSM_CSP_CreateSignatureContext(cspHand, | |
185 | algorithm, | |
186 | NULL, // passPhrase | |
187 | key, | |
188 | &sigHand); | |
189 | if(crtn) { | |
190 | printError("CSSM_CSP_CreateSignatureContext (1)", crtn); | |
191 | return crtn; | |
192 | } | |
193 | if(rsaBlinding) { | |
194 | CSSM_CONTEXT_ATTRIBUTE newAttr; | |
195 | newAttr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING; | |
196 | newAttr.AttributeLength = sizeof(uint32); | |
197 | newAttr.Attribute.Uint32 = 1; | |
198 | crtn = CSSM_UpdateContextAttributes(sigHand, 1, &newAttr); | |
199 | if(crtn) { | |
200 | printError("CSSM_UpdateContextAttributes", crtn); | |
201 | return crtn; | |
202 | } | |
203 | } | |
204 | crtn = CSSM_SignData(sigHand, | |
205 | ptext, | |
206 | 1, | |
207 | digestAlg, | |
208 | sig); | |
209 | if(crtn) { | |
210 | printError("CSSM_SignData", crtn); | |
211 | ocrtn = crtn; | |
212 | } | |
213 | crtn = CSSM_DeleteContext(sigHand); | |
214 | if(crtn) { | |
215 | printError("CSSM_DeleteContext", crtn); | |
216 | ocrtn = crtn; | |
217 | } | |
218 | if(digest.Data != NULL) { | |
219 | CSSM_FREE(digest.Data); | |
220 | } | |
221 | return ocrtn; | |
222 | } | |
223 | ||
224 | ||
225 | /* | |
226 | * Sign/verify test. | |
227 | * | |
228 | * for specified numLoops { | |
229 | * generate random text; | |
230 | * sign with BSAFE priv key, verify with CDSA pub key; | |
231 | * sign with CDSA priv key, verify with BSAFE pub key; | |
232 | * } | |
233 | */ | |
234 | static int sigTest( | |
235 | CSSM_CSP_HANDLE cspHand, | |
236 | unsigned numLoops, | |
237 | ||
238 | /* one matched key pair */ | |
239 | BU_KEY bsafePrivKey, | |
240 | CSSM_KEY_PTR cdsaPubKey, | |
241 | ||
242 | /* another matched key pair */ | |
243 | CSSM_KEY_PTR cdsaPrivKey, | |
244 | BU_KEY bsafePubKey, | |
245 | ||
246 | CSSM_DATA_PTR ptext, | |
247 | unsigned maxPtextSize, | |
248 | CSSM_ALGORITHMS sigAlg, | |
249 | CSSM_BOOL rsaBlinding, | |
250 | CSSM_BOOL quiet, | |
251 | CSSM_BOOL verbose) | |
252 | { | |
253 | CSSM_RETURN crtn; | |
254 | CSSM_DATA sig = {0, NULL}; | |
255 | unsigned loop; | |
256 | uint32 keySizeInBits = cdsaPrivKey->KeyHeader.LogicalKeySizeInBits; | |
257 | ||
258 | if(!quiet) { | |
259 | printf(" ...sig alg %s keySize %u\n", algToStr(sigAlg), (unsigned)keySizeInBits); | |
260 | } | |
261 | for(loop=0; loop<numLoops; loop++) { | |
262 | simpleGenData(ptext, 1, maxPtextSize); | |
263 | if(!quiet) { | |
264 | if(verbose || ((loop % LOOP_NOTIFY) == 0)) { | |
265 | printf(" ...loop %d keySize %u textSize %lu\n", | |
266 | loop, (unsigned)cdsaPrivKey->KeyHeader.LogicalKeySizeInBits, | |
267 | (unsigned long)ptext->Length); | |
268 | } | |
269 | } | |
270 | ||
271 | /* sign with BSAFE, verify with CDSA */ | |
272 | crtn = buSign(bsafePrivKey, | |
273 | sigAlg, | |
274 | ptext, | |
275 | keySizeInBits, | |
276 | &sig); | |
277 | if(crtn) { | |
278 | return testError(quiet); | |
279 | } | |
280 | crtn = cspSigVerify(cspHand, | |
281 | sigAlg, | |
282 | cdsaPubKey, | |
283 | ptext, | |
284 | &sig, | |
285 | CSSM_OK); | |
286 | if(crtn) { | |
287 | printf("***ERROR: Sign with BSAFE, vfy with CDSA, alg %s\n", | |
288 | algToStr(sigAlg)); | |
289 | if(testError(quiet)) { | |
290 | return 1; | |
291 | } | |
292 | } | |
293 | appFreeCssmData(&sig, CSSM_FALSE); | |
294 | ||
295 | /* sign with CDSA, verify with BSAFE */ | |
296 | crtn = _cspSign(cspHand, | |
297 | sigAlg, | |
298 | cdsaPrivKey, | |
299 | ptext, | |
300 | rsaBlinding, | |
301 | &sig); | |
302 | if(crtn) { | |
303 | return testError(quiet); | |
304 | } | |
305 | crtn = buVerify(bsafePubKey, | |
306 | sigAlg, | |
307 | ptext, | |
308 | &sig); | |
309 | if(crtn) { | |
310 | printf("***ERROR: Sign with CDSA, vfy with BSAFE, alg %s\n", | |
311 | algToStr(sigAlg)); | |
312 | if(testError(quiet)) { | |
313 | return 1; | |
314 | } | |
315 | } | |
316 | appFreeCssmData(&sig, CSSM_FALSE); | |
317 | } | |
318 | return CSSM_OK; | |
319 | } | |
320 | ||
321 | /* | |
322 | * RSA Encrypt/decrypt test. | |
323 | * | |
324 | * for specified numLoops { | |
325 | * generate random text; | |
326 | * encrypt with BSAFE pub key, decrypt with CDSA priv key, verify; | |
327 | * encrypt with CDSA pub key, decrypt with BSAFE priv key, verify; | |
328 | * } | |
329 | */ | |
330 | static int encryptTest( | |
331 | CSSM_CSP_HANDLE cspHand, | |
332 | unsigned numLoops, | |
333 | ||
334 | /* one matched key pair */ | |
335 | BU_KEY bsafePrivKey, | |
336 | CSSM_KEY_PTR cdsaPubKey, | |
337 | ||
338 | /* another matched key pair */ | |
339 | CSSM_KEY_PTR cdsaPrivKey, | |
340 | BU_KEY bsafePubKey, | |
341 | ||
342 | CSSM_DATA_PTR ptext, | |
343 | unsigned maxPtextSize, | |
344 | CSSM_BOOL rsaBlinding, | |
345 | CSSM_BOOL quiet, | |
346 | CSSM_BOOL verbose) | |
347 | { | |
348 | CSSM_RETURN crtn; | |
349 | CSSM_DATA ctext = {0, NULL}; | |
350 | CSSM_DATA rptext = {0, NULL}; | |
351 | unsigned loop; | |
352 | unsigned actKeySizeBytes; | |
353 | ||
354 | actKeySizeBytes = cdsaPrivKey->KeyHeader.LogicalKeySizeInBits / 8; | |
355 | if(actKeySizeBytes < 12) { | |
356 | printf("***Key with %u key bits is too small for RSA encrypt\n", | |
357 | (unsigned)cdsaPrivKey->KeyHeader.LogicalKeySizeInBits); | |
358 | return 1; | |
359 | } | |
360 | if(maxPtextSize > (actKeySizeBytes - 11)) { | |
361 | maxPtextSize = actKeySizeBytes - 11; | |
362 | } | |
363 | if(!quiet) { | |
364 | printf(" ...encr alg RSA\n"); | |
365 | } | |
366 | for(loop=0; loop<numLoops; loop++) { | |
367 | simpleGenData(ptext, 1, maxPtextSize); | |
368 | if(!quiet) { | |
369 | if(verbose || ((loop % LOOP_NOTIFY) == 0)) { | |
370 | printf(" ...loop %d keySize %u textSize %lu\n", | |
371 | loop, (unsigned)cdsaPrivKey->KeyHeader.LogicalKeySizeInBits, | |
372 | (unsigned long)ptext->Length); | |
373 | } | |
374 | } | |
375 | ||
376 | /* encrypt with BSAFE, decrypt with CDSA */ | |
377 | crtn = buEncryptDecrypt(bsafePubKey, | |
378 | CSSM_TRUE, // encrypt | |
379 | CSSM_ALGID_RSA, | |
380 | CSSM_ALGMODE_NONE, | |
381 | NULL, // iv | |
382 | cdsaPrivKey->KeyHeader.LogicalKeySizeInBits, | |
383 | 0, // rounds | |
384 | ptext, | |
385 | &ctext); | |
386 | if(crtn) { | |
387 | return testError(quiet); | |
388 | } | |
389 | crtn = _cspDecrypt(cspHand, | |
390 | CSSM_ALGID_RSA, | |
391 | CSSM_ALGMODE_NONE, | |
392 | CSSM_PADDING_PKCS1, | |
393 | rsaBlinding, | |
394 | cdsaPrivKey, | |
395 | &ctext, | |
396 | &rptext); | |
397 | if(crtn) { | |
398 | printf("***ERROR: encrypt with BSAFE, decrypt with CDSA\n"); | |
399 | return testError(quiet); | |
400 | } | |
401 | if(!appCompareCssmData(ptext, &rptext)) { | |
402 | printf("***DATA MISCOMPARE: encrypt with BSAFE, decrypt with CDSA\n"); | |
403 | return testError(quiet); | |
404 | } | |
405 | appFreeCssmData(&ctext, CSSM_FALSE); | |
406 | appFreeCssmData(&rptext, CSSM_FALSE); | |
407 | ||
408 | /* encrypt with CDSA, decrypt with BSAFE */ | |
409 | crtn = cspEncrypt(cspHand, | |
410 | CSSM_ALGID_RSA, | |
411 | CSSM_ALGMODE_NONE, | |
412 | CSSM_PADDING_PKCS1, | |
413 | cdsaPubKey, | |
414 | NULL, // (FEE) pub key | |
415 | 0, // effectiveKeyBits | |
416 | 0, // rounds | |
417 | NULL, // IV | |
418 | ptext, | |
419 | &ctext, | |
420 | CSSM_FALSE); // mallocCtext | |
421 | if(crtn) { | |
422 | return testError(quiet); | |
423 | } | |
424 | crtn = buEncryptDecrypt(bsafePrivKey, | |
425 | CSSM_FALSE, // encrypt | |
426 | CSSM_ALGID_RSA, | |
427 | CSSM_ALGMODE_NONE, | |
428 | NULL, // iv | |
429 | cdsaPrivKey->KeyHeader.LogicalKeySizeInBits, | |
430 | 0, // rounds | |
431 | &ctext, | |
432 | &rptext); | |
433 | if(crtn) { | |
434 | printf("***ERROR: encrypt with CDSA, decrypt with BSAFE\n"); | |
435 | return testError(quiet); | |
436 | } | |
437 | if(!appCompareCssmData(ptext, &rptext)) { | |
438 | printf("***DATA MISCOMPARE: encrypt with CDSA, decrypt with BSAFE\n"); | |
439 | return testError(quiet); | |
440 | } | |
441 | appFreeCssmData(&ctext, CSSM_FALSE); | |
442 | appFreeCssmData(&rptext, CSSM_FALSE); | |
443 | } | |
444 | return CSSM_OK; | |
445 | } | |
446 | ||
447 | static int doTest( | |
448 | CSSM_CSP_HANDLE cspHand, | |
449 | CSSM_ALGORITHMS keyAlg, // RSA/DSA | |
450 | CSSM_ALGORITHMS sigAlg, | |
451 | unsigned sigLoops, // may be zero | |
452 | unsigned encrLoops, // ditto; it will be zero for DSA | |
453 | CSSM_BOOL rsaBlinding, | |
454 | CSSM_DATA_PTR ptext, | |
455 | unsigned maxPtextSize, | |
456 | uint32 keySizeInBits, // 0 --> random per alg | |
457 | CSSM_BOOL pubRefKeys, | |
458 | CSSM_BOOL privRefKeys, | |
459 | CSSM_BOOL bareCsp, // for other workarounds | |
460 | CSSM_BOOL quiet, | |
461 | CSSM_BOOL verbose) | |
462 | { | |
463 | CSSM_KEY cdsaGenPubKey; | |
464 | CSSM_KEY cdsaGenPrivKey; // only used to create bsafeDerivePrivKey | |
465 | CSSM_KEY cdsaTempKey; // raw key if privRefKeys true | |
466 | CSSM_KEY cdsaDerivePrivKey; // same as bsafeGenPrivKey | |
467 | BU_KEY bsafeGenPubKey; | |
468 | BU_KEY bsafeGenPrivKey; // only used to create cdsaDerivePrivKey | |
469 | BU_KEY bsafeDerivePrivKey; // same as cdsaGenPrivKey | |
470 | unsigned actKeySizeBits; | |
471 | CSSM_RETURN crtn; | |
472 | int rtn; | |
473 | ||
474 | if(!keySizeInBits) { | |
475 | /* random key size */ | |
476 | actKeySizeBits = randKeySizeBits(keyAlg, OT_Encrypt); | |
477 | } | |
478 | else { | |
479 | /* caller/user specified */ | |
480 | actKeySizeBits = keySizeInBits; | |
481 | } | |
482 | if(verbose) { | |
483 | printf(" ...generating %s key pair, keySize %d bits...\n", | |
484 | algToStr(keyAlg), actKeySizeBits); | |
485 | } | |
486 | ||
487 | /* | |
488 | * Generate two keypairs | |
489 | */ | |
490 | if(keyAlg == CSSM_ALGID_DSA) { | |
491 | CSSM_BOOL doGenParams; | |
492 | ||
493 | if(bareCsp || CSPDL_DSA_GEN_PARAMS) { | |
494 | doGenParams = CSSM_TRUE; | |
495 | } | |
496 | else { | |
497 | /* CSPDL - no gen params */ | |
498 | doGenParams = CSSM_FALSE; | |
499 | } | |
500 | crtn = cspGenDSAKeyPair(cspHand, | |
501 | "foo", | |
502 | 3, | |
503 | actKeySizeBits, | |
504 | &cdsaGenPubKey, | |
505 | pubRefKeys, | |
506 | CSSM_KEYUSE_ANY, | |
507 | CSSM_KEYBLOB_RAW_FORMAT_NONE, | |
508 | &cdsaGenPrivKey, | |
509 | privRefKeys, | |
510 | CSSM_KEYUSE_SIGN, | |
511 | CSSM_KEYBLOB_RAW_FORMAT_NONE, | |
512 | doGenParams, // genParams | |
513 | NULL); // params | |
514 | } | |
515 | else { | |
516 | crtn = cspGenKeyPair(cspHand, | |
517 | keyAlg, | |
518 | "foo", | |
519 | 3, | |
520 | actKeySizeBits, | |
521 | &cdsaGenPubKey, | |
522 | pubRefKeys, | |
523 | CSSM_KEYUSE_ANY, | |
524 | CSSM_KEYBLOB_RAW_FORMAT_NONE, | |
525 | &cdsaGenPrivKey, | |
526 | privRefKeys, | |
527 | CSSM_KEYUSE_ANY, | |
528 | CSSM_KEYBLOB_RAW_FORMAT_NONE, | |
529 | CSSM_FALSE); // genSeed not used | |
530 | } | |
531 | if(crtn) { | |
532 | return testError(quiet); | |
533 | } | |
534 | crtn = buGenKeyPair(actKeySizeBits, | |
535 | keyAlg, | |
536 | &bsafeGenPubKey, | |
537 | &bsafeGenPrivKey); | |
538 | if(crtn) { | |
539 | return testError(quiet); | |
540 | } | |
541 | ||
542 | /* | |
543 | * Convert private keys to other library. | |
544 | * NOTE: the reason we're only converting private keys is solely due to the | |
545 | * fact that BSAFE does not handle PKCS1 formatted public key blobs. Very odd. | |
546 | * But it's too much of a pain to re-implement that wheel here, and SSL and | |
547 | * cert handling in general verify the CSP's PKCS1-style public key handling. | |
548 | */ | |
549 | if(privRefKeys) { | |
550 | /* first generate a temporary raw CDSA key */ | |
551 | crtn = buBsafePrivKeyToCdsa(keyAlg, | |
552 | actKeySizeBits, | |
553 | bsafeGenPrivKey, | |
554 | &cdsaTempKey); | |
555 | if(crtn) { | |
556 | return testError(quiet); | |
557 | } | |
558 | ||
559 | /* convert it to the ref key we'll actually use */ | |
560 | crtn = cspRawKeyToRef(cspHand, &cdsaTempKey, &cdsaDerivePrivKey); | |
561 | cspFreeKey(cspHand, &cdsaTempKey); | |
562 | } | |
563 | else { | |
564 | crtn = buBsafePrivKeyToCdsa(keyAlg, | |
565 | actKeySizeBits, | |
566 | bsafeGenPrivKey, | |
567 | &cdsaDerivePrivKey); | |
568 | } | |
569 | if(crtn) { | |
570 | return testError(quiet); | |
571 | } | |
572 | if(privRefKeys) { | |
573 | /* we have a CDSA priv ref key; convert it to raw format */ | |
574 | crtn = cspRefKeyToRaw(cspHand, &cdsaGenPrivKey, &cdsaTempKey); | |
575 | if(crtn) { | |
576 | return testError(quiet); | |
577 | } | |
578 | /* now convert it to BSAFE */ | |
579 | crtn = buCdsaPrivKeyToBsafe(&cdsaTempKey, &bsafeDerivePrivKey); | |
580 | cspFreeKey(cspHand, &cdsaTempKey); | |
581 | } | |
582 | else { | |
583 | crtn = buCdsaPrivKeyToBsafe(&cdsaGenPrivKey, &bsafeDerivePrivKey); | |
584 | } | |
585 | if(crtn) { | |
586 | return testError(quiet); | |
587 | } | |
588 | ||
589 | if(sigLoops) { | |
590 | rtn = sigTest(cspHand, | |
591 | sigLoops, | |
592 | bsafeDerivePrivKey, | |
593 | &cdsaGenPubKey, | |
594 | &cdsaDerivePrivKey, | |
595 | bsafeGenPubKey, | |
596 | ptext, | |
597 | maxPtextSize, | |
598 | sigAlg, | |
599 | rsaBlinding, | |
600 | quiet, | |
601 | verbose); | |
602 | if(rtn) { | |
603 | return rtn; | |
604 | } | |
605 | } | |
606 | ||
607 | if(encrLoops) { | |
608 | rtn = encryptTest(cspHand, | |
609 | encrLoops, | |
610 | bsafeDerivePrivKey, | |
611 | &cdsaGenPubKey, | |
612 | &cdsaDerivePrivKey, | |
613 | bsafeGenPubKey, | |
614 | ptext, | |
615 | maxPtextSize, | |
616 | rsaBlinding, | |
617 | quiet, | |
618 | verbose); | |
619 | if(rtn) { | |
620 | return rtn; | |
621 | } | |
622 | } | |
623 | ||
624 | /* free all six keys */ | |
625 | buFreeKey(bsafeGenPubKey); | |
626 | buFreeKey(bsafeGenPrivKey); | |
627 | buFreeKey(bsafeDerivePrivKey); | |
628 | cspFreeKey(cspHand, &cdsaGenPubKey); | |
629 | cspFreeKey(cspHand, &cdsaGenPrivKey); | |
630 | cspFreeKey(cspHand, &cdsaDerivePrivKey); | |
631 | return 0; | |
632 | } | |
633 | ||
634 | int main(int argc, char **argv) | |
635 | { | |
636 | int arg; | |
637 | char *argp; | |
638 | unsigned loop; | |
639 | CSSM_DATA ptext; | |
640 | CSSM_CSP_HANDLE cspHand; | |
641 | int i; | |
642 | int rtn = 0; | |
643 | ||
644 | /* | |
645 | * User-spec'd params | |
646 | */ | |
647 | uint32 keySizeInBits = 0; | |
648 | unsigned oloops = OLOOPS_DEF; | |
649 | unsigned sigLoops = SIG_LOOPS_DEF; | |
650 | unsigned encrLoops = ENC_LOOPS_DEF; | |
651 | CSSM_BOOL verbose = CSSM_FALSE; | |
652 | CSSM_BOOL quiet = CSSM_FALSE; | |
653 | unsigned pauseInterval = 0; | |
654 | CSSM_BOOL bareCsp = CSSM_TRUE; | |
655 | CSSM_BOOL doDSA = CSSM_TRUE; | |
656 | CSSM_BOOL doRSA = CSSM_TRUE; | |
657 | CSSM_BOOL pubRefKeys = CSSM_FALSE; | |
658 | CSSM_BOOL privRefKeys = CSSM_FALSE; | |
659 | ||
660 | for(arg=1; arg<argc; arg++) { | |
661 | argp = argv[arg]; | |
662 | switch(argp[0]) { | |
663 | case 'a': | |
664 | if(argp[1] != '=') { | |
665 | usage(argv); | |
666 | } | |
667 | switch(argp[2]) { | |
668 | case 'r': | |
669 | doDSA = CSSM_FALSE; | |
670 | break; | |
671 | case 'd': | |
672 | doRSA = CSSM_FALSE; | |
673 | break; | |
674 | default: | |
675 | usage(argv); | |
676 | } | |
677 | break; | |
678 | case 'l': | |
679 | oloops = atoi(&argp[2]); | |
680 | break; | |
681 | case 's': | |
682 | sigLoops = atoi(&argp[2]); | |
683 | break; | |
684 | case 'e': | |
685 | encrLoops = atoi(&argp[2]); | |
686 | break; | |
687 | case 'k': | |
688 | keySizeInBits = atoi(&argp[2]); | |
689 | break; | |
690 | case 'v': | |
691 | verbose = CSSM_TRUE; | |
692 | break; | |
693 | case 'r': | |
694 | privRefKeys = CSSM_TRUE; | |
695 | break; | |
696 | case 'R': | |
697 | pubRefKeys = CSSM_TRUE; | |
698 | break; | |
699 | case 'D': | |
700 | bareCsp = CSSM_FALSE; | |
701 | #if CSPDL_ALL_KEYS_ARE_REF | |
702 | privRefKeys = CSSM_TRUE; | |
703 | pubRefKeys = CSSM_TRUE; | |
704 | #endif | |
705 | break; | |
706 | case 'E': | |
707 | sigLoops = 0; | |
708 | break; | |
709 | case 'S': | |
710 | encrLoops = 0; | |
711 | break; | |
712 | case 'q': | |
713 | quiet = CSSM_TRUE; | |
714 | break; | |
715 | case 'p': | |
716 | pauseInterval = atoi(&argp[2]);; | |
717 | break; | |
718 | case 'h': | |
719 | default: | |
720 | usage(argv); | |
721 | } | |
722 | } | |
723 | ptext.Data = (uint8 *)CSSM_MALLOC(MAX_TEXT_SIZE); | |
724 | if(ptext.Data == NULL) { | |
725 | printf("Insufficient heap space\n"); | |
726 | exit(1); | |
727 | } | |
728 | /* ptext length set in inner test loops */ | |
729 | ||
730 | printf("Starting asymCompat; args: "); | |
731 | for(i=1; i<argc; i++) { | |
732 | printf("%s ", argv[i]); | |
733 | } | |
734 | printf("\n"); | |
735 | cspHand = cspDlDbStartup(bareCsp, NULL); | |
736 | if(cspHand == 0) { | |
737 | exit(1); | |
738 | } | |
739 | if(pauseInterval) { | |
740 | fpurge(stdin); | |
741 | printf("Top of test; hit CR to proceed: "); | |
742 | getchar(); | |
743 | } | |
744 | for(loop=1; ; loop++) { | |
745 | if(!quiet) { | |
746 | if(verbose || ((loop % LOOP_NOTIFY) == 0)) { | |
747 | printf("...oloop %d\n", loop); | |
748 | } | |
749 | } | |
750 | ||
751 | if(doRSA) { | |
752 | CSSM_ALGORITHMS sigAlg; | |
753 | if(loop & 1) { | |
754 | sigAlg = CSSM_ALGID_SHA1WithRSA; | |
755 | } | |
756 | else { | |
757 | sigAlg = CSSM_ALGID_MD5WithRSA; | |
758 | } | |
759 | ||
760 | /* enable RSA blinding on half the loops for RSA */ | |
761 | CSSM_BOOL rsaBlinding = CSSM_FALSE; | |
762 | if(loop & 2) { | |
763 | rsaBlinding = CSSM_TRUE; | |
764 | } | |
765 | ||
766 | rtn = doTest(cspHand, | |
767 | CSSM_ALGID_RSA, | |
768 | sigAlg, | |
769 | sigLoops, | |
770 | encrLoops, | |
771 | rsaBlinding, | |
772 | &ptext, | |
773 | MAX_TEXT_SIZE, | |
774 | keySizeInBits, | |
775 | pubRefKeys, | |
776 | privRefKeys, | |
777 | bareCsp, | |
778 | quiet, | |
779 | verbose); | |
780 | if(rtn) { | |
781 | break; | |
782 | } | |
783 | } | |
784 | if(doDSA) { | |
785 | rtn = doTest(cspHand, | |
786 | CSSM_ALGID_DSA, | |
787 | CSSM_ALGID_SHA1WithDSA, | |
788 | sigLoops, | |
789 | 0, // encrLoops - none for DSA | |
790 | CSSM_FALSE, // blinding | |
791 | &ptext, | |
792 | MAX_TEXT_SIZE, | |
793 | keySizeInBits, | |
794 | pubRefKeys, | |
795 | privRefKeys, | |
796 | bareCsp, | |
797 | quiet, | |
798 | verbose); | |
799 | if(rtn) { | |
800 | break; | |
801 | } | |
802 | } | |
803 | if(oloops && (loop == oloops)) { | |
804 | break; | |
805 | } | |
806 | if(pauseInterval && (loop % pauseInterval) == 0) { | |
807 | fpurge(stdin); | |
808 | printf("hit CR to proceed: "); | |
809 | getchar(); | |
810 | } | |
811 | } | |
812 | ||
813 | cspShutdown(cspHand, bareCsp); | |
814 | if(pauseInterval) { | |
815 | fpurge(stdin); | |
816 | printf("ModuleDetach/Unload complete; hit CR to exit: "); | |
817 | getchar(); | |
818 | } | |
819 | if((rtn == 0) && !quiet) { | |
820 | printf("%s test complete\n", argv[0]); | |
821 | } | |
822 | CSSM_FREE(ptext.Data); | |
823 | return rtn; | |
824 | } | |
825 | ||
826 |