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