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