]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
1 | /* |
2 | * Verify SHA2 against FIPS test vectors. | |
3 | */ | |
4 | ||
5 | #include <stdlib.h> | |
6 | #include <stdio.h> | |
7 | #include <strings.h> | |
8 | #include <CommonCrypto/CommonDigest.h> | |
9 | ||
10 | static void usage(char **argv) | |
11 | { | |
12 | printf("Usage: %s [q(uiet)]\n", argv[0]); | |
13 | exit(1); | |
14 | } | |
15 | ||
16 | /* | |
17 | * These test vectors came from FIPS Processing Standards Publication 180-2, | |
18 | * 2002 August 1. | |
19 | * | |
20 | * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf | |
21 | */ | |
22 | ||
23 | /* SHA256 vectors */ | |
24 | static const char *v1_256_text = "abc"; | |
25 | static int v1_256_textLen=3; | |
26 | static unsigned const char v1_256_digest[] = { | |
27 | 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, | |
28 | 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, | |
29 | 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, | |
30 | 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad | |
31 | }; | |
32 | ||
33 | static const char *v2_256_text = "abcdbcdecdefdefgefghfghighijhi" | |
34 | "jkijkljklmklmnlmnomnopnopq"; | |
35 | #define v2_256_textLen strlen(v2_256_text) | |
36 | static unsigned const char v2_256_digest[] = { | |
37 | 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, | |
38 | 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, | |
39 | 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, | |
40 | 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 | |
41 | }; | |
42 | ||
43 | /* Vector 3: text = one million 'a' characters */ | |
44 | static unsigned const char v3_256_digest[] = { | |
45 | 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, | |
46 | 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67, | |
47 | 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, | |
48 | 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 | |
49 | }; | |
50 | ||
51 | /* SHA384 vectors */ | |
52 | static const char *v1_384_text = "abc"; | |
53 | static int v1_384_textLen=3; | |
54 | static unsigned const char v1_384_digest[] = { | |
55 | 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, | |
56 | 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, | |
57 | 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, | |
58 | 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, | |
59 | 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, | |
60 | 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 | |
61 | }; | |
62 | ||
63 | static const char *v2_384_text = "abcdefghbcdefghicdefghijdefghij" | |
64 | "kefghijklfghijklmghijklmn" | |
65 | "hijklmnoijklmnopjklmnopqklmnopqr" | |
66 | "lmnopqrsmnopqrstnopqrstu"; | |
67 | #define v2_384_textLen strlen(v2_384_text) | |
68 | static unsigned const char v2_384_digest[] = { | |
69 | 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, | |
70 | 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, | |
71 | 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, | |
72 | 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, | |
73 | 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, | |
74 | 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 | |
75 | }; | |
76 | ||
77 | /* Vector 3: text = one million 'a' characters */ | |
78 | static unsigned const char v3_384_digest[] = { | |
79 | 0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb, | |
80 | 0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a, 0x4a, 0x1c, | |
81 | 0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52, | |
82 | 0x79, 0x72, 0xce, 0xc5, 0x70, 0x4c, 0x2a, 0x5b, | |
83 | 0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb, | |
84 | 0xae, 0x97, 0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85 | |
85 | }; | |
86 | ||
87 | /* SHA512 vectors */ | |
88 | static const char *v1_512_text = "abc"; | |
89 | static int v1_512_textLen=3; | |
90 | static unsigned const char v1_512_digest[] = { | |
91 | 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, | |
92 | 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, | |
93 | 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, | |
94 | 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, | |
95 | 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, | |
96 | 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, | |
97 | 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, | |
98 | 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f | |
99 | }; | |
100 | ||
101 | static const char *v2_512_text = "abcdefghbcdefghicdefghijdefgh" | |
102 | "ijkefghijklfghijklmghijklmn" | |
103 | "hijklmnoijklmnopjklmnopqklmn" | |
104 | "opqrlmnopqrsmnopqrstnopqrstu"; | |
105 | #define v2_512_textLen strlen(v2_512_text) | |
106 | static unsigned const char v2_512_digest[] = { | |
107 | 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, | |
108 | 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, | |
109 | 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, | |
110 | 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, | |
111 | 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, | |
112 | 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, | |
113 | 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, | |
114 | 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 | |
115 | }; | |
116 | ||
117 | /* Vector 3: one million 'a' characters */ | |
118 | static unsigned const char v3_512_digest[] = { | |
119 | 0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64, | |
120 | 0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63, | |
121 | 0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28, | |
122 | 0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb, | |
123 | 0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a, | |
124 | 0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b, | |
125 | 0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e, | |
126 | 0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b | |
127 | }; | |
128 | ||
129 | /* | |
130 | * SHA224 vectors, not part of the FIPS standard; these were obtained from RFC 3874. | |
131 | */ | |
132 | static const char *v1_224_text = "abc"; | |
133 | static int v1_224_textLen=3; | |
134 | static unsigned const char v1_224_digest[] = { | |
135 | 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22, | |
136 | 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3, | |
137 | 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7, | |
138 | 0xe3, 0x6c, 0x9d, 0xa7 | |
139 | }; | |
140 | ||
141 | static const char *v2_224_text = "abcdbcdecdefdefgefghfghighi" | |
142 | "jhijkijkljklmklmnlmnomnopnopq"; | |
143 | static int v2_224_textLen=56; | |
144 | static unsigned const char v2_224_digest[] = { | |
145 | 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc, | |
146 | 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50, | |
147 | 0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19, | |
148 | 0x52, 0x52, 0x25, 0x25 | |
149 | }; | |
150 | ||
151 | /* Vector 3: one million 'a' characters */ | |
152 | static unsigned const char v3_224_digest[] = { | |
153 | 0x20, 0x79, 0x46, 0x55, 0x98, 0x0c, 0x91, 0xd8, | |
154 | 0xbb, 0xb4, 0xc1, 0xea, 0x97, 0x61, 0x8a, 0x4b, | |
155 | 0xf0, 0x3f, 0x42, 0x58, 0x19, 0x48, 0xb2, 0xee, | |
156 | 0x4e, 0xe7, 0xad, 0x67 | |
157 | }; | |
158 | ||
159 | static void dumpBuffer( | |
160 | const char *bufName, // optional | |
161 | const unsigned char *buf, | |
162 | unsigned len) | |
163 | { | |
164 | unsigned i; | |
165 | ||
166 | if(bufName) { | |
167 | printf("%s\n", bufName); | |
168 | } | |
169 | printf(" "); | |
170 | for(i=0; i<len; i++) { | |
171 | printf("%02X", buf[i]); | |
172 | if((i % 4) == 3) { | |
173 | printf(" "); | |
174 | } | |
175 | if((i % 32) == 31) { | |
176 | printf("\n "); | |
177 | } | |
178 | } | |
179 | printf("\n"); | |
180 | } | |
181 | ||
182 | static int doTest( | |
183 | const char *title, | |
184 | const unsigned char *digest, /* 2 * digestLen bytes, second half should be zero */ | |
185 | const unsigned char *expect, | |
186 | unsigned digestLen) | |
187 | { | |
188 | if(memcmp(digest, expect, digestLen)) { | |
189 | printf("**Error on %s\n", title); | |
190 | dumpBuffer("Expected", expect, digestLen); | |
191 | dumpBuffer("Obtained", digest, digestLen); | |
192 | return 1; | |
193 | } | |
194 | const unsigned char *cp = digest + digestLen; | |
195 | for(unsigned dex=0; dex<digestLen; dex++) { | |
196 | if(*cp++ != 0) { | |
197 | printf("***%s: Buffer overwrite at byte %u\n", title, dex); | |
198 | dumpBuffer("This should be all zeroes:", digest+digestLen, digestLen); | |
199 | return 1; | |
200 | } | |
201 | } | |
202 | return 0; | |
203 | } | |
204 | ||
205 | int main(int argc, char **argv) | |
206 | { | |
207 | bool quiet = false; | |
208 | ||
209 | for(int arg=1; arg<argc; arg++) { | |
210 | switch(argv[arg][0]) { | |
211 | case 'q': | |
212 | quiet = true; | |
213 | break; | |
214 | default: | |
215 | usage(argv); | |
216 | } | |
217 | } | |
218 | ||
219 | if(!quiet) { | |
220 | printf("...testing SHA224\n"); | |
221 | } | |
222 | ||
223 | CC_SHA256_CTX ctx224; | |
224 | /* double the digest and check for mods at end */ | |
225 | unsigned char dig224[CC_SHA224_DIGEST_LENGTH * 2]; | |
226 | ||
227 | memset(dig224, 0, CC_SHA224_DIGEST_LENGTH * 2); | |
228 | CC_SHA224_Init(&ctx224); | |
229 | CC_SHA224_Update(&ctx224, v1_224_text, v1_224_textLen); | |
230 | CC_SHA224_Final(dig224, &ctx224); | |
231 | if(doTest("SHA224 Vector 1", dig224, v1_224_digest, CC_SHA224_DIGEST_LENGTH)) { | |
232 | exit(1); | |
233 | } | |
234 | ||
235 | memset(dig224, 0, CC_SHA224_DIGEST_LENGTH); | |
236 | CC_SHA224_Init(&ctx224); | |
237 | CC_SHA224_Update(&ctx224, v2_224_text, v2_224_textLen); | |
238 | CC_SHA224_Final(dig224, &ctx224); | |
239 | if(doTest("SHA224 Vector 2", dig224, v2_224_digest, CC_SHA224_DIGEST_LENGTH)) { | |
240 | exit(1); | |
241 | } | |
242 | ||
243 | memset(dig224, 0, CC_SHA224_DIGEST_LENGTH); | |
244 | CC_SHA224_Init(&ctx224); | |
245 | /* one million 'a' chars; do 100,000 loops of ten of 'em */ | |
246 | for(unsigned dex=0; dex<100000; dex++) { | |
247 | CC_SHA224_Update(&ctx224, "aaaaaaaaaa", 10); | |
248 | } | |
249 | CC_SHA224_Final(dig224, &ctx224); | |
250 | if(doTest("SHA224 Vector 3", dig224, v3_224_digest, CC_SHA224_DIGEST_LENGTH)) { | |
251 | exit(1); | |
252 | } | |
253 | ||
254 | if(!quiet) { | |
255 | printf("...testing SHA256\n"); | |
256 | } | |
257 | CC_SHA256_CTX ctx256; | |
258 | ||
259 | /* double the digest and check for mods at end */ | |
260 | unsigned char dig256[CC_SHA256_DIGEST_LENGTH * 2]; | |
261 | ||
262 | memset(dig256, 0, CC_SHA256_DIGEST_LENGTH * 2); | |
263 | CC_SHA256_Init(&ctx256); | |
264 | CC_SHA256_Update(&ctx256, v1_256_text, v1_256_textLen); | |
265 | CC_SHA256_Final(dig256, &ctx256); | |
266 | if(doTest("SHA256 Vector 1", dig256, v1_256_digest, CC_SHA256_DIGEST_LENGTH)) { | |
267 | exit(1); | |
268 | } | |
269 | ||
270 | memset(dig256, 0, CC_SHA256_DIGEST_LENGTH); | |
271 | CC_SHA256_Init(&ctx256); | |
272 | CC_SHA256_Update(&ctx256, v2_256_text, v2_256_textLen); | |
273 | CC_SHA256_Final(dig256, &ctx256); | |
274 | if(doTest("SHA256 Vector 2", dig256, v2_256_digest, CC_SHA256_DIGEST_LENGTH)) { | |
275 | exit(1); | |
276 | } | |
277 | ||
278 | memset(dig256, 0, CC_SHA256_DIGEST_LENGTH); | |
279 | CC_SHA256_Init(&ctx256); | |
280 | /* one million 'a' chars; do 100,000 loops of ten of 'em */ | |
281 | for(unsigned dex=0; dex<100000; dex++) { | |
282 | CC_SHA256_Update(&ctx256, "aaaaaaaaaa", 10); | |
283 | } | |
284 | CC_SHA256_Final(dig256, &ctx256); | |
285 | if(doTest("SHA256 Vector 3", dig256, v3_256_digest, CC_SHA256_DIGEST_LENGTH)) { | |
286 | exit(1); | |
287 | } | |
288 | ||
289 | if(!quiet) { | |
290 | printf("...testing SHA384\n"); | |
291 | } | |
292 | ||
293 | CC_SHA512_CTX ctx384; | |
294 | unsigned char dig384[CC_SHA384_DIGEST_LENGTH * 2]; | |
295 | ||
296 | memset(dig384, 0, CC_SHA384_DIGEST_LENGTH * 2); | |
297 | CC_SHA384_Init(&ctx384); | |
298 | CC_SHA384_Update(&ctx384, v1_384_text, v1_384_textLen); | |
299 | CC_SHA384_Final(dig384, &ctx384); | |
300 | if(doTest("SHA384 Vector 1", dig384, v1_384_digest, CC_SHA384_DIGEST_LENGTH)) { | |
301 | exit(1); | |
302 | } | |
303 | ||
304 | memset(dig384, 0, CC_SHA384_DIGEST_LENGTH); | |
305 | CC_SHA384_Init(&ctx384); | |
306 | CC_SHA384_Update(&ctx384, v2_384_text, v2_384_textLen); | |
307 | CC_SHA384_Final(dig384, &ctx384); | |
308 | if(doTest("SHA384 Vector 2", dig384, v2_384_digest, CC_SHA384_DIGEST_LENGTH)) { | |
309 | exit(1); | |
310 | } | |
311 | ||
312 | memset(dig384, 0, CC_SHA384_DIGEST_LENGTH); | |
313 | CC_SHA384_Init(&ctx384); | |
314 | /* one million 'a' chars; do 100,000 loops of ten of 'em */ | |
315 | for(unsigned dex=0; dex<100000; dex++) { | |
316 | CC_SHA384_Update(&ctx384, "aaaaaaaaaa", 10); | |
317 | } | |
318 | CC_SHA384_Final(dig384, &ctx384); | |
319 | if(doTest("SHA384 Vector 3", dig384, v3_384_digest, CC_SHA384_DIGEST_LENGTH)) { | |
320 | exit(1); | |
321 | } | |
322 | ||
323 | if(!quiet) { | |
324 | printf("...testing SHA512\n"); | |
325 | } | |
326 | ||
327 | CC_SHA512_CTX ctx512; | |
328 | unsigned char dig512[CC_SHA512_DIGEST_LENGTH * 2]; | |
329 | ||
330 | memset(dig512, 0, CC_SHA512_DIGEST_LENGTH * 2); | |
331 | CC_SHA512_Init(&ctx512); | |
332 | CC_SHA512_Update(&ctx512, v1_512_text, v1_512_textLen); | |
333 | CC_SHA512_Final(dig512, &ctx512); | |
334 | if(doTest("SHA512 Vector 1", dig512, v1_512_digest, CC_SHA512_DIGEST_LENGTH)) { | |
335 | exit(1); | |
336 | } | |
337 | ||
338 | memset(dig512, 0, CC_SHA512_DIGEST_LENGTH); | |
339 | CC_SHA512_Init(&ctx512); | |
340 | CC_SHA512_Update(&ctx512, v2_512_text, v2_512_textLen); | |
341 | CC_SHA512_Final(dig512, &ctx512); | |
342 | if(doTest("SHA512 Vector 2", dig512, v2_512_digest, CC_SHA512_DIGEST_LENGTH)) { | |
343 | exit(1); | |
344 | } | |
345 | ||
346 | memset(dig512, 0, CC_SHA512_DIGEST_LENGTH); | |
347 | CC_SHA512_Init(&ctx512); | |
348 | /* one million 'a' chars; do 100,000 loops of ten of 'em */ | |
349 | for(unsigned dex=0; dex<100000; dex++) { | |
350 | CC_SHA512_Update(&ctx512, "aaaaaaaaaa", 10); | |
351 | } | |
352 | CC_SHA512_Final(dig512, &ctx512); | |
353 | if(doTest("SHA512 Vector 3", dig512, v3_512_digest, CC_SHA512_DIGEST_LENGTH)) { | |
354 | exit(1); | |
355 | } | |
356 | ||
357 | if(!quiet) { | |
358 | printf("...SHA2 test vectors passed\n"); | |
359 | } | |
360 | return 0; | |
361 | } |