]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/rawSig/rawSig.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / rawSig / rawSig.c
1 /*
2 * rawSig.c - Test compatiblity of (hash+sign) ops vs. manual digest followed
3 * by raw sign.
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 "cspdlTesting.h"
15 #include <string.h>
16
17 /*
18 * Defaults.
19 */
20 #define OLOOPS_DEF 10 /* outer loops, one key pair per loop */
21 #define ILOOPS_DEF 10 /* sig loops */
22 #define MAX_TEXT_SIZE 1024
23
24 #define LOOP_NOTIFY 20
25
26 /*
27 * Enumerate algs our own way to allow iteration.
28 */
29 #define ALG_RSA_MD5 1
30 #define ALG_RSA_SHA1 2
31 #define ALG_RSA_MD2 3
32 #define ALG_FEE_MD5 4
33 #define ALG_FEE_SHA1 5
34 #define ALG_ECDSA_SHA1 6
35 #define ALG_DSA_SHA1 7
36 #define ALG_ANSI_ECDSA_SHA1 8
37 #define ALG_ECDSA_SHA256 9
38 #define ALG_ECDSA_SHA384 10
39 #define ALG_ECDSA_SHA512 11
40 #define ALG_FIRST ALG_RSA_MD5
41 #define ALG_LAST ALG_ECDSA_SHA512
42
43 static void usage(char **argv)
44 {
45 printf("usage: %s [options]\n", argv[0]);
46 printf(" Options:\n");
47 printf(" a=alg (5=RSA/MD5; 2=RSA/MD2; R=RSA/SHA1; d=DSA/SHA1; f=FEE/MD5; F=FEE/SHA1; \n");
48 printf(" e=ECDSA/SHA1; E=ANSI_ECDSA/SHA1; 7=ECDSA/SHA256; 8=ECDSA/SHA384; 9=ECDSA/512; default=all)\n");
49 printf(" l=outerloops (default=%d; 0=forever)\n", OLOOPS_DEF);
50 printf(" i=innerLoops (default=%d)\n", ILOOPS_DEF);
51 printf(" k=keySizeInBits; default is random\n");
52 printf(" p=pauseInterval (default=0, no pause)\n");
53 printf(" s(mall keys)\n");
54 printf(" D (CSP/DL; default = bare CSP)\n");
55 printf(" v(erbose)\n");
56 printf(" q(uiet)\n");
57 printf(" h(elp)\n");
58 exit(1);
59 }
60
61 int main(int argc, char **argv)
62 {
63 int arg;
64 char *argp;
65 unsigned oloop;
66 unsigned iloop;
67 CSSM_DATA ptext = {0, NULL};
68 CSSM_CSP_HANDLE cspHand;
69 int i;
70 int rtn = 0;
71 uint32 keySizeInBits = 0;
72 CSSM_KEY pubKey;
73 CSSM_KEY privKey;
74 CSSM_DATA sig = {0, NULL};
75 CSSM_DATA digest = {0, NULL};
76 CSSM_RETURN crtn;
77 unsigned currAlg;
78
79 /* current alg (e.g. ALG_FEE_SHA1) parsed to come up with these */
80 CSSM_ALGORITHMS digestAlg;
81 CSSM_ALGORITHMS rawSigAlg;
82 CSSM_ALGORITHMS sigAlg;
83 CSSM_ALGORITHMS keyGenAlg;
84 const char *sigAlgStr;
85
86 /*
87 * User-spec'd params
88 */
89 CSSM_BOOL keySizeSpec = CSSM_FALSE;
90 unsigned oloops = OLOOPS_DEF;
91 unsigned iloops = ILOOPS_DEF;
92 CSSM_BOOL verbose = CSSM_FALSE;
93 CSSM_BOOL quiet = CSSM_FALSE;
94 unsigned pauseInterval = 0;
95 CSSM_BOOL bareCsp = CSSM_TRUE;
96 unsigned minAlg = ALG_FIRST;
97 uint32 maxAlg = ALG_LAST;
98 CSSM_BOOL smallKeys = CSSM_FALSE;
99
100 for(arg=1; arg<argc; arg++) {
101 argp = argv[arg];
102 switch(argp[0]) {
103 case 'a':
104 switch(argp[2]) {
105 case 'f':
106 minAlg = maxAlg = ALG_FEE_MD5;
107 break;
108 case 'F':
109 minAlg = maxAlg = ALG_FEE_SHA1;
110 break;
111 case 'e':
112 minAlg = maxAlg = ALG_ECDSA_SHA1;
113 break;
114 case '5':
115 minAlg = maxAlg = ALG_RSA_MD5;
116 break;
117 case '2':
118 minAlg = maxAlg = ALG_RSA_MD2;
119 break;
120 case 'R':
121 minAlg = maxAlg = ALG_RSA_SHA1;
122 break;
123 case 'd':
124 minAlg = maxAlg = ALG_DSA_SHA1;
125 break;
126 case 'E':
127 minAlg = maxAlg = ALG_ANSI_ECDSA_SHA1;
128 break;
129 case '7':
130 minAlg = maxAlg = ALG_ECDSA_SHA256;
131 break;
132 case '8':
133 minAlg = maxAlg = ALG_ECDSA_SHA384;
134 break;
135 case '9':
136 minAlg = maxAlg = ALG_ECDSA_SHA512;
137 break;
138 default:
139 usage(argv);
140 }
141 break;
142 case 'l':
143 oloops = atoi(&argp[2]);
144 break;
145 case 'i':
146 iloops = atoi(&argp[2]);
147 break;
148 case 'k':
149 keySizeInBits = atoi(&argp[2]);
150 keySizeSpec = CSSM_TRUE;
151 break;
152 case 'v':
153 verbose = CSSM_TRUE;
154 break;
155 case 'D':
156 bareCsp = CSSM_FALSE;
157 break;
158 case 'q':
159 quiet = CSSM_TRUE;
160 break;
161 case 's':
162 smallKeys = CSSM_TRUE;
163 break;
164 case 'p':
165 pauseInterval = atoi(&argp[2]);;
166 break;
167 case 'h':
168 default:
169 usage(argv);
170 }
171 }
172
173 ptext.Data = (uint8 *)CSSM_MALLOC(MAX_TEXT_SIZE);
174 if(ptext.Data == NULL) {
175 printf("Insufficient heap space\n");
176 exit(1);
177 }
178 /* ptext length set in inner test loop */
179
180 printf("Starting rawSig; args: ");
181 for(i=1; i<argc; i++) {
182 printf("%s ", argv[i]);
183 }
184 printf("\n");
185 cspHand = cspDlDbStartup(bareCsp, NULL);
186 if(cspHand == 0) {
187 exit(1);
188 }
189 if(pauseInterval) {
190 fpurge(stdin);
191 printf("Top of test; hit CR to proceed: ");
192 getchar();
193 }
194 for(currAlg=minAlg; currAlg<=maxAlg; currAlg++) {
195 /* get current algs */
196 switch(currAlg) {
197 case ALG_RSA_MD5:
198 digestAlg = CSSM_ALGID_MD5;
199 rawSigAlg = CSSM_ALGID_RSA;
200 sigAlg = CSSM_ALGID_MD5WithRSA;
201 keyGenAlg = CSSM_ALGID_RSA;
202 sigAlgStr = "MD5WithRSA";
203 break;
204 case ALG_RSA_MD2:
205 digestAlg = CSSM_ALGID_MD2;
206 rawSigAlg = CSSM_ALGID_RSA;
207 sigAlg = CSSM_ALGID_MD2WithRSA;
208 keyGenAlg = CSSM_ALGID_RSA;
209 sigAlgStr = "MD2WithRSA";
210 break;
211 case ALG_RSA_SHA1:
212 digestAlg = CSSM_ALGID_SHA1;
213 rawSigAlg = CSSM_ALGID_RSA;
214 sigAlg = CSSM_ALGID_SHA1WithRSA;
215 keyGenAlg = CSSM_ALGID_RSA;
216 sigAlgStr = "SHA1WithRSA";
217 break;
218 case ALG_DSA_SHA1:
219 digestAlg = CSSM_ALGID_SHA1;
220 rawSigAlg = CSSM_ALGID_DSA;
221 sigAlg = CSSM_ALGID_SHA1WithDSA;
222 keyGenAlg = CSSM_ALGID_DSA;
223 sigAlgStr = "SHA1WithDSA";
224 break;
225 case ALG_FEE_MD5:
226 digestAlg = CSSM_ALGID_MD5;
227 rawSigAlg = CSSM_ALGID_FEE;
228 sigAlg = CSSM_ALGID_FEE_MD5;
229 keyGenAlg = CSSM_ALGID_FEE;
230 sigAlgStr = "MD5WithFEE";
231 break;
232 case ALG_FEE_SHA1:
233 digestAlg = CSSM_ALGID_SHA1;
234 rawSigAlg = CSSM_ALGID_FEE;
235 sigAlg = CSSM_ALGID_FEE_SHA1;
236 keyGenAlg = CSSM_ALGID_FEE;
237 sigAlgStr = "SHA1WithFEE";
238 break;
239 case ALG_ECDSA_SHA1:
240 digestAlg = CSSM_ALGID_SHA1;
241 rawSigAlg = CSSM_ALGID_ECDSA;
242 sigAlg = CSSM_ALGID_SHA1WithECDSA;
243 keyGenAlg = CSSM_ALGID_FEE;
244 sigAlgStr = "SHA1WithECDSA";
245 break;
246 case ALG_ANSI_ECDSA_SHA1:
247 digestAlg = CSSM_ALGID_SHA1;
248 rawSigAlg = CSSM_ALGID_ECDSA;
249 sigAlg = CSSM_ALGID_SHA1WithECDSA;
250 keyGenAlg = CSSM_ALGID_ECDSA;
251 sigAlgStr = "ANSI ECDSA";
252 break;
253 case ALG_ECDSA_SHA256:
254 digestAlg = CSSM_ALGID_SHA256;
255 rawSigAlg = CSSM_ALGID_ECDSA;
256 sigAlg = CSSM_ALGID_SHA256WithECDSA;
257 keyGenAlg = CSSM_ALGID_ECDSA;
258 sigAlgStr = "ECDSA/SHA256";
259 break;
260 case ALG_ECDSA_SHA384:
261 digestAlg = CSSM_ALGID_SHA384;
262 rawSigAlg = CSSM_ALGID_ECDSA;
263 sigAlg = CSSM_ALGID_SHA384WithECDSA;
264 keyGenAlg = CSSM_ALGID_ECDSA;
265 sigAlgStr = "ECDSA/SHA384";
266 break;
267 case ALG_ECDSA_SHA512:
268 digestAlg = CSSM_ALGID_SHA512;
269 rawSigAlg = CSSM_ALGID_ECDSA;
270 sigAlg = CSSM_ALGID_SHA512WithECDSA;
271 keyGenAlg = CSSM_ALGID_ECDSA;
272 sigAlgStr = "ECDSA/SHA512";
273 break;
274 default:
275 printf("BRRZAP!\n");
276 exit(1);
277 }
278 if(!quiet) {
279 printf("Testing alg %s...\n", sigAlgStr);
280 }
281 for(oloop=0; ; oloop++) {
282
283 /* key size? */
284 if(smallKeys) {
285 keySizeInBits = cspDefaultKeySize(keyGenAlg);
286 }
287 else if(!keySizeSpec) {
288 /* random key size */
289 keySizeInBits = randKeySizeBits(rawSigAlg, OT_Sign);
290 }
291
292 if(!quiet) {
293 if(verbose || ((oloop % LOOP_NOTIFY) == 0)) {
294 printf(" ...oloop %d keySize %u\n", oloop, (unsigned)keySizeInBits);
295 }
296 }
297
298 /* generate a key pair */
299 if(currAlg == ALG_DSA_SHA1) {
300 CSSM_BOOL doGenParams;
301
302 if(bareCsp || CSPDL_DSA_GEN_PARAMS) {
303 doGenParams = CSSM_TRUE;
304 }
305 else {
306 /* CSPDL - no gen params */
307 doGenParams = CSSM_FALSE;
308 }
309 crtn = cspGenDSAKeyPair(cspHand,
310 "foo",
311 3,
312 keySizeInBits,
313 &pubKey,
314 CSSM_TRUE, // all keys ref for speed
315 CSSM_KEYUSE_VERIFY,
316 CSSM_KEYBLOB_RAW_FORMAT_NONE,
317 &privKey,
318 CSSM_TRUE,
319 CSSM_KEYUSE_SIGN,
320 CSSM_KEYBLOB_RAW_FORMAT_NONE,
321 doGenParams, // genParams
322 NULL); // params
323 }
324 else {
325 crtn = cspGenKeyPair(cspHand,
326 keyGenAlg,
327 "foo",
328 3,
329 keySizeInBits,
330 &pubKey,
331 CSSM_TRUE, // all keys ref for speed
332 CSSM_KEYUSE_VERIFY,
333 CSSM_KEYBLOB_RAW_FORMAT_NONE,
334 &privKey,
335 CSSM_TRUE,
336 CSSM_KEYUSE_SIGN,
337 CSSM_KEYBLOB_RAW_FORMAT_NONE,
338 CSSM_FALSE); // genSeed not used
339 }
340 if(crtn) {
341 return testError(quiet);
342 }
343
344 for(iloop=0; iloop<iloops; iloop++) {
345 CSSM_CC_HANDLE sigHand;
346
347 /* new plaintext each inner loop */
348 simpleGenData(&ptext, 1, MAX_TEXT_SIZE);
349 if(!quiet) {
350 if(verbose || ((iloop % LOOP_NOTIFY) == 0)) {
351 printf(" ...iloop %d text size %lu\n",
352 iloop, ptext.Length);
353 }
354 }
355
356 /*** phase 1 ***/
357
358 /* digest+sign */
359 crtn = cspStagedSign(cspHand,
360 sigAlg,
361 &privKey,
362 &ptext,
363 CSSM_TRUE, // multiUpdates
364 &sig);
365 if(crtn && testError(quiet)) {
366 goto abort;
367 }
368
369 /* manual digest */
370 crtn = cspStagedDigest(cspHand,
371 digestAlg,
372 CSSM_FALSE, // mallocDigest
373 CSSM_TRUE, // multiUpdates
374 &ptext,
375 &digest);
376 if(crtn && testError(quiet)) {
377 goto abort;
378 }
379
380 /* raw verify of the digest */
381 crtn = CSSM_CSP_CreateSignatureContext(cspHand,
382 rawSigAlg,
383 NULL, // passPhrase
384 &pubKey,
385 &sigHand);
386 if(crtn) {
387 printError("CSSM_CSP_CreateSignatureContext (1)", crtn);
388 return crtn;
389 }
390 crtn = CSSM_VerifyData(sigHand,
391 &digest,
392 1,
393 digestAlg,
394 &sig);
395 if(crtn) {
396 printError("CSSM_VerifyData(raw)", crtn);
397 if(testError(quiet)) {
398 goto abort;
399 }
400 }
401
402 /* free resources - reuse the digest for raw sign */
403 appFreeCssmData(&sig, CSSM_FALSE);
404 CSSM_DeleteContext(sigHand);
405
406 /*** phase 2 ***/
407
408 /* raw sign the digest */
409 crtn = CSSM_CSP_CreateSignatureContext(cspHand,
410 rawSigAlg,
411 NULL, // passPhrase
412 &privKey,
413 &sigHand);
414 if(crtn) {
415 printError("CSSM_CSP_CreateSignatureContext (2)", crtn);
416 return crtn;
417 }
418 crtn = CSSM_SignData(sigHand,
419 &digest,
420 1,
421 digestAlg,
422 &sig);
423 if(crtn) {
424 printError("CSSM_SignData(raw)", crtn);
425 if(testError(quiet)) {
426 goto abort;
427 }
428 }
429
430 /* all-in-one verify */
431 crtn = cspStagedSigVerify(cspHand,
432 sigAlg,
433 &pubKey,
434 &ptext,
435 &sig,
436 CSSM_TRUE, // multiUpdates
437 CSSM_OK);
438 if(crtn && testError(quiet)) {
439 goto abort;
440 }
441
442 /* clean up */
443 appFreeCssmData(&sig, CSSM_FALSE);
444 appFreeCssmData(&digest, CSSM_FALSE);
445 CSSM_DeleteContext(sigHand);
446 } /* end of inner loop */
447
448 /* free keys */
449 cspFreeKey(cspHand, &pubKey);
450 cspFreeKey(cspHand, &privKey);
451
452 if(oloops && (oloop == oloops)) {
453 break;
454 }
455 if(pauseInterval && ((oloop % pauseInterval) == 0)) {
456 fpurge(stdin);
457 printf("hit CR to proceed: ");
458 getchar();
459 }
460 } /* oloop */
461 } /* for alg */
462
463 abort:
464 cspShutdown(cspHand, bareCsp);
465 if(pauseInterval) {
466 fpurge(stdin);
467 printf("ModuleDetach/Unload complete; hit CR to exit: ");
468 getchar();
469 }
470 if((rtn == 0) && !quiet) {
471 printf("%s test complete\n", argv[0]);
472 }
473 CSSM_FREE(ptext.Data);
474 return rtn;
475 }
476
477