xref: /openbsd/regress/lib/libcrypto/sha/sha_test.c (revision 684e5946)
1 /*	$OpenBSD: sha_test.c,v 1.6 2023/07/19 15:11:42 joshua Exp $ */
2 /*
3  * Copyright (c) 2022, 2023 Joshua Sing <joshua@hypera.dev>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <openssl/evp.h>
19 #include <openssl/sha.h>
20 
21 #include <stdint.h>
22 #include <string.h>
23 
24 struct sha_test {
25 	const int algorithm;
26 	const uint8_t in[128];
27 	const size_t in_len;
28 	const uint8_t out[EVP_MAX_MD_SIZE];
29 };
30 
31 static const struct sha_test sha_tests[] = {
32 	/* SHA-1 */
33 	{
34 		.algorithm = NID_sha1,
35 		.in = "abc",
36 		.in_len = 3,
37 		.out = {
38 			0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
39 			0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
40 			0x9c, 0xd0, 0xd8, 0x9d,
41 		},
42 	},
43 	{
44 		.algorithm = NID_sha1,
45 		.in = "",
46 		.in_len = 0,
47 		.out = {
48 			0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
49 			0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
50 			0xaf, 0xd8, 0x07, 0x09,
51 		},
52 	},
53 	{
54 		.algorithm = NID_sha1,
55 		.in =
56 		    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno"
57 		    "mnopnopq",
58 		.in_len = 56,
59 		.out = {
60 			0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e,
61 			0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5,
62 			0xe5, 0x46, 0x70, 0xf1,
63 		},
64 	},
65 	{
66 		.algorithm = NID_sha1,
67 		.in =
68 		    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm"
69 		    "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
70 		    "mnopqrstnopqrstu",
71 		.in_len = 112,
72 		.out = {
73 			0xa4, 0x9b, 0x24, 0x46, 0xa0, 0x2c, 0x64, 0x5b,
74 			0xf4, 0x19, 0xf9, 0x95, 0xb6, 0x70, 0x91, 0x25,
75 			0x3a, 0x04, 0xa2, 0x59,
76 		},
77 	},
78 
79 	/* SHA-224 */
80 	{
81 		.algorithm = NID_sha224,
82 		.in = "abc",
83 		.in_len = 3,
84 		.out = {
85 			0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22,
86 			0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3,
87 			0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7,
88 			0xe3, 0x6c, 0x9d, 0xa7,
89 		},
90 	},
91 	{
92 		.algorithm = NID_sha224,
93 		.in = "",
94 		.in_len = 0,
95 		.out = {
96 			0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9,
97 			0x47, 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4,
98 			0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a,
99 			0xc5, 0xb3, 0xe4, 0x2f,
100 		},
101 	},
102 	{
103 		.algorithm = NID_sha224,
104 		.in =
105 		    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno"
106 		    "mnopnopq",
107 		.in_len = 56,
108 		.out = {
109 			0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc,
110 			0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50,
111 			0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19,
112 			0x52, 0x52, 0x25, 0x25,
113 		},
114 	},
115 	{
116 		.algorithm = NID_sha224,
117 		.in =
118 		    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm"
119 		    "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
120 		    "mnopqrstnopqrstu",
121 		.in_len = 112,
122 		.out = {
123 			0xc9, 0x7c, 0xa9, 0xa5, 0x59, 0x85, 0x0c, 0xe9,
124 			0x7a, 0x04, 0xa9, 0x6d, 0xef, 0x6d, 0x99, 0xa9,
125 			0xe0, 0xe0, 0xe2, 0xab, 0x14, 0xe6, 0xb8, 0xdf,
126 			0x26, 0x5f, 0xc0, 0xb3,
127 		},
128 	},
129 
130 	/* SHA-256 */
131 	{
132 		.algorithm = NID_sha256,
133 		.in = "abc",
134 		.in_len = 3,
135 		.out = {
136 			0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
137 			0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
138 			0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
139 			0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
140 		},
141 	},
142 	{
143 		.algorithm = NID_sha256,
144 		.in = "",
145 		.in_len = 0,
146 		.out = {
147 			0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
148 			0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
149 			0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
150 			0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
151 		},
152 	},
153 	{
154 		.algorithm = NID_sha256,
155 		.in =
156 		    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno"
157 		    "mnopnopq",
158 		.in_len = 56,
159 		.out = {
160 			0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
161 			0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
162 			0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
163 			0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1,
164 		},
165 	},
166 	{
167 		.algorithm = NID_sha256,
168 		.in =
169 		    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm"
170 		    "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
171 		    "mnopqrstnopqrstu",
172 		.in_len = 112,
173 		.out = {
174 			0xcf, 0x5b, 0x16, 0xa7, 0x78, 0xaf, 0x83, 0x80,
175 			0x03, 0x6c, 0xe5, 0x9e, 0x7b, 0x04, 0x92, 0x37,
176 			0x0b, 0x24, 0x9b, 0x11, 0xe8, 0xf0, 0x7a, 0x51,
177 			0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1,
178 		},
179 	},
180 
181 	/* SHA-384 */
182 	{
183 		.algorithm = NID_sha384,
184 		.in = "abc",
185 		.in_len = 3,
186 		.out = {
187 			0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
188 			0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
189 			0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
190 			0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
191 			0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
192 			0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7,
193 		},
194 	},
195 	{
196 		.algorithm = NID_sha384,
197 		.in = "",
198 		.in_len = 0,
199 		.out = {
200 			0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
201 			0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
202 			0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
203 			0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
204 			0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
205 			0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b,
206 		},
207 	},
208 	{
209 		.algorithm = NID_sha384,
210 		.in =
211 		    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno"
212 		    "mnopnopq",
213 		.in_len = 56,
214 		.out = {
215 			0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39,
216 			0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39,
217 			0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab,
218 			0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6,
219 			0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f,
220 			0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b,
221 		},
222 	},
223 	{
224 		.algorithm = NID_sha384,
225 		.in =
226 		    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm"
227 		    "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
228 		    "mnopqrstnopqrstu",
229 		.in_len = 112,
230 		.out = {
231 			0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
232 			0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
233 			0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
234 			0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
235 			0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
236 			0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39,
237 		},
238 	},
239 
240 	/* SHA-512 */
241 	{
242 		.algorithm = NID_sha512,
243 		.in = "abc",
244 		.in_len = 3,
245 		.out = {
246 			0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
247 			0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
248 			0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
249 			0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
250 			0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
251 			0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
252 			0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
253 			0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
254 		},
255 	},
256 	{
257 		.algorithm = NID_sha512,
258 		.in = "",
259 		.in_len = 0,
260 		.out = {
261 			0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
262 			0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
263 			0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
264 			0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
265 			0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
266 			0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
267 			0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
268 			0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
269 		},
270 	},
271 	{
272 		.algorithm = NID_sha512,
273 		.in =
274 		    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno"
275 		    "mnopnopq",
276 		.in_len = 56,
277 		.out = {
278 			0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a,
279 			0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16,
280 			0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8,
281 			0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35,
282 			0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9,
283 			0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0,
284 			0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03,
285 			0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45,
286 		},
287 	},
288 	{
289 		.algorithm = NID_sha512,
290 		.in =
291 		    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm"
292 		    "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
293 		    "mnopqrstnopqrstu",
294 		.in_len = 112,
295 		.out = {
296 			0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
297 			0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
298 			0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
299 			0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
300 			0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
301 			0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
302 			0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
303 			0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09,
304 		},
305 	},
306 
307 	/* SHA3-224 */
308 	{
309 		.algorithm = NID_sha3_224,
310 		.in = "abc",
311 		.in_len = 3,
312 		.out = {
313 			0xe6, 0x42, 0x82, 0x4c, 0x3f, 0x8c, 0xf2, 0x4a,
314 			0xd0, 0x92, 0x34, 0xee, 0x7d, 0x3c, 0x76, 0x6f,
315 			0xc9, 0xa3, 0xa5, 0x16, 0x8d, 0x0c, 0x94, 0xad,
316 			0x73, 0xb4, 0x6f, 0xdf,
317 		},
318 	},
319 	{
320 		.algorithm = NID_sha3_224,
321 		.in = "",
322 		.in_len = 0,
323 		.out = {
324 			0x6b, 0x4e, 0x03, 0x42, 0x36, 0x67, 0xdb, 0xb7,
325 			0x3b, 0x6e, 0x15, 0x45, 0x4f, 0x0e, 0xb1, 0xab,
326 			0xd4, 0x59, 0x7f, 0x9a, 0x1b, 0x07, 0x8e, 0x3f,
327 			0x5b, 0x5a, 0x6b, 0xc7,
328 		},
329 	},
330 	{
331 		.algorithm = NID_sha3_224,
332 		.in =
333 		    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno"
334 		    "mnopnopq",
335 		.in_len = 56,
336 		.out = {
337 			0x8a, 0x24, 0x10, 0x8b, 0x15, 0x4a, 0xda, 0x21,
338 			0xc9, 0xfd, 0x55, 0x74, 0x49, 0x44, 0x79, 0xba,
339 			0x5c, 0x7e, 0x7a, 0xb7, 0x6e, 0xf2, 0x64, 0xea,
340 			0xd0, 0xfc, 0xce, 0x33,
341 		},
342 	},
343 	{
344 		.algorithm = NID_sha3_224,
345 		.in =
346 		    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm"
347 		    "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
348 		    "mnopqrstnopqrstu",
349 		.in_len = 112,
350 		.out = {
351 			0x54, 0x3e, 0x68, 0x68, 0xe1, 0x66, 0x6c, 0x1a,
352 			0x64, 0x36, 0x30, 0xdf, 0x77, 0x36, 0x7a, 0xe5,
353 			0xa6, 0x2a, 0x85, 0x07, 0x0a, 0x51, 0xc1, 0x4c,
354 			0xbf, 0x66, 0x5c, 0xbc,
355 		},
356 	},
357 
358 	/* SHA3-256 */
359 	{
360 		.algorithm = NID_sha3_256,
361 		.in = "abc",
362 		.in_len = 3,
363 		.out = {
364 			0x3a, 0x98, 0x5d, 0xa7, 0x4f, 0xe2, 0x25, 0xb2,
365 			0x04, 0x5c, 0x17, 0x2d, 0x6b, 0xd3, 0x90, 0xbd,
366 			0x85, 0x5f, 0x08, 0x6e, 0x3e, 0x9d, 0x52, 0x5b,
367 			0x46, 0xbf, 0xe2, 0x45, 0x11, 0x43, 0x15, 0x32,
368 		},
369 	},
370 	{
371 		.algorithm = NID_sha3_256,
372 		.in = "",
373 		.in_len = 0,
374 		.out = {
375 			0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66,
376 			0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62,
377 			0xf5, 0x80, 0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa,
378 			0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a,
379 		},
380 	},
381 	{
382 		.algorithm = NID_sha3_256,
383 		.in =
384 		    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno"
385 		    "mnopnopq",
386 		.in_len = 56,
387 		.out = {
388 			0x41, 0xc0, 0xdb, 0xa2, 0xa9, 0xd6, 0x24, 0x08,
389 			0x49, 0x10, 0x03, 0x76, 0xa8, 0x23, 0x5e, 0x2c,
390 			0x82, 0xe1, 0xb9, 0x99, 0x8a, 0x99, 0x9e, 0x21,
391 			0xdb, 0x32, 0xdd, 0x97, 0x49, 0x6d, 0x33, 0x76,
392 		},
393 	},
394 	{
395 		.algorithm = NID_sha3_256,
396 		.in =
397 		    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm"
398 		    "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
399 		    "mnopqrstnopqrstu",
400 		.in_len = 112,
401 		.out = {
402 			0x91, 0x6f, 0x60, 0x61, 0xfe, 0x87, 0x97, 0x41,
403 			0xca, 0x64, 0x69, 0xb4, 0x39, 0x71, 0xdf, 0xdb,
404 			0x28, 0xb1, 0xa3, 0x2d, 0xc3, 0x6c, 0xb3, 0x25,
405 			0x4e, 0x81, 0x2b, 0xe2, 0x7a, 0xad, 0x1d, 0x18,
406 		},
407 	},
408 
409 	/* SHA3-384 */
410 	{
411 		.algorithm = NID_sha3_384,
412 		.in = "abc",
413 		.in_len = 3,
414 		.out = {
415 			0xec, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6f, 0xc9,
416 			0x26, 0x45, 0x9f, 0x58, 0xe2, 0xc6, 0xad, 0x8d,
417 			0xf9, 0xb4, 0x73, 0xcb, 0x0f, 0xc0, 0x8c, 0x25,
418 			0x96, 0xda, 0x7c, 0xf0, 0xe4, 0x9b, 0xe4, 0xb2,
419 			0x98, 0xd8, 0x8c, 0xea, 0x92, 0x7a, 0xc7, 0xf5,
420 			0x39, 0xf1, 0xed, 0xf2, 0x28, 0x37, 0x6d, 0x25,
421 		},
422 	},
423 	{
424 		.algorithm = NID_sha3_384,
425 		.in = "",
426 		.in_len = 0,
427 		.out = {
428 			0x0c, 0x63, 0xa7, 0x5b, 0x84, 0x5e, 0x4f, 0x7d,
429 			0x01, 0x10, 0x7d, 0x85, 0x2e, 0x4c, 0x24, 0x85,
430 			0xc5, 0x1a, 0x50, 0xaa, 0xaa, 0x94, 0xfc, 0x61,
431 			0x99, 0x5e, 0x71, 0xbb, 0xee, 0x98, 0x3a, 0x2a,
432 			0xc3, 0x71, 0x38, 0x31, 0x26, 0x4a, 0xdb, 0x47,
433 			0xfb, 0x6b, 0xd1, 0xe0, 0x58, 0xd5, 0xf0, 0x04,
434 		},
435 	},
436 	{
437 		.algorithm = NID_sha3_384,
438 		.in =
439 		    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno"
440 		    "mnopnopq",
441 		.in_len = 56,
442 		.out = {
443 			0x99, 0x1c, 0x66, 0x57, 0x55, 0xeb, 0x3a, 0x4b,
444 			0x6b, 0xbd, 0xfb, 0x75, 0xc7, 0x8a, 0x49, 0x2e,
445 			0x8c, 0x56, 0xa2, 0x2c, 0x5c, 0x4d, 0x7e, 0x42,
446 			0x9b, 0xfd, 0xbc, 0x32, 0xb9, 0xd4, 0xad, 0x5a,
447 			0xa0, 0x4a, 0x1f, 0x07, 0x6e, 0x62, 0xfe, 0xa1,
448 			0x9e, 0xef, 0x51, 0xac, 0xd0, 0x65, 0x7c, 0x22,
449 		},
450 	},
451 	{
452 		.algorithm = NID_sha3_384,
453 		.in =
454 		    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm"
455 		    "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
456 		    "mnopqrstnopqrstu",
457 		.in_len = 112,
458 		.out = {
459 			0x79, 0x40, 0x7d, 0x3b, 0x59, 0x16, 0xb5, 0x9c,
460 			0x3e, 0x30, 0xb0, 0x98, 0x22, 0x97, 0x47, 0x91,
461 			0xc3, 0x13, 0xfb, 0x9e, 0xcc, 0x84, 0x9e, 0x40,
462 			0x6f, 0x23, 0x59, 0x2d, 0x04, 0xf6, 0x25, 0xdc,
463 			0x8c, 0x70, 0x9b, 0x98, 0xb4, 0x3b, 0x38, 0x52,
464 			0xb3, 0x37, 0x21, 0x61, 0x79, 0xaa, 0x7f, 0xc7,
465 		},
466 	},
467 
468 	/* SHA3-512 */
469 	{
470 		.algorithm = NID_sha3_512,
471 		.in = "abc",
472 		.in_len = 3,
473 		.out = {
474 			0xb7, 0x51, 0x85, 0x0b, 0x1a, 0x57, 0x16, 0x8a,
475 			0x56, 0x93, 0xcd, 0x92, 0x4b, 0x6b, 0x09, 0x6e,
476 			0x08, 0xf6, 0x21, 0x82, 0x74, 0x44, 0xf7, 0x0d,
477 			0x88, 0x4f, 0x5d, 0x02, 0x40, 0xd2, 0x71, 0x2e,
478 			0x10, 0xe1, 0x16, 0xe9, 0x19, 0x2a, 0xf3, 0xc9,
479 			0x1a, 0x7e, 0xc5, 0x76, 0x47, 0xe3, 0x93, 0x40,
480 			0x57, 0x34, 0x0b, 0x4c, 0xf4, 0x08, 0xd5, 0xa5,
481 			0x65, 0x92, 0xf8, 0x27, 0x4e, 0xec, 0x53, 0xf0,
482 		},
483 	},
484 	{
485 		.algorithm = NID_sha3_512,
486 		.in = "",
487 		.in_len = 0,
488 		.out = {
489 			0xa6, 0x9f, 0x73, 0xcc, 0xa2, 0x3a, 0x9a, 0xc5,
490 			0xc8, 0xb5, 0x67, 0xdc, 0x18, 0x5a, 0x75, 0x6e,
491 			0x97, 0xc9, 0x82, 0x16, 0x4f, 0xe2, 0x58, 0x59,
492 			0xe0, 0xd1, 0xdc, 0xc1, 0x47, 0x5c, 0x80, 0xa6,
493 			0x15, 0xb2, 0x12, 0x3a, 0xf1, 0xf5, 0xf9, 0x4c,
494 			0x11, 0xe3, 0xe9, 0x40, 0x2c, 0x3a, 0xc5, 0x58,
495 			0xf5, 0x00, 0x19, 0x9d, 0x95, 0xb6, 0xd3, 0xe3,
496 			0x01, 0x75, 0x85, 0x86, 0x28, 0x1d, 0xcd, 0x26,
497 		},
498 	},
499 	{
500 		.algorithm = NID_sha3_512,
501 		.in =
502 		    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno"
503 		    "mnopnopq",
504 		.in_len = 56,
505 		.out = {
506 			0x04, 0xa3, 0x71, 0xe8, 0x4e, 0xcf, 0xb5, 0xb8,
507 			0xb7, 0x7c, 0xb4, 0x86, 0x10, 0xfc, 0xa8, 0x18,
508 			0x2d, 0xd4, 0x57, 0xce, 0x6f, 0x32, 0x6a, 0x0f,
509 			0xd3, 0xd7, 0xec, 0x2f, 0x1e, 0x91, 0x63, 0x6d,
510 			0xee, 0x69, 0x1f, 0xbe, 0x0c, 0x98, 0x53, 0x02,
511 			0xba, 0x1b, 0x0d, 0x8d, 0xc7, 0x8c, 0x08, 0x63,
512 			0x46, 0xb5, 0x33, 0xb4, 0x9c, 0x03, 0x0d, 0x99,
513 			0xa2, 0x7d, 0xaf, 0x11, 0x39, 0xd6, 0xe7, 0x5e,
514 		},
515 	},
516 	{
517 		.algorithm = NID_sha3_512,
518 		.in =
519 		    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm"
520 		    "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
521 		    "mnopqrstnopqrstu",
522 		.in_len = 112,
523 		.out = {
524 			0xaf, 0xeb, 0xb2, 0xef, 0x54, 0x2e, 0x65, 0x79,
525 			0xc5, 0x0c, 0xad, 0x06, 0xd2, 0xe5, 0x78, 0xf9,
526 			0xf8, 0xdd, 0x68, 0x81, 0xd7, 0xdc, 0x82, 0x4d,
527 			0x26, 0x36, 0x0f, 0xee, 0xbf, 0x18, 0xa4, 0xfa,
528 			0x73, 0xe3, 0x26, 0x11, 0x22, 0x94, 0x8e, 0xfc,
529 			0xfd, 0x49, 0x2e, 0x74, 0xe8, 0x2e, 0x21, 0x89,
530 			0xed, 0x0f, 0xb4, 0x40, 0xd1, 0x87, 0xf3, 0x82,
531 			0x27, 0x0c, 0xb4, 0x55, 0xf2, 0x1d, 0xd1, 0x85,
532 		},
533 	},
534 };
535 
536 struct sha_repetition_test {
537 	const int algorithm;
538 	const uint8_t in;
539 	const size_t in_repetitions;
540 	const uint8_t out[EVP_MAX_MD_SIZE];
541 };
542 
543 static const struct sha_repetition_test sha_repetition_tests[] = {
544 	/* SHA-1 */
545 	{
546 		.algorithm = NID_sha1,
547 		.in = 'a',
548 		.in_repetitions = 1000000,
549 		.out = {
550 			0x34, 0xaa, 0x97, 0x3c, 0xd4, 0xc4, 0xda, 0xa4,
551 			0xf6, 0x1e, 0xeb, 0x2b, 0xdb, 0xad, 0x27, 0x31,
552 			0x65, 0x34, 0x01, 0x6f,
553 		},
554 	},
555 
556 	/* SHA-224 */
557 	{
558 		.algorithm = NID_sha224,
559 		.in = 'a',
560 		.in_repetitions = 1000000,
561 		.out = {
562 			0x20, 0x79, 0x46, 0x55, 0x98, 0x0c, 0x91, 0xd8,
563 			0xbb, 0xb4, 0xc1, 0xea, 0x97, 0x61, 0x8a, 0x4b,
564 			0xf0, 0x3f, 0x42, 0x58, 0x19, 0x48, 0xb2, 0xee,
565 			0x4e, 0xe7, 0xad, 0x67,
566 		},
567 	},
568 
569 	/* SHA-256 */
570 	{
571 		.algorithm = NID_sha256,
572 		.in = 'a',
573 		.in_repetitions = 1000000,
574 		.out = {
575 			0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92,
576 			0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67,
577 			0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e,
578 			0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0,
579 		},
580 	},
581 
582 	/* SHA-384 */
583 	{
584 		.algorithm = NID_sha384,
585 		.in = 'a',
586 		.in_repetitions = 1000000,
587 		.out = {
588 			0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb,
589 			0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a, 0x4a, 0x1c,
590 			0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52,
591 			0x79, 0x72, 0xce, 0xc5, 0x70, 0x4c, 0x2a, 0x5b,
592 			0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb,
593 			0xae, 0x97, 0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85,
594 		},
595 	},
596 
597 	/* SHA-512 */
598 	{
599 		.algorithm = NID_sha512,
600 		.in = 'a',
601 		.in_repetitions = 1000000,
602 		.out = {
603 			0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64,
604 			0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63,
605 			0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28,
606 			0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb,
607 			0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a,
608 			0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b,
609 			0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e,
610 			0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b,
611 		},
612 	},
613 
614 	/* SHA3-224 */
615 	{
616 		.algorithm = NID_sha3_224,
617 		.in = 'a',
618 		.in_repetitions = 1000000,
619 		.out = {
620 			0xd6, 0x93, 0x35, 0xb9, 0x33, 0x25, 0x19, 0x2e,
621 			0x51, 0x6a, 0x91, 0x2e, 0x6d, 0x19, 0xa1, 0x5c,
622 			0xb5, 0x1c, 0x6e, 0xd5, 0xc1, 0x52, 0x43, 0xe7,
623 			0xa7, 0xfd, 0x65, 0x3c,
624 		},
625 	},
626 
627 	/* SHA3-256 */
628 	{
629 		.algorithm = NID_sha3_256,
630 		.in = 'a',
631 		.in_repetitions = 1000000,
632 		.out = {
633 			0x5c, 0x88, 0x75, 0xae, 0x47, 0x4a, 0x36, 0x34,
634 			0xba, 0x4f, 0xd5, 0x5e, 0xc8, 0x5b, 0xff, 0xd6,
635 			0x61, 0xf3, 0x2a, 0xca, 0x75, 0xc6, 0xd6, 0x99,
636 			0xd0, 0xcd, 0xcb, 0x6c, 0x11, 0x58, 0x91, 0xc1,
637 		},
638 	},
639 
640 	/* SHA3-384 */
641 	{
642 		.algorithm = NID_sha3_384,
643 		.in = 'a',
644 		.in_repetitions = 1000000,
645 		.out = {
646 			0xee, 0xe9, 0xe2, 0x4d, 0x78, 0xc1, 0x85, 0x53,
647 			0x37, 0x98, 0x34, 0x51, 0xdf, 0x97, 0xc8, 0xad,
648 			0x9e, 0xed, 0xf2, 0x56, 0xc6, 0x33, 0x4f, 0x8e,
649 			0x94, 0x8d, 0x25, 0x2d, 0x5e, 0x0e, 0x76, 0x84,
650 			0x7a, 0xa0, 0x77, 0x4d, 0xdb, 0x90, 0xa8, 0x42,
651 			0x19, 0x0d, 0x2c, 0x55, 0x8b, 0x4b, 0x83, 0x40,
652 		},
653 	},
654 
655 	/* SHA3-512 */
656 	{
657 		.algorithm = NID_sha3_512,
658 		.in = 'a',
659 		.in_repetitions = 1000000,
660 		.out = {
661 			0x3c, 0x3a, 0x87, 0x6d, 0xa1, 0x40, 0x34, 0xab,
662 			0x60, 0x62, 0x7c, 0x07, 0x7b, 0xb9, 0x8f, 0x7e,
663 			0x12, 0x0a, 0x2a, 0x53, 0x70, 0x21, 0x2d, 0xff,
664 			0xb3, 0x38, 0x5a, 0x18, 0xd4, 0xf3, 0x88, 0x59,
665 			0xed, 0x31, 0x1d, 0x0a, 0x9d, 0x51, 0x41, 0xce,
666 			0x9c, 0xc5, 0xc6, 0x6e, 0xe6, 0x89, 0xb2, 0x66,
667 			0xa8, 0xaa, 0x18, 0xac, 0xe8, 0x28, 0x2a, 0x0e,
668 			0x0d, 0xb5, 0x96, 0xc9, 0x0b, 0x0a, 0x7b, 0x87,
669 		},
670 	},
671 };
672 
673 #define N_SHA_TESTS (sizeof(sha_tests) / sizeof(sha_tests[0]))
674 #define N_SHA_REPETITION_TESTS (sizeof(sha_repetition_tests) / sizeof(sha_repetition_tests[0]))
675 
676 typedef unsigned char *(*sha_hash_func)(const unsigned char *, size_t,
677     unsigned char *);
678 
679 static int
sha_hash_from_algorithm(int algorithm,const char ** out_label,sha_hash_func * out_func,const EVP_MD ** out_md,size_t * out_len)680 sha_hash_from_algorithm(int algorithm, const char **out_label,
681     sha_hash_func *out_func, const EVP_MD **out_md, size_t *out_len)
682 {
683 	const char *label;
684 	sha_hash_func sha_func;
685 	const EVP_MD *md;
686 	size_t len;
687 
688 	switch (algorithm) {
689 	case NID_sha1:
690 		label = SN_sha1;
691 		sha_func = SHA1;
692 		md = EVP_sha1();
693 		len = SHA_DIGEST_LENGTH;
694 		break;
695 	case NID_sha224:
696 		label = SN_sha224;
697 		sha_func = SHA224;
698 		md = EVP_sha224();
699 		len = SHA224_DIGEST_LENGTH;
700 		break;
701 	case NID_sha256:
702 		label = SN_sha256;
703 		sha_func = SHA256;
704 		md = EVP_sha256();
705 		len = SHA256_DIGEST_LENGTH;
706 		break;
707 	case NID_sha384:
708 		label = SN_sha384;
709 		sha_func = SHA384;
710 		md = EVP_sha384();
711 		len = SHA384_DIGEST_LENGTH;
712 		break;
713 	case NID_sha512:
714 		label = SN_sha512;
715 		sha_func = SHA512;
716 		md = EVP_sha512();
717 		len = SHA512_DIGEST_LENGTH;
718 		break;
719 	case NID_sha3_224:
720 		label = SN_sha3_224;
721 		sha_func = NULL;
722 		md = EVP_sha3_224();
723 		len = 224 / 8;
724 		break;
725 	case NID_sha3_256:
726 		label = SN_sha3_256;
727 		sha_func = NULL;
728 		md = EVP_sha3_256();
729 		len = 256 / 8;
730 		break;
731 	case NID_sha3_384:
732 		label = SN_sha3_384;
733 		sha_func = NULL;
734 		md = EVP_sha3_384();
735 		len = 384 / 8;
736 		break;
737 	case NID_sha3_512:
738 		label = SN_sha3_512;
739 		sha_func = NULL;
740 		md = EVP_sha3_512();
741 		len = 512 / 8;
742 		break;
743 	default:
744 		fprintf(stderr, "FAIL: unknown algorithm (%d)\n",
745 		    algorithm);
746 		return 0;
747 	}
748 
749 	if (out_label != NULL)
750 		*out_label = label;
751 	if (out_func != NULL)
752 		*out_func = sha_func;
753 	if (out_md != NULL)
754 		*out_md = md;
755 	if (out_len != NULL)
756 		*out_len = len;
757 
758 	return 1;
759 }
760 
761 static int
sha_test(void)762 sha_test(void)
763 {
764 	sha_hash_func sha_func;
765 	const struct sha_test *st;
766 	EVP_MD_CTX *hash = NULL;
767 	const EVP_MD *md;
768 	uint8_t out[EVP_MAX_MD_SIZE];
769 	size_t in_len, out_len;
770 	size_t i;
771 	const char *label;
772 	int failed = 1;
773 
774 	if ((hash = EVP_MD_CTX_new()) == NULL) {
775 		fprintf(stderr, "FAIL: EVP_MD_CTX_new() failed\n");
776 		goto failed;
777 	}
778 
779 	for (i = 0; i < N_SHA_TESTS; i++) {
780 		st = &sha_tests[i];
781 		if (!sha_hash_from_algorithm(st->algorithm, &label, &sha_func,
782 		    &md, &out_len))
783 			goto failed;
784 
785 		/* Digest */
786 		if (sha_func != NULL) {
787 			memset(out, 0, sizeof(out));
788 			sha_func(st->in, st->in_len, out);
789 			if (memcmp(st->out, out, out_len) != 0) {
790 				fprintf(stderr, "FAIL (%s:%zu): mismatch\n",
791 				    label, i);
792 				goto failed;
793 			}
794 		}
795 
796 		/* EVP single-shot digest */
797 		memset(out, 0, sizeof(out));
798 		if (!EVP_Digest(st->in, st->in_len, out, NULL, md, NULL)) {
799 			fprintf(stderr, "FAIL (%s:%zu): EVP_Digest failed\n",
800 			    label, i);
801 			goto failed;
802 		}
803 
804 		if (memcmp(st->out, out, out_len) != 0) {
805 			fprintf(stderr,
806 			    "FAIL (%s:%zu): EVP single-shot mismatch\n",
807 			    label, i);
808 			goto failed;
809 		}
810 
811 		/* EVP digest */
812 		memset(out, 0, sizeof(out));
813 		if (!EVP_DigestInit_ex(hash, md, NULL)) {
814 			fprintf(stderr,
815 			    "FAIL (%s:%zu): EVP_DigestInit_ex failed\n",
816 			    label, i);
817 			goto failed;
818 		}
819 
820 		in_len = st->in_len / 2;
821 		if (!EVP_DigestUpdate(hash, st->in, in_len)) {
822 			fprintf(stderr,
823 			    "FAIL (%s:%zu): EVP_DigestUpdate first half "
824 			    "failed\n", label, i);
825 			goto failed;
826 		}
827 
828 		if (!EVP_DigestUpdate(hash, st->in + in_len,
829 		    st->in_len - in_len)) {
830 			fprintf(stderr,
831 			    "FAIL (%s:%zu): EVP_DigestUpdate second half "
832 			    "failed\n", label, i);
833 			goto failed;
834 		}
835 
836 		if (!EVP_DigestFinal_ex(hash, out, NULL)) {
837 			fprintf(stderr,
838 			    "FAIL (%s:%zu): EVP_DigestFinal_ex failed\n",
839 			    label, i);
840 			goto failed;
841 		}
842 
843 		if (memcmp(st->out, out, out_len) != 0) {
844 			fprintf(stderr, "FAIL (%s:%zu): EVP mismatch\n",
845 			    label, i);
846 			goto failed;
847 		}
848 	}
849 
850 	failed = 0;
851 
852  failed:
853 	EVP_MD_CTX_free(hash);
854 	return failed;
855 }
856 
857 static int
sha_repetition_test(void)858 sha_repetition_test(void)
859 {
860 	const struct sha_repetition_test *st;
861 	EVP_MD_CTX *hash = NULL;
862 	const EVP_MD *md;
863 	uint8_t buf[1024];
864 	uint8_t out[EVP_MAX_MD_SIZE];
865 	size_t out_len, part_len;
866 	size_t i, j;
867 	const char *label;
868 	int failed = 1;
869 
870 	if ((hash = EVP_MD_CTX_new()) == NULL) {
871 		fprintf(stderr, "FAIL: EVP_MD_CTX_new() failed\n");
872 		goto failed;
873 	}
874 
875 	for (i = 0; i < N_SHA_REPETITION_TESTS; i++) {
876 		st = &sha_repetition_tests[i];
877 		if (!sha_hash_from_algorithm(st->algorithm, &label, NULL, &md,
878 		    &out_len))
879 			goto failed;
880 
881 		/* EVP digest */
882 		if (!EVP_DigestInit_ex(hash, md, NULL)) {
883 			fprintf(stderr,
884 			    "FAIL (%s:%zu): EVP_DigestInit_ex failed\n",
885 			    label, i);
886 			goto failed;
887 		}
888 
889 		memset(buf, st->in, sizeof(buf));
890 
891 		for (j = 0; j < st->in_repetitions;) {
892 			part_len = arc4random_uniform(sizeof(buf));
893 			if (part_len > st->in_repetitions - j)
894 				part_len = st->in_repetitions - j;
895 
896 			if (!EVP_DigestUpdate(hash, buf, part_len)) {
897 				fprintf(stderr,
898 				    "FAIL (%s:%zu): EVP_DigestUpdate failed\n",
899 				    label, i);
900 				goto failed;
901 			}
902 
903 			j += part_len;
904 		}
905 
906 		if (!EVP_DigestFinal_ex(hash, out, NULL)) {
907 			fprintf(stderr,
908 			    "FAIL (%s:%zu): EVP_DigestFinal_ex failed\n",
909 			    label, i);
910 			goto failed;
911 		}
912 
913 		if (memcmp(st->out, out, out_len) != 0) {
914 			fprintf(stderr, "FAIL (%s:%zu): EVP mismatch\n",
915 			    label, i);
916 			goto failed;
917 		}
918 	}
919 
920 	failed = 0;
921 
922  failed:
923 	EVP_MD_CTX_free(hash);
924 	return failed;
925 }
926 
927 int
main(int argc,char ** argv)928 main(int argc, char **argv)
929 {
930 	int failed = 0;
931 
932 	failed |= sha_test();
933 	failed |= sha_repetition_test();
934 
935 	return failed;
936 }
937