1 /* $NetBSD: t_hashes.c,v 1.5 2014/12/10 04:37:53 christos Exp $ */
4 * Copyright (C) 2010, 2013 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 /* Id: t_hashes.c,v 1.5 2010/10/04 22:27:41 marka Exp */
22 * -d1 or larger shows hash or HMAC result even if correct
29 #include <isc/hmacmd5.h>
30 #include <isc/hmacsha.h>
32 #include <isc/print.h>
34 #include <isc/string.h>
37 #include <tests/t_api.h>
42 typedef void(*HASH_INIT
)(void *);
43 typedef void(*HMAC_INIT
)(void *, const unsigned char *, unsigned int);
44 typedef void(*UPDATE
)(void *, const unsigned char *, unsigned int);
45 typedef void(*FINAL
)(void *, const unsigned char *);
46 typedef void(*SIGN
)(void *, const unsigned char *, unsigned int);
50 const unsigned char *key
;
51 const unsigned int key_len
;
52 const unsigned char *str
;
53 const unsigned int str_len
;
55 #define STR_INIT(s) (const unsigned char *)(s), sizeof(s)-1
59 unsigned char b
[1024];
60 unsigned char md5
[16];
61 unsigned char sha1
[ISC_SHA1_DIGESTLENGTH
];
62 unsigned char sha224
[ISC_SHA224_DIGESTLENGTH
];
63 unsigned char sha256
[ISC_SHA256_DIGESTLENGTH
];
64 unsigned char sha384
[ISC_SHA384_DIGESTLENGTH
];
65 unsigned char sha512
[ISC_SHA512_DIGESTLENGTH
];
67 #define DIGEST_FILL 0xdf
71 const unsigned int digest_len
;
76 * two ad hoc hash examples
78 static IN_ abc
= { "\"abc\"", NULL
, 0, STR_INIT("abc")};
79 static OUT_ abc_sha1
= {
80 "a9993e364706816aba3e25717850c26c9cd0d89d",
81 ISC_SHA1_DIGESTLENGTH
};
82 static OUT_ abc_sha224
= {
83 "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7",
84 ISC_SHA224_DIGESTLENGTH
};
85 static OUT_ abc_md5
= {
86 "900150983cd24fb0d6963f7d28e17f72",
89 static IN_ abc_blah
= { "\"abcdbc...\"", NULL
, 0,
90 STR_INIT("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")};
91 static OUT_ abc_blah_sha1
= {
92 "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
93 ISC_SHA1_DIGESTLENGTH
};
94 static OUT_ abc_blah_sha224
= {
95 "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525",
96 ISC_SHA224_DIGESTLENGTH
};
97 static OUT_ abc_blah_md5
= {
98 "8215ef0796a20bcaaae116d3876c664a",
102 * three HMAC-md5 examples from RFC 2104
104 static const unsigned char rfc2104_1_key
[16] = {
105 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
106 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
107 static IN_ rfc2104_1
= {"RFC 2104 #1", rfc2104_1_key
, sizeof(rfc2104_1_key
),
108 STR_INIT("Hi There")};
109 static OUT_ rfc2104_1_hmac
= {
110 "9294727a3638bb1c13f48ef8158bfc9d",
113 static IN_ rfc2104_2
= {"RFC 2104 #2", STR_INIT("Jefe"),
114 STR_INIT("what do ya want for nothing?")};
115 static OUT_ rfc2104_2_hmac
= {
116 "750c783e6ab0b503eaa86e310a5db738",
119 static const unsigned char rfc2104_3_key
[16] = {
120 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
121 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
122 static const unsigned char rfc2104_3_s
[50] = {
123 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
124 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
125 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
126 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
127 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
128 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
130 static IN_ rfc2104_3
= {"RFC 2104 #3", rfc2104_3_key
, sizeof(rfc2104_3_key
),
131 rfc2104_3_s
, sizeof(rfc2104_3_s
)};
132 static OUT_ rfc2104_3_hmac
= {
133 "56be34521d144c88dbb8c733f0e8b3f6",
137 * four three HMAC-SHA tests cut-and-pasted from RFC 4634 starting on page 86
139 static const unsigned char rfc4634_1_key
[20] = {
140 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
141 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
143 static IN_ rfc4634_1
= {"RFC 4634 #1", rfc4634_1_key
, sizeof(rfc4634_1_key
),
144 STR_INIT("Hi There")};
145 static OUT_ rfc4634_1_sha1
= {
146 "B617318655057264E28BC0B6FB378C8EF146BE00",
147 ISC_SHA1_DIGESTLENGTH
};
148 static OUT_ rfc4634_1_sha224
= {
149 "896FB1128ABBDF196832107CD49DF33F47B4B1169912BA4F53684B22",
150 ISC_SHA224_DIGESTLENGTH
};
151 static OUT_ rfc4634_1_sha256
= {
152 "B0344C61D8DB38535CA8AFCEAF0BF12B881DC200C9833DA726E9376C2E32"
154 ISC_SHA256_DIGESTLENGTH
};
155 static OUT_ rfc4634_1_sha384
= {
156 "AFD03944D84895626B0825F4AB46907F15F9DADBE4101EC682AA034C7CEB"
157 "C59CFAEA9EA9076EDE7F4AF152E8B2FA9CB6",
158 ISC_SHA384_DIGESTLENGTH
};
159 static OUT_ rfc4634_1_sha512
= {
160 "87AA7CDEA5EF619D4FF0B4241A1D6CB02379F4E2CE4EC2787AD0B30545E1"
161 "7CDEDAA833B7D6B8A702038B274EAEA3F4E4BE9D914EEB61F1702E696C20"
163 ISC_SHA512_DIGESTLENGTH
};
165 static IN_ rfc4634_2
= {"RFC 4634 #2", STR_INIT("Jefe"),
166 STR_INIT("what do ya want for nothing?")};
167 static OUT_ rfc4634_2_sha1
= {
168 "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79",
169 ISC_SHA1_DIGESTLENGTH
};
170 static OUT_ rfc4634_2_sha224
= {
171 "A30E01098BC6DBBF45690F3A7E9E6D0F8BBEA2A39E6148008FD05E44",
172 ISC_SHA224_DIGESTLENGTH
};
173 static OUT_ rfc4634_2_sha256
= {
174 "5BDCC146BF60754E6A042426089575C75A003F089D2739839DEC58B964EC"
176 ISC_SHA256_DIGESTLENGTH
};
177 static OUT_ rfc4634_2_sha384
= {
178 "AF45D2E376484031617F78D2B58A6B1B9C7EF464F5A01B47E42EC3736322"
179 "445E8E2240CA5E69E2C78B3239ECFAB21649",
180 ISC_SHA384_DIGESTLENGTH
};
181 static OUT_ rfc4634_2_sha512
= {
182 "164B7A7BFCF819E2E395FBE73B56E0A387BD64222E831FD610270CD7EA25"
183 "05549758BF75C05A994A6D034F65F8F0E6FDCAEAB1A34D4A6B4B636E070A"
185 ISC_SHA512_DIGESTLENGTH
};
187 static const unsigned char rfc4634_3_key
[20] = {
188 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
189 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
191 static const unsigned char rfc4634_3_s
[50] = {
192 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
193 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
194 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
195 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
196 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd
198 static IN_ rfc4634_3
= {"RFC 4634 #3", rfc4634_3_key
, sizeof(rfc4634_3_key
),
199 rfc4634_3_s
, sizeof(rfc4634_3_s
)};
200 static OUT_ rfc4634_3_sha1
= {
201 "125D7342B9AC11CD91A39AF48AA17B4F63F175D3",
202 ISC_SHA1_DIGESTLENGTH
};
203 static OUT_ rfc4634_3_sha224
= {
204 "7FB3CB3588C6C1F6FFA9694D7D6AD2649365B0C1F65D69D1EC8333EA",
205 ISC_SHA224_DIGESTLENGTH
};
206 static OUT_ rfc4634_3_sha256
= {
207 "773EA91E36800E46854DB8EBD09181A72959098B3EF8C122D9635514CED5"
209 ISC_SHA256_DIGESTLENGTH
};
210 static OUT_ rfc4634_3_sha384
= {
211 "88062608D3E6AD8A0AA2ACE014C8A86F0AA635D947AC9FEBE83EF4E55966"
212 "144B2A5AB39DC13814B94E3AB6E101A34F27",
213 ISC_SHA384_DIGESTLENGTH
};
214 static OUT_ rfc4634_3_sha512
= {
215 "FA73B0089D56A284EFB0F0756C890BE9B1B5DBDD8EE81A3655F83E33B227"
216 "9D39BF3E848279A722C806B485A47E67C807B946A337BEE8942674278859"
218 ISC_SHA512_DIGESTLENGTH
};
220 static const unsigned char rfc4634_4_key
[25] = {
221 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
222 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
223 0x15, 0x16, 0x17, 0x18, 0x19
225 static const unsigned char rfc4634_4_s
[50] = {
226 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
227 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
228 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
229 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
230 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd
232 static IN_ rfc4634_4
= {"RFC 4634 #3", rfc4634_4_key
, sizeof(rfc4634_4_key
),
233 rfc4634_4_s
, sizeof(rfc4634_4_s
)};
234 static OUT_ rfc4634_4_sha1
= {
235 "4C9007F4026250C6BC8414F9BF50C86C2D7235DA",
236 ISC_SHA1_DIGESTLENGTH
};
237 static OUT_ rfc4634_4_sha224
= {
238 "6C11506874013CAC6A2ABC1BB382627CEC6A90D86EFC012DE7AFEC5A",
239 ISC_SHA224_DIGESTLENGTH
};
240 static OUT_ rfc4634_4_sha256
= {
241 "82558A389A443C0EA4CC819899F2083A85F0FAA3E578F8077A2E3FF46729"
243 ISC_SHA256_DIGESTLENGTH
};
244 static OUT_ rfc4634_4_sha384
= {
245 "3E8A69B7783C25851933AB6290AF6CA77A9981480850009CC5577C6E1F57"
246 "3B4E6801DD23C4A7D679CCF8A386C674CFFB",
247 ISC_SHA384_DIGESTLENGTH
};
248 static OUT_ rfc4634_4_sha512
= {
249 "B0BA465637458C6990E5A8C5F61D4AF7E576D97FF94B872DE76F8050361E"
250 "E3DBA91CA5C11AA25EB4D679275CC5788063A5F19741120C4F2DE2ADEBEB"
252 ISC_SHA512_DIGESTLENGTH
};
257 d2str(char *buf
, unsigned int buf_len
,
258 const unsigned char *d
, unsigned int d_len
)
263 for (i
= 0; i
< d_len
&& l
< buf_len
-4; ++i
) {
264 l
+= snprintf(&buf
[l
], buf_len
-l
, "%02x", d
[i
]);
266 if (l
>= buf_len
-3) {
267 REQUIRE(buf_len
> sizeof("..."));
268 strcpy(&buf
[l
-sizeof(" ...")], " ...");
276 * Compare binary digest or HMAC to string of hex digits from an RFC
279 ck(const char *name
, const IN_
*in
, const OUT_
*out
)
281 char buf
[sizeof(dbuf
)*2+1];
282 const char *str_name
;
285 d2str(buf
, sizeof(buf
), dbuf
.b
, out
->digest_len
);
286 str_name
= in
->name
!= NULL
? in
->name
: (const char *)in
->str
;
289 t_info("%s(%s) = %s\n", name
, str_name
, buf
);
291 if (strcasecmp(buf
, out
->str
)) {
292 t_info("%s(%s)\n%9s %s\n%9s %s\n",
295 "should be", out
->str
);
301 * check that the hash or HMAC is no longer than we think it is
303 for (l
= out
->digest_len
; l
< sizeof(dbuf
); ++l
) {
304 if (dbuf
.b
[l
] != DIGEST_FILL
) {
305 t_info("byte #%d after end of %s(%s) changed to %02x\n",
306 l
-out
->digest_len
, name
, str_name
, dbuf
.b
[l
]);
316 t_hash(const char *hname
, HASH_INIT init
, UPDATE update
, FINAL final
,
320 unsigned char b
[1024];
326 update(&ctx
, in
->str
, in
->str_len
);
327 memset(dbuf
.b
, DIGEST_FILL
, sizeof(dbuf
));
335 * isc_sha224_final has a different calling sequence
338 t_sha224(IN_
*in
, OUT_
*out
)
342 memset(dbuf
.b
, DIGEST_FILL
, sizeof(dbuf
));
343 isc_sha224_init(&ctx
);
344 isc_sha224_update(&ctx
, in
->str
, in
->str_len
);
345 memset(dbuf
.b
, DIGEST_FILL
, sizeof(dbuf
));
346 isc_sha224_final(dbuf
.b
, &ctx
);
347 ck("SHA224", in
, out
);
353 t_hashes(IN_
*in
, OUT_
*out_sha1
, OUT_
*out_sha224
, OUT_
*out_md5
)
355 t_hash("SHA1", (HASH_INIT
)isc_sha1_init
, (UPDATE
)isc_sha1_update
,
356 (FINAL
)isc_sha1_final
, in
, out_sha1
);
357 t_sha224(in
, out_sha224
);
358 t_hash("md5", (HASH_INIT
)isc_md5_init
, (UPDATE
)isc_md5_update
,
359 (FINAL
)isc_md5_final
, in
, out_md5
);
365 * isc_hmacmd5_sign has a different calling sequence
368 t_md5hmac(IN_
*in
, OUT_
*out
)
372 isc_hmacmd5_init(&ctx
, in
->key
, in
->key_len
);
373 isc_hmacmd5_update(&ctx
, in
->str
, in
->str_len
);
374 memset(dbuf
.b
, DIGEST_FILL
, sizeof(dbuf
));
375 isc_hmacmd5_sign(&ctx
, dbuf
.b
);
376 ck("HMAC-md5", in
, out
);
382 t_hmac(const char *hname
, HMAC_INIT init
, UPDATE update
, SIGN sign
,
386 unsigned char b
[1024];
387 isc_hmacmd5_t hmacmd5
;
388 isc_hmacsha1_t hmacsha1
;
389 isc_hmacsha224_t hmacsha224
;
390 isc_hmacsha256_t hmacsha256
;
391 isc_hmacsha384_t hmacsha384
;
392 isc_hmacsha512_t hmacsha512
;
395 init(&ctx
, in
->key
, in
->key_len
);
396 update(&ctx
, in
->str
, in
->str_len
);
397 memset(dbuf
.b
, DIGEST_FILL
, sizeof(dbuf
));
398 sign(&ctx
, dbuf
.b
, out
->digest_len
);
405 t_hmacs(IN_
*in
, OUT_
*out_sha1
, OUT_
*out_sha224
, OUT_
*out_sha256
,
406 OUT_
*out_sha384
, OUT_
*out_sha512
)
408 t_hmac("HMAC-SHA1", (HMAC_INIT
)isc_hmacsha1_init
,
409 (UPDATE
)isc_hmacsha1_update
, (SIGN
)isc_hmacsha1_sign
,
411 t_hmac("HMAC-SHA224", (HMAC_INIT
)isc_hmacsha224_init
,
412 (UPDATE
)isc_hmacsha224_update
, (SIGN
)isc_hmacsha224_sign
,
414 t_hmac("HMAC-SHA256", (HMAC_INIT
)isc_hmacsha256_init
,
415 (UPDATE
)isc_hmacsha256_update
, (SIGN
)isc_hmacsha256_sign
,
417 t_hmac("HMAC-SHA384", (HMAC_INIT
)isc_hmacsha384_init
,
418 (UPDATE
)isc_hmacsha384_update
, (SIGN
)isc_hmacsha384_sign
,
420 t_hmac("HMAC-SHA512", (HMAC_INIT
)isc_hmacsha512_init
,
421 (UPDATE
)isc_hmacsha512_update
, (SIGN
)isc_hmacsha512_sign
,
428 * This will almost never fail, and so there is no need for the extra noise
429 * that would come from breaking it into several tests.
435 * two ad hoc hash examples
437 t_hashes(&abc
, &abc_sha1
, &abc_sha224
, &abc_md5
);
438 t_hashes(&abc_blah
, &abc_blah_sha1
, &abc_blah_sha224
, &abc_blah_md5
);
441 * three HMAC-md5 examples from RFC 2104
443 t_md5hmac(&rfc2104_1
, &rfc2104_1_hmac
);
444 t_md5hmac(&rfc2104_2
, &rfc2104_2_hmac
);
445 t_md5hmac(&rfc2104_3
, &rfc2104_3_hmac
);
448 * four HMAC-SHA tests from RFC 4634 starting on page 86
450 t_hmacs(&rfc4634_1
, &rfc4634_1_sha1
, &rfc4634_1_sha224
,
451 &rfc4634_1_sha256
, &rfc4634_1_sha384
, &rfc4634_1_sha512
);
452 t_hmacs(&rfc4634_2
, &rfc4634_2_sha1
, &rfc4634_2_sha224
,
453 &rfc4634_2_sha256
, &rfc4634_2_sha384
, &rfc4634_2_sha512
);
454 t_hmacs(&rfc4634_3
, &rfc4634_3_sha1
, &rfc4634_3_sha224
,
455 &rfc4634_3_sha256
, &rfc4634_3_sha384
, &rfc4634_3_sha512
);
456 t_hmacs(&rfc4634_4
, &rfc4634_4_sha1
, &rfc4634_4_sha224
,
457 &rfc4634_4_sha256
, &rfc4634_4_sha384
, &rfc4634_4_sha512
);
466 testspec_t T_testlist
[] = {
467 { (PFV
) t1
, "hashes" },
473 main(int argc
, char **argv
) {
474 t_settests(T_testlist
);
475 return (t_main(argc
, argv
));