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