]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/hashClone/hashClone.c
Security-57740.31.2.tar.gz
[apple/security.git] / SecurityTests / cspxutils / hashClone / hashClone.c
1 /*
2 * hashClone.c - test CSSM_DigestDataClone function
3 */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <time.h>
8 #include <Security/cssm.h>
9 #include <Security/cssmapple.h>
10 #include "cspwrap.h"
11 #include "common.h"
12
13 /*
14 * Defaults
15 */
16 #define LOOPS_DEF 50
17 #define MAX_PTEXT (8 * 1024)
18 #define MIN_PTEXT 16
19 #define LOOP_NOTIFY 20
20
21 /*
22 * Enumerated algs
23 */
24 typedef unsigned privAlg;
25 enum {
26 ALG_MD5 = 1,
27 ALG_SHA1,
28 ALG_MD2,
29 ALG_SHA224,
30 ALG_SHA256,
31 ALG_SHA384,
32 ALG_SHA512
33 };
34
35 #define ALG_FIRST ALG_MD5
36 #define ALG_LAST ALG_SHA512
37
38 static void usage(char **argv)
39 {
40 printf("usage: %s [options]\n", argv[0]);
41 printf(" Options:\n");
42 printf(" a=algorithm (s=SHA1; m=MD5; M=MD2; 4=SHA224; 2=SHA256; 3=SHA384; 5=SHA512; "
43 "default=all\n");
44 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
45 printf(" p=pauseInterval (default=0, no pause)\n");
46 printf(" D (CSP/DL; default = bare CSP)\n");
47 printf(" v(erbose)\n");
48 printf(" q(uiet)\n");
49 printf(" h(elp)\n");
50 exit(1);
51 }
52
53 static int doTest(CSSM_CSP_HANDLE cspHand,
54 CSSM_ALGORITHMS alg,
55 const char *algStr,
56 CSSM_DATA_PTR ptext,
57 CSSM_BOOL verbose,
58 CSSM_BOOL quiet)
59 {
60 CSSM_CC_HANDLE digHand1 = 0; // reference
61 CSSM_CC_HANDLE digHand2 = 0; // to be cloned
62 CSSM_CC_HANDLE digHand3 = 0; // cloned from digHand2
63 CSSM_DATA dig1 = {0, NULL};
64 CSSM_DATA dig2 = {0, NULL};
65 CSSM_DATA dig3 = {0, NULL};
66 CSSM_RETURN crtn;
67 unsigned thisMove; // this update
68 unsigned toMove; // total to go
69 unsigned totalRequest; // originally requested
70 CSSM_DATA thisText; // actually passed to update
71
72 /* cook up two digest contexts */
73 crtn = CSSM_CSP_CreateDigestContext(cspHand,
74 alg,
75 &digHand1);
76 if(crtn) {
77 printError("CSSM_CSP_CreateDigestContext (1)", crtn);
78 return testError(quiet);
79 }
80 crtn = CSSM_CSP_CreateDigestContext(cspHand,
81 alg,
82 &digHand2);
83 if(crtn) {
84 printError("CSSM_CSP_CreateDigestContext (2)", crtn);
85 return testError(quiet);
86 }
87 crtn = CSSM_DigestDataInit(digHand1);
88 if(crtn) {
89 printError("CSSM_DigestDataInit (1)", crtn);
90 return testError(quiet);
91 }
92 crtn = CSSM_DigestDataInit(digHand2);
93 if(crtn) {
94 printError("CSSM_DigestDataInit (2)", crtn);
95 return testError(quiet);
96 }
97
98 /* do some random updates to first two digests, until we've digested
99 * at least half of the requested data */
100 totalRequest = ptext->Length;
101 toMove = ptext->Length;
102 thisText.Data = ptext->Data;
103 while(toMove > (totalRequest / 2)) {
104 thisMove = genRand((MIN_PTEXT / 2), toMove);
105 thisText.Length = thisMove;
106 if(verbose) {
107 printf(" ..updating digest1, digest2 with %d bytes\n", thisMove);
108 }
109 crtn = CSSM_DigestDataUpdate(digHand1, &thisText, 1);
110 if(crtn) {
111 printError("CSSM_DigestDataUpdate (1)", crtn);
112 return testError(quiet);
113 }
114 crtn = CSSM_DigestDataUpdate(digHand2, &thisText, 1);
115 if(crtn) {
116 printError("CSSM_DigestDataUpdate (2)", crtn);
117 return testError(quiet);
118 }
119 thisText.Data += thisMove;
120 toMove -= thisMove;
121 }
122
123 /* digest3 := clone(digest2) */
124 crtn = CSSM_DigestDataClone(digHand2, &digHand3);
125 if(crtn) {
126 printError("CSSM_DigestDataClone", crtn);
127 return testError(quiet);
128 }
129
130 /* finish off remaining ptext, updating all 3 digests identically */
131 while(toMove) {
132 thisMove = genRand(1, toMove);
133 thisText.Length = thisMove;
134 if(verbose) {
135 printf(" ..updating all three digests with %d bytes\n", thisMove);
136 }
137 crtn = CSSM_DigestDataUpdate(digHand1, &thisText, 1);
138 if(crtn) {
139 printError("CSSM_DigestDataUpdate (3)", crtn);
140 return testError(quiet);
141 }
142 crtn = CSSM_DigestDataUpdate(digHand2, &thisText, 1);
143 if(crtn) {
144 printError("CSSM_DigestDataUpdate (4)", crtn);
145 return testError(quiet);
146 }
147 crtn = CSSM_DigestDataUpdate(digHand3, &thisText, 1);
148 if(crtn) {
149 printError("CSSM_DigestDataUpdate (5)", crtn);
150 return testError(quiet);
151 }
152 thisText.Data += thisMove;
153 toMove -= thisMove;
154 }
155
156 /* obtain all three digests */
157 crtn = CSSM_DigestDataFinal(digHand1, &dig1);
158 if(crtn) {
159 printError("CSSM_DigestDataFinal (1)", crtn);
160 return testError(quiet);
161 }
162 crtn = CSSM_DigestDataFinal(digHand2, &dig2);
163 if(crtn) {
164 printError("CSSM_DigestDataFinal (2)", crtn);
165 return testError(quiet);
166 }
167 crtn = CSSM_DigestDataFinal(digHand3, &dig3);
168 if(crtn) {
169 printError("CSSM_DigestDataFinal (3)", crtn);
170 return testError(quiet);
171 }
172
173 /* ensure all three digests identical */
174 if(!appCompareCssmData(&dig1, &dig2)) {
175 printf("***Digest miscompare(dig1, dig2)***\n");
176 if(testError(quiet)) {
177 return 1;
178 }
179 }
180 if(!appCompareCssmData(&dig2, &dig3)) {
181 printf("***Digest miscompare(dig2, dig3)***\n");
182 if(testError(quiet)) {
183 return 1;
184 }
185 }
186
187 /* free resources */
188 appFreeCssmData(&dig1, CSSM_FALSE);
189 appFreeCssmData(&dig2, CSSM_FALSE);
190 appFreeCssmData(&dig3, CSSM_FALSE);
191 CSSM_DeleteContext(digHand1);
192 CSSM_DeleteContext(digHand2);
193 CSSM_DeleteContext(digHand3);
194 return 0;
195 }
196
197 int main(int argc, char **argv)
198 {
199 int arg;
200 char *argp;
201 unsigned loop;
202 CSSM_DATA ptext;
203 CSSM_CSP_HANDLE cspHand;
204 const char *algStr;
205 privAlg alg; // ALG_MD5, etc.
206 CSSM_ALGORITHMS cssmAlg; // CSSM_ALGID_MD5, etc.
207 int j;
208
209 /*
210 * User-spec'd params
211 */
212 unsigned loops = LOOPS_DEF;
213 CSSM_BOOL verbose = CSSM_FALSE;
214 CSSM_BOOL quiet = CSSM_FALSE;
215 unsigned minAlg = ALG_FIRST;
216 unsigned maxAlg = ALG_LAST;
217 unsigned pauseInterval = 0;
218 CSSM_BOOL bareCsp = CSSM_TRUE;
219
220 for(arg=1; arg<argc; arg++) {
221 argp = argv[arg];
222 switch(argp[0]) {
223 case 'a':
224 if(argp[1] != '=') {
225 usage(argv);
226 }
227 switch(argp[2]) {
228 case 's':
229 minAlg = maxAlg = ALG_SHA1;
230 break;
231 case 'm':
232 minAlg = maxAlg = ALG_MD5;
233 break;
234 case 'M':
235 minAlg = maxAlg = ALG_MD2;
236 break;
237 case '4':
238 minAlg = maxAlg = ALG_SHA224;
239 break;
240 case '2':
241 minAlg = maxAlg = ALG_SHA256;
242 break;
243 case '3':
244 minAlg = maxAlg = ALG_SHA384;
245 break;
246 case '5':
247 minAlg = maxAlg = ALG_SHA512;
248 break;
249 default:
250 usage(argv);
251 }
252 break;
253 case 'l':
254 loops = atoi(&argp[2]);
255 break;
256 case 'p':
257 pauseInterval = atoi(&argp[2]);;
258 break;
259 case 'v':
260 verbose = CSSM_TRUE;
261 break;
262 case 'q':
263 quiet = CSSM_TRUE;
264 break;
265 case 'D':
266 bareCsp = CSSM_FALSE;
267 break;
268 case 'h':
269 default:
270 usage(argv);
271 }
272 }
273 ptext.Data = (uint8 *)CSSM_MALLOC(MAX_PTEXT);
274 /* length set in test loop */
275 if(ptext.Data == NULL) {
276 printf("Insufficient heap\n");
277 exit(1);
278 }
279
280 printf("Starting hashClone; args: ");
281 for(j=1; j<argc; j++) {
282 printf("%s ", argv[j]);
283 }
284 printf("\n");
285 cspHand = cspDlDbStartup(bareCsp, NULL);
286 if(cspHand == 0) {
287 exit(1);
288 }
289
290 for(alg=minAlg; alg<=maxAlg; alg++) {
291 switch(alg) {
292 case ALG_MD5:
293 algStr = "MD5";
294 cssmAlg = CSSM_ALGID_MD5;
295 break;
296 case ALG_MD2:
297 algStr = "MD2";
298 cssmAlg = CSSM_ALGID_MD2;
299 break;
300 case ALG_SHA1:
301 algStr = "SHA1";
302 cssmAlg = CSSM_ALGID_SHA1;
303 break;
304 case ALG_SHA224:
305 algStr = "SHA224";
306 cssmAlg = CSSM_ALGID_SHA224;
307 break;
308 case ALG_SHA256:
309 algStr = "SHA256";
310 cssmAlg = CSSM_ALGID_SHA256;
311 break;
312 case ALG_SHA384:
313 algStr = "SHA384";
314 cssmAlg = CSSM_ALGID_SHA384;
315 break;
316 case ALG_SHA512:
317 algStr = "SHA512";
318 cssmAlg = CSSM_ALGID_SHA512;
319 break;
320 }
321 if(!quiet) {
322 printf("Testing alg %s\n", algStr);
323 }
324 for(loop=1; ; loop++) {
325 simpleGenData(&ptext, MIN_PTEXT, MAX_PTEXT);
326 if(!quiet) {
327 if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
328 printf("..loop %d text size %lu\n", loop, ptext.Length);
329 }
330 }
331 if(doTest(cspHand,
332 cssmAlg,
333 algStr,
334 &ptext,
335 verbose,
336 quiet)) {
337 exit(1);
338 }
339 if(loops && (loop == loops)) {
340 break;
341 }
342 if(pauseInterval && ((loop % pauseInterval) == 0)) {
343 fpurge(stdin);
344 printf("Hit CR to proceed: ");
345 getchar();
346 }
347 }
348 }
349 cspShutdown(cspHand, bareCsp);
350 if(!quiet) {
351 printf("%s test complete\n", argv[0]);
352 }
353 return 0;
354 }