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