]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/hashCompat/hashCompat.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / hashCompat / hashCompat.c
1 /*
2 * hashCompat.c - test compatibilty of two different implementations of a
3 * various digest algorithms - one in the standard AppleCSP, one in BSAFE.
4 *
5 * Written by Doug Mitchell.
6 */
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <time.h>
11 #include <Security/cssm.h>
12 #include <Security/cssmapple.h>
13 #include "cspwrap.h"
14 #include "common.h"
15 #include "bsafeUtils.h"
16 #include <string.h>
17
18 /*
19 * Defaults.
20 */
21 #define LOOPS_DEF 200
22 #define MIN_EXP 2 /* for data size 10**exp */
23 #define DEFAULT_MAX_EXP 4
24 #define MAX_EXP 5
25
26 #define MAX_DATA_SIZE (100000 + 100) /* bytes */
27 #define LOOP_NOTIFY 20
28
29 /*
30 * Enumerate algs our own way to allow iteration.
31 */
32 enum {
33 ALG_SHA1 = 1,
34 ALG_MD5,
35 ALG_MD2
36 };
37
38 #define ALG_FIRST ALG_SHA1
39 #define ALG_LAST ALG_MD2
40
41 static void usage(char **argv)
42 {
43 printf("usage: %s [options]\n", argv[0]);
44 printf(" Options:\n");
45 printf(" a=algorithm (s=SHA1; 5=MD5; 2=MD2; default=all\n");
46 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
47 printf(" n=minExp (default=%d)\n", MIN_EXP);
48 printf(" x=maxExp (default=%d, max=%d)\n", DEFAULT_MAX_EXP, MAX_EXP);
49 printf(" p=pauseInterval (default=0, no pause)\n");
50 printf(" D (CSP/DL; default = bare CSP)\n");
51 printf(" v(erbose)\n");
52 printf(" q(uiet)\n");
53 printf(" h(elp)\n");
54 exit(1);
55 }
56
57 /*
58 * generate digest using reference BSAFE.
59 */
60 static CSSM_RETURN genDigestBSAFE(
61 CSSM_ALGORITHMS hashAlg,
62 const CSSM_DATA *inText,
63 CSSM_DATA_PTR outText) // mallocd and returned
64 {
65 CSSM_RETURN crtn;
66
67 crtn = buGenDigest(hashAlg,
68 inText,
69 outText);
70 return crtn;
71 }
72
73 /*
74 * Generate digest using CSP.
75 */
76 static CSSM_RETURN genDigestCSSM(
77 CSSM_CSP_HANDLE cspHand,
78 CSSM_ALGORITHMS hashAlg,
79 const CSSM_DATA *inText,
80 CSSM_DATA_PTR outText) // mallocd and returned if doGen
81 {
82
83 outText->Data = NULL;
84 outText->Length = 0;
85 return cspStagedDigest(cspHand,
86 hashAlg,
87 CSSM_TRUE, // mallocDigest
88 CSSM_TRUE, // multiUpdates
89 inText,
90 outText);
91 }
92
93 #define LOG_FREQ 20
94
95 static int doTest(CSSM_CSP_HANDLE cspHand,
96 const CSSM_DATA *ptext,
97 uint32 hashAlg,
98 CSSM_BOOL quiet)
99 {
100 CSSM_DATA hashRef = {0, NULL}; // digest, BSAFE reference
101 CSSM_DATA hashTest = {0, NULL}; // digest, CSP test
102 int rtn = 0;
103 CSSM_RETURN crtn;
104
105 /*
106 * generate with each method;
107 * verify digests compare;
108 */
109 crtn = genDigestBSAFE(hashAlg,
110 ptext,
111 &hashRef);
112 if(crtn) {
113 return testError(quiet);
114 }
115 crtn = genDigestCSSM(cspHand,
116 hashAlg,
117 ptext,
118 &hashTest);
119 if(crtn) {
120 return testError(quiet);
121 }
122
123 /* ensure both methods resulted in same hash */
124 if(hashRef.Length != hashTest.Length) {
125 printf("hash length mismatch (1)\n");
126 rtn = testError(quiet);
127 if(rtn) {
128 goto abort;
129 }
130 }
131 if(memcmp(hashRef.Data, hashTest.Data, hashTest.Length)) {
132 printf("hash miscompare\n");
133 rtn = testError(quiet);
134 }
135 else {
136 rtn = 0;
137 }
138 abort:
139 if(hashTest.Length) {
140 CSSM_FREE(hashTest.Data);
141 }
142 if(hashRef.Length) {
143 CSSM_FREE(hashRef.Data);
144 }
145 return rtn;
146 }
147
148
149 int main(int argc, char **argv)
150 {
151 int arg;
152 char *argp;
153 unsigned loop;
154 CSSM_DATA ptext;
155 CSSM_CSP_HANDLE cspHand;
156 const char *algStr;
157 uint32 hashAlg; // CSSM_ALGID_xxx
158 int i;
159 unsigned currAlg; // ALG_xxx
160 int rtn = 0;
161
162 /*
163 * User-spec'd params
164 */
165 unsigned minAlg = ALG_FIRST;
166 unsigned maxAlg = ALG_LAST;
167 unsigned loops = LOOPS_DEF;
168 CSSM_BOOL verbose = CSSM_FALSE;
169 unsigned minExp = MIN_EXP;
170 unsigned maxExp = DEFAULT_MAX_EXP;
171 CSSM_BOOL quiet = CSSM_FALSE;
172 unsigned pauseInterval = 0;
173 CSSM_BOOL bareCsp = CSSM_TRUE;
174
175
176 for(arg=1; arg<argc; arg++) {
177 argp = argv[arg];
178 switch(argp[0]) {
179 case 'a':
180 if(argp[1] != '=') {
181 usage(argv);
182 }
183 switch(argp[2]) {
184 case 's':
185 minAlg = maxAlg = ALG_SHA1;
186 break;
187 case '5':
188 minAlg = maxAlg = ALG_MD5;
189 break;
190 case '2':
191 minAlg = maxAlg = ALG_MD2;
192 break;
193 default:
194 usage(argv);
195 }
196 break;
197 case 'l':
198 loops = atoi(&argp[2]);
199 break;
200 case 'n':
201 minExp = atoi(&argp[2]);
202 break;
203 case 'x':
204 maxExp = atoi(&argp[2]);
205 if(maxExp > MAX_EXP) {
206 usage(argv);
207 }
208 break;
209 case 'v':
210 verbose = CSSM_TRUE;
211 break;
212 case 'D':
213 bareCsp = CSSM_FALSE;
214 break;
215 case 'q':
216 quiet = CSSM_TRUE;
217 break;
218 case 'p':
219 pauseInterval = atoi(&argp[2]);;
220 break;
221 case 'h':
222 default:
223 usage(argv);
224 }
225 }
226 if(minExp > maxExp) {
227 printf("***minExp must be <= maxExp\n");
228 usage(argv);
229 }
230 ptext.Data = (uint8 *)CSSM_MALLOC(MAX_DATA_SIZE);
231 if(ptext.Data == NULL) {
232 printf("Insufficient heap space\n");
233 exit(1);
234 }
235 /* ptext length set in test loop */
236
237 printf("Starting hashCompat; args: ");
238 for(i=1; i<argc; i++) {
239 printf("%s ", argv[i]);
240 }
241 printf("\n");
242 cspHand = cspDlDbStartup(bareCsp, NULL);
243 if(cspHand == 0) {
244 exit(1);
245 }
246 if(pauseInterval) {
247 fpurge(stdin);
248 printf("Top of test; hit CR to proceed: ");
249 getchar();
250 }
251 for(currAlg=minAlg; currAlg<=maxAlg; currAlg++) {
252 switch(currAlg) {
253 case ALG_SHA1:
254 hashAlg = CSSM_ALGID_SHA1;
255 algStr = "SHA1";
256 break;
257 case ALG_MD5:
258 hashAlg = CSSM_ALGID_MD5;
259 algStr = "MD5";
260 break;
261 case ALG_MD2:
262 hashAlg = CSSM_ALGID_MD2;
263 algStr = "MD2";
264 break;
265 default:
266 printf("***Brrzap. Bad alg.\n");
267 exit(1);
268 }
269
270 if(!quiet || verbose) {
271 printf("Testing alg %s\n", algStr);
272 }
273 for(loop=1; ; loop++) {
274 /* random ptext length and data */
275 ptext.Length = genData(ptext.Data, minExp, maxExp, DT_Random);
276 if(!quiet) {
277 if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
278 printf("..loop %d text size %lu \n", loop, ptext.Length);
279 }
280 }
281
282 if(doTest(cspHand,
283 &ptext,
284 hashAlg,
285 quiet)) {
286 rtn = 1;
287 break;
288 }
289 if(pauseInterval && ((loop % pauseInterval) == 0)) {
290 char c;
291 fpurge(stdin);
292 printf("Hit CR to proceed, q to abort: ");
293 c = getchar();
294 if(c == 'q') {
295 goto testDone;
296 }
297 }
298 if(loops && (loop == loops)) {
299 break;
300 }
301 } /* main loop */
302 if(rtn) {
303 break;
304 }
305 } /* for algs */
306
307 testDone:
308 cspShutdown(cspHand, bareCsp);
309 if(pauseInterval) {
310 fpurge(stdin);
311 printf("ModuleDetach/Unload complete; hit CR to exit: ");
312 getchar();
313 }
314 if((rtn == 0) && !quiet) {
315 printf("%s complete\n", argv[0]);
316 }
317 CSSM_FREE(ptext.Data);
318 return rtn;
319 }
320
321