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