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, 153 0xea, 154 0x24, 155 0x6a, 156 0xab, 157 0x80, 158 0x37, 159 0x9e, 160 0x08, 161 0xe2, 162 0x19, 163 0x9e, 164 0x09, 165 0x69, 166 0xe2, 167 0xee, 168 0x1a, 169 0x5d, 170 0xd1, 171 0x68, 172 0x68, 173 0xec, 174 0x8d, 175 0x42, 176 0xd0, 177 0xf8, 178 0xb8, 179 0x44, 180 0x74, 181 0x54, 182 0x87, 183 0x3e, 184 }; 185 186 static EVP_MD_CTX *shake_setup(const char *name) 187 { 188 EVP_MD_CTX *ctx = NULL; 189 EVP_MD *md = NULL; 190 191 if (!TEST_ptr(md = EVP_MD_fetch(NULL, name, NULL))) 192 return NULL; 193 194 if (!TEST_ptr(ctx = EVP_MD_CTX_new())) 195 goto err; 196 if (!TEST_true(EVP_DigestInit_ex2(ctx, md, NULL))) 197 goto err; 198 EVP_MD_free(md); 199 return ctx; 200 err: 201 EVP_MD_free(md); 202 EVP_MD_CTX_free(ctx); 203 return NULL; 204 } 205 206 static int shake_kat_test(void) 207 { 208 int ret = 0; 209 EVP_MD_CTX *ctx = NULL; 210 unsigned char out[sizeof(shake256_output)]; 211 212 if (!TEST_ptr(ctx = shake_setup("SHAKE256"))) 213 return 0; 214 if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input, 215 sizeof(shake256_input))) 216 || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))) 217 || !TEST_mem_eq(out, sizeof(out), 218 shake256_output, sizeof(shake256_output)) 219 /* Test that a second call to EVP_DigestFinalXOF fails */ 220 || !TEST_false(EVP_DigestFinalXOF(ctx, out, sizeof(out))) 221 /* Test that a call to EVP_DigestSqueeze fails */ 222 || !TEST_false(EVP_DigestSqueeze(ctx, out, sizeof(out)))) 223 goto err; 224 ret = 1; 225 err: 226 EVP_MD_CTX_free(ctx); 227 return ret; 228 } 229 230 static int shake_kat_digestfinal_test(void) 231 { 232 int ret = 0; 233 unsigned int digest_length = 0; 234 EVP_MD_CTX *ctx = NULL; 235 unsigned char out[sizeof(shake256_output)]; 236 237 /* Test that EVP_DigestFinal without setting XOFLEN fails */ 238 if (!TEST_ptr(ctx = shake_setup("SHAKE256"))) 239 return 0; 240 if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input, 241 sizeof(shake256_input)))) 242 return 0; 243 ERR_set_mark(); 244 if (!TEST_false(EVP_DigestFinal(ctx, out, &digest_length))) { 245 ERR_clear_last_mark(); 246 return 0; 247 } 248 ERR_pop_to_mark(); 249 EVP_MD_CTX_free(ctx); 250 251 /* However EVP_DigestFinalXOF must work */ 252 if (!TEST_ptr(ctx = shake_setup("SHAKE256"))) 253 return 0; 254 if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input, 255 sizeof(shake256_input)))) 256 return 0; 257 if (!TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))) 258 || !TEST_mem_eq(out, sizeof(out), 259 shake256_output, sizeof(shake256_output)) 260 || !TEST_false(EVP_DigestFinalXOF(ctx, out, sizeof(out)))) 261 goto err; 262 ret = 1; 263 err: 264 EVP_MD_CTX_free(ctx); 265 return ret; 266 } 267 268 /* 269 * Test that EVP_DigestFinal() returns the output length 270 * set by the OSSL_DIGEST_PARAM_XOFLEN param. 271 */ 272 static int shake_kat_digestfinal_xoflen_test(void) 273 { 274 int ret = 0; 275 unsigned int digest_length = 0; 276 EVP_MD_CTX *ctx = NULL; 277 const EVP_MD *md; 278 unsigned char out[sizeof(shake256_output)]; 279 OSSL_PARAM params[2]; 280 size_t sz = 12; 281 282 if (!TEST_ptr(ctx = shake_setup("SHAKE256"))) 283 return 0; 284 md = EVP_MD_CTX_get0_md(ctx); 285 286 memset(out, 0, sizeof(out)); 287 params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz); 288 params[1] = OSSL_PARAM_construct_end(); 289 290 if (!TEST_int_eq(EVP_MD_CTX_size(ctx), -1) 291 || !TEST_int_eq(EVP_MD_CTX_set_params(ctx, params), 1) 292 || !TEST_int_eq(EVP_MD_CTX_size(ctx), sz) 293 || !TEST_int_eq(EVP_MD_get_size(md), 0) 294 || !TEST_true(EVP_MD_xof(md)) 295 || !TEST_true(EVP_DigestUpdate(ctx, shake256_input, 296 sizeof(shake256_input))) 297 || !TEST_true(EVP_DigestFinal(ctx, out, &digest_length)) 298 || !TEST_uint_eq(digest_length, (unsigned int)sz) 299 || !TEST_mem_eq(out, digest_length, 300 shake256_output, digest_length) 301 || !TEST_uchar_eq(out[digest_length], 0)) 302 goto err; 303 ret = 1; 304 err: 305 EVP_MD_CTX_free(ctx); 306 return ret; 307 } 308 309 /* 310 * Test that multiple absorb calls gives the expected result. 311 * This is a nested test that uses multiple strides for the input. 312 */ 313 static int shake_absorb_test(void) 314 { 315 int ret = 0; 316 EVP_MD_CTX *ctx = NULL; 317 unsigned char out[sizeof(shake256_largemsg_output)]; 318 size_t total = sizeof(shake256_largemsg_input); 319 size_t i, stride, sz; 320 321 if (!TEST_ptr(ctx = shake_setup("SHAKE256"))) 322 return 0; 323 324 for (stride = 1; stride < total; ++stride) { 325 sz = 0; 326 for (i = 0; i < total; i += sz) { 327 sz += stride; 328 if ((i + sz) > total) 329 sz = total - i; 330 if (!TEST_true(EVP_DigestUpdate(ctx, shake256_largemsg_input + i, 331 sz))) 332 goto err; 333 } 334 if (!TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))) 335 || !TEST_mem_eq(out, sizeof(out), 336 shake256_largemsg_output, 337 sizeof(shake256_largemsg_output))) 338 goto err; 339 if (!TEST_true(EVP_DigestInit_ex2(ctx, NULL, NULL))) 340 goto err; 341 } 342 ret = 1; 343 err: 344 EVP_MD_CTX_free(ctx); 345 return ret; 346 } 347 348 /* 349 * Table containing the size of the output to squeeze for the 350 * initially call, followed by a size for each subsequent call. 351 */ 352 static const struct { 353 size_t startsz, incsz; 354 } stride_tests[] = { 355 { 1, 1 }, 356 { 1, 136 }, 357 { 1, 136 / 2 }, 358 { 1, 136 / 2 - 1 }, 359 { 1, 136 / 2 + 1 }, 360 { 1, 136 * 3 }, 361 { 8, 8 }, 362 { 9, 9 }, 363 { 10, 10 }, 364 { 136 / 2 - 1, 136 }, 365 { 136 / 2 - 1, 136 - 1 }, 366 { 136 / 2 - 1, 136 + 1 }, 367 { 136 / 2, 136 }, 368 { 136 / 2, 136 - 1 }, 369 { 136 / 2, 136 + 1 }, 370 { 136 / 2 + 1, 136 }, 371 { 136 / 2 + 1, 136 - 1 }, 372 { 136 / 2 + 1, 136 + 1 }, 373 { 136, 2 }, 374 { 136, 136 }, 375 { 136 - 1, 136 }, 376 { 136 - 1, 136 - 1 }, 377 { 136 - 1, 136 + 1 }, 378 { 136 + 1, 136 }, 379 { 136 + 1, 136 - 1 }, 380 { 136 + 1, 136 + 1 }, 381 { 136 * 3, 136 }, 382 { 136 * 3, 136 + 1 }, 383 { 136 * 3, 136 - 1 }, 384 { 136 * 3, 136 / 2 }, 385 { 136 * 3, 136 / 2 + 1 }, 386 { 136 * 3, 136 / 2 - 1 }, 387 }; 388 389 /* 390 * Helper to do multiple squeezes of output data using SHAKE256. 391 * tst is an index into the stride_tests[] containing an initial starting 392 * output length, followed by a second output length to use for all remaining 393 * squeezes. expected_outlen contains the total number of bytes to squeeze. 394 * in and inlen represent the input to absorb. expected_out and expected_outlen 395 * represent the expected output. 396 */ 397 static int do_shake_squeeze_test(int tst, 398 const unsigned char *in, size_t inlen, 399 const unsigned char *expected_out, 400 size_t expected_outlen) 401 { 402 int ret = 0; 403 EVP_MD_CTX *ctx = NULL; 404 unsigned char *out = NULL; 405 size_t i = 0, sz = stride_tests[tst].startsz; 406 407 if (!TEST_ptr(ctx = shake_setup("SHAKE256"))) 408 return 0; 409 if (!TEST_ptr(out = OPENSSL_malloc(expected_outlen))) 410 goto err; 411 if (!TEST_true(EVP_DigestUpdate(ctx, in, inlen))) 412 goto err; 413 414 while (i < expected_outlen) { 415 if ((i + sz) > expected_outlen) 416 sz = expected_outlen - i; 417 if (!TEST_true(EVP_DigestSqueeze(ctx, out + i, sz))) 418 goto err; 419 i += sz; 420 sz = stride_tests[tst].incsz; 421 } 422 if (!TEST_mem_eq(out, expected_outlen, expected_out, expected_outlen)) 423 goto err; 424 ret = 1; 425 err: 426 OPENSSL_free(out); 427 EVP_MD_CTX_free(ctx); 428 return ret; 429 } 430 431 static int shake_squeeze_kat_test(int tst) 432 { 433 return do_shake_squeeze_test(tst, shake256_input, sizeof(shake256_input), 434 shake256_output, sizeof(shake256_output)); 435 } 436 437 /* 438 * Generate some random input to absorb, and then 439 * squeeze it out in one operation to get a expected 440 * output. Use this to test that multiple squeeze calls 441 * on the same input gives the same output. 442 */ 443 static int shake_squeeze_large_test(int tst) 444 { 445 int ret = 0; 446 EVP_MD_CTX *ctx = NULL; 447 unsigned char msg[16]; 448 unsigned char out[2000]; 449 450 if (!TEST_int_gt(RAND_bytes(msg, sizeof(msg)), 0) 451 || !TEST_ptr(ctx = shake_setup("SHAKE256")) 452 || !TEST_true(EVP_DigestUpdate(ctx, msg, sizeof(msg))) 453 || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))) 454 goto err; 455 456 ret = do_shake_squeeze_test(tst, msg, sizeof(msg), out, sizeof(out)); 457 err: 458 EVP_MD_CTX_free(ctx); 459 return ret; 460 } 461 462 static const size_t dupoffset_tests[] = { 463 1, 135, 136, 137, 136 * 3 - 1, 136 * 3, 136 * 3 + 1 464 }; 465 466 /* Helper function to test that EVP_MD_CTX_dup() copies the internal state */ 467 static int do_shake_squeeze_dup_test(int tst, const char *alg, 468 const unsigned char *in, size_t inlen, 469 const unsigned char *expected_out, 470 size_t expected_outlen) 471 { 472 int ret = 0; 473 EVP_MD_CTX *cur, *ctx = NULL, *dupctx = NULL; 474 unsigned char *out = NULL; 475 size_t i = 0, sz = 10; 476 size_t dupoffset = dupoffset_tests[tst]; 477 478 if (!TEST_ptr(ctx = shake_setup(alg))) 479 return 0; 480 cur = ctx; 481 if (!TEST_ptr(out = OPENSSL_malloc(expected_outlen))) 482 goto err; 483 if (!TEST_true(EVP_DigestUpdate(ctx, in, inlen))) 484 goto err; 485 486 while (i < expected_outlen) { 487 if ((i + sz) > expected_outlen) 488 sz = expected_outlen - i; 489 if (!TEST_true(EVP_DigestSqueeze(cur, out + i, sz))) 490 goto err; 491 i += sz; 492 /* At a certain offset we swap to a new ctx that copies the state */ 493 if (dupctx == NULL && i >= dupoffset) { 494 if (!TEST_ptr(dupctx = EVP_MD_CTX_dup(ctx))) 495 goto err; 496 cur = dupctx; 497 } 498 } 499 if (!TEST_mem_eq(out, expected_outlen, expected_out, expected_outlen)) 500 goto err; 501 ret = 1; 502 err: 503 OPENSSL_free(out); 504 EVP_MD_CTX_free(ctx); 505 EVP_MD_CTX_free(dupctx); 506 return ret; 507 } 508 509 /* Test that the internal state can be copied */ 510 static int shake_squeeze_dup_test(int tst) 511 { 512 int ret = 0; 513 EVP_MD_CTX *ctx = NULL; 514 unsigned char msg[16]; 515 unsigned char out[1000]; 516 const char *alg = "SHAKE128"; 517 518 if (!TEST_int_gt(RAND_bytes(msg, sizeof(msg)), 0) 519 || !TEST_ptr(ctx = shake_setup(alg)) 520 || !TEST_true(EVP_DigestUpdate(ctx, msg, sizeof(msg))) 521 || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))) 522 goto err; 523 524 ret = do_shake_squeeze_dup_test(tst, alg, msg, sizeof(msg), 525 out, sizeof(out)); 526 err: 527 EVP_MD_CTX_free(ctx); 528 return ret; 529 } 530 531 /* Test that a squeeze without a preceding absorb works */ 532 static int shake_squeeze_no_absorb_test(void) 533 { 534 int ret = 0; 535 EVP_MD_CTX *ctx = NULL; 536 unsigned char out[1000]; 537 unsigned char out2[1000]; 538 const char *alg = "SHAKE128"; 539 540 if (!TEST_ptr(ctx = shake_setup(alg)) 541 || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))) 542 goto err; 543 544 if (!TEST_true(EVP_DigestInit_ex2(ctx, NULL, NULL)) 545 || !TEST_true(EVP_DigestSqueeze(ctx, out2, sizeof(out2) / 2)) 546 || !TEST_true(EVP_DigestSqueeze(ctx, out2 + sizeof(out2) / 2, 547 sizeof(out2) / 2))) 548 goto err; 549 550 if (!TEST_mem_eq(out2, sizeof(out2), out, sizeof(out))) 551 goto err; 552 ret = 1; 553 554 err: 555 EVP_MD_CTX_free(ctx); 556 return ret; 557 } 558 559 static int xof_fail_test(void) 560 { 561 int ret; 562 EVP_MD *md = NULL; 563 564 ret = TEST_ptr(md = EVP_MD_fetch(NULL, "SHA256", NULL)) 565 && TEST_false(EVP_MD_xof(md)); 566 EVP_MD_free(md); 567 return ret; 568 } 569 570 int setup_tests(void) 571 { 572 ADD_TEST(shake_kat_test); 573 ADD_TEST(shake_kat_digestfinal_test); 574 ADD_TEST(shake_kat_digestfinal_xoflen_test); 575 ADD_TEST(shake_absorb_test); 576 ADD_ALL_TESTS(shake_squeeze_kat_test, OSSL_NELEM(stride_tests)); 577 ADD_ALL_TESTS(shake_squeeze_large_test, OSSL_NELEM(stride_tests)); 578 ADD_ALL_TESTS(shake_squeeze_dup_test, OSSL_NELEM(dupoffset_tests)); 579 ADD_TEST(xof_fail_test); 580 ADD_TEST(shake_squeeze_no_absorb_test); 581 return 1; 582 } 583