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