1 /* 2 * Copyright 2022-2026 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/core_names.h> 12 #include <openssl/rand.h> 13 #include <openssl/hpke.h> 14 #include "testutil.h" 15 16 /* a size to use for stack buffers */ 17 #define OSSL_HPKE_TSTSIZE 512 18 19 static OSSL_LIB_CTX *testctx = NULL; 20 static OSSL_PROVIDER *nullprov = NULL; 21 static OSSL_PROVIDER *deflprov = NULL; 22 static char *testpropq = "provider=default"; 23 static int verbose = 0; 24 25 typedef struct { 26 int mode; 27 OSSL_HPKE_SUITE suite; 28 const unsigned char *ikmE; 29 size_t ikmElen; 30 const unsigned char *expected_pkEm; 31 size_t expected_pkEmlen; 32 const unsigned char *ikmR; 33 size_t ikmRlen; 34 const unsigned char *expected_pkRm; 35 size_t expected_pkRmlen; 36 const unsigned char *expected_skRm; 37 size_t expected_skRmlen; 38 const unsigned char *expected_secret; 39 size_t expected_secretlen; 40 const unsigned char *ksinfo; 41 size_t ksinfolen; 42 const unsigned char *ikmAuth; 43 size_t ikmAuthlen; 44 const unsigned char *psk; 45 size_t psklen; 46 const char *pskid; /* want terminating NUL here */ 47 } TEST_BASEDATA; 48 49 typedef struct { 50 int seq; 51 const unsigned char *pt; 52 size_t ptlen; 53 const unsigned char *aad; 54 size_t aadlen; 55 const unsigned char *expected_ct; 56 size_t expected_ctlen; 57 } TEST_AEADDATA; 58 59 typedef struct { 60 const unsigned char *context; 61 size_t contextlen; 62 const unsigned char *expected_secret; 63 size_t expected_secretlen; 64 } TEST_EXPORTDATA; 65 66 /** 67 * @brief Test that an EVP_PKEY encoded public key matches the supplied buffer 68 * @param pkey is the EVP_PKEY we want to check 69 * @param pub is the expected public key buffer 70 * @param publen is the length of the above 71 * @return 1 for good, 0 for bad 72 */ 73 static int cmpkey(const EVP_PKEY *pkey, 74 const unsigned char *pub, size_t publen) 75 { 76 unsigned char pubbuf[256]; 77 size_t pubbuflen = 0; 78 int erv = 0; 79 80 if (!TEST_true(publen <= sizeof(pubbuf))) 81 return 0; 82 erv = EVP_PKEY_get_octet_string_param(pkey, 83 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, 84 pubbuf, sizeof(pubbuf), &pubbuflen); 85 if (!TEST_true(erv)) 86 return 0; 87 if (pub != NULL && !TEST_mem_eq(pubbuf, pubbuflen, pub, publen)) 88 return 0; 89 return 1; 90 } 91 92 static int do_testhpke(const TEST_BASEDATA *base, 93 const TEST_AEADDATA *aead, size_t aeadsz, 94 const TEST_EXPORTDATA *export, size_t exportsz) 95 { 96 OSSL_LIB_CTX *libctx = testctx; 97 const char *propq = testpropq; 98 OSSL_HPKE_CTX *sealctx = NULL, *openctx = NULL; 99 unsigned char ct[256]; 100 unsigned char enc[256]; 101 unsigned char ptout[256]; 102 size_t ptoutlen = sizeof(ptout); 103 size_t enclen = sizeof(enc); 104 size_t ctlen = sizeof(ct); 105 unsigned char pub[OSSL_HPKE_TSTSIZE]; 106 size_t publen = sizeof(pub); 107 EVP_PKEY *privE = NULL; 108 unsigned char authpub[OSSL_HPKE_TSTSIZE]; 109 size_t authpublen = sizeof(authpub); 110 EVP_PKEY *authpriv = NULL; 111 unsigned char rpub[OSSL_HPKE_TSTSIZE]; 112 size_t rpublen = sizeof(pub); 113 EVP_PKEY *privR = NULL; 114 int ret = 0; 115 size_t i; 116 uint64_t lastseq = 0; 117 118 if (!TEST_true(OSSL_HPKE_keygen(base->suite, pub, &publen, &privE, 119 base->ikmE, base->ikmElen, libctx, propq))) 120 goto end; 121 if (!TEST_true(cmpkey(privE, base->expected_pkEm, base->expected_pkEmlen))) 122 goto end; 123 if (!TEST_ptr(sealctx = OSSL_HPKE_CTX_new(base->mode, base->suite, 124 OSSL_HPKE_ROLE_SENDER, 125 libctx, propq))) 126 goto end; 127 if (!TEST_true(OSSL_HPKE_CTX_set1_ikme(sealctx, base->ikmE, base->ikmElen))) 128 goto end; 129 if (base->mode == OSSL_HPKE_MODE_AUTH 130 || base->mode == OSSL_HPKE_MODE_PSKAUTH) { 131 if (!TEST_true(base->ikmAuth != NULL && base->ikmAuthlen > 0)) 132 goto end; 133 if (!TEST_true(OSSL_HPKE_keygen(base->suite, 134 authpub, &authpublen, &authpriv, 135 base->ikmAuth, base->ikmAuthlen, 136 libctx, propq))) 137 goto end; 138 if (!TEST_true(OSSL_HPKE_CTX_set1_authpriv(sealctx, authpriv))) 139 goto end; 140 } 141 if (!TEST_true(OSSL_HPKE_keygen(base->suite, rpub, &rpublen, &privR, 142 base->ikmR, base->ikmRlen, libctx, propq))) 143 goto end; 144 if (!TEST_true(cmpkey(privR, base->expected_pkRm, base->expected_pkRmlen))) 145 goto end; 146 if (base->mode == OSSL_HPKE_MODE_PSK 147 || base->mode == OSSL_HPKE_MODE_PSKAUTH) { 148 if (!TEST_true(OSSL_HPKE_CTX_set1_psk(sealctx, base->pskid, 149 base->psk, base->psklen))) 150 goto end; 151 } 152 if (!TEST_true(OSSL_HPKE_encap(sealctx, enc, &enclen, 153 rpub, rpublen, 154 base->ksinfo, base->ksinfolen))) 155 goto end; 156 if (!TEST_true(cmpkey(privE, enc, enclen))) 157 goto end; 158 for (i = 0; i < aeadsz; ++i) { 159 ctlen = sizeof(ct); 160 memset(ct, 0, ctlen); 161 if (!TEST_true(OSSL_HPKE_seal(sealctx, ct, &ctlen, 162 aead[i].aad, aead[i].aadlen, 163 aead[i].pt, aead[i].ptlen))) 164 goto end; 165 if (!TEST_mem_eq(ct, ctlen, aead[i].expected_ct, 166 aead[i].expected_ctlen)) 167 goto end; 168 if (!TEST_true(OSSL_HPKE_CTX_get_seq(sealctx, &lastseq))) 169 goto end; 170 if (lastseq != (uint64_t)(i + 1)) 171 goto end; 172 } 173 if (!TEST_ptr(openctx = OSSL_HPKE_CTX_new(base->mode, base->suite, 174 OSSL_HPKE_ROLE_RECEIVER, 175 libctx, propq))) 176 goto end; 177 if (base->mode == OSSL_HPKE_MODE_PSK 178 || base->mode == OSSL_HPKE_MODE_PSKAUTH) { 179 if (!TEST_true(base->pskid != NULL && base->psk != NULL 180 && base->psklen > 0)) 181 goto end; 182 if (!TEST_true(OSSL_HPKE_CTX_set1_psk(openctx, base->pskid, 183 base->psk, base->psklen))) 184 goto end; 185 } 186 if (base->mode == OSSL_HPKE_MODE_AUTH 187 || base->mode == OSSL_HPKE_MODE_PSKAUTH) { 188 if (!TEST_true(OSSL_HPKE_CTX_set1_authpub(openctx, 189 authpub, authpublen))) 190 goto end; 191 } 192 if (!TEST_true(OSSL_HPKE_decap(openctx, enc, enclen, privR, 193 base->ksinfo, base->ksinfolen))) 194 goto end; 195 for (i = 0; i < aeadsz; ++i) { 196 ptoutlen = sizeof(ptout); 197 memset(ptout, 0, ptoutlen); 198 if (!TEST_true(OSSL_HPKE_open(openctx, ptout, &ptoutlen, 199 aead[i].aad, aead[i].aadlen, 200 aead[i].expected_ct, 201 aead[i].expected_ctlen))) 202 goto end; 203 if (!TEST_mem_eq(aead[i].pt, aead[i].ptlen, ptout, ptoutlen)) 204 goto end; 205 /* check the sequence is being incremented as expected */ 206 if (!TEST_true(OSSL_HPKE_CTX_get_seq(openctx, &lastseq))) 207 goto end; 208 if (lastseq != (uint64_t)(i + 1)) 209 goto end; 210 } 211 /* check exporters */ 212 for (i = 0; i < exportsz; ++i) { 213 size_t len = export[i].expected_secretlen; 214 unsigned char eval[OSSL_HPKE_TSTSIZE]; 215 216 if (len > sizeof(eval)) 217 goto end; 218 /* export with too long label should fail */ 219 if (!TEST_false(OSSL_HPKE_export(sealctx, eval, len, 220 export[i].context, -1))) 221 goto end; 222 /* good export call */ 223 if (!TEST_true(OSSL_HPKE_export(sealctx, eval, len, 224 export[i].context, 225 export[i].contextlen))) 226 goto end; 227 if (!TEST_mem_eq(eval, len, export[i].expected_secret, 228 export[i].expected_secretlen)) 229 goto end; 230 231 /* check seal fails if export only mode */ 232 if (aeadsz == 0) { 233 234 if (!TEST_false(OSSL_HPKE_seal(sealctx, ct, &ctlen, 235 NULL, 0, ptout, ptoutlen))) 236 goto end; 237 } 238 } 239 ret = 1; 240 end: 241 OSSL_HPKE_CTX_free(sealctx); 242 OSSL_HPKE_CTX_free(openctx); 243 EVP_PKEY_free(privE); 244 EVP_PKEY_free(privR); 245 EVP_PKEY_free(authpriv); 246 return ret; 247 } 248 249 static const unsigned char pt[] = { 250 0x42, 0x65, 0x61, 0x75, 0x74, 0x79, 0x20, 0x69, 251 0x73, 0x20, 0x74, 0x72, 0x75, 0x74, 0x68, 0x2c, 252 0x20, 0x74, 0x72, 0x75, 0x74, 0x68, 0x20, 0x62, 253 0x65, 0x61, 0x75, 0x74, 0x79 254 }; 255 static const unsigned char ksinfo[] = { 256 0x4f, 0x64, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x61, 257 0x20, 0x47, 0x72, 0x65, 0x63, 0x69, 0x61, 0x6e, 258 0x20, 0x55, 0x72, 0x6e 259 }; 260 #ifndef OPENSSL_NO_ECX 261 /* 262 * static const char *pskid = "Ennyn Durin aran Moria"; 263 */ 264 static const unsigned char pskid[] = { 265 0x45, 0x6e, 0x6e, 0x79, 0x6e, 0x20, 0x44, 0x75, 266 0x72, 0x69, 0x6e, 0x20, 0x61, 0x72, 0x61, 0x6e, 267 0x20, 0x4d, 0x6f, 0x72, 0x69, 0x61, 0x00 268 }; 269 static const unsigned char psk[] = { 270 0x02, 0x47, 0xfd, 0x33, 0xb9, 0x13, 0x76, 0x0f, 271 0xa1, 0xfa, 0x51, 0xe1, 0x89, 0x2d, 0x9f, 0x30, 272 0x7f, 0xbe, 0x65, 0xeb, 0x17, 0x1e, 0x81, 0x32, 273 0xc2, 0xaf, 0x18, 0x55, 0x5a, 0x73, 0x8b, 0x82 274 }; 275 276 /* these need to be "outside" the function below to keep check-ansi CI happy */ 277 static const unsigned char first_ikme[] = { 278 0x78, 0x62, 0x8c, 0x35, 0x4e, 0x46, 0xf3, 0xe1, 279 0x69, 0xbd, 0x23, 0x1b, 0xe7, 0xb2, 0xff, 0x1c, 280 0x77, 0xaa, 0x30, 0x24, 0x60, 0xa2, 0x6d, 0xbf, 281 0xa1, 0x55, 0x15, 0x68, 0x4c, 0x00, 0x13, 0x0b 282 }; 283 static const unsigned char first_ikmr[] = { 284 0xd4, 0xa0, 0x9d, 0x09, 0xf5, 0x75, 0xfe, 0xf4, 285 0x25, 0x90, 0x5d, 0x2a, 0xb3, 0x96, 0xc1, 0x44, 286 0x91, 0x41, 0x46, 0x3f, 0x69, 0x8f, 0x8e, 0xfd, 287 0xb7, 0xac, 0xcf, 0xaf, 0xf8, 0x99, 0x50, 0x98 288 }; 289 static const unsigned char first_ikmepub[] = { 290 0x0a, 0xd0, 0x95, 0x0d, 0x9f, 0xb9, 0x58, 0x8e, 0x59, 0x69, 291 0x0b, 0x74, 0xf1, 0x23, 0x7e, 0xcd, 0xf1, 0xd7, 0x75, 0xcd, 292 0x60, 0xbe, 0x2e, 0xca, 0x57, 0xaf, 0x5a, 0x4b, 0x04, 0x71, 293 0xc9, 0x1b 294 }; 295 static const unsigned char first_ikmrpub[] = { 296 0x9f, 0xed, 0x7e, 0x8c, 0x17, 0x38, 0x75, 0x60, 297 0xe9, 0x2c, 0xc6, 0x46, 0x2a, 0x68, 0x04, 0x96, 298 0x57, 0x24, 0x6a, 0x09, 0xbf, 0xa8, 0xad, 0xe7, 299 0xae, 0xfe, 0x58, 0x96, 0x72, 0x01, 0x63, 0x66 300 }; 301 static const unsigned char first_ikmrpriv[] = { 302 0xc5, 0xeb, 0x01, 0xeb, 0x45, 0x7f, 0xe6, 0xc6, 303 0xf5, 0x75, 0x77, 0xc5, 0x41, 0x3b, 0x93, 0x15, 304 0x50, 0xa1, 0x62, 0xc7, 0x1a, 0x03, 0xac, 0x8d, 305 0x19, 0x6b, 0xab, 0xbd, 0x4e, 0x5c, 0xe0, 0xfd 306 }; 307 static const unsigned char first_expected_shared_secret[] = { 308 0x72, 0x76, 0x99, 0xf0, 0x09, 0xff, 0xe3, 0xc0, 309 0x76, 0x31, 0x50, 0x19, 0xc6, 0x96, 0x48, 0x36, 310 0x6b, 0x69, 0x17, 0x14, 0x39, 0xbd, 0x7d, 0xd0, 311 0x80, 0x77, 0x43, 0xbd, 0xe7, 0x69, 0x86, 0xcd 312 }; 313 static const unsigned char first_aad0[] = { 314 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2d, 0x30 315 }; 316 static const unsigned char first_ct0[] = { 317 0xe5, 0x2c, 0x6f, 0xed, 0x7f, 0x75, 0x8d, 0x0c, 318 0xf7, 0x14, 0x56, 0x89, 0xf2, 0x1b, 0xc1, 0xbe, 319 0x6e, 0xc9, 0xea, 0x09, 0x7f, 0xef, 0x4e, 0x95, 320 0x94, 0x40, 0x01, 0x2f, 0x4f, 0xeb, 0x73, 0xfb, 321 0x61, 0x1b, 0x94, 0x61, 0x99, 0xe6, 0x81, 0xf4, 322 0xcf, 0xc3, 0x4d, 0xb8, 0xea 323 }; 324 static const unsigned char first_aad1[] = { 325 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2d, 0x31 326 }; 327 static const unsigned char first_ct1[] = { 328 0x49, 0xf3, 0xb1, 0x9b, 0x28, 0xa9, 0xea, 0x9f, 329 0x43, 0xe8, 0xc7, 0x12, 0x04, 0xc0, 0x0d, 0x4a, 330 0x49, 0x0e, 0xe7, 0xf6, 0x13, 0x87, 0xb6, 0x71, 331 0x9d, 0xb7, 0x65, 0xe9, 0x48, 0x12, 0x3b, 0x45, 332 0xb6, 0x16, 0x33, 0xef, 0x05, 0x9b, 0xa2, 0x2c, 333 0xd6, 0x24, 0x37, 0xc8, 0xba 334 }; 335 static const unsigned char first_aad2[] = { 336 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2d, 0x32 337 }; 338 static const unsigned char first_ct2[] = { 339 0x25, 0x7c, 0xa6, 0xa0, 0x84, 0x73, 0xdc, 0x85, 340 0x1f, 0xde, 0x45, 0xaf, 0xd5, 0x98, 0xcc, 0x83, 341 0xe3, 0x26, 0xdd, 0xd0, 0xab, 0xe1, 0xef, 0x23, 342 0xba, 0xa3, 0xba, 0xa4, 0xdd, 0x8c, 0xde, 0x99, 343 0xfc, 0xe2, 0xc1, 0xe8, 0xce, 0x68, 0x7b, 0x0b, 344 0x47, 0xea, 0xd1, 0xad, 0xc9 345 }; 346 static const unsigned char first_export1[] = { 347 0xdf, 0xf1, 0x7a, 0xf3, 0x54, 0xc8, 0xb4, 0x16, 348 0x73, 0x56, 0x7d, 0xb6, 0x25, 0x9f, 0xd6, 0x02, 349 0x99, 0x67, 0xb4, 0xe1, 0xaa, 0xd1, 0x30, 0x23, 350 0xc2, 0xae, 0x5d, 0xf8, 0xf4, 0xf4, 0x3b, 0xf6 351 }; 352 static const unsigned char first_context2[] = { 0x00 }; 353 static const unsigned char first_export2[] = { 354 0x6a, 0x84, 0x72, 0x61, 0xd8, 0x20, 0x7f, 0xe5, 355 0x96, 0xbe, 0xfb, 0x52, 0x92, 0x84, 0x63, 0x88, 356 0x1a, 0xb4, 0x93, 0xda, 0x34, 0x5b, 0x10, 0xe1, 357 0xdc, 0xc6, 0x45, 0xe3, 0xb9, 0x4e, 0x2d, 0x95 358 }; 359 static const unsigned char first_context3[] = { 360 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 361 0x65, 0x78, 0x74 362 }; 363 static const unsigned char first_export3[] = { 364 0x8a, 0xff, 0x52, 0xb4, 0x5a, 0x1b, 0xe3, 0xa7, 365 0x34, 0xbc, 0x7a, 0x41, 0xe2, 0x0b, 0x4e, 0x05, 366 0x5a, 0xd4, 0xc4, 0xd2, 0x21, 0x04, 0xb0, 0xc2, 367 0x02, 0x85, 0xa7, 0xc4, 0x30, 0x24, 0x01, 0xcd 368 }; 369 370 static int x25519kdfsha256_hkdfsha256_aes128gcm_psk_test(void) 371 { 372 const TEST_BASEDATA pskdata = { 373 /* "X25519", NULL, "SHA256", "SHA256", "AES-128-GCM", */ 374 OSSL_HPKE_MODE_PSK, 375 { OSSL_HPKE_KEM_ID_X25519, 376 OSSL_HPKE_KDF_ID_HKDF_SHA256, 377 OSSL_HPKE_AEAD_ID_AES_GCM_128 }, 378 first_ikme, sizeof(first_ikme), 379 first_ikmepub, sizeof(first_ikmepub), 380 first_ikmr, sizeof(first_ikmr), 381 first_ikmrpub, sizeof(first_ikmrpub), 382 first_ikmrpriv, sizeof(first_ikmrpriv), 383 first_expected_shared_secret, sizeof(first_expected_shared_secret), 384 ksinfo, sizeof(ksinfo), 385 NULL, 0, /* No Auth */ 386 psk, sizeof(psk), (char *)pskid 387 }; 388 const TEST_AEADDATA aeaddata[] = { 389 { 0, 390 pt, sizeof(pt), 391 first_aad0, sizeof(first_aad0), 392 first_ct0, sizeof(first_ct0) }, 393 { 1, 394 pt, sizeof(pt), 395 first_aad1, sizeof(first_aad1), 396 first_ct1, sizeof(first_ct1) }, 397 { 2, 398 pt, sizeof(pt), 399 first_aad2, sizeof(first_aad2), 400 first_ct2, sizeof(first_ct2) } 401 }; 402 const TEST_EXPORTDATA exportdata[] = { 403 { NULL, 0, first_export1, sizeof(first_export1) }, 404 { first_context2, sizeof(first_context2), 405 first_export2, sizeof(first_export2) }, 406 { first_context3, sizeof(first_context3), 407 first_export3, sizeof(first_export3) }, 408 }; 409 return do_testhpke(&pskdata, aeaddata, OSSL_NELEM(aeaddata), 410 exportdata, OSSL_NELEM(exportdata)); 411 } 412 413 static const unsigned char second_ikme[] = { 414 0x72, 0x68, 0x60, 0x0d, 0x40, 0x3f, 0xce, 0x43, 415 0x15, 0x61, 0xae, 0xf5, 0x83, 0xee, 0x16, 0x13, 416 0x52, 0x7c, 0xff, 0x65, 0x5c, 0x13, 0x43, 0xf2, 417 0x98, 0x12, 0xe6, 0x67, 0x06, 0xdf, 0x32, 0x34 418 }; 419 static const unsigned char second_ikmepub[] = { 420 0x37, 0xfd, 0xa3, 0x56, 0x7b, 0xdb, 0xd6, 0x28, 0xe8, 0x86, 421 0x68, 0xc3, 0xc8, 0xd7, 0xe9, 0x7d, 0x1d, 0x12, 0x53, 0xb6, 422 0xd4, 0xea, 0x6d, 0x44, 0xc1, 0x50, 0xf7, 0x41, 0xf1, 0xbf, 423 0x44, 0x31 424 }; 425 static const unsigned char second_ikmr[] = { 426 0x6d, 0xb9, 0xdf, 0x30, 0xaa, 0x07, 0xdd, 0x42, 427 0xee, 0x5e, 0x81, 0x81, 0xaf, 0xdb, 0x97, 0x7e, 428 0x53, 0x8f, 0x5e, 0x1f, 0xec, 0x8a, 0x06, 0x22, 429 0x3f, 0x33, 0xf7, 0x01, 0x3e, 0x52, 0x50, 0x37 430 }; 431 static const unsigned char second_ikmrpub[] = { 432 0x39, 0x48, 0xcf, 0xe0, 0xad, 0x1d, 0xdb, 0x69, 433 0x5d, 0x78, 0x0e, 0x59, 0x07, 0x71, 0x95, 0xda, 434 0x6c, 0x56, 0x50, 0x6b, 0x02, 0x73, 0x29, 0x79, 435 0x4a, 0xb0, 0x2b, 0xca, 0x80, 0x81, 0x5c, 0x4d 436 }; 437 static const unsigned char second_ikmrpriv[] = { 438 0x46, 0x12, 0xc5, 0x50, 0x26, 0x3f, 0xc8, 0xad, 439 0x58, 0x37, 0x5d, 0xf3, 0xf5, 0x57, 0xaa, 0xc5, 440 0x31, 0xd2, 0x68, 0x50, 0x90, 0x3e, 0x55, 0xa9, 441 0xf2, 0x3f, 0x21, 0xd8, 0x53, 0x4e, 0x8a, 0xc8 442 }; 443 static const unsigned char second_expected_shared_secret[] = { 444 0xfe, 0x0e, 0x18, 0xc9, 0xf0, 0x24, 0xce, 0x43, 445 0x79, 0x9a, 0xe3, 0x93, 0xc7, 0xe8, 0xfe, 0x8f, 446 0xce, 0x9d, 0x21, 0x88, 0x75, 0xe8, 0x22, 0x7b, 447 0x01, 0x87, 0xc0, 0x4e, 0x7d, 0x2e, 0xa1, 0xfc 448 }; 449 static const unsigned char second_aead0[] = { 450 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2d, 0x30 451 }; 452 static const unsigned char second_ct0[] = { 453 0xf9, 0x38, 0x55, 0x8b, 0x5d, 0x72, 0xf1, 0xa2, 454 0x38, 0x10, 0xb4, 0xbe, 0x2a, 0xb4, 0xf8, 0x43, 455 0x31, 0xac, 0xc0, 0x2f, 0xc9, 0x7b, 0xab, 0xc5, 456 0x3a, 0x52, 0xae, 0x82, 0x18, 0xa3, 0x55, 0xa9, 457 0x6d, 0x87, 0x70, 0xac, 0x83, 0xd0, 0x7b, 0xea, 458 0x87, 0xe1, 0x3c, 0x51, 0x2a 459 }; 460 static const unsigned char second_aead1[] = { 461 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2d, 0x31 462 }; 463 static const unsigned char second_ct1[] = { 464 0xaf, 0x2d, 0x7e, 0x9a, 0xc9, 0xae, 0x7e, 0x27, 465 0x0f, 0x46, 0xba, 0x1f, 0x97, 0x5b, 0xe5, 0x3c, 466 0x09, 0xf8, 0xd8, 0x75, 0xbd, 0xc8, 0x53, 0x54, 467 0x58, 0xc2, 0x49, 0x4e, 0x8a, 0x6e, 0xab, 0x25, 468 0x1c, 0x03, 0xd0, 0xc2, 0x2a, 0x56, 0xb8, 0xca, 469 0x42, 0xc2, 0x06, 0x3b, 0x84 470 }; 471 static const unsigned char second_export1[] = { 472 0x38, 0x53, 0xfe, 0x2b, 0x40, 0x35, 0x19, 0x5a, 473 0x57, 0x3f, 0xfc, 0x53, 0x85, 0x6e, 0x77, 0x05, 474 0x8e, 0x15, 0xd9, 0xea, 0x06, 0x4d, 0xe3, 0xe5, 475 0x9f, 0x49, 0x61, 0xd0, 0x09, 0x52, 0x50, 0xee 476 }; 477 static const unsigned char second_context2[] = { 0x00 }; 478 static const unsigned char second_export2[] = { 479 0x2e, 0x8f, 0x0b, 0x54, 0x67, 0x3c, 0x70, 0x29, 480 0x64, 0x9d, 0x4e, 0xb9, 0xd5, 0xe3, 0x3b, 0xf1, 481 0x87, 0x2c, 0xf7, 0x6d, 0x62, 0x3f, 0xf1, 0x64, 482 0xac, 0x18, 0x5d, 0xa9, 0xe8, 0x8c, 0x21, 0xa5 483 }; 484 static const unsigned char second_context3[] = { 485 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 486 0x65, 0x78, 0x74 487 }; 488 static const unsigned char second_export3[] = { 489 0xe9, 0xe4, 0x30, 0x65, 0x10, 0x2c, 0x38, 0x36, 490 0x40, 0x1b, 0xed, 0x8c, 0x3c, 0x3c, 0x75, 0xae, 491 0x46, 0xbe, 0x16, 0x39, 0x86, 0x93, 0x91, 0xd6, 492 0x2c, 0x61, 0xf1, 0xec, 0x7a, 0xf5, 0x49, 0x31 493 }; 494 495 static int x25519kdfsha256_hkdfsha256_aes128gcm_base_test(void) 496 { 497 const TEST_BASEDATA basedata = { 498 OSSL_HPKE_MODE_BASE, 499 { OSSL_HPKE_KEM_ID_X25519, 500 OSSL_HPKE_KDF_ID_HKDF_SHA256, 501 OSSL_HPKE_AEAD_ID_AES_GCM_128 }, 502 second_ikme, sizeof(second_ikme), 503 second_ikmepub, sizeof(second_ikmepub), 504 second_ikmr, sizeof(second_ikmr), 505 second_ikmrpub, sizeof(second_ikmrpub), 506 second_ikmrpriv, sizeof(second_ikmrpriv), 507 second_expected_shared_secret, sizeof(second_expected_shared_secret), 508 ksinfo, sizeof(ksinfo), 509 NULL, 0, /* no auth ikm */ 510 NULL, 0, NULL /* no psk */ 511 }; 512 const TEST_AEADDATA aeaddata[] = { 513 { 0, 514 pt, sizeof(pt), 515 second_aead0, sizeof(second_aead0), 516 second_ct0, sizeof(second_ct0) }, 517 { 1, 518 pt, sizeof(pt), 519 second_aead1, sizeof(second_aead1), 520 second_ct1, sizeof(second_ct1) } 521 }; 522 const TEST_EXPORTDATA exportdata[] = { 523 { NULL, 0, second_export1, sizeof(second_export1) }, 524 { second_context2, sizeof(second_context2), 525 second_export2, sizeof(second_export2) }, 526 { second_context3, sizeof(second_context3), 527 second_export3, sizeof(second_export3) }, 528 }; 529 return do_testhpke(&basedata, aeaddata, OSSL_NELEM(aeaddata), 530 exportdata, OSSL_NELEM(exportdata)); 531 } 532 #endif 533 534 static const unsigned char third_ikme[] = { 535 0x42, 0x70, 0xe5, 0x4f, 0xfd, 0x08, 0xd7, 0x9d, 536 0x59, 0x28, 0x02, 0x0a, 0xf4, 0x68, 0x6d, 0x8f, 537 0x6b, 0x7d, 0x35, 0xdb, 0xe4, 0x70, 0x26, 0x5f, 538 0x1f, 0x5a, 0xa2, 0x28, 0x16, 0xce, 0x86, 0x0e 539 }; 540 static const unsigned char third_ikmepub[] = { 541 0x04, 0xa9, 0x27, 0x19, 0xc6, 0x19, 0x5d, 0x50, 0x85, 0x10, 542 0x4f, 0x46, 0x9a, 0x8b, 0x98, 0x14, 0xd5, 0x83, 0x8f, 0xf7, 543 0x2b, 0x60, 0x50, 0x1e, 0x2c, 0x44, 0x66, 0xe5, 0xe6, 0x7b, 544 0x32, 0x5a, 0xc9, 0x85, 0x36, 0xd7, 0xb6, 0x1a, 0x1a, 0xf4, 545 0xb7, 0x8e, 0x5b, 0x7f, 0x95, 0x1c, 0x09, 0x00, 0xbe, 0x86, 546 0x3c, 0x40, 0x3c, 0xe6, 0x5c, 0x9b, 0xfc, 0xb9, 0x38, 0x26, 547 0x57, 0x22, 0x2d, 0x18, 0xc4 548 }; 549 static const unsigned char third_ikmr[] = { 550 0x66, 0x8b, 0x37, 0x17, 0x1f, 0x10, 0x72, 0xf3, 551 0xcf, 0x12, 0xea, 0x8a, 0x23, 0x6a, 0x45, 0xdf, 552 0x23, 0xfc, 0x13, 0xb8, 0x2a, 0xf3, 0x60, 0x9a, 553 0xd1, 0xe3, 0x54, 0xf6, 0xef, 0x81, 0x75, 0x50 554 }; 555 static const unsigned char third_ikmrpub[] = { 556 0x04, 0xfe, 0x8c, 0x19, 0xce, 0x09, 0x05, 0x19, 557 0x1e, 0xbc, 0x29, 0x8a, 0x92, 0x45, 0x79, 0x25, 558 0x31, 0xf2, 0x6f, 0x0c, 0xec, 0xe2, 0x46, 0x06, 559 0x39, 0xe8, 0xbc, 0x39, 0xcb, 0x7f, 0x70, 0x6a, 560 0x82, 0x6a, 0x77, 0x9b, 0x4c, 0xf9, 0x69, 0xb8, 561 0xa0, 0xe5, 0x39, 0xc7, 0xf6, 0x2f, 0xb3, 0xd3, 562 0x0a, 0xd6, 0xaa, 0x8f, 0x80, 0xe3, 0x0f, 0x1d, 563 0x12, 0x8a, 0xaf, 0xd6, 0x8a, 0x2c, 0xe7, 0x2e, 564 0xa0 565 }; 566 static const unsigned char third_ikmrpriv[] = { 567 0xf3, 0xce, 0x7f, 0xda, 0xe5, 0x7e, 0x1a, 0x31, 568 0x0d, 0x87, 0xf1, 0xeb, 0xbd, 0xe6, 0xf3, 0x28, 569 0xbe, 0x0a, 0x99, 0xcd, 0xbc, 0xad, 0xf4, 0xd6, 570 0x58, 0x9c, 0xf2, 0x9d, 0xe4, 0xb8, 0xff, 0xd2 571 }; 572 static const unsigned char third_expected_shared_secret[] = { 573 0xc0, 0xd2, 0x6a, 0xea, 0xb5, 0x36, 0x60, 0x9a, 574 0x57, 0x2b, 0x07, 0x69, 0x5d, 0x93, 0x3b, 0x58, 575 0x9d, 0xcf, 0x36, 0x3f, 0xf9, 0xd9, 0x3c, 0x93, 576 0xad, 0xea, 0x53, 0x7a, 0xea, 0xbb, 0x8c, 0xb8 577 }; 578 static const unsigned char third_aead0[] = { 579 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2d, 0x30 580 }; 581 static const unsigned char third_ct0[] = { 582 0x5a, 0xd5, 0x90, 0xbb, 0x8b, 0xaa, 0x57, 0x7f, 583 0x86, 0x19, 0xdb, 0x35, 0xa3, 0x63, 0x11, 0x22, 584 0x6a, 0x89, 0x6e, 0x73, 0x42, 0xa6, 0xd8, 0x36, 585 0xd8, 0xb7, 0xbc, 0xd2, 0xf2, 0x0b, 0x6c, 0x7f, 586 0x90, 0x76, 0xac, 0x23, 0x2e, 0x3a, 0xb2, 0x52, 587 0x3f, 0x39, 0x51, 0x34, 0x34 588 }; 589 static const unsigned char third_aead1[] = { 590 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2d, 0x31 591 }; 592 static const unsigned char third_ct1[] = { 593 0xfa, 0x6f, 0x03, 0x7b, 0x47, 0xfc, 0x21, 0x82, 594 0x6b, 0x61, 0x01, 0x72, 0xca, 0x96, 0x37, 0xe8, 595 0x2d, 0x6e, 0x58, 0x01, 0xeb, 0x31, 0xcb, 0xd3, 596 0x74, 0x82, 0x71, 0xaf, 0xfd, 0x4e, 0xcb, 0x06, 597 0x64, 0x6e, 0x03, 0x29, 0xcb, 0xdf, 0x3c, 0x3c, 598 0xd6, 0x55, 0xb2, 0x8e, 0x82 599 }; 600 static const unsigned char third_export1[] = { 601 0x5e, 0x9b, 0xc3, 0xd2, 0x36, 0xe1, 0x91, 0x1d, 602 0x95, 0xe6, 0x5b, 0x57, 0x6a, 0x8a, 0x86, 0xd4, 603 0x78, 0xfb, 0x82, 0x7e, 0x8b, 0xdf, 0xe7, 0x7b, 604 0x74, 0x1b, 0x28, 0x98, 0x90, 0x49, 0x0d, 0x4d 605 }; 606 static const unsigned char third_context2[] = { 0x00 }; 607 static const unsigned char third_export2[] = { 608 0x6c, 0xff, 0x87, 0x65, 0x89, 0x31, 0xbd, 0xa8, 609 0x3d, 0xc8, 0x57, 0xe6, 0x35, 0x3e, 0xfe, 0x49, 610 0x87, 0xa2, 0x01, 0xb8, 0x49, 0x65, 0x8d, 0x9b, 611 0x04, 0x7a, 0xab, 0x4c, 0xf2, 0x16, 0xe7, 0x96 612 }; 613 static const unsigned char third_context3[] = { 614 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 615 0x65, 0x78, 0x74 616 }; 617 static const unsigned char third_export3[] = { 618 0xd8, 0xf1, 0xea, 0x79, 0x42, 0xad, 0xbb, 0xa7, 619 0x41, 0x2c, 0x6d, 0x43, 0x1c, 0x62, 0xd0, 0x13, 620 0x71, 0xea, 0x47, 0x6b, 0x82, 0x3e, 0xb6, 0x97, 621 0xe1, 0xf6, 0xe6, 0xca, 0xe1, 0xda, 0xb8, 0x5a 622 }; 623 624 static int P256kdfsha256_hkdfsha256_aes128gcm_base_test(void) 625 { 626 const TEST_BASEDATA basedata = { 627 OSSL_HPKE_MODE_BASE, 628 { OSSL_HPKE_KEM_ID_P256, 629 OSSL_HPKE_KDF_ID_HKDF_SHA256, 630 OSSL_HPKE_AEAD_ID_AES_GCM_128 }, 631 third_ikme, sizeof(third_ikme), 632 third_ikmepub, sizeof(third_ikmepub), 633 third_ikmr, sizeof(third_ikmr), 634 third_ikmrpub, sizeof(third_ikmrpub), 635 third_ikmrpriv, sizeof(third_ikmrpriv), 636 third_expected_shared_secret, sizeof(third_expected_shared_secret), 637 ksinfo, sizeof(ksinfo), 638 NULL, 0, /* no auth */ 639 NULL, 0, NULL /* PSK stuff */ 640 }; 641 const TEST_AEADDATA aeaddata[] = { 642 { 0, 643 pt, sizeof(pt), 644 third_aead0, sizeof(third_aead0), 645 third_ct0, sizeof(third_ct0) }, 646 { 1, 647 pt, sizeof(pt), 648 third_aead1, sizeof(third_aead1), 649 third_ct1, sizeof(third_ct1) } 650 }; 651 const TEST_EXPORTDATA exportdata[] = { 652 { NULL, 0, third_export1, sizeof(third_export1) }, 653 { third_context2, sizeof(third_context2), 654 third_export2, sizeof(third_export2) }, 655 { third_context3, sizeof(third_context3), 656 third_export3, sizeof(third_export3) }, 657 }; 658 return do_testhpke(&basedata, aeaddata, OSSL_NELEM(aeaddata), 659 exportdata, OSSL_NELEM(exportdata)); 660 } 661 662 #ifndef OPENSSL_NO_ECX 663 static const unsigned char fourth_ikme[] = { 664 0x55, 0xbc, 0x24, 0x5e, 0xe4, 0xef, 0xda, 0x25, 665 0xd3, 0x8f, 0x2d, 0x54, 0xd5, 0xbb, 0x66, 0x65, 666 0x29, 0x1b, 0x99, 0xf8, 0x10, 0x8a, 0x8c, 0x4b, 667 0x68, 0x6c, 0x2b, 0x14, 0x89, 0x3e, 0xa5, 0xd9 668 }; 669 static const unsigned char fourth_ikmepub[] = { 670 0xe5, 0xe8, 0xf9, 0xbf, 0xff, 0x6c, 0x2f, 0x29, 671 0x79, 0x1f, 0xc3, 0x51, 0xd2, 0xc2, 0x5c, 0xe1, 672 0x29, 0x9a, 0xa5, 0xea, 0xca, 0x78, 0xa7, 0x57, 673 0xc0, 0xb4, 0xfb, 0x4b, 0xcd, 0x83, 0x09, 0x18 674 }; 675 static const unsigned char fourth_ikmr[] = { 676 0x68, 0x3a, 0xe0, 0xda, 0x1d, 0x22, 0x18, 0x1e, 677 0x74, 0xed, 0x2e, 0x50, 0x3e, 0xbf, 0x82, 0x84, 678 0x0d, 0xeb, 0x1d, 0x5e, 0x87, 0x2c, 0xad, 0xe2, 679 0x0f, 0x4b, 0x45, 0x8d, 0x99, 0x78, 0x3e, 0x31 680 }; 681 static const unsigned char fourth_ikmrpub[] = { 682 0x19, 0x41, 0x41, 0xca, 0x6c, 0x3c, 0x3b, 0xeb, 683 0x47, 0x92, 0xcd, 0x97, 0xba, 0x0e, 0xa1, 0xfa, 684 0xff, 0x09, 0xd9, 0x84, 0x35, 0x01, 0x23, 0x45, 685 0x76, 0x6e, 0xe3, 0x3a, 0xae, 0x2d, 0x76, 0x64 686 }; 687 static const unsigned char fourth_ikmrpriv[] = { 688 0x33, 0xd1, 0x96, 0xc8, 0x30, 0xa1, 0x2f, 0x9a, 689 0xc6, 0x5d, 0x6e, 0x56, 0x5a, 0x59, 0x0d, 0x80, 690 0xf0, 0x4e, 0xe9, 0xb1, 0x9c, 0x83, 0xc8, 0x7f, 691 0x2c, 0x17, 0x0d, 0x97, 0x2a, 0x81, 0x28, 0x48 692 }; 693 static const unsigned char fourth_expected_shared_secret[] = { 694 0xe8, 0x17, 0x16, 0xce, 0x8f, 0x73, 0x14, 0x1d, 695 0x4f, 0x25, 0xee, 0x90, 0x98, 0xef, 0xc9, 0x68, 696 0xc9, 0x1e, 0x5b, 0x8c, 0xe5, 0x2f, 0xff, 0xf5, 697 0x9d, 0x64, 0x03, 0x9e, 0x82, 0x91, 0x8b, 0x66 698 }; 699 static const unsigned char fourth_export1[] = { 700 0x7a, 0x36, 0x22, 0x1b, 0xd5, 0x6d, 0x50, 0xfb, 701 0x51, 0xee, 0x65, 0xed, 0xfd, 0x98, 0xd0, 0x6a, 702 0x23, 0xc4, 0xdc, 0x87, 0x08, 0x5a, 0xa5, 0x86, 703 0x6c, 0xb7, 0x08, 0x72, 0x44, 0xbd, 0x2a, 0x36 704 }; 705 static const unsigned char fourth_context2[] = { 0x00 }; 706 static const unsigned char fourth_export2[] = { 707 0xd5, 0x53, 0x5b, 0x87, 0x09, 0x9c, 0x6c, 0x3c, 708 0xe8, 0x0d, 0xc1, 0x12, 0xa2, 0x67, 0x1c, 0x6e, 709 0xc8, 0xe8, 0x11, 0xa2, 0xf2, 0x84, 0xf9, 0x48, 710 0xce, 0xc6, 0xdd, 0x17, 0x08, 0xee, 0x33, 0xf0 711 }; 712 static const unsigned char fourth_context3[] = { 713 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 714 0x65, 0x78, 0x74 715 }; 716 static const unsigned char fourth_export3[] = { 717 0xff, 0xaa, 0xbc, 0x85, 0xa7, 0x76, 0x13, 0x6c, 718 0xa0, 0xc3, 0x78, 0xe5, 0xd0, 0x84, 0xc9, 0x14, 719 0x0a, 0xb5, 0x52, 0xb7, 0x8f, 0x03, 0x9d, 0x2e, 720 0x87, 0x75, 0xf2, 0x6e, 0xff, 0xf4, 0xc7, 0x0e 721 }; 722 723 static int export_only_test(void) 724 { 725 /* based on RFC9180 A.7 */ 726 const TEST_BASEDATA basedata = { 727 OSSL_HPKE_MODE_BASE, 728 { OSSL_HPKE_KEM_ID_X25519, 729 OSSL_HPKE_KDF_ID_HKDF_SHA256, 730 OSSL_HPKE_AEAD_ID_EXPORTONLY }, 731 fourth_ikme, sizeof(fourth_ikme), 732 fourth_ikmepub, sizeof(fourth_ikmepub), 733 fourth_ikmr, sizeof(fourth_ikmr), 734 fourth_ikmrpub, sizeof(fourth_ikmrpub), 735 fourth_ikmrpriv, sizeof(fourth_ikmrpriv), 736 fourth_expected_shared_secret, sizeof(fourth_expected_shared_secret), 737 ksinfo, sizeof(ksinfo), 738 NULL, 0, /* no auth */ 739 NULL, 0, NULL /* PSK stuff */ 740 }; 741 const TEST_EXPORTDATA exportdata[] = { 742 { NULL, 0, fourth_export1, sizeof(fourth_export1) }, 743 { fourth_context2, sizeof(fourth_context2), 744 fourth_export2, sizeof(fourth_export2) }, 745 { fourth_context3, sizeof(fourth_context3), 746 fourth_export3, sizeof(fourth_export3) }, 747 }; 748 return do_testhpke(&basedata, NULL, 0, 749 exportdata, OSSL_NELEM(exportdata)); 750 } 751 #endif 752 753 /* 754 * Randomly toss a coin 755 */ 756 #define COIN_IS_HEADS (test_random() % 2) 757 758 /* tables of HPKE modes and suite values */ 759 static int hpke_mode_list[] = { 760 OSSL_HPKE_MODE_BASE, 761 OSSL_HPKE_MODE_PSK, 762 OSSL_HPKE_MODE_AUTH, 763 OSSL_HPKE_MODE_PSKAUTH 764 }; 765 static uint16_t hpke_kem_list[] = { 766 OSSL_HPKE_KEM_ID_P256, 767 OSSL_HPKE_KEM_ID_P384, 768 OSSL_HPKE_KEM_ID_P521, 769 #ifndef OPENSSL_NO_ECX 770 OSSL_HPKE_KEM_ID_X25519, 771 OSSL_HPKE_KEM_ID_X448 772 #endif 773 }; 774 static uint16_t hpke_kdf_list[] = { 775 OSSL_HPKE_KDF_ID_HKDF_SHA256, 776 OSSL_HPKE_KDF_ID_HKDF_SHA384, 777 OSSL_HPKE_KDF_ID_HKDF_SHA512 778 }; 779 static uint16_t hpke_aead_list[] = { 780 OSSL_HPKE_AEAD_ID_AES_GCM_128, 781 OSSL_HPKE_AEAD_ID_AES_GCM_256, 782 #if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) 783 OSSL_HPKE_AEAD_ID_CHACHA_POLY1305 784 #endif 785 }; 786 787 /* 788 * Strings that can be used with names or IANA codepoints. 789 * Note that the initial entries from these lists should 790 * match the lists above, i.e. kem_str_list[0] and 791 * hpke_kem_list[0] should refer to the same KEM. We use 792 * that for verbose output via TEST_note() below. 793 * Subsequent entries are only used for tests of 794 * OSSL_HPKE_str2suite() 795 */ 796 static const char *mode_str_list[] = { 797 "base", "psk", "auth", "pskauth" 798 }; 799 static const char *kem_str_list[] = { 800 #ifndef OPENSSL_NO_ECX 801 "P-256", "P-384", "P-521", "x25519", "x448", 802 "0x10", "0x11", "0x12", "0x20", "0x21", 803 "16", "17", "18", "32", "33" 804 #else 805 "P-256", "P-384", "P-521", 806 "0x10", "0x11", "0x12", 807 "16", "17", "18" 808 #endif 809 }; 810 static const char *kdf_str_list[] = { 811 "hkdf-sha256", "hkdf-sha384", "hkdf-sha512", 812 "0x1", "0x01", "0x2", "0x02", "0x3", "0x03", 813 "1", "2", "3" 814 }; 815 static const char *aead_str_list[] = { 816 "aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "exporter", 817 "0x1", "0x01", "0x2", "0x02", "0x3", "0x03", 818 "1", "2", "3", 819 "0xff", "255" 820 }; 821 /* table of bogus strings that better not work */ 822 static const char *bogus_suite_strs[] = { 823 "3,33,3", 824 "bogus,bogus,bogus", 825 "bogus,33,3,1,bogus", 826 "bogus,33,3,1", 827 "bogus,bogus", 828 "bogus", 829 /* one bad token */ 830 "0x10,0x01,bogus", 831 "0x10,bogus,0x01", 832 "bogus,0x02,0x01", 833 /* in reverse order */ 834 "aes-256-gcm,hkdf-sha512,x25519", 835 /* surplus separators */ 836 ",,0x10,0x01,0x02", 837 "0x10,,0x01,0x02", 838 "0x10,0x01,,0x02", 839 /* embedded NUL chars */ 840 "0x10,\00x01,,0x02", 841 "0x10,\0" 842 "0x01,0x02", 843 "0x10\0,0x01,0x02", 844 "0x10,0x01\0,0x02", 845 "0x10,0x01,\0" 846 "0x02", 847 /* embedded whitespace */ 848 " aes-256-gcm,hkdf-sha512,x25519", 849 "aes-256-gcm, hkdf-sha512,x25519", 850 "aes-256-gcm ,hkdf-sha512,x25519", 851 "aes-256-gcm,hkdf-sha512, x25519", 852 "aes-256-gcm,hkdf-sha512 ,x25519", 853 "aes-256-gcm,hkdf-sha512,x25519 ", 854 /* good value followed by extra stuff */ 855 "0x10,0x01,0x02,", 856 "0x10,0x01,0x02,,,", 857 "0x10,0x01,0x01,0x02", 858 "0x10,0x01,0x01,blah", 859 "0x10,0x01,0x01 0x02", 860 /* too few but good tokens */ 861 "0x10,0x01", 862 "0x10", 863 /* empty things */ 864 NULL, 865 "", 866 ",", 867 ",," 868 }; 869 870 /** 871 * @brief round-trips, generating keys, encrypt and decrypt 872 * 873 * This iterates over all mode and ciphersuite options trying 874 * a key gen, encrypt and decrypt for each. The aad, info, and 875 * seq inputs are randomly set or omitted each time. EVP and 876 * non-EVP key generation are randomly selected. 877 * 878 * @return 1 for success, other otherwise 879 */ 880 static int test_hpke_modes_suites(void) 881 { 882 int overallresult = 1; 883 size_t mind = 0; /* index into hpke_mode_list */ 884 size_t kemind = 0; /* index into hpke_kem_list */ 885 size_t kdfind = 0; /* index into hpke_kdf_list */ 886 size_t aeadind = 0; /* index into hpke_aead_list */ 887 888 /* iterate over the different modes */ 889 for (mind = 0; mind < OSSL_NELEM(hpke_mode_list); mind++) { 890 int hpke_mode = hpke_mode_list[mind]; 891 size_t aadlen = OSSL_HPKE_TSTSIZE; 892 unsigned char aad[OSSL_HPKE_TSTSIZE]; 893 unsigned char *aadp = NULL; 894 size_t infolen = 32; 895 unsigned char info[32]; 896 unsigned char *infop = NULL; 897 unsigned char lpsk[32]; 898 unsigned char *pskp = NULL; 899 char lpskid[32]; 900 size_t psklen = 32; 901 char *pskidp = NULL; 902 EVP_PKEY *privp = NULL; 903 OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT; 904 size_t plainlen = OSSL_HPKE_TSTSIZE; 905 unsigned char plain[OSSL_HPKE_TSTSIZE]; 906 OSSL_HPKE_CTX *rctx = NULL; 907 OSSL_HPKE_CTX *ctx = NULL; 908 909 memset(plain, 0x00, OSSL_HPKE_TSTSIZE); 910 strcpy((char *)plain, "a message not in a bottle"); 911 plainlen = strlen((char *)plain); 912 /* 913 * Randomly try with/without info, aad, seq. Given mode and suite 914 * combos, and this being run even a few times, we'll exercise many 915 * code paths fairly quickly. We don't really care what the values 916 * are but it'll be easier to debug if they're known, so we set 'em. 917 */ 918 if (COIN_IS_HEADS) { 919 aadp = aad; 920 memset(aad, 'a', aadlen); 921 } else { 922 aadlen = 0; 923 } 924 if (COIN_IS_HEADS) { 925 infop = info; 926 memset(info, 'i', infolen); 927 } else { 928 infolen = 0; 929 } 930 if (hpke_mode == OSSL_HPKE_MODE_PSK 931 || hpke_mode == OSSL_HPKE_MODE_PSKAUTH) { 932 pskp = lpsk; 933 memset(lpsk, 'P', psklen); 934 pskidp = lpskid; 935 memset(lpskid, 'I', psklen - 1); 936 lpskid[psklen - 1] = '\0'; 937 } else { 938 psklen = 0; 939 } 940 for (kemind = 0; /* iterate over the kems, kdfs and aeads */ 941 overallresult == 1 && kemind < OSSL_NELEM(hpke_kem_list); 942 kemind++) { 943 uint16_t kem_id = hpke_kem_list[kemind]; 944 size_t authpublen = OSSL_HPKE_TSTSIZE; 945 unsigned char authpub[OSSL_HPKE_TSTSIZE]; 946 unsigned char *authpubp = NULL; 947 EVP_PKEY *authpriv = NULL; 948 949 hpke_suite.kem_id = kem_id; 950 if (hpke_mode == OSSL_HPKE_MODE_AUTH 951 || hpke_mode == OSSL_HPKE_MODE_PSKAUTH) { 952 if (TEST_true(OSSL_HPKE_keygen(hpke_suite, authpub, &authpublen, 953 &authpriv, NULL, 0, 954 testctx, NULL)) 955 != 1) { 956 overallresult = 0; 957 } 958 authpubp = authpub; 959 } else { 960 authpublen = 0; 961 } 962 for (kdfind = 0; 963 overallresult == 1 && kdfind < OSSL_NELEM(hpke_kdf_list); 964 kdfind++) { 965 uint16_t kdf_id = hpke_kdf_list[kdfind]; 966 967 hpke_suite.kdf_id = kdf_id; 968 for (aeadind = 0; 969 overallresult == 1 970 && aeadind < OSSL_NELEM(hpke_aead_list); 971 aeadind++) { 972 uint16_t aead_id = hpke_aead_list[aeadind]; 973 size_t publen = OSSL_HPKE_TSTSIZE; 974 unsigned char pub[OSSL_HPKE_TSTSIZE]; 975 size_t senderpublen = OSSL_HPKE_TSTSIZE; 976 unsigned char senderpub[OSSL_HPKE_TSTSIZE]; 977 size_t cipherlen = OSSL_HPKE_TSTSIZE; 978 unsigned char cipher[OSSL_HPKE_TSTSIZE]; 979 size_t clearlen = OSSL_HPKE_TSTSIZE; 980 unsigned char clear[OSSL_HPKE_TSTSIZE]; 981 982 hpke_suite.aead_id = aead_id; 983 if (!TEST_true(OSSL_HPKE_keygen(hpke_suite, 984 pub, &publen, &privp, 985 NULL, 0, testctx, NULL))) 986 overallresult = 0; 987 if (!TEST_ptr(ctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 988 OSSL_HPKE_ROLE_SENDER, 989 testctx, NULL))) 990 overallresult = 0; 991 if (hpke_mode == OSSL_HPKE_MODE_PSK 992 || hpke_mode == OSSL_HPKE_MODE_PSKAUTH) { 993 if (!TEST_true(OSSL_HPKE_CTX_set1_psk(ctx, pskidp, 994 pskp, psklen))) 995 overallresult = 0; 996 } 997 if (hpke_mode == OSSL_HPKE_MODE_AUTH 998 || hpke_mode == OSSL_HPKE_MODE_PSKAUTH) { 999 if (!TEST_true(OSSL_HPKE_CTX_set1_authpriv(ctx, 1000 authpriv))) 1001 overallresult = 0; 1002 } 1003 if (!TEST_true(OSSL_HPKE_encap(ctx, senderpub, 1004 &senderpublen, 1005 pub, publen, 1006 infop, infolen))) 1007 overallresult = 0; 1008 /* throw in a call with a too-short cipherlen */ 1009 cipherlen = 15; 1010 if (!TEST_false(OSSL_HPKE_seal(ctx, cipher, &cipherlen, 1011 aadp, aadlen, 1012 plain, plainlen))) 1013 overallresult = 0; 1014 /* fix back real cipherlen */ 1015 cipherlen = OSSL_HPKE_TSTSIZE; 1016 if (!TEST_true(OSSL_HPKE_seal(ctx, cipher, &cipherlen, 1017 aadp, aadlen, 1018 plain, plainlen))) 1019 overallresult = 0; 1020 OSSL_HPKE_CTX_free(ctx); 1021 memset(clear, 0, clearlen); 1022 rctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 1023 OSSL_HPKE_ROLE_RECEIVER, 1024 testctx, NULL); 1025 if (!TEST_ptr(rctx)) 1026 overallresult = 0; 1027 if (hpke_mode == OSSL_HPKE_MODE_PSK 1028 || hpke_mode == OSSL_HPKE_MODE_PSKAUTH) { 1029 if (!TEST_true(OSSL_HPKE_CTX_set1_psk(rctx, pskidp, 1030 pskp, psklen))) 1031 overallresult = 0; 1032 } 1033 if (hpke_mode == OSSL_HPKE_MODE_AUTH 1034 || hpke_mode == OSSL_HPKE_MODE_PSKAUTH) { 1035 /* check a borked p256 key */ 1036 if (hpke_suite.kem_id == OSSL_HPKE_KEM_ID_P256) { 1037 /* set to fail decode of authpub this time */ 1038 if (!TEST_false(OSSL_HPKE_CTX_set1_authpub(rctx, 1039 authpub, 1040 10))) 1041 overallresult = 0; 1042 } 1043 if (!TEST_true(OSSL_HPKE_CTX_set1_authpub(rctx, 1044 authpubp, 1045 authpublen))) 1046 overallresult = 0; 1047 } 1048 if (!TEST_true(OSSL_HPKE_decap(rctx, senderpub, 1049 senderpublen, privp, 1050 infop, infolen))) 1051 overallresult = 0; 1052 /* throw in a call with a too-short clearlen */ 1053 clearlen = 15; 1054 if (!TEST_false(OSSL_HPKE_open(rctx, clear, &clearlen, 1055 aadp, aadlen, cipher, 1056 cipherlen))) 1057 overallresult = 0; 1058 /* fix up real clearlen again */ 1059 clearlen = OSSL_HPKE_TSTSIZE; 1060 if (!TEST_true(OSSL_HPKE_open(rctx, clear, &clearlen, 1061 aadp, aadlen, cipher, 1062 cipherlen))) 1063 overallresult = 0; 1064 OSSL_HPKE_CTX_free(rctx); 1065 EVP_PKEY_free(privp); 1066 privp = NULL; 1067 /* check output */ 1068 if (!TEST_mem_eq(clear, clearlen, plain, plainlen)) { 1069 overallresult = 0; 1070 } 1071 if (verbose || overallresult != 1) { 1072 const char *res = NULL; 1073 1074 res = (overallresult == 1 ? "worked" : "failed"); 1075 TEST_note("HPKE %s for mode: %s/0x%02x, " 1076 "kem: %s/0x%02x, kdf: %s/0x%02x, " 1077 "aead: %s/0x%02x", 1078 res, 1079 mode_str_list[mind], (int)mind, 1080 kem_str_list[kemind], kem_id, 1081 kdf_str_list[kdfind], kdf_id, 1082 aead_str_list[aeadind], aead_id); 1083 } 1084 } 1085 } 1086 EVP_PKEY_free(authpriv); 1087 } 1088 } 1089 return overallresult; 1090 } 1091 1092 /** 1093 * @brief check roundtrip for export 1094 * @return 1 for success, other otherwise 1095 */ 1096 static int test_hpke_export(void) 1097 { 1098 int erv = 0; 1099 EVP_PKEY *privp = NULL; 1100 unsigned char pub[OSSL_HPKE_TSTSIZE]; 1101 size_t publen = sizeof(pub); 1102 int hpke_mode = OSSL_HPKE_MODE_BASE; 1103 OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT; 1104 OSSL_HPKE_CTX *ctx = NULL; 1105 OSSL_HPKE_CTX *rctx = NULL; 1106 unsigned char exp[32]; 1107 unsigned char exp2[32]; 1108 unsigned char rexp[32]; 1109 unsigned char rexp2[32]; 1110 unsigned char plain[] = "quick brown fox"; 1111 size_t plainlen = sizeof(plain); 1112 unsigned char enc[OSSL_HPKE_TSTSIZE]; 1113 size_t enclen = sizeof(enc); 1114 unsigned char cipher[OSSL_HPKE_TSTSIZE]; 1115 size_t cipherlen = sizeof(cipher); 1116 unsigned char clear[OSSL_HPKE_TSTSIZE]; 1117 size_t clearlen = sizeof(clear); 1118 char *estr = "foo"; 1119 1120 if (!TEST_true(OSSL_HPKE_keygen(hpke_suite, pub, &publen, &privp, 1121 NULL, 0, testctx, NULL))) 1122 goto end; 1123 if (!TEST_ptr(ctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 1124 OSSL_HPKE_ROLE_SENDER, 1125 testctx, NULL))) 1126 goto end; 1127 /* a few error cases 1st */ 1128 if (!TEST_false(OSSL_HPKE_export(NULL, exp, sizeof(exp), 1129 (unsigned char *)estr, strlen(estr)))) 1130 goto end; 1131 /* ctx before encap should fail too */ 1132 if (!TEST_false(OSSL_HPKE_export(ctx, exp, sizeof(exp), 1133 (unsigned char *)estr, strlen(estr)))) 1134 goto end; 1135 if (!TEST_true(OSSL_HPKE_encap(ctx, enc, &enclen, pub, publen, NULL, 0))) 1136 goto end; 1137 if (!TEST_true(OSSL_HPKE_seal(ctx, cipher, &cipherlen, NULL, 0, 1138 plain, plainlen))) 1139 goto end; 1140 /* now for real */ 1141 if (!TEST_true(OSSL_HPKE_export(ctx, exp, sizeof(exp), 1142 (unsigned char *)estr, strlen(estr)))) 1143 goto end; 1144 /* check a 2nd call with same input gives same output */ 1145 if (!TEST_true(OSSL_HPKE_export(ctx, exp2, sizeof(exp2), 1146 (unsigned char *)estr, strlen(estr)))) 1147 goto end; 1148 if (!TEST_mem_eq(exp, sizeof(exp), exp2, sizeof(exp2))) 1149 goto end; 1150 if (!TEST_ptr(rctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 1151 OSSL_HPKE_ROLE_RECEIVER, 1152 testctx, NULL))) 1153 goto end; 1154 if (!TEST_true(OSSL_HPKE_decap(rctx, enc, enclen, privp, NULL, 0))) 1155 goto end; 1156 if (!TEST_true(OSSL_HPKE_open(rctx, clear, &clearlen, NULL, 0, 1157 cipher, cipherlen))) 1158 goto end; 1159 if (!TEST_true(OSSL_HPKE_export(rctx, rexp, sizeof(rexp), 1160 (unsigned char *)estr, strlen(estr)))) 1161 goto end; 1162 /* check a 2nd call with same input gives same output */ 1163 if (!TEST_true(OSSL_HPKE_export(rctx, rexp2, sizeof(rexp2), 1164 (unsigned char *)estr, strlen(estr)))) 1165 goto end; 1166 if (!TEST_mem_eq(rexp, sizeof(rexp), rexp2, sizeof(rexp2))) 1167 goto end; 1168 if (!TEST_mem_eq(exp, sizeof(exp), rexp, sizeof(rexp))) 1169 goto end; 1170 erv = 1; 1171 end: 1172 OSSL_HPKE_CTX_free(ctx); 1173 OSSL_HPKE_CTX_free(rctx); 1174 EVP_PKEY_free(privp); 1175 return erv; 1176 } 1177 1178 /** 1179 * @brief Check mapping from strings to HPKE suites 1180 * @return 1 for success, other otherwise 1181 */ 1182 static int test_hpke_suite_strs(void) 1183 { 1184 int overallresult = 1; 1185 int kemind = 0; 1186 int kdfind = 0; 1187 int aeadind = 0; 1188 int sind = 0; 1189 char sstr[128]; 1190 OSSL_HPKE_SUITE stirred; 1191 char giant[2048]; 1192 1193 for (kemind = 0; kemind != OSSL_NELEM(kem_str_list); kemind++) { 1194 for (kdfind = 0; kdfind != OSSL_NELEM(kdf_str_list); kdfind++) { 1195 for (aeadind = 0; aeadind != OSSL_NELEM(aead_str_list); aeadind++) { 1196 BIO_snprintf(sstr, 128, "%s,%s,%s", kem_str_list[kemind], 1197 kdf_str_list[kdfind], aead_str_list[aeadind]); 1198 if (TEST_true(OSSL_HPKE_str2suite(sstr, &stirred)) != 1) { 1199 if (verbose) 1200 TEST_note("Unexpected str2suite fail for :%s", 1201 bogus_suite_strs[sind]); 1202 overallresult = 0; 1203 } 1204 } 1205 } 1206 } 1207 for (sind = 0; sind != OSSL_NELEM(bogus_suite_strs); sind++) { 1208 if (TEST_false(OSSL_HPKE_str2suite(bogus_suite_strs[sind], 1209 &stirred)) 1210 != 1) { 1211 if (verbose) 1212 TEST_note("OSSL_HPKE_str2suite didn't fail for bogus[%d]:%s", 1213 sind, bogus_suite_strs[sind]); 1214 overallresult = 0; 1215 } 1216 } 1217 /* check a few errors */ 1218 if (!TEST_false(OSSL_HPKE_str2suite("", &stirred))) 1219 overallresult = 0; 1220 if (!TEST_false(OSSL_HPKE_str2suite(NULL, &stirred))) 1221 overallresult = 0; 1222 if (!TEST_false(OSSL_HPKE_str2suite("", NULL))) 1223 overallresult = 0; 1224 memset(giant, 'A', sizeof(giant) - 1); 1225 giant[sizeof(giant) - 1] = '\0'; 1226 if (!TEST_false(OSSL_HPKE_str2suite(giant, &stirred))) 1227 overallresult = 0; 1228 1229 return overallresult; 1230 } 1231 1232 /** 1233 * @brief try the various GREASEy APIs 1234 * @return 1 for success, other otherwise 1235 */ 1236 static int test_hpke_grease(void) 1237 { 1238 int overallresult = 1; 1239 OSSL_HPKE_SUITE g_suite; 1240 unsigned char g_pub[OSSL_HPKE_TSTSIZE]; 1241 size_t g_pub_len = OSSL_HPKE_TSTSIZE; 1242 unsigned char g_cipher[OSSL_HPKE_TSTSIZE]; 1243 size_t g_cipher_len = 266; 1244 size_t clearlen = 128; 1245 size_t expanded = 0; 1246 size_t enclen = 0; 1247 size_t ikmelen = 0; 1248 1249 memset(&g_suite, 0, sizeof(OSSL_HPKE_SUITE)); 1250 /* GREASEing */ 1251 /* check too short for public value */ 1252 g_pub_len = 10; 1253 if (TEST_false(OSSL_HPKE_get_grease_value(NULL, &g_suite, 1254 g_pub, &g_pub_len, 1255 g_cipher, g_cipher_len, 1256 testctx, NULL)) 1257 != 1) { 1258 overallresult = 0; 1259 } 1260 /* reset to work */ 1261 g_pub_len = OSSL_HPKE_TSTSIZE; 1262 if (TEST_true(OSSL_HPKE_get_grease_value(NULL, &g_suite, 1263 g_pub, &g_pub_len, 1264 g_cipher, g_cipher_len, 1265 testctx, NULL)) 1266 != 1) { 1267 overallresult = 0; 1268 } 1269 /* expansion */ 1270 expanded = OSSL_HPKE_get_ciphertext_size(g_suite, clearlen); 1271 if (!TEST_size_t_gt(expanded, clearlen)) { 1272 overallresult = 0; 1273 } 1274 enclen = OSSL_HPKE_get_public_encap_size(g_suite); 1275 if (!TEST_size_t_ne(enclen, 0)) 1276 overallresult = 0; 1277 /* not really GREASE but we'll check ikmelen thing */ 1278 ikmelen = OSSL_HPKE_get_recommended_ikmelen(g_suite); 1279 if (!TEST_size_t_ne(ikmelen, 0)) 1280 overallresult = 0; 1281 1282 return overallresult; 1283 } 1284 1285 /* 1286 * Make a set of calls with odd parameters 1287 */ 1288 static int test_hpke_oddcalls(void) 1289 { 1290 int erv = 0; 1291 EVP_PKEY *privp = NULL; 1292 unsigned char pub[OSSL_HPKE_TSTSIZE]; 1293 size_t publen = sizeof(pub); 1294 int hpke_mode = OSSL_HPKE_MODE_BASE; 1295 int bad_mode = 0xbad; 1296 OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT; 1297 OSSL_HPKE_SUITE bad_suite = { 0xbad, 0xbad, 0xbad }; 1298 OSSL_HPKE_CTX *ctx = NULL; 1299 OSSL_HPKE_CTX *rctx = NULL; 1300 unsigned char plain[] = "quick brown fox"; 1301 size_t plainlen = sizeof(plain); 1302 unsigned char enc[OSSL_HPKE_TSTSIZE], smallenc[10]; 1303 size_t enclen = sizeof(enc), smallenclen = sizeof(smallenc); 1304 unsigned char cipher[OSSL_HPKE_TSTSIZE]; 1305 size_t cipherlen = sizeof(cipher); 1306 unsigned char clear[OSSL_HPKE_TSTSIZE]; 1307 size_t clearlen = sizeof(clear); 1308 unsigned char fake_ikm[OSSL_HPKE_TSTSIZE]; 1309 char *badpropq = "yeah, this won't work"; 1310 uint64_t lseq = 0; 1311 char giant_pskid[OSSL_HPKE_MAX_PARMLEN + 10]; 1312 unsigned char info[OSSL_HPKE_TSTSIZE]; 1313 1314 /* many of the calls below are designed to get better test coverage */ 1315 1316 /* NULL ctx calls */ 1317 OSSL_HPKE_CTX_free(NULL); 1318 if (!TEST_false(OSSL_HPKE_CTX_set_seq(NULL, 1))) 1319 goto end; 1320 if (!TEST_false(OSSL_HPKE_CTX_get_seq(NULL, &lseq))) 1321 goto end; 1322 if (!TEST_false(OSSL_HPKE_CTX_set1_authpub(NULL, pub, publen))) 1323 goto end; 1324 if (!TEST_false(OSSL_HPKE_CTX_set1_authpriv(NULL, privp))) 1325 goto end; 1326 if (!TEST_false(OSSL_HPKE_CTX_set1_ikme(NULL, NULL, 0))) 1327 goto end; 1328 if (!TEST_false(OSSL_HPKE_CTX_set1_psk(NULL, NULL, NULL, 0))) 1329 goto end; 1330 1331 /* bad suite calls */ 1332 hpke_suite.aead_id = 0xbad; 1333 if (!TEST_false(OSSL_HPKE_suite_check(hpke_suite))) 1334 goto end; 1335 hpke_suite.aead_id = OSSL_HPKE_AEAD_ID_AES_GCM_128; 1336 if (!TEST_false(OSSL_HPKE_suite_check(bad_suite))) 1337 goto end; 1338 if (!TEST_false(OSSL_HPKE_get_recommended_ikmelen(bad_suite))) 1339 goto end; 1340 if (!TEST_false(OSSL_HPKE_get_public_encap_size(bad_suite))) 1341 goto end; 1342 if (!TEST_false(OSSL_HPKE_get_ciphertext_size(bad_suite, 0))) 1343 goto end; 1344 if (!TEST_false(OSSL_HPKE_keygen(bad_suite, pub, &publen, &privp, 1345 NULL, 0, testctx, badpropq))) 1346 goto end; 1347 if (!TEST_false(OSSL_HPKE_keygen(bad_suite, pub, &publen, &privp, 1348 NULL, 0, testctx, NULL))) 1349 goto end; 1350 1351 /* dodgy keygen calls */ 1352 /* no pub */ 1353 if (!TEST_false(OSSL_HPKE_keygen(hpke_suite, NULL, &publen, &privp, 1354 NULL, 0, testctx, NULL))) 1355 goto end; 1356 /* ikmlen but NULL ikm */ 1357 if (!TEST_false(OSSL_HPKE_keygen(hpke_suite, pub, &publen, &privp, 1358 NULL, 80, testctx, NULL))) 1359 goto end; 1360 /* zero ikmlen but ikm */ 1361 if (!TEST_false(OSSL_HPKE_keygen(hpke_suite, pub, &publen, &privp, 1362 fake_ikm, 0, testctx, NULL))) 1363 goto end; 1364 /* GIANT ikmlen */ 1365 if (!TEST_false(OSSL_HPKE_keygen(hpke_suite, pub, &publen, &privp, 1366 fake_ikm, -1, testctx, NULL))) 1367 goto end; 1368 /* short publen */ 1369 publen = 10; 1370 if (!TEST_false(OSSL_HPKE_keygen(hpke_suite, pub, &publen, &privp, 1371 NULL, 0, testctx, NULL))) 1372 goto end; 1373 publen = sizeof(pub); 1374 1375 /* encap/decap with NULLs */ 1376 if (!TEST_false(OSSL_HPKE_encap(NULL, NULL, NULL, NULL, 0, NULL, 0))) 1377 goto end; 1378 if (!TEST_false(OSSL_HPKE_decap(NULL, NULL, 0, NULL, NULL, 0))) 1379 goto end; 1380 1381 /* 1382 * run through a sender/recipient set of calls but with 1383 * failing calls interspersed whenever possible 1384 */ 1385 /* good keygen */ 1386 if (!TEST_true(OSSL_HPKE_keygen(hpke_suite, pub, &publen, &privp, 1387 NULL, 0, testctx, NULL))) 1388 goto end; 1389 1390 /* a psk context with no psk => encap fail */ 1391 if (!TEST_ptr(ctx = OSSL_HPKE_CTX_new(OSSL_HPKE_MODE_PSK, hpke_suite, 1392 OSSL_HPKE_ROLE_SENDER, 1393 testctx, NULL))) 1394 goto end; 1395 /* set bad length psk */ 1396 if (!TEST_false(OSSL_HPKE_CTX_set1_psk(ctx, "foo", 1397 (unsigned char *)"bar", -1))) 1398 goto end; 1399 /* set bad length pskid */ 1400 memset(giant_pskid, 'A', sizeof(giant_pskid) - 1); 1401 giant_pskid[sizeof(giant_pskid) - 1] = '\0'; 1402 if (!TEST_false(OSSL_HPKE_CTX_set1_psk(ctx, giant_pskid, 1403 (unsigned char *)"bar", 3))) 1404 goto end; 1405 /* still no psk really set so encap fails */ 1406 if (!TEST_false(OSSL_HPKE_encap(ctx, enc, &enclen, pub, publen, NULL, 0))) 1407 goto end; 1408 OSSL_HPKE_CTX_free(ctx); 1409 1410 /* bad suite */ 1411 if (!TEST_ptr_null(ctx = OSSL_HPKE_CTX_new(hpke_mode, bad_suite, 1412 OSSL_HPKE_ROLE_SENDER, 1413 testctx, NULL))) 1414 goto end; 1415 /* bad mode */ 1416 if (!TEST_ptr_null(ctx = OSSL_HPKE_CTX_new(bad_mode, hpke_suite, 1417 OSSL_HPKE_ROLE_SENDER, 1418 testctx, NULL))) 1419 goto end; 1420 /* make good ctx */ 1421 if (!TEST_ptr(ctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 1422 OSSL_HPKE_ROLE_SENDER, 1423 testctx, NULL))) 1424 goto end; 1425 /* too long ikm */ 1426 if (!TEST_false(OSSL_HPKE_CTX_set1_ikme(ctx, fake_ikm, -1))) 1427 goto end; 1428 /* zero length ikm */ 1429 if (!TEST_false(OSSL_HPKE_CTX_set1_ikme(ctx, fake_ikm, 0))) 1430 goto end; 1431 /* NULL authpub */ 1432 if (!TEST_false(OSSL_HPKE_CTX_set1_authpub(ctx, NULL, 0))) 1433 goto end; 1434 /* NULL auth priv */ 1435 if (!TEST_false(OSSL_HPKE_CTX_set1_authpriv(ctx, NULL))) 1436 goto end; 1437 /* priv good, but mode is bad */ 1438 if (!TEST_false(OSSL_HPKE_CTX_set1_authpriv(ctx, privp))) 1439 goto end; 1440 /* bad mode for psk */ 1441 if (!TEST_false(OSSL_HPKE_CTX_set1_psk(ctx, "foo", 1442 (unsigned char *)"bar", 3))) 1443 goto end; 1444 /* seal before encap */ 1445 if (!TEST_false(OSSL_HPKE_seal(ctx, cipher, &cipherlen, NULL, 0, 1446 plain, plainlen))) 1447 goto end; 1448 /* encap with dodgy public */ 1449 if (!TEST_false(OSSL_HPKE_encap(ctx, enc, &enclen, pub, 1, NULL, 0))) 1450 goto end; 1451 /* encap with too big info */ 1452 if (!TEST_false(OSSL_HPKE_encap(ctx, enc, &enclen, pub, 1, info, -1))) 1453 goto end; 1454 /* encap with NULL info & non-zero infolen */ 1455 if (!TEST_false(OSSL_HPKE_encap(ctx, enc, &enclen, pub, 1, NULL, 1))) 1456 goto end; 1457 /* encap with non-NULL info & zero infolen */ 1458 if (!TEST_false(OSSL_HPKE_encap(ctx, enc, &enclen, pub, 1, info, 0))) 1459 goto end; 1460 /* encap with too small enc */ 1461 if (!TEST_false(OSSL_HPKE_encap(ctx, smallenc, &smallenclen, pub, 1, NULL, 0))) 1462 goto end; 1463 /* good encap */ 1464 if (!TEST_true(OSSL_HPKE_encap(ctx, enc, &enclen, pub, publen, NULL, 0))) 1465 goto end; 1466 /* second encap fail */ 1467 if (!TEST_false(OSSL_HPKE_encap(ctx, enc, &enclen, pub, publen, NULL, 0))) 1468 goto end; 1469 plainlen = 0; 1470 /* should fail for no plaintext */ 1471 if (!TEST_false(OSSL_HPKE_seal(ctx, cipher, &cipherlen, NULL, 0, 1472 plain, plainlen))) 1473 goto end; 1474 plainlen = sizeof(plain); 1475 /* working seal */ 1476 if (!TEST_true(OSSL_HPKE_seal(ctx, cipher, &cipherlen, NULL, 0, 1477 plain, plainlen))) 1478 goto end; 1479 1480 /* receiver side */ 1481 /* decap fail with psk mode but no psk set */ 1482 if (!TEST_ptr(rctx = OSSL_HPKE_CTX_new(OSSL_HPKE_MODE_PSK, hpke_suite, 1483 OSSL_HPKE_ROLE_RECEIVER, 1484 testctx, NULL))) 1485 goto end; 1486 if (!TEST_false(OSSL_HPKE_decap(rctx, enc, enclen, privp, NULL, 0))) 1487 goto end; 1488 /* done with PSK mode */ 1489 OSSL_HPKE_CTX_free(rctx); 1490 1491 /* back good calls for base mode */ 1492 if (!TEST_ptr(rctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 1493 OSSL_HPKE_ROLE_RECEIVER, 1494 testctx, NULL))) 1495 goto end; 1496 /* open before decap */ 1497 if (!TEST_false(OSSL_HPKE_open(rctx, clear, &clearlen, NULL, 0, 1498 cipher, cipherlen))) 1499 goto end; 1500 /* decap with info too long */ 1501 if (!TEST_false(OSSL_HPKE_decap(rctx, enc, enclen, privp, info, -1))) 1502 goto end; 1503 /* good decap */ 1504 if (!TEST_true(OSSL_HPKE_decap(rctx, enc, enclen, privp, NULL, 0))) 1505 goto end; 1506 /* second decap fail */ 1507 if (!TEST_false(OSSL_HPKE_decap(rctx, enc, enclen, privp, NULL, 0))) 1508 goto end; 1509 /* no space for recovered clear */ 1510 clearlen = 0; 1511 if (!TEST_false(OSSL_HPKE_open(rctx, clear, &clearlen, NULL, 0, 1512 cipher, cipherlen))) 1513 goto end; 1514 clearlen = OSSL_HPKE_TSTSIZE; 1515 /* seq wrap around test */ 1516 if (!TEST_true(OSSL_HPKE_CTX_set_seq(rctx, -1))) 1517 goto end; 1518 if (!TEST_false(OSSL_HPKE_open(rctx, clear, &clearlen, NULL, 0, 1519 cipher, cipherlen))) 1520 goto end; 1521 if (!TEST_true(OSSL_HPKE_CTX_set_seq(rctx, 0))) 1522 goto end; 1523 if (!TEST_true(OSSL_HPKE_open(rctx, clear, &clearlen, NULL, 0, 1524 cipher, cipherlen))) 1525 goto end; 1526 if (!TEST_mem_eq(plain, plainlen, clear, clearlen)) 1527 goto end; 1528 erv = 1; 1529 end: 1530 OSSL_HPKE_CTX_free(ctx); 1531 OSSL_HPKE_CTX_free(rctx); 1532 EVP_PKEY_free(privp); 1533 return erv; 1534 } 1535 1536 #ifndef OPENSSL_NO_ECX 1537 /* from RFC 9180 Appendix A.1.1 */ 1538 static const unsigned char ikm25519[] = { 1539 0x72, 0x68, 0x60, 0x0d, 0x40, 0x3f, 0xce, 0x43, 1540 0x15, 0x61, 0xae, 0xf5, 0x83, 0xee, 0x16, 0x13, 1541 0x52, 0x7c, 0xff, 0x65, 0x5c, 0x13, 0x43, 0xf2, 1542 0x98, 0x12, 0xe6, 0x67, 0x06, 0xdf, 0x32, 0x34 1543 }; 1544 static const unsigned char pub25519[] = { 1545 0x37, 0xfd, 0xa3, 0x56, 0x7b, 0xdb, 0xd6, 0x28, 1546 0xe8, 0x86, 0x68, 0xc3, 0xc8, 0xd7, 0xe9, 0x7d, 1547 0x1d, 0x12, 0x53, 0xb6, 0xd4, 0xea, 0x6d, 0x44, 1548 0xc1, 0x50, 0xf7, 0x41, 0xf1, 0xbf, 0x44, 0x31 1549 }; 1550 #endif 1551 1552 /* from RFC9180 Appendix A.3.1 */ 1553 static const unsigned char ikmp256[] = { 1554 0x42, 0x70, 0xe5, 0x4f, 0xfd, 0x08, 0xd7, 0x9d, 1555 0x59, 0x28, 0x02, 0x0a, 0xf4, 0x68, 0x6d, 0x8f, 1556 0x6b, 0x7d, 0x35, 0xdb, 0xe4, 0x70, 0x26, 0x5f, 1557 0x1f, 0x5a, 0xa2, 0x28, 0x16, 0xce, 0x86, 0x0e 1558 }; 1559 static const unsigned char pubp256[] = { 1560 0x04, 0xa9, 0x27, 0x19, 0xc6, 0x19, 0x5d, 0x50, 1561 0x85, 0x10, 0x4f, 0x46, 0x9a, 0x8b, 0x98, 0x14, 1562 0xd5, 0x83, 0x8f, 0xf7, 0x2b, 0x60, 0x50, 0x1e, 1563 0x2c, 0x44, 0x66, 0xe5, 0xe6, 0x7b, 0x32, 0x5a, 1564 0xc9, 0x85, 0x36, 0xd7, 0xb6, 0x1a, 0x1a, 0xf4, 1565 0xb7, 0x8e, 0x5b, 0x7f, 0x95, 0x1c, 0x09, 0x00, 1566 0xbe, 0x86, 0x3c, 0x40, 0x3c, 0xe6, 0x5c, 0x9b, 1567 0xfc, 0xb9, 0x38, 0x26, 0x57, 0x22, 0x2d, 0x18, 1568 0xc4 1569 }; 1570 1571 /* 1572 * A test vector that exercises the counter iteration 1573 * for p256. This was contributed by Ilari L. on the 1574 * CFRG list, see the mail archive: 1575 * https://mailarchive.ietf.org/arch/msg/cfrg/4zwl_y5YN6OU9oeWZOMHNOlOa2w/ 1576 */ 1577 static const unsigned char ikmiter[] = { 1578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1581 0x00, 0x00, 0x00, 0x03, 0x01, 0x38, 0xb5, 0xec 1582 }; 1583 static const unsigned char pubiter[] = { 1584 0x04, 0x7d, 0x0c, 0x87, 0xff, 0xd5, 0xd1, 0x45, 1585 0x54, 0xa7, 0x51, 0xdf, 0xa3, 0x99, 0x26, 0xa9, 1586 0xe3, 0x0e, 0x7c, 0x3c, 0x65, 0x62, 0x4f, 0x4b, 1587 0x5f, 0xb3, 0xad, 0x7a, 0xa4, 0xda, 0xc2, 0x4a, 1588 0xd8, 0xf5, 0xbe, 0xd0, 0xe8, 0x6e, 0xb8, 0x84, 1589 0x1c, 0xe4, 0x89, 0x2e, 0x0f, 0xc3, 0x87, 0xbb, 1590 0xdb, 0xfe, 0x16, 0x0d, 0x58, 0x9c, 0x89, 0x2d, 1591 0xd4, 0xb1, 0x46, 0x4a, 0xc3, 0x51, 0xc5, 0x6f, 1592 0xb6 1593 }; 1594 1595 /* from RFC9180 Appendix A.6.1 */ 1596 static const unsigned char ikmp521[] = { 1597 0x7f, 0x06, 0xab, 0x82, 0x15, 0x10, 0x5f, 0xc4, 1598 0x6a, 0xce, 0xeb, 0x2e, 0x3d, 0xc5, 0x02, 0x8b, 1599 0x44, 0x36, 0x4f, 0x96, 0x04, 0x26, 0xeb, 0x0d, 1600 0x8e, 0x40, 0x26, 0xc2, 0xf8, 0xb5, 0xd7, 0xe7, 1601 0xa9, 0x86, 0x68, 0x8f, 0x15, 0x91, 0xab, 0xf5, 1602 0xab, 0x75, 0x3c, 0x35, 0x7a, 0x5d, 0x6f, 0x04, 1603 0x40, 0x41, 0x4b, 0x4e, 0xd4, 0xed, 0xe7, 0x13, 1604 0x17, 0x77, 0x2a, 0xc9, 0x8d, 0x92, 0x39, 0xf7, 1605 0x09, 0x04 1606 }; 1607 static const unsigned char pubp521[] = { 1608 0x04, 0x01, 0x38, 0xb3, 0x85, 0xca, 0x16, 0xbb, 1609 0x0d, 0x5f, 0xa0, 0xc0, 0x66, 0x5f, 0xbb, 0xd7, 1610 0xe6, 0x9e, 0x3e, 0xe2, 0x9f, 0x63, 0x99, 0x1d, 1611 0x3e, 0x9b, 0x5f, 0xa7, 0x40, 0xaa, 0xb8, 0x90, 1612 0x0a, 0xae, 0xed, 0x46, 0xed, 0x73, 0xa4, 0x90, 1613 0x55, 0x75, 0x84, 0x25, 0xa0, 0xce, 0x36, 0x50, 1614 0x7c, 0x54, 0xb2, 0x9c, 0xc5, 0xb8, 0x5a, 0x5c, 1615 0xee, 0x6b, 0xae, 0x0c, 0xf1, 0xc2, 0x1f, 0x27, 1616 0x31, 0xec, 0xe2, 0x01, 0x3d, 0xc3, 0xfb, 0x7c, 1617 0x8d, 0x21, 0x65, 0x4b, 0xb1, 0x61, 0xb4, 0x63, 1618 0x96, 0x2c, 0xa1, 0x9e, 0x8c, 0x65, 0x4f, 0xf2, 1619 0x4c, 0x94, 0xdd, 0x28, 0x98, 0xde, 0x12, 0x05, 1620 0x1f, 0x1e, 0xd0, 0x69, 0x22, 0x37, 0xfb, 0x02, 1621 0xb2, 0xf8, 0xd1, 0xdc, 0x1c, 0x73, 0xe9, 0xb3, 1622 0x66, 0xb5, 0x29, 0xeb, 0x43, 0x6e, 0x98, 0xa9, 1623 0x96, 0xee, 0x52, 0x2a, 0xef, 0x86, 0x3d, 0xd5, 1624 0x73, 0x9d, 0x2f, 0x29, 0xb0 1625 }; 1626 1627 static int test_hpke_random_suites(void) 1628 { 1629 OSSL_HPKE_SUITE def_suite = OSSL_HPKE_SUITE_DEFAULT; 1630 OSSL_HPKE_SUITE suite = OSSL_HPKE_SUITE_DEFAULT; 1631 OSSL_HPKE_SUITE suite2 = { 0xff01, 0xff02, 0xff03 }; 1632 unsigned char enc[200]; 1633 size_t enclen = sizeof(enc); 1634 unsigned char ct[500]; 1635 size_t ctlen = sizeof(ct); 1636 1637 /* test with NULL/0 inputs */ 1638 if (!TEST_false(OSSL_HPKE_get_grease_value(NULL, NULL, 1639 NULL, NULL, NULL, 0, 1640 testctx, NULL))) 1641 return 0; 1642 enclen = 10; 1643 if (!TEST_false(OSSL_HPKE_get_grease_value(&def_suite, &suite2, 1644 enc, &enclen, ct, ctlen, 1645 testctx, NULL))) 1646 return 0; 1647 1648 enclen = sizeof(enc); /* reset, 'cause get_grease() will have set */ 1649 /* test with a should-be-good suite */ 1650 if (!TEST_true(OSSL_HPKE_get_grease_value(&def_suite, &suite2, 1651 enc, &enclen, ct, ctlen, 1652 testctx, NULL))) 1653 return 0; 1654 /* no suggested suite */ 1655 enclen = sizeof(enc); /* reset, 'cause get_grease() will have set */ 1656 if (!TEST_true(OSSL_HPKE_get_grease_value(NULL, &suite2, 1657 enc, &enclen, 1658 ct, ctlen, 1659 testctx, NULL))) 1660 return 0; 1661 /* suggested suite with P-521, just to be sure we hit long values */ 1662 enclen = sizeof(enc); /* reset, 'cause get_grease() will have set */ 1663 suite.kem_id = OSSL_HPKE_KEM_ID_P521; 1664 if (!TEST_true(OSSL_HPKE_get_grease_value(&suite, &suite2, 1665 enc, &enclen, ct, ctlen, 1666 testctx, NULL))) 1667 return 0; 1668 enclen = sizeof(enc); 1669 ctlen = 2; /* too-short cttext (can't fit an aead tag) */ 1670 if (!TEST_false(OSSL_HPKE_get_grease_value(NULL, &suite2, 1671 enc, &enclen, ct, ctlen, 1672 testctx, NULL))) 1673 return 0; 1674 1675 ctlen = sizeof(ct); 1676 enclen = sizeof(enc); 1677 1678 suite.kem_id = OSSL_HPKE_KEM_ID_X25519; /* back to default */ 1679 suite.aead_id = 0x1234; /* bad aead */ 1680 if (!TEST_false(OSSL_HPKE_get_grease_value(&suite, &suite2, 1681 enc, &enclen, ct, ctlen, 1682 testctx, NULL))) 1683 return 0; 1684 enclen = sizeof(enc); 1685 suite.aead_id = def_suite.aead_id; /* good aead */ 1686 suite.kdf_id = 0x3451; /* bad kdf */ 1687 if (!TEST_false(OSSL_HPKE_get_grease_value(&suite, &suite2, 1688 enc, &enclen, ct, ctlen, 1689 testctx, NULL))) 1690 return 0; 1691 enclen = sizeof(enc); 1692 suite.kdf_id = def_suite.kdf_id; /* good kdf */ 1693 suite.kem_id = 0x4517; /* bad kem */ 1694 if (!TEST_false(OSSL_HPKE_get_grease_value(&suite, &suite2, 1695 enc, &enclen, ct, ctlen, 1696 testctx, NULL))) 1697 return 0; 1698 return 1; 1699 } 1700 1701 /* 1702 * @brief generate a key pair from initial key material (ikm) and check public 1703 * @param kem_id the KEM to use (RFC9180 code point) 1704 * @ikm is the initial key material buffer 1705 * @ikmlen is the length of ikm 1706 * @pub is the public key buffer 1707 * @publen is the length of the public key 1708 * @return 1 for good, other otherwise 1709 * 1710 * This calls OSSL_HPKE_keygen specifying only the IKM, then 1711 * compares the key pair values with the already-known values 1712 * that were input. 1713 */ 1714 static int test_hpke_one_ikm_gen(uint16_t kem_id, 1715 const unsigned char *ikm, size_t ikmlen, 1716 const unsigned char *pub, size_t publen) 1717 { 1718 OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT; 1719 unsigned char lpub[OSSL_HPKE_TSTSIZE]; 1720 size_t lpublen = OSSL_HPKE_TSTSIZE; 1721 EVP_PKEY *sk = NULL; 1722 1723 hpke_suite.kem_id = kem_id; 1724 if (!TEST_true(OSSL_HPKE_keygen(hpke_suite, lpub, &lpublen, &sk, 1725 ikm, ikmlen, testctx, NULL))) 1726 return 0; 1727 if (!TEST_ptr(sk)) 1728 return 0; 1729 EVP_PKEY_free(sk); 1730 if (!TEST_mem_eq(pub, publen, lpub, lpublen)) 1731 return 0; 1732 return 1; 1733 } 1734 1735 /* 1736 * @brief test some uses of IKM produce the expected public keys 1737 */ 1738 static int test_hpke_ikms(void) 1739 { 1740 int res = 1; 1741 1742 #ifndef OPENSSL_NO_ECX 1743 res = test_hpke_one_ikm_gen(OSSL_HPKE_KEM_ID_X25519, 1744 ikm25519, sizeof(ikm25519), 1745 pub25519, sizeof(pub25519)); 1746 if (res != 1) 1747 return res; 1748 #endif 1749 1750 res = test_hpke_one_ikm_gen(OSSL_HPKE_KEM_ID_P521, 1751 ikmp521, sizeof(ikmp521), 1752 pubp521, sizeof(pubp521)); 1753 if (res != 1) 1754 return res; 1755 1756 res = test_hpke_one_ikm_gen(OSSL_HPKE_KEM_ID_P256, 1757 ikmp256, sizeof(ikmp256), 1758 pubp256, sizeof(pubp256)); 1759 if (res != 1) 1760 return res; 1761 1762 res = test_hpke_one_ikm_gen(OSSL_HPKE_KEM_ID_P256, 1763 ikmiter, sizeof(ikmiter), 1764 pubiter, sizeof(pubiter)); 1765 if (res != 1) 1766 return res; 1767 1768 return res; 1769 } 1770 1771 /* 1772 * Test that use of a compressed format auth public key works 1773 * We'll do a typical round-trip for auth mode but provide the 1774 * auth public key in compressed form. That should work. 1775 */ 1776 static int test_hpke_compressed(void) 1777 { 1778 int erv = 0; 1779 EVP_PKEY *privp = NULL; 1780 unsigned char pub[OSSL_HPKE_TSTSIZE]; 1781 size_t publen = sizeof(pub); 1782 EVP_PKEY *authpriv = NULL; 1783 unsigned char authpub[OSSL_HPKE_TSTSIZE]; 1784 size_t authpublen = sizeof(authpub); 1785 int hpke_mode = OSSL_HPKE_MODE_AUTH; 1786 OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT; 1787 OSSL_HPKE_CTX *ctx = NULL; 1788 OSSL_HPKE_CTX *rctx = NULL; 1789 unsigned char plain[] = "quick brown fox"; 1790 size_t plainlen = sizeof(plain); 1791 unsigned char enc[OSSL_HPKE_TSTSIZE]; 1792 size_t enclen = sizeof(enc); 1793 unsigned char cipher[OSSL_HPKE_TSTSIZE]; 1794 size_t cipherlen = sizeof(cipher); 1795 unsigned char clear[OSSL_HPKE_TSTSIZE]; 1796 size_t clearlen = sizeof(clear); 1797 1798 hpke_suite.kem_id = OSSL_HPKE_KEM_ID_P256; 1799 1800 /* generate auth key pair */ 1801 if (!TEST_true(OSSL_HPKE_keygen(hpke_suite, authpub, &authpublen, &authpriv, 1802 NULL, 0, testctx, NULL))) 1803 goto end; 1804 /* now get the compressed form public key */ 1805 if (!TEST_true(EVP_PKEY_set_utf8_string_param(authpriv, 1806 OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, 1807 OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED))) 1808 goto end; 1809 if (!TEST_true(EVP_PKEY_get_octet_string_param(authpriv, 1810 OSSL_PKEY_PARAM_PUB_KEY, 1811 authpub, 1812 sizeof(authpub), 1813 &authpublen))) 1814 goto end; 1815 1816 /* sender side as usual */ 1817 if (!TEST_true(OSSL_HPKE_keygen(hpke_suite, pub, &publen, &privp, 1818 NULL, 0, testctx, NULL))) 1819 goto end; 1820 if (!TEST_ptr(ctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 1821 OSSL_HPKE_ROLE_SENDER, 1822 testctx, NULL))) 1823 goto end; 1824 if (!TEST_true(OSSL_HPKE_CTX_set1_authpriv(ctx, authpriv))) 1825 goto end; 1826 if (!TEST_true(OSSL_HPKE_encap(ctx, enc, &enclen, pub, publen, NULL, 0))) 1827 goto end; 1828 if (!TEST_true(OSSL_HPKE_seal(ctx, cipher, &cipherlen, NULL, 0, 1829 plain, plainlen))) 1830 goto end; 1831 1832 /* receiver side providing compressed form of auth public */ 1833 if (!TEST_ptr(rctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 1834 OSSL_HPKE_ROLE_RECEIVER, 1835 testctx, NULL))) 1836 goto end; 1837 if (!TEST_true(OSSL_HPKE_CTX_set1_authpub(rctx, authpub, authpublen))) 1838 goto end; 1839 if (!TEST_true(OSSL_HPKE_decap(rctx, enc, enclen, privp, NULL, 0))) 1840 goto end; 1841 if (!TEST_true(OSSL_HPKE_open(rctx, clear, &clearlen, NULL, 0, 1842 cipher, cipherlen))) 1843 goto end; 1844 erv = 1; 1845 1846 end: 1847 EVP_PKEY_free(privp); 1848 EVP_PKEY_free(authpriv); 1849 OSSL_HPKE_CTX_free(ctx); 1850 OSSL_HPKE_CTX_free(rctx); 1851 return erv; 1852 } 1853 1854 /* 1855 * Test that nonce reuse calls are prevented as we expect 1856 */ 1857 static int test_hpke_noncereuse(void) 1858 { 1859 int erv = 0; 1860 EVP_PKEY *privp = NULL; 1861 unsigned char pub[OSSL_HPKE_TSTSIZE]; 1862 size_t publen = sizeof(pub); 1863 int hpke_mode = OSSL_HPKE_MODE_BASE; 1864 OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT; 1865 OSSL_HPKE_CTX *ctx = NULL; 1866 OSSL_HPKE_CTX *rctx = NULL; 1867 unsigned char plain[] = "quick brown fox"; 1868 size_t plainlen = sizeof(plain); 1869 unsigned char enc[OSSL_HPKE_TSTSIZE]; 1870 size_t enclen = sizeof(enc); 1871 unsigned char cipher[OSSL_HPKE_TSTSIZE]; 1872 size_t cipherlen = sizeof(cipher); 1873 unsigned char clear[OSSL_HPKE_TSTSIZE]; 1874 size_t clearlen = sizeof(clear); 1875 uint64_t seq = 0xbad1dea; 1876 1877 /* sender side is not allowed set seq once some crypto done */ 1878 if (!TEST_true(OSSL_HPKE_keygen(hpke_suite, pub, &publen, &privp, 1879 NULL, 0, testctx, NULL))) 1880 goto end; 1881 if (!TEST_ptr(ctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 1882 OSSL_HPKE_ROLE_SENDER, 1883 testctx, NULL))) 1884 goto end; 1885 /* set seq will fail before any crypto done */ 1886 if (!TEST_false(OSSL_HPKE_CTX_set_seq(ctx, seq))) 1887 goto end; 1888 if (!TEST_true(OSSL_HPKE_encap(ctx, enc, &enclen, pub, publen, NULL, 0))) 1889 goto end; 1890 /* set seq will also fail after some crypto done */ 1891 if (!TEST_false(OSSL_HPKE_CTX_set_seq(ctx, seq + 1))) 1892 goto end; 1893 if (!TEST_true(OSSL_HPKE_seal(ctx, cipher, &cipherlen, NULL, 0, 1894 plain, plainlen))) 1895 goto end; 1896 1897 /* receiver side is allowed control seq */ 1898 if (!TEST_ptr(rctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, 1899 OSSL_HPKE_ROLE_RECEIVER, 1900 testctx, NULL))) 1901 goto end; 1902 /* set seq will work before any crypto done */ 1903 if (!TEST_true(OSSL_HPKE_CTX_set_seq(rctx, seq))) 1904 goto end; 1905 if (!TEST_true(OSSL_HPKE_decap(rctx, enc, enclen, privp, NULL, 0))) 1906 goto end; 1907 /* set seq will work for receivers even after crypto done */ 1908 if (!TEST_true(OSSL_HPKE_CTX_set_seq(rctx, seq))) 1909 goto end; 1910 /* but that value isn't good so decap will fail */ 1911 if (!TEST_false(OSSL_HPKE_open(rctx, clear, &clearlen, NULL, 0, 1912 cipher, cipherlen))) 1913 goto end; 1914 /* reset seq to correct value and _open() should work */ 1915 if (!TEST_true(OSSL_HPKE_CTX_set_seq(rctx, 0))) 1916 goto end; 1917 if (!TEST_true(OSSL_HPKE_open(rctx, clear, &clearlen, NULL, 0, 1918 cipher, cipherlen))) 1919 goto end; 1920 erv = 1; 1921 1922 end: 1923 EVP_PKEY_free(privp); 1924 OSSL_HPKE_CTX_free(ctx); 1925 OSSL_HPKE_CTX_free(rctx); 1926 return erv; 1927 } 1928 1929 typedef enum OPTION_choice { 1930 OPT_ERR = -1, 1931 OPT_EOF = 0, 1932 OPT_VERBOSE, 1933 OPT_TEST_ENUM 1934 } OPTION_CHOICE; 1935 1936 const OPTIONS *test_get_options(void) 1937 { 1938 static const OPTIONS test_options[] = { 1939 OPT_TEST_OPTIONS_DEFAULT_USAGE, 1940 { "v", OPT_VERBOSE, '-', "Enable verbose mode" }, 1941 { OPT_HELP_STR, 1, '-', "Run HPKE tests\n" }, 1942 { NULL } 1943 }; 1944 return test_options; 1945 } 1946 1947 int setup_tests(void) 1948 { 1949 OPTION_CHOICE o; 1950 1951 while ((o = opt_next()) != OPT_EOF) { 1952 switch (o) { 1953 case OPT_VERBOSE: 1954 verbose = 1; /* Print progress dots */ 1955 break; 1956 case OPT_TEST_CASES: 1957 break; 1958 default: 1959 return 0; 1960 } 1961 } 1962 1963 if (!test_get_libctx(&testctx, &nullprov, NULL, &deflprov, "default")) 1964 return 0; 1965 #ifndef OPENSSL_NO_ECX 1966 ADD_TEST(export_only_test); 1967 ADD_TEST(x25519kdfsha256_hkdfsha256_aes128gcm_base_test); 1968 ADD_TEST(x25519kdfsha256_hkdfsha256_aes128gcm_psk_test); 1969 #endif 1970 ADD_TEST(P256kdfsha256_hkdfsha256_aes128gcm_base_test); 1971 ADD_TEST(test_hpke_export); 1972 ADD_TEST(test_hpke_modes_suites); 1973 ADD_TEST(test_hpke_suite_strs); 1974 ADD_TEST(test_hpke_grease); 1975 ADD_TEST(test_hpke_ikms); 1976 ADD_TEST(test_hpke_random_suites); 1977 ADD_TEST(test_hpke_oddcalls); 1978 ADD_TEST(test_hpke_compressed); 1979 ADD_TEST(test_hpke_noncereuse); 1980 return 1; 1981 } 1982 1983 void cleanup_tests(void) 1984 { 1985 OSSL_PROVIDER_unload(deflprov); 1986 OSSL_PROVIDER_unload(nullprov); 1987 OSSL_LIB_CTX_free(testctx); 1988 } 1989