summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/regress/lib/libc/hash/Makefile3
-rw-r--r--src/regress/lib/libc/hash/hash_test.c943
2 files changed, 946 insertions, 0 deletions
diff --git a/src/regress/lib/libc/hash/Makefile b/src/regress/lib/libc/hash/Makefile
new file mode 100644
index 0000000000..54e4baace8
--- /dev/null
+++ b/src/regress/lib/libc/hash/Makefile
@@ -0,0 +1,3 @@
1PROG = hash_test
2
3.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/hash/hash_test.c b/src/regress/lib/libc/hash/hash_test.c
new file mode 100644
index 0000000000..67b1f380ed
--- /dev/null
+++ b/src/regress/lib/libc/hash/hash_test.c
@@ -0,0 +1,943 @@
1/* $OpenBSD: hash_test.c,v 1.1.1.1 2025/04/14 17:32:05 tb Exp $ */
2
3/*
4 * Copyright (c) 2025 Theo Buehler <tb@openbsd.org>
5 *
6 * Permission to use, copy, modify, and 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.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20
21#include <md5.h>
22#include <rmd160.h>
23#include <sha1.h>
24#include <sha2.h>
25#include <stdio.h>
26#include <string.h>
27
28#define ALL_HASHES_ALLOW_NULL 0
29
30#define MAX_DIGEST_LENGTH SHA512_DIGEST_LENGTH
31
32struct hash_test_case {
33 const char *in;
34 const uint8_t out[MAX_DIGEST_LENGTH];
35};
36
37enum {
38 hash_md5,
39 hash_rmd160,
40 hash_sha1,
41 hash_sha224,
42 hash_sha256,
43 hash_sha384,
44 hash_sha512,
45 hash_sha512_256,
46 NUM_HASHES,
47};
48
49/* RFC 1321, Appendix A.5 */
50static const struct hash_test_case md5_tests[] = {
51#if ALL_HASHES_ALLOW_NULL
52 {
53 .out = {
54 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
55 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e,
56 },
57 },
58#endif
59 {
60 .in = "",
61 .out = {
62 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
63 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e,
64 },
65 },
66 {
67 .in = "a",
68 .out = {
69 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
70 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61,
71 },
72 },
73 {
74 .in = "abc",
75 .out = {
76 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
77 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72,
78 },
79 },
80 {
81 .in = "message digest",
82 .out = {
83 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
84 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0,
85 },
86 },
87 {
88 .in = "abcdefghijklmnopqrstuvwxyz",
89 .out = {
90 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
91 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b,
92 },
93 },
94 {
95 .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
96 "abcdefghijklmnopqrstuvwxyz0123456789",
97 .out = {
98 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
99 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f,
100 },
101 },
102 {
103 .in = "1234567890123456789012345678901234567890"
104 "1234567890123456789012345678901234567890",
105 .out = {
106 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
107 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a,
108 },
109 },
110};
111
112#define N_MD5_TESTS (sizeof(md5_tests) / sizeof(md5_tests[0]))
113
114static void
115md5_init(void *ctx)
116{
117 MD5Init(ctx);
118}
119
120static void
121md5_update(void *ctx, const uint8_t *data, size_t len)
122{
123 MD5Update(ctx, data, len);
124}
125
126static void
127md5_final(void *digest, void *ctx)
128{
129 MD5Final(digest, ctx);
130}
131
132/* https://homes.esat.kuleuven.be/~bosselae/ripemd160.html */
133static const struct hash_test_case rmd160_tests[] = {
134#if ALL_HASHES_ALLOW_NULL
135 {
136 .out = {
137 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54,
138 0x61, 0x28, 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48,
139 0xb2, 0x25, 0x8d, 0x31,
140 },
141 },
142#endif
143 {
144 .in = "",
145 .out = {
146 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54,
147 0x61, 0x28, 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48,
148 0xb2, 0x25, 0x8d, 0x31,
149 },
150 },
151 {
152 .in = "a",
153 .out = {
154 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9,
155 0xda, 0xae, 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83,
156 0x5a, 0x46, 0x7f, 0xfe,
157 },
158 },
159 {
160 .in = "abc",
161 .out = {
162 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a,
163 0x9b, 0x04, 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87,
164 0xf1, 0x5a, 0x0b, 0xfc,
165 },
166 },
167 {
168 .in = "message digest",
169 .out = {
170 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5,
171 0x72, 0xb8, 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa,
172 0x21, 0x59, 0x5f, 0x36,
173 },
174 },
175 {
176 .in = "abcdefghijklmnopqrstuvwxyz",
177 .out = {
178 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b,
179 0x56, 0xbb, 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65,
180 0xb3, 0x70, 0x8d, 0xbc,
181 },
182 },
183 {
184 .in = "abcdbcdecdefdefgefghfghighijhijkijkljkl"
185 "mklmnlmnomnopnopq",
186 .out = {
187 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88,
188 0xe4, 0x05, 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a,
189 0xda, 0x62, 0xeb, 0x2b,
190 },
191 },
192 {
193 .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
194 "0123456789",
195 .out = {
196 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02,
197 0x86, 0xed, 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79,
198 0xb2, 0x1f, 0x51, 0x89,
199 },
200 },
201 {
202 .in = "1234567890123456789012345678901234567890"
203 "1234567890123456789012345678901234567890",
204 .out = {
205 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39,
206 0xf4, 0xdb, 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf,
207 0x63, 0x32, 0x6b, 0xfb,
208 },
209 },
210};
211
212#define N_RMD160_TESTS (sizeof(rmd160_tests) / sizeof(rmd160_tests[0]))
213
214static void
215rmd160_init(void *ctx)
216{
217 RMD160Init(ctx);
218}
219
220static void
221rmd160_update(void *ctx, const uint8_t *data, size_t len)
222{
223 RMD160Update(ctx, data, len);
224}
225
226static void
227rmd160_final(void *digest, void *ctx)
228{
229 RMD160Final(digest, ctx);
230}
231
232/* RFC 3174 - Appendix A (plus two zero-length tests) */
233static const struct hash_test_case sha1_tests[] = {
234#if ALL_HASHES_ALLOW_NULL
235 {
236 .out = {
237 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
238 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
239 0xaf, 0xd8, 0x07, 0x09,
240 },
241 },
242#endif
243 {
244 .in = "",
245 .out = {
246 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
247 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
248 0xaf, 0xd8, 0x07, 0x09,
249 },
250 },
251 {
252 .in = "abc",
253 .out = {
254 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
255 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
256 0x9c, 0xd0, 0xd8, 0x9d,
257 },
258 },
259 {
260 .in = "abcdbcdecdefdefgefghfghighijhi"
261 "jkijkljklmklmnlmnomnopnopq",
262 .out = {
263 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e,
264 0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5,
265 0xe5, 0x46, 0x70, 0xf1,
266 },
267 },
268 {
269 .in = "0123456701234567012345670123456701234567012345670123456701234567"
270 "0123456701234567012345670123456701234567012345670123456701234567"
271 "0123456701234567012345670123456701234567012345670123456701234567"
272 "0123456701234567012345670123456701234567012345670123456701234567"
273 "0123456701234567012345670123456701234567012345670123456701234567"
274 "0123456701234567012345670123456701234567012345670123456701234567"
275 "0123456701234567012345670123456701234567012345670123456701234567"
276 "0123456701234567012345670123456701234567012345670123456701234567"
277 "0123456701234567012345670123456701234567012345670123456701234567"
278 "0123456701234567012345670123456701234567012345670123456701234567",
279 .out = {
280 0xde, 0xa3, 0x56, 0xa2, 0xcd, 0xdd, 0x90, 0xc7,
281 0xa7, 0xec, 0xed, 0xc5, 0xeb, 0xb5, 0x63, 0x93,
282 0x4f, 0x46, 0x04, 0x52,
283 },
284 },
285};
286
287#define N_SHA1_TESTS (sizeof(sha1_tests) / sizeof(sha1_tests[0]))
288
289static void
290sha1_init(void *ctx)
291{
292 SHA1Init(ctx);
293}
294
295static void
296sha1_update(void *ctx, const uint8_t *data, size_t len)
297{
298 SHA1Update(ctx, data, len);
299}
300
301static void
302sha1_final(void *digest, void *ctx)
303{
304 SHA1Final(digest, ctx);
305}
306
307static const struct hash_test_case sha224_tests[] = {
308 {
309 .out = {
310 0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9,
311 0x47, 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4,
312 0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a,
313 0xc5, 0xb3, 0xe4, 0x2f,
314 },
315 },
316 {
317 .in = "",
318 .out = {
319 0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9,
320 0x47, 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4,
321 0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a,
322 0xc5, 0xb3, 0xe4, 0x2f,
323 },
324 },
325 {
326 .in = "abc",
327 .out = {
328 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22,
329 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3,
330 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7,
331 0xe3, 0x6c, 0x9d, 0xa7,
332 },
333 },
334 {
335 .in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
336 .out = {
337 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc,
338 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50,
339 0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19,
340 0x52, 0x52, 0x25, 0x25,
341 },
342 },
343 {
344 .in = "0123456701234567012345670123456701234567012345670123456701234567"
345 "0123456701234567012345670123456701234567012345670123456701234567"
346 "0123456701234567012345670123456701234567012345670123456701234567"
347 "0123456701234567012345670123456701234567012345670123456701234567"
348 "0123456701234567012345670123456701234567012345670123456701234567"
349 "0123456701234567012345670123456701234567012345670123456701234567"
350 "0123456701234567012345670123456701234567012345670123456701234567"
351 "0123456701234567012345670123456701234567012345670123456701234567"
352 "0123456701234567012345670123456701234567012345670123456701234567"
353 "0123456701234567012345670123456701234567012345670123456701234567",
354 .out = {
355 0x56, 0x7f, 0x69, 0xf1, 0x68, 0xcd, 0x78, 0x44,
356 0xe6, 0x52, 0x59, 0xce, 0x65, 0x8f, 0xe7, 0xaa,
357 0xdf, 0xa2, 0x52, 0x16, 0xe6, 0x8e, 0xca, 0x0e,
358 0xb7, 0xab, 0x82, 0x62,
359 },
360 },
361 {
362 .in = "\x07",
363 .out = {
364 0x00, 0xec, 0xd5, 0xf1, 0x38, 0x42, 0x2b, 0x8a,
365 0xd7, 0x4c, 0x97, 0x99, 0xfd, 0x82, 0x6c, 0x53,
366 0x1b, 0xad, 0x2f, 0xca, 0xbc, 0x74, 0x50, 0xbe,
367 0xe2, 0xaa, 0x8c, 0x2a,
368 },
369 },
370};
371
372#define N_SHA224_TESTS (sizeof(sha224_tests) / sizeof(sha224_tests[0]))
373
374static void
375sha224_init(void *ctx)
376{
377 SHA224Init(ctx);
378}
379
380static void
381sha224_update(void *ctx, const uint8_t *data, size_t len)
382{
383 SHA224Update(ctx, data, len);
384}
385
386static void
387sha224_final(void *digest, void *ctx)
388{
389 SHA224Final(digest, ctx);
390}
391
392static const struct hash_test_case sha256_tests[] = {
393 {
394 .out = {
395 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
396 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
397 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
398 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
399 },
400 },
401 {
402 .in = "",
403 .out = {
404 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
405 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
406 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
407 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
408 },
409 },
410 {
411 .in = "abc",
412 .out = {
413 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
414 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
415 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
416 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD,
417 },
418 },
419 {
420 .in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
421 .out = {
422 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
423 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
424 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
425 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1,
426 },
427 },
428 {
429 .in = "0123456701234567012345670123456701234567012345670123456701234567"
430 "0123456701234567012345670123456701234567012345670123456701234567"
431 "0123456701234567012345670123456701234567012345670123456701234567"
432 "0123456701234567012345670123456701234567012345670123456701234567"
433 "0123456701234567012345670123456701234567012345670123456701234567"
434 "0123456701234567012345670123456701234567012345670123456701234567"
435 "0123456701234567012345670123456701234567012345670123456701234567"
436 "0123456701234567012345670123456701234567012345670123456701234567"
437 "0123456701234567012345670123456701234567012345670123456701234567"
438 "0123456701234567012345670123456701234567012345670123456701234567",
439 .out = {
440 0x59, 0x48, 0x47, 0x32, 0x84, 0x51, 0xBD, 0xFA,
441 0x85, 0x05, 0x62, 0x25, 0x46, 0x2C, 0xC1, 0xD8,
442 0x67, 0xD8, 0x77, 0xFB, 0x38, 0x8D, 0xF0, 0xCE,
443 0x35, 0xF2, 0x5A, 0xB5, 0x56, 0x2B, 0xFB, 0xB5,
444 },
445 },
446 {
447 .in = "\x19",
448 .out = {
449 0x68, 0xaa, 0x2e, 0x2e, 0xe5, 0xdf, 0xf9, 0x6e,
450 0x33, 0x55, 0xe6, 0xc7, 0xee, 0x37, 0x3e, 0x3d,
451 0x6a, 0x4e, 0x17, 0xf7, 0x5f, 0x95, 0x18, 0xd8,
452 0x43, 0x70, 0x9c, 0x0c, 0x9b, 0xc3, 0xe3, 0xd4,
453 },
454 },
455};
456
457#define N_SHA256_TESTS (sizeof(sha256_tests) / sizeof(sha256_tests[0]))
458
459static void
460sha256_init(void *ctx)
461{
462 SHA256Init(ctx);
463}
464
465static void
466sha256_update(void *ctx, const uint8_t *data, size_t len)
467{
468 SHA256Update(ctx, data, len);
469}
470
471static void
472sha256_final(void *digest, void *ctx)
473{
474 SHA256Final(digest, ctx);
475}
476
477static const struct hash_test_case sha384_tests[] = {
478 {
479 .out = {
480 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
481 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
482 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
483 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
484 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
485 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b,
486 },
487 },
488 {
489 .in = "",
490 .out = {
491 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
492 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
493 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
494 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
495 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
496 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b,
497 },
498 },
499 {
500 .in = "abc",
501 .out = {
502 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
503 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
504 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
505 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
506 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
507 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7,
508 },
509 },
510 {
511 .in = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
512 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
513 .out = {
514 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
515 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
516 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
517 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
518 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
519 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39,
520 },
521 },
522 {
523 .in = "0123456701234567012345670123456701234567012345670123456701234567"
524 "0123456701234567012345670123456701234567012345670123456701234567"
525 "0123456701234567012345670123456701234567012345670123456701234567"
526 "0123456701234567012345670123456701234567012345670123456701234567"
527 "0123456701234567012345670123456701234567012345670123456701234567"
528 "0123456701234567012345670123456701234567012345670123456701234567"
529 "0123456701234567012345670123456701234567012345670123456701234567"
530 "0123456701234567012345670123456701234567012345670123456701234567"
531 "0123456701234567012345670123456701234567012345670123456701234567"
532 "0123456701234567012345670123456701234567012345670123456701234567",
533 .out = {
534 0x2f, 0xc6, 0x4a, 0x4f, 0x50, 0x0d, 0xdb, 0x68,
535 0x28, 0xf6, 0xa3, 0x43, 0x0b, 0x8d, 0xd7, 0x2a,
536 0x36, 0x8e, 0xb7, 0xf3, 0xa8, 0x32, 0x2a, 0x70,
537 0xbc, 0x84, 0x27, 0x5b, 0x9c, 0x0b, 0x3a, 0xb0,
538 0x0d, 0x27, 0xa5, 0xcc, 0x3c, 0x2d, 0x22, 0x4a,
539 0xa6, 0xb6, 0x1a, 0x0d, 0x79, 0xfb, 0x45, 0x96,
540 },
541 },
542 {
543 .in = "\xb9",
544 .out = {
545 0xbc, 0x80, 0x89, 0xa1, 0x90, 0x07, 0xc0, 0xb1,
546 0x41, 0x95, 0xf4, 0xec, 0xc7, 0x40, 0x94, 0xfe,
547 0xc6, 0x4f, 0x01, 0xf9, 0x09, 0x29, 0x28, 0x2c,
548 0x2f, 0xb3, 0x92, 0x88, 0x15, 0x78, 0x20, 0x8a,
549 0xd4, 0x66, 0x82, 0x8b, 0x1c, 0x6c, 0x28, 0x3d,
550 0x27, 0x22, 0xcf, 0x0a, 0xd1, 0xab, 0x69, 0x38,
551 },
552 },
553};
554
555#define N_SHA384_TESTS (sizeof(sha384_tests) / sizeof(sha384_tests[0]))
556
557static void
558sha384_init(void *ctx)
559{
560 SHA384Init(ctx);
561}
562
563static void
564sha384_update(void *ctx, const uint8_t *data, size_t len)
565{
566 SHA384Update(ctx, data, len);
567}
568
569static void
570sha384_final(void *digest, void *ctx)
571{
572 SHA384Final(digest, ctx);
573}
574
575static const struct hash_test_case sha512_tests[] = {
576 {
577 .out = {
578 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
579 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
580 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
581 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
582 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
583 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
584 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
585 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
586 },
587 },
588 {
589 .in = "",
590 .out = {
591 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
592 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
593 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
594 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
595 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
596 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
597 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
598 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
599 },
600 },
601 {
602 .in = "abc",
603 .out = {
604 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
605 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
606 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
607 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
608 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
609 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
610 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
611 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
612 },
613 },
614 {
615 .in = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
616 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
617 .out = {
618 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
619 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
620 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
621 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
622 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
623 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
624 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
625 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09,
626 },
627 },
628 {
629 .in = "0123456701234567012345670123456701234567012345670123456701234567"
630 "0123456701234567012345670123456701234567012345670123456701234567"
631 "0123456701234567012345670123456701234567012345670123456701234567"
632 "0123456701234567012345670123456701234567012345670123456701234567"
633 "0123456701234567012345670123456701234567012345670123456701234567"
634 "0123456701234567012345670123456701234567012345670123456701234567"
635 "0123456701234567012345670123456701234567012345670123456701234567"
636 "0123456701234567012345670123456701234567012345670123456701234567"
637 "0123456701234567012345670123456701234567012345670123456701234567"
638 "0123456701234567012345670123456701234567012345670123456701234567",
639 .out = {
640 0x89, 0xd0, 0x5b, 0xa6, 0x32, 0xc6, 0x99, 0xc3,
641 0x12, 0x31, 0xde, 0xd4, 0xff, 0xc1, 0x27, 0xd5,
642 0xa8, 0x94, 0xda, 0xd4, 0x12, 0xc0, 0xe0, 0x24,
643 0xdb, 0x87, 0x2d, 0x1a, 0xbd, 0x2b, 0xa8, 0x14,
644 0x1a, 0x0f, 0x85, 0x07, 0x2a, 0x9b, 0xe1, 0xe2,
645 0xaa, 0x04, 0xcf, 0x33, 0xc7, 0x65, 0xcb, 0x51,
646 0x08, 0x13, 0xa3, 0x9c, 0xd5, 0xa8, 0x4c, 0x4a,
647 0xca, 0xa6, 0x4d, 0x3f, 0x3f, 0xb7, 0xba, 0xe9,
648 },
649 },
650 {
651 .in = "\xd0",
652 .out = {
653 0x99, 0x92, 0x20, 0x29, 0x38, 0xe8, 0x82, 0xe7,
654 0x3e, 0x20, 0xf6, 0xb6, 0x9e, 0x68, 0xa0, 0xa7,
655 0x14, 0x90, 0x90, 0x42, 0x3d, 0x93, 0xc8, 0x1b,
656 0xab, 0x3f, 0x21, 0x67, 0x8d, 0x4a, 0xce, 0xee,
657 0xe5, 0x0e, 0x4e, 0x8c, 0xaf, 0xad, 0xa4, 0xc8,
658 0x5a, 0x54, 0xea, 0x83, 0x06, 0x82, 0x6c, 0x4a,
659 0xd6, 0xe7, 0x4c, 0xec, 0xe9, 0x63, 0x1b, 0xfa,
660 0x8a, 0x54, 0x9b, 0x4a, 0xb3, 0xfb, 0xba, 0x15,
661 },
662 },
663};
664
665#define N_SHA512_TESTS (sizeof(sha512_tests) / sizeof(sha512_tests[0]))
666
667static void
668sha512_init(void *ctx)
669{
670 SHA512Init(ctx);
671}
672
673static void
674sha512_update(void *ctx, const uint8_t *data, size_t len)
675{
676 SHA512Update(ctx, data, len);
677}
678
679static void
680sha512_final(void *digest, void *ctx)
681{
682 SHA512Final(digest, ctx);
683}
684
685static const struct hash_test_case sha512_256_tests[] = {
686 {
687 .out = {
688 0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28,
689 0xab, 0x87, 0xc3, 0x62, 0x2c, 0x51, 0x14, 0x06,
690 0x9b, 0xdd, 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74,
691 0x98, 0xd0, 0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a,
692 },
693 },
694 {
695 .in = "",
696 .out = {
697 0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28,
698 0xab, 0x87, 0xc3, 0x62, 0x2c, 0x51, 0x14, 0x06,
699 0x9b, 0xdd, 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74,
700 0x98, 0xd0, 0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a,
701 },
702 },
703 {
704 .in = "abc",
705 .out = {
706 0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9,
707 0x9b, 0x2e, 0x29, 0xb7, 0x6b, 0x4c, 0x7d, 0xab,
708 0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, 0x6d, 0x46,
709 0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23,
710 },
711 },
712 {
713 .in = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
714 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
715 .out = {
716 0x39, 0x28, 0xe1, 0x84, 0xfb, 0x86, 0x90, 0xf8,
717 0x40, 0xda, 0x39, 0x88, 0x12, 0x1d, 0x31, 0xbe,
718 0x65, 0xcb, 0x9d, 0x3e, 0xf8, 0x3e, 0xe6, 0x14,
719 0x6f, 0xea, 0xc8, 0x61, 0xe1, 0x9b, 0x56, 0x3a,
720 },
721 },
722 {
723 .in = "0123456701234567012345670123456701234567012345670123456701234567"
724 "0123456701234567012345670123456701234567012345670123456701234567"
725 "0123456701234567012345670123456701234567012345670123456701234567"
726 "0123456701234567012345670123456701234567012345670123456701234567"
727 "0123456701234567012345670123456701234567012345670123456701234567"
728 "0123456701234567012345670123456701234567012345670123456701234567"
729 "0123456701234567012345670123456701234567012345670123456701234567"
730 "0123456701234567012345670123456701234567012345670123456701234567"
731 "0123456701234567012345670123456701234567012345670123456701234567"
732 "0123456701234567012345670123456701234567012345670123456701234567",
733 .out = {
734 0xcf, 0x78, 0xe4, 0xba, 0x93, 0x5b, 0x4d, 0x9e,
735 0xb9, 0x10, 0x52, 0xae, 0xdd, 0xf8, 0xe2, 0xd6,
736 0x06, 0xc5, 0x90, 0xf7, 0x08, 0x57, 0x36, 0x93,
737 0xea, 0x94, 0xbe, 0x82, 0x6a, 0x66, 0x6e, 0xe4,
738 },
739 },
740};
741
742#define N_SHA512_256_TESTS (sizeof(sha512_256_tests) / sizeof(sha512_256_tests[0]))
743
744static void
745sha512_256_init(void *ctx)
746{
747 SHA512_256Init(ctx);
748}
749
750static void
751sha512_256_update(void *ctx, const uint8_t *data, size_t len)
752{
753 SHA512_256Update(ctx, data, len);
754}
755
756static void
757sha512_256_final(void *digest, void *ctx)
758{
759 SHA512_256Final(digest, ctx);
760}
761
762struct hash_ctx {
763 uint8_t *digest;
764 size_t digest_len;
765 void *ctx;
766 void (*init)(void *);
767 void (*update)(void *, const uint8_t *, size_t);
768 void (*final)(void *, void *final);
769};
770
771static const struct hash_tests {
772 const char *name;
773 size_t num_tests;
774 const struct hash_test_case *tests;
775} hash_tests[] = {
776 [hash_md5] = {
777 .name = "RFC 1321 MD5",
778 .num_tests = N_MD5_TESTS,
779 .tests = md5_tests,
780 },
781 [hash_rmd160] = {
782 .name = "Bosselaers RMD160",
783 .num_tests = N_RMD160_TESTS,
784 .tests = rmd160_tests,
785 },
786 [hash_sha1] = {
787 .name = "RFC 3174 SHA1",
788 .num_tests = N_SHA1_TESTS,
789 .tests = sha1_tests,
790 },
791 [hash_sha224] = {
792 .name = "RFC 6234 SHA224",
793 .num_tests = N_SHA224_TESTS,
794 .tests = sha224_tests,
795 },
796 [hash_sha256] = {
797 .name = "RFC 6234 SHA256",
798 .num_tests = N_SHA256_TESTS,
799 .tests = sha256_tests,
800 },
801 [hash_sha384] = {
802 .name = "RFC 6234 SHA384",
803 .num_tests = N_SHA384_TESTS,
804 .tests = sha384_tests,
805 },
806 [hash_sha512] = {
807 .name = "RFC 6234 SHA512",
808 .num_tests = N_SHA512_TESTS,
809 .tests = sha512_tests,
810 },
811 [hash_sha512_256] = {
812 .name = "RFC 6234 SHA512_256 (generated)",
813 .num_tests = N_SHA512_256_TESTS,
814 .tests = sha512_256_tests,
815 },
816};
817
818static int
819hash_test_case(struct hash_ctx *ctx, const struct hash_test_case *tc,
820 const char *name, size_t testno)
821{
822 size_t in_len = tc->in != NULL ? strlen(tc->in) : 0;
823
824 ctx->init(ctx->ctx);
825 ctx->update(ctx->ctx, (uint8_t *)tc->in, in_len);
826 ctx->final(ctx->digest, ctx->ctx);
827
828 if (memcmp(tc->out, ctx->digest, ctx->digest_len) != 0) {
829 fprintf(stderr, "FAIL: %s test %zu\n", name, testno);
830 return 1;
831 }
832
833 return 0;
834}
835
836static int
837hash_test(struct hash_ctx *ctx, const struct hash_tests *tests)
838{
839 size_t i;
840 int failed = 0;
841
842 for (i = 0; i < tests->num_tests; i++) {
843 const struct hash_test_case *tc = &tests->tests[i];
844
845 failed |= hash_test_case(ctx, tc, tests->name, i);
846 }
847
848 return failed;
849}
850
851int
852main(void)
853{
854 uint8_t md5_digest[MD5_DIGEST_LENGTH];
855 uint8_t rmd160_digest[RMD160_DIGEST_LENGTH];
856 uint8_t sha1_digest[SHA1_DIGEST_LENGTH];
857 uint8_t sha224_digest[SHA224_DIGEST_LENGTH];
858 uint8_t sha256_digest[SHA256_DIGEST_LENGTH];
859 uint8_t sha384_digest[SHA384_DIGEST_LENGTH];
860 uint8_t sha512_digest[SHA512_DIGEST_LENGTH];
861 uint8_t sha512_256_digest[SHA512_256_DIGEST_LENGTH];
862 MD5_CTX md5_ctx;
863 RMD160_CTX rmd160_ctx;
864 SHA1_CTX sha1_ctx;
865 SHA2_CTX sha224_ctx;
866 SHA2_CTX sha256_ctx;
867 SHA2_CTX sha384_ctx;
868 SHA2_CTX sha512_ctx;
869 SHA2_CTX sha512_256_ctx;
870 struct hash_ctx ctx[] = {
871 [hash_md5] = {
872 .digest = md5_digest,
873 .digest_len = sizeof(md5_digest),
874 .ctx = &md5_ctx,
875 .init = md5_init,
876 .update = md5_update,
877 .final = md5_final,
878 },
879 [hash_rmd160] = {
880 .digest = rmd160_digest,
881 .digest_len = sizeof(rmd160_digest),
882 .ctx = &rmd160_ctx,
883 .init = rmd160_init,
884 .update = rmd160_update,
885 .final = rmd160_final,
886 },
887 [hash_sha1] = {
888 .digest = sha1_digest,
889 .digest_len = sizeof(sha1_digest),
890 .ctx = &sha1_ctx,
891 .init = sha1_init,
892 .update = sha1_update,
893 .final = sha1_final,
894 },
895 [hash_sha224] = {
896 .digest = sha224_digest,
897 .digest_len = sizeof(sha224_digest),
898 .ctx = &sha224_ctx,
899 .init = sha224_init,
900 .update = sha224_update,
901 .final = sha224_final,
902 },
903 [hash_sha256] = {
904 .digest = sha256_digest,
905 .digest_len = sizeof(sha256_digest),
906 .ctx = &sha256_ctx,
907 .init = sha256_init,
908 .update = sha256_update,
909 .final = sha256_final,
910 },
911 [hash_sha384] = {
912 .digest = sha384_digest,
913 .digest_len = sizeof(sha384_digest),
914 .ctx = &sha384_ctx,
915 .init = sha384_init,
916 .update = sha384_update,
917 .final = sha384_final,
918 },
919 [hash_sha512] = {
920 .digest = sha512_digest,
921 .digest_len = sizeof(sha512_digest),
922 .ctx = &sha512_ctx,
923 .init = sha512_init,
924 .update = sha512_update,
925 .final = sha512_final,
926 },
927 [hash_sha512_256] = {
928 .digest = sha512_256_digest,
929 .digest_len = sizeof(sha512_256_digest),
930 .ctx = &sha512_256_ctx,
931 .init = sha512_256_init,
932 .update = sha512_256_update,
933 .final = sha512_256_final,
934 },
935 };
936 int i;
937 int failed = 0;
938
939 for (i = 0; i < NUM_HASHES; i++)
940 failed |= hash_test(&ctx[i], &hash_tests[i]);
941
942 return failed;
943}