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