1 /*
2 * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <openssl/evp.h>
11 #include <openssl/rand.h>
12 #include <openssl/core_names.h>
13 #include "testutil.h"
14 #include "internal/nelem.h"
15
16 static const unsigned char shake256_input[] = {
17 0x8d, 0x80, 0x01, 0xe2, 0xc0, 0x96, 0xf1, 0xb8,
18 0x8e, 0x7c, 0x92, 0x24, 0xa0, 0x86, 0xef, 0xd4,
19 0x79, 0x7f, 0xbf, 0x74, 0xa8, 0x03, 0x3a, 0x2d,
20 0x42, 0x2a, 0x2b, 0x6b, 0x8f, 0x67, 0x47, 0xe4
21 };
22
23 /*
24 * This KAT output is 250 bytes, which is more than
25 * the SHAKE256 block size (136 bytes).
26 */
27 static const unsigned char shake256_output[] = {
28 0x2e, 0x97, 0x5f, 0x6a, 0x8a, 0x14, 0xf0, 0x70,
29 0x4d, 0x51, 0xb1, 0x36, 0x67, 0xd8, 0x19, 0x5c,
30 0x21, 0x9f, 0x71, 0xe6, 0x34, 0x56, 0x96, 0xc4,
31 0x9f, 0xa4, 0xb9, 0xd0, 0x8e, 0x92, 0x25, 0xd3,
32 0xd3, 0x93, 0x93, 0x42, 0x51, 0x52, 0xc9, 0x7e,
33 0x71, 0xdd, 0x24, 0x60, 0x1c, 0x11, 0xab, 0xcf,
34 0xa0, 0xf1, 0x2f, 0x53, 0xc6, 0x80, 0xbd, 0x3a,
35 0xe7, 0x57, 0xb8, 0x13, 0x4a, 0x9c, 0x10, 0xd4,
36 0x29, 0x61, 0x58, 0x69, 0x21, 0x7f, 0xdd, 0x58,
37 0x85, 0xc4, 0xdb, 0x17, 0x49, 0x85, 0x70, 0x3a,
38 0x6d, 0x6d, 0xe9, 0x4a, 0x66, 0x7e, 0xac, 0x30,
39 0x23, 0x44, 0x3a, 0x83, 0x37, 0xae, 0x1b, 0xc6,
40 0x01, 0xb7, 0x6d, 0x7d, 0x38, 0xec, 0x3c, 0x34,
41 0x46, 0x31, 0x05, 0xf0, 0xd3, 0x94, 0x9d, 0x78,
42 0xe5, 0x62, 0xa0, 0x39, 0xe4, 0x46, 0x95, 0x48,
43 0xb6, 0x09, 0x39, 0x5d, 0xe5, 0xa4, 0xfd, 0x43,
44 0xc4, 0x6c, 0xa9, 0xfd, 0x6e, 0xe2, 0x9a, 0xda,
45 0x5e, 0xfc, 0x07, 0xd8, 0x4d, 0x55, 0x32, 0x49,
46 0x45, 0x0d, 0xab, 0x4a, 0x49, 0xc4, 0x83, 0xde,
47 0xd2, 0x50, 0xc9, 0x33, 0x8f, 0x85, 0xcd, 0x93,
48 0x7a, 0xe6, 0x6b, 0xb4, 0x36, 0xf3, 0xb4, 0x02,
49 0x6e, 0x85, 0x9f, 0xda, 0x1c, 0xa5, 0x71, 0x43,
50 0x2f, 0x3b, 0xfc, 0x09, 0xe7, 0xc0, 0x3c, 0xa4,
51 0xd1, 0x83, 0xb7, 0x41, 0x11, 0x1c, 0xa0, 0x48,
52 0x3d, 0x0e, 0xda, 0xbc, 0x03, 0xfe, 0xb2, 0x3b,
53 0x17, 0xee, 0x48, 0xe8, 0x44, 0xba, 0x24, 0x08,
54 0xd9, 0xdc, 0xfd, 0x01, 0x39, 0xd2, 0xe8, 0xc7,
55 0x31, 0x01, 0x25, 0xae, 0xe8, 0x01, 0xc6, 0x1a,
56 0xb7, 0x90, 0x0d, 0x1e, 0xfc, 0x47, 0xc0, 0x78,
57 0x28, 0x17, 0x66, 0xf3, 0x61, 0xc5, 0xe6, 0x11,
58 0x13, 0x46, 0x23, 0x5e, 0x1d, 0xc3, 0x83, 0x25,
59 0x66, 0x6c
60 };
61
62 static const unsigned char shake256_largemsg_input[] = {
63 0xb2, 0xd2, 0x38, 0x65, 0xaf, 0x8f, 0x25, 0x6e,
64 0x64, 0x40, 0xe2, 0x0d, 0x49, 0x8e, 0x3e, 0x64,
65 0x46, 0xd2, 0x03, 0xa4, 0x19, 0xe3, 0x7b, 0x80,
66 0xf7, 0x2b, 0x32, 0xe2, 0x76, 0x01, 0xfe, 0xdd,
67 0xaa, 0x33, 0x3d, 0xe4, 0x8e, 0xe1, 0x5e, 0x39,
68 0xa6, 0x92, 0xa3, 0xa7, 0xe3, 0x81, 0x24, 0x74,
69 0xc7, 0x38, 0x18, 0x92, 0xc9, 0x60, 0x50, 0x15,
70 0xfb, 0xd8, 0x04, 0xea, 0xea, 0x04, 0xd2, 0xc5,
71 0xc6, 0x68, 0x04, 0x5b, 0xc3, 0x75, 0x12, 0xd2,
72 0xbe, 0xa2, 0x67, 0x75, 0x24, 0xbf, 0x68, 0xad,
73 0x10, 0x86, 0xb3, 0x2c, 0xb3, 0x74, 0xa4, 0x6c,
74 0xf9, 0xd7, 0x1e, 0x58, 0x69, 0x27, 0x88, 0x49,
75 0x4e, 0x99, 0x15, 0x33, 0x14, 0xf2, 0x49, 0x21,
76 0xf4, 0x99, 0xb9, 0xde, 0xd4, 0xf1, 0x12, 0xf5,
77 0x68, 0xe5, 0x5c, 0xdc, 0x9e, 0xc5, 0x80, 0x6d,
78 0x39, 0x50, 0x08, 0x95, 0xbb, 0x12, 0x27, 0x50,
79 0x89, 0xf0, 0xf9, 0xd5, 0x4a, 0x01, 0x0b, 0x0d,
80 0x90, 0x9f, 0x1e, 0x4a, 0xba, 0xbe, 0x28, 0x36,
81 0x19, 0x7d, 0x9c, 0x0a, 0x51, 0xfb, 0xeb, 0x00,
82 0x02, 0x6c, 0x4b, 0x0a, 0xa8, 0x6c, 0xb7, 0xc4,
83 0xc0, 0x92, 0x37, 0xa7, 0x2d, 0x49, 0x61, 0x80,
84 0xd9, 0xdb, 0x20, 0x21, 0x9f, 0xcf, 0xb4, 0x57,
85 0x69, 0x75, 0xfa, 0x1c, 0x95, 0xbf, 0xee, 0x0d,
86 0x9e, 0x52, 0x6e, 0x1e, 0xf8, 0xdd, 0x41, 0x8c,
87 0x3b, 0xaa, 0x57, 0x13, 0x84, 0x73, 0x52, 0x62,
88 0x18, 0x76, 0x46, 0xcc, 0x4b, 0xcb, 0xbd, 0x40,
89 0xa1, 0xf6, 0xff, 0x7b, 0x32, 0xb9, 0x90, 0x7c,
90 0x53, 0x2c, 0xf9, 0x38, 0x72, 0x0f, 0xcb, 0x90,
91 0x42, 0x5e, 0xe2, 0x80, 0x19, 0x26, 0xe7, 0x99,
92 0x96, 0x98, 0x18, 0xb1, 0x86, 0x5b, 0x4c, 0xd9,
93 0x08, 0x27, 0x31, 0x8f, 0xf0, 0x90, 0xd9, 0x35,
94 0x6a, 0x1f, 0x75, 0xc2, 0xe0, 0xa7, 0x60, 0xb8,
95 0x1d, 0xd6, 0x5f, 0x56, 0xb2, 0x0b, 0x27, 0x0e,
96 0x98, 0x67, 0x1f, 0x39, 0x18, 0x27, 0x68, 0x0a,
97 0xe8, 0x31, 0x1b, 0xc0, 0x97, 0xec, 0xd1, 0x20,
98 0x2a, 0x55, 0x69, 0x23, 0x08, 0x50, 0x05, 0xec,
99 0x13, 0x3b, 0x56, 0xfc, 0x18, 0xc9, 0x1a, 0xa9,
100 0x69, 0x0e, 0xe2, 0xcc, 0xc8, 0xd6, 0x19, 0xbb,
101 0x87, 0x3b, 0x42, 0x77, 0xee, 0x77, 0x81, 0x26,
102 0xdd, 0xf6, 0x5d, 0xc3, 0xb2, 0xb0, 0xc4, 0x14,
103 0x6d, 0xb5, 0x4f, 0xdc, 0x13, 0x09, 0xc8, 0x53,
104 0x50, 0xb3, 0xea, 0xd3, 0x5f, 0x11, 0x67, 0xd4,
105 0x2f, 0x6e, 0x30, 0x1a, 0xbe, 0xd6, 0xf0, 0x2d,
106 0xc9, 0x29, 0xd9, 0x0a, 0xa8, 0x6f, 0xa4, 0x18,
107 0x74, 0x6b, 0xd3, 0x5d, 0x6a, 0x73, 0x3a, 0xf2,
108 0x94, 0x7f, 0xbd, 0xb4, 0xa6, 0x7f, 0x5b, 0x3d,
109 0x26, 0xf2, 0x6c, 0x13, 0xcf, 0xb4, 0x26, 0x1e,
110 0x38, 0x17, 0x66, 0x60, 0xb1, 0x36, 0xae, 0xe0,
111 0x6d, 0x86, 0x69, 0xe7, 0xe7, 0xae, 0x77, 0x6f,
112 0x7e, 0x99, 0xe5, 0xd9, 0x62, 0xc9, 0xfc, 0xde,
113 0xb4, 0xee, 0x7e, 0xc8, 0xe9, 0xb7, 0x2c, 0xe2,
114 0x70, 0xe8, 0x8b, 0x2d, 0x94, 0xad, 0xe8, 0x54,
115 0xa3, 0x2d, 0x9a, 0xe2, 0x50, 0x63, 0x87, 0xb3,
116 0x56, 0x29, 0xea, 0xa8, 0x5e, 0x96, 0x53, 0x9f,
117 0x23, 0x8a, 0xef, 0xa3, 0xd4, 0x87, 0x09, 0x5f,
118 0xba, 0xc3, 0xd1, 0xd9, 0x1a, 0x7b, 0x5c, 0x5d,
119 0x5d, 0x89, 0xed, 0xb6, 0x6e, 0x39, 0x73, 0xa5,
120 0x64, 0x59, 0x52, 0x8b, 0x61, 0x8f, 0x66, 0x69,
121 0xb9, 0xf0, 0x45, 0x0a, 0x57, 0xcd, 0xc5, 0x7f,
122 0x5d, 0xd0, 0xbf, 0xcc, 0x0b, 0x48, 0x12, 0xe1,
123 0xe2, 0xc2, 0xea, 0xcc, 0x09, 0xd9, 0x42, 0x2c,
124 0xef, 0x4f, 0xa7, 0xe9, 0x32, 0x5c, 0x3f, 0x22,
125 0xc0, 0x45, 0x0b, 0x67, 0x3c, 0x31, 0x69, 0x29,
126 0xa3, 0x39, 0xdd, 0x6e, 0x2f, 0xbe, 0x10, 0xc9,
127 0x7b, 0xff, 0x19, 0x8a, 0xe9, 0xea, 0xfc, 0x32,
128 0x41, 0x33, 0x70, 0x2a, 0x9a, 0xa4, 0xe6, 0xb4,
129 0x7e, 0xb4, 0xc6, 0x21, 0x49, 0x5a, 0xfc, 0x45,
130 0xd2, 0x23, 0xb3, 0x28, 0x4d, 0x83, 0x60, 0xfe,
131 0x70, 0x68, 0x03, 0x59, 0xd5, 0x15, 0xaa, 0x9e,
132 0xa0, 0x2e, 0x36, 0xb5, 0x61, 0x0f, 0x61, 0x05,
133 0x3c, 0x62, 0x00, 0xa0, 0x47, 0xf1, 0x86, 0xba,
134 0x33, 0xb8, 0xca, 0x60, 0x2f, 0x3f, 0x0a, 0x67,
135 0x09, 0x27, 0x2f, 0xa2, 0x96, 0x02, 0x52, 0x58,
136 0x55, 0x68, 0x80, 0xf4, 0x4f, 0x47, 0xba, 0xff,
137 0x41, 0x7a, 0x40, 0x4c, 0xfd, 0x9d, 0x10, 0x72,
138 0x0e, 0x20, 0xa9, 0x7f, 0x9b, 0x9b, 0x14, 0xeb,
139 0x8e, 0x61, 0x25, 0xcb, 0xf4, 0x58, 0xff, 0x47,
140 0xa7, 0x08, 0xd6, 0x4e, 0x2b, 0xf1, 0xf9, 0x89,
141 0xd7, 0x22, 0x0f, 0x8d, 0x35, 0x07, 0xa0, 0x54,
142 0xab, 0x83, 0xd8, 0xee, 0x5a, 0x3e, 0x88, 0x74,
143 0x46, 0x41, 0x6e, 0x3e, 0xb7, 0xc0, 0xb6, 0x55,
144 0xe0, 0x36, 0xc0, 0x2b, 0xbf, 0xb8, 0x24, 0x8a,
145 0x44, 0x82, 0xf4, 0xcb, 0xb5, 0xd7, 0x41, 0x48,
146 0x51, 0x08, 0xe0, 0x14, 0x34, 0xd2, 0x6d, 0xe9,
147 0x7a, 0xec, 0x91, 0x61, 0xa7, 0xe1, 0x81, 0x69,
148 0x47, 0x1c, 0xc7, 0xf3
149 };
150
151 static const unsigned char shake256_largemsg_output[] = {
152 0x64, 0xea, 0x24, 0x6a, 0xab, 0x80, 0x37, 0x9e,
153 0x08, 0xe2, 0x19, 0x9e, 0x09, 0x69, 0xe2, 0xee,
154 0x1a, 0x5d, 0xd1, 0x68, 0x68, 0xec, 0x8d, 0x42,
155 0xd0, 0xf8, 0xb8, 0x44, 0x74, 0x54, 0x87, 0x3e,
156 };
157
shake_setup(const char * name)158 static EVP_MD_CTX *shake_setup(const char *name)
159 {
160 EVP_MD_CTX *ctx = NULL;
161 EVP_MD *md = NULL;
162
163 if (!TEST_ptr(md = EVP_MD_fetch(NULL, name, NULL)))
164 return NULL;
165
166 if (!TEST_ptr(ctx = EVP_MD_CTX_new()))
167 goto err;
168 if (!TEST_true(EVP_DigestInit_ex2(ctx, md, NULL)))
169 goto err;
170 EVP_MD_free(md);
171 return ctx;
172 err:
173 EVP_MD_free(md);
174 EVP_MD_CTX_free(ctx);
175 return NULL;
176 }
177
shake_kat_test(void)178 static int shake_kat_test(void)
179 {
180 int ret = 0;
181 EVP_MD_CTX *ctx = NULL;
182 unsigned char out[sizeof(shake256_output)];
183
184 if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
185 return 0;
186 if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
187 sizeof(shake256_input)))
188 || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
189 || !TEST_mem_eq(out, sizeof(out),
190 shake256_output,sizeof(shake256_output))
191 /* Test that a second call to EVP_DigestFinalXOF fails */
192 || !TEST_false(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
193 /* Test that a call to EVP_DigestSqueeze fails */
194 || !TEST_false(EVP_DigestSqueeze(ctx, out, sizeof(out))))
195 goto err;
196 ret = 1;
197 err:
198 EVP_MD_CTX_free(ctx);
199 return ret;
200 }
201
shake_kat_digestfinal_test(void)202 static int shake_kat_digestfinal_test(void)
203 {
204 int ret = 0;
205 unsigned int digest_length = 0;
206 EVP_MD_CTX *ctx = NULL;
207 unsigned char out[sizeof(shake256_output)];
208
209 /* Test that EVP_DigestFinal without setting XOFLEN fails */
210 if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
211 return 0;
212 if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
213 sizeof(shake256_input))))
214 return 0;
215 ERR_set_mark();
216 if (!TEST_false(EVP_DigestFinal(ctx, out, &digest_length))) {
217 ERR_clear_last_mark();
218 return 0;
219 }
220 ERR_pop_to_mark();
221 EVP_MD_CTX_free(ctx);
222
223 /* However EVP_DigestFinalXOF must work */
224 if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
225 return 0;
226 if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
227 sizeof(shake256_input))))
228 return 0;
229 if (!TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
230 || !TEST_mem_eq(out, sizeof(out),
231 shake256_output, sizeof(shake256_output))
232 || !TEST_false(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
233 goto err;
234 ret = 1;
235 err:
236 EVP_MD_CTX_free(ctx);
237 return ret;
238 }
239
240 /*
241 * Test that EVP_DigestFinal() returns the output length
242 * set by the OSSL_DIGEST_PARAM_XOFLEN param.
243 */
shake_kat_digestfinal_xoflen_test(void)244 static int shake_kat_digestfinal_xoflen_test(void)
245 {
246 int ret = 0;
247 unsigned int digest_length = 0;
248 EVP_MD_CTX *ctx = NULL;
249 const EVP_MD *md;
250 unsigned char out[sizeof(shake256_output)];
251 OSSL_PARAM params[2];
252 size_t sz = 12;
253
254 if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
255 return 0;
256 md = EVP_MD_CTX_get0_md(ctx);
257
258 memset(out, 0, sizeof(out));
259 params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz);
260 params[1] = OSSL_PARAM_construct_end();
261
262 if (!TEST_int_eq(EVP_MD_CTX_size(ctx), -1)
263 || !TEST_int_eq(EVP_MD_CTX_set_params(ctx, params), 1)
264 || !TEST_int_eq(EVP_MD_CTX_size(ctx), sz)
265 || !TEST_int_eq(EVP_MD_get_size(md), 0)
266 || !TEST_true(EVP_MD_xof(md))
267 || !TEST_true(EVP_DigestUpdate(ctx, shake256_input,
268 sizeof(shake256_input)))
269 || !TEST_true(EVP_DigestFinal(ctx, out, &digest_length))
270 || !TEST_uint_eq(digest_length, (unsigned int)sz)
271 || !TEST_mem_eq(out, digest_length,
272 shake256_output, digest_length)
273 || !TEST_uchar_eq(out[digest_length], 0))
274 goto err;
275 ret = 1;
276 err:
277 EVP_MD_CTX_free(ctx);
278 return ret;
279 }
280
281 /*
282 * Test that multiple absorb calls gives the expected result.
283 * This is a nested test that uses multiple strides for the input.
284 */
shake_absorb_test(void)285 static int shake_absorb_test(void)
286 {
287 int ret = 0;
288 EVP_MD_CTX *ctx = NULL;
289 unsigned char out[sizeof(shake256_largemsg_output)];
290 size_t total = sizeof(shake256_largemsg_input);
291 size_t i, stride, sz;
292
293 if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
294 return 0;
295
296 for (stride = 1; stride < total; ++stride) {
297 sz = 0;
298 for (i = 0; i < total; i += sz) {
299 sz += stride;
300 if ((i + sz) > total)
301 sz = total - i;
302 if (!TEST_true(EVP_DigestUpdate(ctx, shake256_largemsg_input + i,
303 sz)))
304 goto err;
305 }
306 if (!TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
307 || !TEST_mem_eq(out, sizeof(out),
308 shake256_largemsg_output,
309 sizeof(shake256_largemsg_output)))
310 goto err;
311 if (!TEST_true(EVP_DigestInit_ex2(ctx, NULL, NULL)))
312 goto err;
313 }
314 ret = 1;
315 err:
316 EVP_MD_CTX_free(ctx);
317 return ret;
318 }
319
320 /*
321 * Table containing the size of the output to squeeze for the
322 * initially call, followed by a size for each subsequent call.
323 */
324 static const struct {
325 size_t startsz, incsz;
326 } stride_tests[] = {
327 { 1, 1 },
328 { 1, 136 },
329 { 1, 136/2 },
330 { 1, 136/2-1 },
331 { 1, 136/2+1 },
332 { 1, 136*3 },
333 { 8, 8 },
334 { 9, 9 },
335 { 10, 10 },
336 { 136/2 - 1, 136 },
337 { 136/2 - 1, 136-1 },
338 { 136/2 - 1, 136+1 },
339 { 136/2, 136 },
340 { 136/2, 136-1 },
341 { 136/2, 136+1 },
342 { 136/2 + 1, 136 },
343 { 136/2 + 1, 136-1 },
344 { 136/2 + 1, 136+1 },
345 { 136, 2 },
346 { 136, 136 },
347 { 136-1, 136 },
348 { 136-1, 136-1 },
349 { 136-1, 136+1 },
350 { 136+1, 136 },
351 { 136+1, 136-1 },
352 { 136+1, 136+1 },
353 { 136*3, 136 },
354 { 136*3, 136 + 1 },
355 { 136*3, 136 - 1 },
356 { 136*3, 136/2 },
357 { 136*3, 136/2 + 1 },
358 { 136*3, 136/2 - 1 },
359 };
360
361 /*
362 * Helper to do multiple squeezes of output data using SHAKE256.
363 * tst is an index into the stride_tests[] containing an initial starting
364 * output length, followed by a second output length to use for all remaining
365 * squeezes. expected_outlen contains the total number of bytes to squeeze.
366 * in and inlen represent the input to absorb. expected_out and expected_outlen
367 * represent the expected output.
368 */
do_shake_squeeze_test(int tst,const unsigned char * in,size_t inlen,const unsigned char * expected_out,size_t expected_outlen)369 static int do_shake_squeeze_test(int tst,
370 const unsigned char *in, size_t inlen,
371 const unsigned char *expected_out,
372 size_t expected_outlen)
373 {
374 int ret = 0;
375 EVP_MD_CTX *ctx = NULL;
376 unsigned char *out = NULL;
377 size_t i = 0, sz = stride_tests[tst].startsz;
378
379 if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
380 return 0;
381 if (!TEST_ptr(out = OPENSSL_malloc(expected_outlen)))
382 goto err;
383 if (!TEST_true(EVP_DigestUpdate(ctx, in, inlen)))
384 goto err;
385
386 while (i < expected_outlen) {
387 if ((i + sz) > expected_outlen)
388 sz = expected_outlen - i;
389 if (!TEST_true(EVP_DigestSqueeze(ctx, out + i, sz)))
390 goto err;
391 i += sz;
392 sz = stride_tests[tst].incsz;
393 }
394 if (!TEST_mem_eq(out, expected_outlen, expected_out, expected_outlen))
395 goto err;
396 ret = 1;
397 err:
398 OPENSSL_free(out);
399 EVP_MD_CTX_free(ctx);
400 return ret;
401 }
402
shake_squeeze_kat_test(int tst)403 static int shake_squeeze_kat_test(int tst)
404 {
405 return do_shake_squeeze_test(tst, shake256_input, sizeof(shake256_input),
406 shake256_output, sizeof(shake256_output));
407 }
408
409 /*
410 * Generate some random input to absorb, and then
411 * squeeze it out in one operation to get a expected
412 * output. Use this to test that multiple squeeze calls
413 * on the same input gives the same output.
414 */
shake_squeeze_large_test(int tst)415 static int shake_squeeze_large_test(int tst)
416 {
417 int ret = 0;
418 EVP_MD_CTX *ctx = NULL;
419 unsigned char msg[16];
420 unsigned char out[2000];
421
422 if (!TEST_int_gt(RAND_bytes(msg, sizeof(msg)), 0)
423 || !TEST_ptr(ctx = shake_setup("SHAKE256"))
424 || !TEST_true(EVP_DigestUpdate(ctx, msg, sizeof(msg)))
425 || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
426 goto err;
427
428 ret = do_shake_squeeze_test(tst, msg, sizeof(msg), out, sizeof(out));
429 err:
430 EVP_MD_CTX_free(ctx);
431 return ret;
432 }
433
434 static const size_t dupoffset_tests[] = {
435 1, 135, 136, 137, 136*3-1, 136*3, 136*3+1
436 };
437
438 /* Helper function to test that EVP_MD_CTX_dup() copies the internal state */
do_shake_squeeze_dup_test(int tst,const char * alg,const unsigned char * in,size_t inlen,const unsigned char * expected_out,size_t expected_outlen)439 static int do_shake_squeeze_dup_test(int tst, const char *alg,
440 const unsigned char *in, size_t inlen,
441 const unsigned char *expected_out,
442 size_t expected_outlen)
443 {
444 int ret = 0;
445 EVP_MD_CTX *cur, *ctx = NULL, *dupctx = NULL;
446 unsigned char *out = NULL;
447 size_t i = 0, sz = 10;
448 size_t dupoffset = dupoffset_tests[tst];
449
450 if (!TEST_ptr(ctx = shake_setup(alg)))
451 return 0;
452 cur = ctx;
453 if (!TEST_ptr(out = OPENSSL_malloc(expected_outlen)))
454 goto err;
455 if (!TEST_true(EVP_DigestUpdate(ctx, in, inlen)))
456 goto err;
457
458 while (i < expected_outlen) {
459 if ((i + sz) > expected_outlen)
460 sz = expected_outlen - i;
461 if (!TEST_true(EVP_DigestSqueeze(cur, out + i, sz)))
462 goto err;
463 i += sz;
464 /* At a certain offset we swap to a new ctx that copies the state */
465 if (dupctx == NULL && i >= dupoffset) {
466 if (!TEST_ptr(dupctx = EVP_MD_CTX_dup(ctx)))
467 goto err;
468 cur = dupctx;
469 }
470 }
471 if (!TEST_mem_eq(out, expected_outlen, expected_out, expected_outlen))
472 goto err;
473 ret = 1;
474 err:
475 OPENSSL_free(out);
476 EVP_MD_CTX_free(ctx);
477 EVP_MD_CTX_free(dupctx);
478 return ret;
479 }
480
481 /* Test that the internal state can be copied */
shake_squeeze_dup_test(int tst)482 static int shake_squeeze_dup_test(int tst)
483 {
484 int ret = 0;
485 EVP_MD_CTX *ctx = NULL;
486 unsigned char msg[16];
487 unsigned char out[1000];
488 const char *alg = "SHAKE128";
489
490 if (!TEST_int_gt(RAND_bytes(msg, sizeof(msg)), 0)
491 || !TEST_ptr(ctx = shake_setup(alg))
492 || !TEST_true(EVP_DigestUpdate(ctx, msg, sizeof(msg)))
493 || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
494 goto err;
495
496 ret = do_shake_squeeze_dup_test(tst, alg, msg, sizeof(msg),
497 out, sizeof(out));
498 err:
499 EVP_MD_CTX_free(ctx);
500 return ret;
501 }
502
503 /* Test that a squeeze without a preceding absorb works */
shake_squeeze_no_absorb_test(void)504 static int shake_squeeze_no_absorb_test(void)
505 {
506 int ret = 0;
507 EVP_MD_CTX *ctx = NULL;
508 unsigned char out[1000];
509 unsigned char out2[1000];
510 const char *alg = "SHAKE128";
511
512 if (!TEST_ptr(ctx = shake_setup(alg))
513 || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
514 goto err;
515
516 if (!TEST_true(EVP_DigestInit_ex2(ctx, NULL, NULL))
517 || !TEST_true(EVP_DigestSqueeze(ctx, out2, sizeof(out2) / 2))
518 || !TEST_true(EVP_DigestSqueeze(ctx, out2 + sizeof(out2) / 2,
519 sizeof(out2) / 2)))
520 goto err;
521
522 if (!TEST_mem_eq(out2, sizeof(out2), out, sizeof(out)))
523 goto err;
524 ret = 1;
525
526 err:
527 EVP_MD_CTX_free(ctx);
528 return ret;
529 }
530
xof_fail_test(void)531 static int xof_fail_test(void)
532 {
533 int ret;
534 EVP_MD *md = NULL;
535
536 ret = TEST_ptr(md = EVP_MD_fetch(NULL, "SHA256", NULL))
537 && TEST_false(EVP_MD_xof(md));
538 EVP_MD_free(md);
539 return ret;
540 }
541
setup_tests(void)542 int setup_tests(void)
543 {
544 ADD_TEST(shake_kat_test);
545 ADD_TEST(shake_kat_digestfinal_test);
546 ADD_TEST(shake_kat_digestfinal_xoflen_test);
547 ADD_TEST(shake_absorb_test);
548 ADD_ALL_TESTS(shake_squeeze_kat_test, OSSL_NELEM(stride_tests));
549 ADD_ALL_TESTS(shake_squeeze_large_test, OSSL_NELEM(stride_tests));
550 ADD_ALL_TESTS(shake_squeeze_dup_test, OSSL_NELEM(dupoffset_tests));
551 ADD_TEST(xof_fail_test);
552 ADD_TEST(shake_squeeze_no_absorb_test);
553 return 1;
554 }
555