2 * Verify CDSA implementation of SHA2 against FIPS test vectors.
10 /* this is for hard-coded lengths only */
11 #include <CommonCrypto/CommonDigest.h>
13 static void usage(char **argv
)
15 printf("Usage: %s [option...]\n", argv
[0]);
17 printf(" D (CSP/DL; default = bare CSP)\n");
23 * These test vectors came from FIPS Processing Standards Publication 180-2,
26 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
30 static const char *v1_256_text
= "abc";
31 static int v1_256_textLen
=3;
32 static unsigned const char v1_256_digest
[] = {
33 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
34 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
35 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
36 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
39 static const char *v2_256_text
= "abcdbcdecdefdefgefghfghighijhi"
40 "jkijkljklmklmnlmnomnopnopq";
41 #define v2_256_textLen strlen(v2_256_text)
42 static unsigned const char v2_256_digest
[] = {
43 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
44 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
45 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
46 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
49 /* Vector 3: text = one million 'a' characters */
50 static unsigned const char v3_256_digest
[] = {
51 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92,
52 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67,
53 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e,
54 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0
58 static const char *v1_384_text
= "abc";
59 static int v1_384_textLen
=3;
60 static unsigned const char v1_384_digest
[] = {
61 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
62 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
63 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
64 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
65 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
66 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7
69 static const char *v2_384_text
= "abcdefghbcdefghicdefghijdefghij"
70 "kefghijklfghijklmghijklmn"
71 "hijklmnoijklmnopjklmnopqklmnopqr"
72 "lmnopqrsmnopqrstnopqrstu";
73 #define v2_384_textLen strlen(v2_384_text)
74 static unsigned const char v2_384_digest
[] = {
75 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
76 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
77 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
78 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
79 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
80 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39
83 /* Vector 3: text = one million 'a' characters */
84 static unsigned const char v3_384_digest
[] = {
85 0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb,
86 0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a, 0x4a, 0x1c,
87 0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52,
88 0x79, 0x72, 0xce, 0xc5, 0x70, 0x4c, 0x2a, 0x5b,
89 0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb,
90 0xae, 0x97, 0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85
94 static const char *v1_512_text
= "abc";
95 static int v1_512_textLen
=3;
96 static unsigned const char v1_512_digest
[] = {
97 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
98 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
99 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
100 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
101 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
102 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
103 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
104 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
107 static const char *v2_512_text
= "abcdefghbcdefghicdefghijdefgh"
108 "ijkefghijklfghijklmghijklmn"
109 "hijklmnoijklmnopjklmnopqklmn"
110 "opqrlmnopqrsmnopqrstnopqrstu";
111 #define v2_512_textLen strlen(v2_512_text)
112 static unsigned const char v2_512_digest
[] = {
113 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
114 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
115 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
116 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
117 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
118 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
119 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
120 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09
123 /* Vector 3: one million 'a' characters */
124 static unsigned const char v3_512_digest
[] = {
125 0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64,
126 0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63,
127 0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28,
128 0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb,
129 0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a,
130 0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b,
131 0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e,
132 0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b
136 * SHA224 vectors, not part of the FIPS standard; these were obtained from RFC 3874.
138 static const char *v1_224_text
= "abc";
139 static int v1_224_textLen
=3;
140 static unsigned const char v1_224_digest
[] = {
141 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22,
142 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3,
143 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7,
144 0xe3, 0x6c, 0x9d, 0xa7
147 static const char *v2_224_text
= "abcdbcdecdefdefgefghfghighi"
148 "jhijkijkljklmklmnlmnomnopnopq";
149 static int v2_224_textLen
=56;
150 static unsigned const char v2_224_digest
[] = {
151 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc,
152 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50,
153 0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19,
154 0x52, 0x52, 0x25, 0x25
157 /* Vector 3: one million 'a' characters */
158 static unsigned const char v3_224_digest
[] = {
159 0x20, 0x79, 0x46, 0x55, 0x98, 0x0c, 0x91, 0xd8,
160 0xbb, 0xb4, 0xc1, 0xea, 0x97, 0x61, 0x8a, 0x4b,
161 0xf0, 0x3f, 0x42, 0x58, 0x19, 0x48, 0xb2, 0xee,
162 0x4e, 0xe7, 0xad, 0x67
165 static void dumpBuffer(
166 const char *bufName
, // optional
167 const unsigned char *buf
,
173 printf("%s\n", bufName
);
176 for(i
=0; i
<len
; i
++) {
177 printf("%02X", buf
[i
]);
188 /* digest a million 'a' characters */
189 static CSSM_RETURN
digestMillion(
190 CSSM_CSP_HANDLE cspHand
,
194 CSSM_CC_HANDLE digestHand
;
196 CSSM_RETURN crtn
= CSSM_CSP_CreateDigestContext(cspHand
, alg
, &digestHand
);
198 printError("CSSM_CSP_CreateDigestContext (1)", crtn
);
201 crtn
= CSSM_DigestDataInit(digestHand
);
203 printError("CSSM_CSP_CreateDigestContext (1)", crtn
);
207 /* 100,000 copies of ten of 'em */
208 char *data
= (char *)"aaaaaaaaaa";
209 CSSM_DATA ptext
= {10, (uint8
*)data
};
210 for(unsigned dex
=0; dex
<100000; dex
++) {
211 crtn
= CSSM_DigestDataUpdate(digestHand
, &ptext
, 1);
213 printError("CSSM_CSP_CreateDigestContext (1)", crtn
);
217 crtn
= CSSM_DigestDataFinal(digestHand
, digest
);
218 CSSM_DeleteContext(digestHand
);
220 printError("CSSM_DigestDataFinal", crtn
);
227 const unsigned char *digest
, /* 2 * digestLen bytes, second half should be zero */
228 const unsigned char *expect
,
231 if(memcmp(digest
, expect
, digestLen
)) {
232 printf("**Error on %s\n", title
);
233 dumpBuffer("Expected", expect
, digestLen
);
234 dumpBuffer("Obtained", digest
, digestLen
);
237 const unsigned char *cp
= digest
+ digestLen
;
238 for(unsigned dex
=0; dex
<digestLen
; dex
++) {
240 printf("***%s: Buffer overwrite at byte %u\n", title
, dex
);
241 dumpBuffer("This should be all zeroes:", digest
+digestLen
, digestLen
);
248 int main(int argc
, char **argv
)
251 bool bareCsp
= CSSM_TRUE
;
253 for(int arg
=1; arg
<argc
; arg
++) {
254 switch(argv
[arg
][0]) {
259 bareCsp
= CSSM_FALSE
;
265 testStartBanner("sha2VectorsCdsa", argc
, argv
);
267 CSSM_CSP_HANDLE cspHand
= cspDlDbStartup(bareCsp
, NULL
);
273 printf("...testing SHA224\n");
276 /* double the digest and check for mods at end */
277 unsigned char dig224
[CC_SHA224_DIGEST_LENGTH
* 2];
278 memset(dig224
, 0, CC_SHA224_DIGEST_LENGTH
* 2);
279 CSSM_DATA digest
= {CC_SHA224_DIGEST_LENGTH
* 2, dig224
};
280 CSSM_DATA ptext
= {v1_224_textLen
, (uint8
*)v1_224_text
};
282 if(cspDigest(cspHand
, CSSM_ALGID_SHA224
, CSSM_FALSE
, &ptext
, &digest
)) {
283 printf("***Digest error, aborting\n");
286 if(doTest("SHA224 Vector 1", dig224
, v1_224_digest
, CC_SHA224_DIGEST_LENGTH
)) {
290 memset(dig224
, 0, CC_SHA224_DIGEST_LENGTH
);
291 ptext
.Data
= (uint8
*)v2_224_text
;
292 ptext
.Length
= v2_224_textLen
;
293 if(cspDigest(cspHand
, CSSM_ALGID_SHA224
, CSSM_FALSE
, &ptext
, &digest
)) {
294 printf("***Digest error, aborting\n");
297 if(doTest("SHA224 Vector 2", dig224
, v2_224_digest
, CC_SHA224_DIGEST_LENGTH
)) {
301 memset(dig224
, 0, CC_SHA224_DIGEST_LENGTH
);
302 if(digestMillion(cspHand
, CSSM_ALGID_SHA224
, &digest
)) {
303 printf("***Digest error, aborting\n");
306 if(doTest("SHA224 Vector 3", dig224
, v3_224_digest
, CC_SHA224_DIGEST_LENGTH
)) {
311 printf("...testing SHA256\n");
314 /* double the digest and check for mods at end */
315 unsigned char dig256
[CC_SHA256_DIGEST_LENGTH
* 2];
316 memset(dig256
, 0, CC_SHA256_DIGEST_LENGTH
* 2);
317 digest
.Length
= CC_SHA256_DIGEST_LENGTH
* 2;
318 digest
.Data
= dig256
;
319 ptext
.Length
= v1_256_textLen
;
320 ptext
.Data
= (uint8
*)v1_256_text
;
322 if(cspDigest(cspHand
, CSSM_ALGID_SHA256
, CSSM_FALSE
, &ptext
, &digest
)) {
323 printf("***Digest error, aborting\n");
326 if(doTest("SHA256 Vector 1", dig256
, v1_256_digest
, CC_SHA256_DIGEST_LENGTH
)) {
330 memset(dig256
, 0, CC_SHA256_DIGEST_LENGTH
);
331 ptext
.Data
= (uint8
*)v2_256_text
;
332 ptext
.Length
= v2_256_textLen
;
333 if(cspDigest(cspHand
, CSSM_ALGID_SHA256
, CSSM_FALSE
, &ptext
, &digest
)) {
334 printf("***Digest error, aborting\n");
337 if(doTest("SHA256 Vector 2", dig256
, v2_256_digest
, CC_SHA256_DIGEST_LENGTH
)) {
341 memset(dig256
, 0, CC_SHA256_DIGEST_LENGTH
);
342 if(digestMillion(cspHand
, CSSM_ALGID_SHA256
, &digest
)) {
343 printf("***Digest error, aborting\n");
346 if(doTest("SHA256 Vector 3", dig256
, v3_256_digest
, CC_SHA256_DIGEST_LENGTH
)) {
351 printf("...testing SHA384\n");
354 unsigned char dig384
[CC_SHA384_DIGEST_LENGTH
* 2];
355 memset(dig384
, 0, CC_SHA384_DIGEST_LENGTH
* 2);
356 digest
.Data
= (uint8
*)dig384
;
357 digest
.Length
= CC_SHA384_DIGEST_LENGTH
* 2;
358 ptext
.Data
= (uint8
*)v1_384_text
;
359 ptext
.Length
= v1_384_textLen
;
360 if(cspDigest(cspHand
, CSSM_ALGID_SHA384
, CSSM_FALSE
, &ptext
, &digest
)) {
361 printf("***Digest error, aborting\n");
364 if(doTest("SHA384 Vector 1", dig384
, v1_384_digest
, CC_SHA384_DIGEST_LENGTH
)) {
368 memset(dig384
, 0, CC_SHA384_DIGEST_LENGTH
);
369 ptext
.Data
= (uint8
*)v2_384_text
;
370 ptext
.Length
= v2_384_textLen
;
371 if(cspDigest(cspHand
, CSSM_ALGID_SHA384
, CSSM_FALSE
, &ptext
, &digest
)) {
372 printf("***Digest error, aborting\n");
375 if(doTest("SHA384 Vector 2", dig384
, v2_384_digest
, CC_SHA384_DIGEST_LENGTH
)) {
379 memset(dig384
, 0, CC_SHA384_DIGEST_LENGTH
);
380 if(digestMillion(cspHand
, CSSM_ALGID_SHA384
, &digest
)) {
381 printf("***Digest error, aborting\n");
384 if(doTest("SHA384 Vector 3", dig384
, v3_384_digest
, CC_SHA384_DIGEST_LENGTH
)) {
389 printf("...testing SHA512\n");
392 unsigned char dig512
[CC_SHA512_DIGEST_LENGTH
* 2];
393 memset(dig512
, 0, CC_SHA512_DIGEST_LENGTH
* 2);
394 digest
.Data
= (uint8
*)dig512
;
395 digest
.Length
= CC_SHA512_DIGEST_LENGTH
* 2;
397 ptext
.Data
= (uint8
*)v1_512_text
;
398 ptext
.Length
= v1_512_textLen
;
399 if(cspDigest(cspHand
, CSSM_ALGID_SHA512
, CSSM_FALSE
, &ptext
, &digest
)) {
400 printf("***Digest error, aborting\n");
403 if(doTest("SHA512 Vector 1", dig512
, v1_512_digest
, CC_SHA512_DIGEST_LENGTH
)) {
407 memset(dig512
, 0, CC_SHA512_DIGEST_LENGTH
);
408 ptext
.Data
= (uint8
*)v2_512_text
;
409 ptext
.Length
= v2_512_textLen
;
410 if(cspDigest(cspHand
, CSSM_ALGID_SHA512
, CSSM_FALSE
, &ptext
, &digest
)) {
411 printf("***Digest error, aborting\n");
414 if(doTest("SHA512 Vector 2", dig512
, v2_512_digest
, CC_SHA512_DIGEST_LENGTH
)) {
418 memset(dig512
, 0, CC_SHA512_DIGEST_LENGTH
);
419 if(digestMillion(cspHand
, CSSM_ALGID_SHA512
, &digest
)) {
420 printf("***Digest error, aborting\n");
423 if(doTest("SHA512 Vector 3", dig512
, v3_512_digest
, CC_SHA512_DIGEST_LENGTH
)) {
428 printf("...SHA2 test vectors passed\n");