Home | History | Annotate | Line # | Download | only in test
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4      1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos  * in the file LICENSE in the source distribution or at
      7      1.1  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9      1.1  christos 
     10      1.1  christos #include <openssl/evp.h>
     11      1.1  christos #include <openssl/core_names.h>
     12      1.1  christos #include <openssl/param_build.h>
     13      1.1  christos #include <openssl/proverr.h>
     14      1.1  christos #include "internal/nelem.h"
     15      1.1  christos #include "testutil.h"
     16      1.1  christos 
     17  1.1.1.2  christos #define TEST_KEM_ENCAP 0
     18  1.1.1.2  christos #define TEST_KEM_DECAP 1
     19      1.1  christos #define TEST_KEM_ENCAP_DECAP 2
     20      1.1  christos 
     21  1.1.1.2  christos #define TEST_TYPE_AUTH 0
     22  1.1.1.2  christos #define TEST_TYPE_NOAUTH 1
     23      1.1  christos #define TEST_TYPE_AUTH_NOAUTH 2
     24      1.1  christos 
     25  1.1.1.2  christos #define TEST_KEYTYPE_P256 0
     26  1.1.1.2  christos #define TEST_KEYTYPE_X25519 1
     27      1.1  christos #define TEST_KEYTYPES_P256_X25519 2
     28      1.1  christos 
     29      1.1  christos static OSSL_LIB_CTX *libctx = NULL;
     30      1.1  christos static OSSL_PROVIDER *nullprov = NULL;
     31      1.1  christos static OSSL_PROVIDER *libprov = NULL;
     32      1.1  christos static OSSL_PARAM opparam[2];
     33      1.1  christos static EVP_PKEY *rkey[TEST_KEYTYPES_P256_X25519] = { NULL, NULL };
     34      1.1  christos static EVP_PKEY_CTX *rctx[TEST_KEYTYPES_P256_X25519] = { NULL, NULL };
     35      1.1  christos 
     36      1.1  christos #include "dhkem_test.inc"
     37      1.1  christos 
     38      1.1  christos /* Perform encapsulate KAT's */
     39      1.1  christos static int test_dhkem_encapsulate(int tstid)
     40      1.1  christos {
     41      1.1  christos     int ret = 0;
     42      1.1  christos     EVP_PKEY *rpub = NULL, *spriv = NULL;
     43      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[tstid];
     44      1.1  christos 
     45      1.1  christos     TEST_note("Test %s %s Decapsulate", t->curve,
     46  1.1.1.2  christos         t->spriv != NULL ? "Auth" : "");
     47      1.1  christos 
     48      1.1  christos     if (!TEST_ptr(rpub = new_raw_public_key(t->curve, t->rpub, t->rpublen)))
     49      1.1  christos         goto err;
     50      1.1  christos 
     51      1.1  christos     if (t->spriv != NULL) {
     52      1.1  christos         if (!TEST_ptr(spriv = new_raw_private_key(t->curve,
     53  1.1.1.2  christos                           t->spriv, t->sprivlen,
     54  1.1.1.2  christos                           t->spub, t->spublen)))
     55      1.1  christos             goto err;
     56      1.1  christos     }
     57      1.1  christos     ret = do_encap(t, rpub, spriv);
     58      1.1  christos err:
     59      1.1  christos     EVP_PKEY_free(spriv);
     60      1.1  christos     EVP_PKEY_free(rpub);
     61      1.1  christos     return ret;
     62      1.1  christos }
     63      1.1  christos 
     64      1.1  christos /* Perform decapsulate KAT's */
     65      1.1  christos static int test_dhkem_decapsulate(int tstid)
     66      1.1  christos {
     67      1.1  christos     int ret = 0;
     68      1.1  christos     EVP_PKEY *rpriv = NULL, *spub = NULL;
     69      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[tstid];
     70      1.1  christos 
     71      1.1  christos     TEST_note("Test %s %s Decapsulate", t->curve, t->spub != NULL ? "Auth" : "");
     72      1.1  christos 
     73      1.1  christos     if (!TEST_ptr(rpriv = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
     74  1.1.1.2  christos                       t->rpub, t->rpublen)))
     75      1.1  christos         goto err;
     76      1.1  christos     if (t->spub != NULL) {
     77      1.1  christos         if (!TEST_ptr(spub = new_raw_public_key(t->curve, t->spub, t->spublen)))
     78      1.1  christos             goto err;
     79      1.1  christos     }
     80      1.1  christos     ret = do_decap(t, rpriv, spub);
     81      1.1  christos err:
     82      1.1  christos     EVP_PKEY_free(spub);
     83      1.1  christos     EVP_PKEY_free(rpriv);
     84      1.1  christos     return ret;
     85      1.1  christos }
     86      1.1  christos 
     87      1.1  christos /* Test that there are settables and they have correct data types */
     88      1.1  christos static int test_settables(int tstid)
     89      1.1  christos {
     90      1.1  christos     EVP_PKEY_CTX *ctx = rctx[tstid];
     91      1.1  christos     const OSSL_PARAM *settableparams;
     92      1.1  christos     const OSSL_PARAM *p;
     93      1.1  christos 
     94      1.1  christos     return TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1)
     95  1.1.1.2  christos         && TEST_ptr(settableparams = EVP_PKEY_CTX_settable_params(ctx))
     96  1.1.1.2  christos         && TEST_ptr(p = OSSL_PARAM_locate_const(settableparams,
     97  1.1.1.2  christos                         OSSL_KEM_PARAM_OPERATION))
     98  1.1.1.2  christos         && TEST_uint_eq(p->data_type, OSSL_PARAM_UTF8_STRING)
     99  1.1.1.2  christos         && TEST_ptr(p = OSSL_PARAM_locate_const(settableparams,
    100  1.1.1.2  christos                         OSSL_KEM_PARAM_IKME))
    101  1.1.1.2  christos         && TEST_uint_eq(p->data_type, OSSL_PARAM_OCTET_STRING);
    102      1.1  christos }
    103      1.1  christos 
    104      1.1  christos /* Test initing multiple times passes */
    105      1.1  christos static int test_init_multiple(int tstid)
    106      1.1  christos {
    107      1.1  christos     EVP_PKEY_CTX *ctx = rctx[tstid];
    108      1.1  christos 
    109      1.1  christos     return TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1)
    110  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1)
    111  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), 1)
    112  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), 1);
    113      1.1  christos }
    114      1.1  christos 
    115      1.1  christos /* Fail is various bad inputs are passed to the derivekey (keygen) operation */
    116      1.1  christos static int test_ec_dhkem_derivekey_fail(void)
    117      1.1  christos {
    118      1.1  christos     int ret = 0;
    119      1.1  christos     EVP_PKEY *pkey = NULL;
    120      1.1  christos     OSSL_PARAM params[3];
    121      1.1  christos     EVP_PKEY_CTX *genctx = NULL;
    122      1.1  christos     const TEST_DERIVEKEY_DATA *t = &ec_derivekey_data[0];
    123      1.1  christos     BIGNUM *priv = NULL;
    124      1.1  christos 
    125      1.1  christos     /* Check non nist curve fails */
    126      1.1  christos     params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
    127  1.1.1.2  christos         "secp256k1", 0);
    128      1.1  christos     params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
    129  1.1.1.2  christos         (char *)t->ikm, t->ikmlen);
    130      1.1  christos     params[2] = OSSL_PARAM_construct_end();
    131      1.1  christos 
    132      1.1  christos     if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL))
    133      1.1  christos         || !TEST_int_eq(EVP_PKEY_keygen_init(genctx), 1)
    134      1.1  christos         || !TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
    135  1.1.1.2  christos         || !TEST_int_eq(EVP_PKEY_generate(genctx, &pkey), 0))
    136      1.1  christos         goto err;
    137      1.1  christos 
    138      1.1  christos     /* Fail if curve is not one of P-256, P-384 or P-521 */
    139      1.1  christos     params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
    140  1.1.1.2  christos         "P-224", 0);
    141      1.1  christos     params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
    142  1.1.1.2  christos         (char *)t->ikm, t->ikmlen);
    143      1.1  christos     params[2] = OSSL_PARAM_construct_end();
    144      1.1  christos     if (!TEST_int_eq(EVP_PKEY_keygen_init(genctx), 1)
    145      1.1  christos         || !TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
    146      1.1  christos         || !TEST_int_eq(EVP_PKEY_generate(genctx, &pkey), 0))
    147      1.1  christos         goto err;
    148      1.1  christos 
    149      1.1  christos     /* Fail if ikm len is too small*/
    150      1.1  christos     params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
    151  1.1.1.2  christos         "P-256", 0);
    152      1.1  christos     params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
    153  1.1.1.2  christos         (char *)t->ikm, t->ikmlen - 1);
    154      1.1  christos     params[2] = OSSL_PARAM_construct_end();
    155      1.1  christos     if (!TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
    156      1.1  christos         || !TEST_int_eq(EVP_PKEY_generate(genctx, &pkey), 0))
    157      1.1  christos         goto err;
    158      1.1  christos 
    159      1.1  christos     ret = 1;
    160      1.1  christos err:
    161      1.1  christos     BN_free(priv);
    162      1.1  christos     EVP_PKEY_free(pkey);
    163      1.1  christos     EVP_PKEY_CTX_free(genctx);
    164      1.1  christos     return ret;
    165      1.1  christos }
    166      1.1  christos 
    167      1.1  christos /* Succeed even if the operation parameter is not set */
    168      1.1  christos static int test_no_operation_set(int tstid)
    169      1.1  christos {
    170      1.1  christos     EVP_PKEY_CTX *ctx = rctx[tstid];
    171      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[tstid];
    172      1.1  christos     size_t len = 0;
    173      1.1  christos 
    174      1.1  christos     return TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1)
    175  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate(ctx, NULL, &len, NULL, NULL), 1)
    176  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), 1)
    177  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate(ctx, NULL, &len,
    178  1.1.1.2  christos                            t->expected_enc,
    179  1.1.1.2  christos                            t->expected_enclen),
    180  1.1.1.2  christos             1);
    181      1.1  christos }
    182      1.1  christos 
    183      1.1  christos /* Fail if the ikm is too small */
    184      1.1  christos static int test_ikm_small(int tstid)
    185      1.1  christos {
    186      1.1  christos     unsigned char tmp[16] = { 0 };
    187      1.1  christos     unsigned char secret[256];
    188      1.1  christos     unsigned char enc[256];
    189      1.1  christos     size_t secretlen = sizeof(secret);
    190      1.1  christos     size_t enclen = sizeof(enc);
    191      1.1  christos     OSSL_PARAM params[3];
    192      1.1  christos     EVP_PKEY_CTX *ctx = rctx[tstid];
    193      1.1  christos 
    194      1.1  christos     params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION,
    195  1.1.1.2  christos         OSSL_KEM_PARAM_OPERATION_DHKEM,
    196  1.1.1.2  christos         0);
    197      1.1  christos     params[1] = OSSL_PARAM_construct_octet_string(OSSL_KEM_PARAM_IKME,
    198  1.1.1.2  christos         tmp, sizeof(tmp));
    199      1.1  christos     params[2] = OSSL_PARAM_construct_end();
    200      1.1  christos 
    201      1.1  christos     return TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, params), 1)
    202  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc, &enclen,
    203  1.1.1.2  christos                            secret, &secretlen),
    204  1.1.1.2  christos             0);
    205      1.1  christos }
    206      1.1  christos 
    207      1.1  christos /* Fail if buffers lengths are too small to hold returned data */
    208      1.1  christos static int test_input_size_small(int tstid)
    209      1.1  christos {
    210      1.1  christos     int ret = 0;
    211      1.1  christos     unsigned char sec[256];
    212      1.1  christos     unsigned char enc[256];
    213      1.1  christos     size_t seclen = sizeof(sec);
    214      1.1  christos     size_t enclen = sizeof(enc);
    215      1.1  christos     EVP_PKEY_CTX *ctx = rctx[tstid];
    216      1.1  christos 
    217      1.1  christos     if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, opparam), 1)
    218      1.1  christos         || !TEST_int_eq(EVP_PKEY_encapsulate(ctx, NULL, &enclen,
    219  1.1.1.2  christos                             NULL, &seclen),
    220  1.1.1.2  christos             1))
    221  1.1.1.2  christos         goto err;
    222      1.1  christos 
    223      1.1  christos     /* buffer too small for enc */
    224      1.1  christos     enclen--;
    225      1.1  christos     if (!TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc, &enclen, sec, &seclen),
    226  1.1.1.2  christos             0))
    227      1.1  christos         goto err;
    228      1.1  christos     enclen++;
    229      1.1  christos     /* buffer too small for secret */
    230      1.1  christos     seclen--;
    231      1.1  christos     if (!TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc, &enclen, sec, &seclen), 0))
    232      1.1  christos         goto err;
    233      1.1  christos     seclen++;
    234      1.1  christos     if (!TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), 1))
    235      1.1  christos         goto err;
    236  1.1.1.2  christos     /* buffer too small for decapsulate secret */
    237      1.1  christos     seclen--;
    238      1.1  christos     if (!TEST_int_eq(EVP_PKEY_decapsulate(ctx, sec, &seclen, enc, enclen), 0))
    239      1.1  christos         goto err;
    240      1.1  christos     seclen++;
    241  1.1.1.2  christos     /* incorrect enclen passed to decap  */
    242      1.1  christos     enclen--;
    243      1.1  christos     ret = TEST_int_eq(EVP_PKEY_decapsulate(ctx, sec, &seclen, enc, enclen), 0);
    244      1.1  christos err:
    245      1.1  christos     return ret;
    246      1.1  christos }
    247      1.1  christos 
    248      1.1  christos /* Fail if the auth key has a different curve */
    249      1.1  christos static int test_ec_auth_key_curve_mismatch(void)
    250      1.1  christos {
    251      1.1  christos     int ret = 0;
    252      1.1  christos     EVP_PKEY *auth = NULL;
    253      1.1  christos 
    254      1.1  christos     if (!TEST_ptr(auth = EVP_PKEY_Q_keygen(libctx, NULL, "EC", "P-521")))
    255      1.1  christos         return 0;
    256      1.1  christos 
    257      1.1  christos     ret = TEST_int_eq(EVP_PKEY_auth_encapsulate_init(rctx[0], auth, opparam), 0);
    258      1.1  christos     EVP_PKEY_free(auth);
    259      1.1  christos     return ret;
    260      1.1  christos }
    261      1.1  christos 
    262      1.1  christos /* Fail if the auth key has a different key type to the recipient */
    263      1.1  christos static int test_auth_key_type_mismatch(int tstid)
    264      1.1  christos {
    265      1.1  christos     int id1 = tstid;
    266      1.1  christos     int id2 = !tstid;
    267      1.1  christos 
    268      1.1  christos     return TEST_int_eq(EVP_PKEY_auth_encapsulate_init(rctx[id1],
    269  1.1.1.2  christos                            rkey[id2], opparam),
    270  1.1.1.2  christos         0);
    271      1.1  christos }
    272      1.1  christos 
    273      1.1  christos static int test_ec_invalid_private_key(void)
    274      1.1  christos {
    275      1.1  christos     int ret = 0;
    276      1.1  christos     EVP_PKEY *priv = NULL;
    277      1.1  christos     EVP_PKEY_CTX *ctx = NULL;
    278      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[0];
    279      1.1  christos     static const unsigned char order[] = {
    280      1.1  christos         0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    281      1.1  christos         0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
    282      1.1  christos         0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
    283      1.1  christos     };
    284      1.1  christos 
    285      1.1  christos     ret = TEST_ptr(priv = new_raw_private_key("P-256", order, sizeof(order),
    286  1.1.1.2  christos                        t->rpub, t->rpublen))
    287  1.1.1.2  christos         && TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, priv, NULL))
    288  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 0);
    289      1.1  christos     EVP_PKEY_free(priv);
    290      1.1  christos     EVP_PKEY_CTX_free(ctx);
    291      1.1  christos     return ret;
    292      1.1  christos }
    293      1.1  christos 
    294      1.1  christos static int test_ec_public_key_infinity(void)
    295      1.1  christos {
    296      1.1  christos     int ret = 0;
    297      1.1  christos     EVP_PKEY *key = NULL;
    298      1.1  christos     EVP_PKEY_CTX *keyctx = NULL;
    299      1.1  christos     unsigned char s[256];
    300      1.1  christos     unsigned char e[256];
    301      1.1  christos     size_t slen = sizeof(s);
    302      1.1  christos     size_t elen = sizeof(e);
    303      1.1  christos     unsigned char tmp[1] = { 0 }; /* The encoding for an EC point at infinity */
    304      1.1  christos     EVP_PKEY_CTX *ctx = rctx[0];
    305      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[0];
    306      1.1  christos 
    307      1.1  christos     ret = TEST_ptr(key = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
    308  1.1.1.2  christos                        tmp, sizeof(tmp)))
    309  1.1.1.2  christos         && TEST_ptr(keyctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL))
    310  1.1.1.2  christos         /* Fail if the recipient public key is invalid */
    311  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate_init(keyctx, opparam), 1)
    312  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate(keyctx, e, &elen, s, &slen), 0)
    313  1.1.1.2  christos         /* Fail the decap if the recipient public key is invalid */
    314  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate_init(keyctx, opparam), 1)
    315  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate(keyctx, s, &slen,
    316  1.1.1.2  christos                            t->expected_enc,
    317  1.1.1.2  christos                            t->expected_enclen),
    318  1.1.1.2  christos             0)
    319  1.1.1.2  christos         /* Fail if the auth key has a bad public key */
    320  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, key, opparam), 1)
    321  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate(ctx, e, &elen, s, &slen), 0);
    322      1.1  christos 
    323      1.1  christos     EVP_PKEY_free(key);
    324      1.1  christos     EVP_PKEY_CTX_free(keyctx);
    325      1.1  christos     return ret;
    326      1.1  christos }
    327      1.1  christos 
    328      1.1  christos /* Test incorrectly passing NULL values fail */
    329      1.1  christos static int test_null_params(int tstid)
    330      1.1  christos {
    331      1.1  christos     EVP_PKEY_CTX *ctx = rctx[tstid];
    332      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[tstid];
    333      1.1  christos 
    334      1.1  christos     /* auth_encap/decap init must be passed a non NULL value */
    335      1.1  christos     return TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, NULL, opparam), 0)
    336  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_auth_decapsulate_init(ctx, NULL, opparam), 0)
    337  1.1.1.2  christos         /* Check decap fails if NULL params are passed */
    338  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), 1)
    339  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate(ctx, NULL, NULL,
    340  1.1.1.2  christos                            t->expected_enc,
    341  1.1.1.2  christos                            t->expected_enclen),
    342  1.1.1.2  christos             0)
    343  1.1.1.2  christos         /* Check encap fails if NULL params are passed */
    344  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, opparam), 1)
    345  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate(ctx, NULL, NULL,
    346  1.1.1.2  christos                            NULL, NULL),
    347  1.1.1.2  christos             0);
    348      1.1  christos }
    349      1.1  christos 
    350      1.1  christos static int test_set_params(int tstid)
    351      1.1  christos {
    352      1.1  christos     int ret = 0;
    353      1.1  christos     EVP_PKEY_CTX *ctx = rctx[tstid];
    354      1.1  christos     OSSL_PARAM badparams[4];
    355      1.1  christos     int val = 1;
    356      1.1  christos 
    357      1.1  christos     /* wrong data type for operation param */
    358      1.1  christos     badparams[0] = OSSL_PARAM_construct_int(OSSL_KEM_PARAM_OPERATION, &val);
    359      1.1  christos     badparams[1] = OSSL_PARAM_construct_end();
    360      1.1  christos     if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 0))
    361      1.1  christos         goto err;
    362      1.1  christos     /* unknown string used for the operation param */
    363      1.1  christos     badparams[0] = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION,
    364  1.1.1.2  christos         "unknown_op", 0);
    365      1.1  christos     badparams[1] = OSSL_PARAM_construct_end();
    366      1.1  christos     if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 0))
    367      1.1  christos         goto err;
    368      1.1  christos 
    369      1.1  christos     /* NULL string set for the operation param */
    370      1.1  christos     badparams[0] = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION,
    371  1.1.1.2  christos         NULL, 0);
    372      1.1  christos     badparams[1] = OSSL_PARAM_construct_end();
    373      1.1  christos     if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 0))
    374      1.1  christos         goto err;
    375      1.1  christos 
    376      1.1  christos     /* wrong data type for ikme param */
    377      1.1  christos     badparams[0] = OSSL_PARAM_construct_int(OSSL_KEM_PARAM_IKME, &val);
    378      1.1  christos     badparams[1] = OSSL_PARAM_construct_end();
    379      1.1  christos     if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 0))
    380      1.1  christos         goto err;
    381      1.1  christos 
    382      1.1  christos     /* Setting the ikme to NULL is allowed */
    383      1.1  christos     badparams[0] = OSSL_PARAM_construct_octet_string(OSSL_KEM_PARAM_IKME, NULL, 0);
    384      1.1  christos     badparams[1] = OSSL_PARAM_construct_end();
    385      1.1  christos     if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 1))
    386      1.1  christos         goto err;
    387      1.1  christos 
    388      1.1  christos     /* Test that unknown params are ignored */
    389      1.1  christos     badparams[0] = OSSL_PARAM_construct_int("unknownparam", &val);
    390      1.1  christos     badparams[1] = OSSL_PARAM_construct_end();
    391      1.1  christos     ret = TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 1);
    392      1.1  christos err:
    393      1.1  christos     return ret;
    394      1.1  christos }
    395      1.1  christos 
    396      1.1  christos /*
    397      1.1  christos  * ECX keys autogen the public key if a private key is loaded,
    398      1.1  christos  * So this test passes for ECX, but fails for EC
    399      1.1  christos  */
    400      1.1  christos static int test_nopublic(int tstid)
    401      1.1  christos {
    402      1.1  christos     int ret = 0;
    403      1.1  christos     EVP_PKEY_CTX *ctx = NULL;
    404      1.1  christos     EVP_PKEY *priv = NULL;
    405      1.1  christos     int encap = ((tstid & 1) == 0);
    406      1.1  christos     int keytype = tstid >= TEST_KEM_ENCAP_DECAP;
    407      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[keytype];
    408      1.1  christos     int expected = (keytype == TEST_KEYTYPE_X25519);
    409      1.1  christos 
    410      1.1  christos     TEST_note("%s %s", t->curve, encap ? "Encap" : "Decap");
    411      1.1  christos     if (!TEST_ptr(priv = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
    412  1.1.1.2  christos                       NULL, 0)))
    413      1.1  christos         goto err;
    414      1.1  christos     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, priv, NULL)))
    415      1.1  christos         goto err;
    416      1.1  christos 
    417      1.1  christos     if (encap) {
    418      1.1  christos         if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, opparam), expected))
    419      1.1  christos             goto err;
    420      1.1  christos     } else {
    421      1.1  christos         if (!TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), expected))
    422  1.1.1.2  christos             goto err;
    423      1.1  christos     }
    424      1.1  christos     if (expected == 0
    425      1.1  christos         && !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), PROV_R_NOT_A_PUBLIC_KEY))
    426      1.1  christos         goto err;
    427      1.1  christos     ret = 1;
    428      1.1  christos err:
    429      1.1  christos     EVP_PKEY_free(priv);
    430      1.1  christos     EVP_PKEY_CTX_free(ctx);
    431      1.1  christos     return ret;
    432      1.1  christos }
    433      1.1  christos 
    434      1.1  christos /* Test that not setting the auth public key fails the auth encap/decap init */
    435      1.1  christos static int test_noauthpublic(int tstid)
    436      1.1  christos {
    437      1.1  christos     int ret = 0;
    438      1.1  christos     EVP_PKEY *auth = NULL;
    439      1.1  christos     int encap = ((tstid & 1) == 0);
    440      1.1  christos     int keytype = tstid >= TEST_KEM_ENCAP_DECAP;
    441      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[keytype];
    442      1.1  christos     EVP_PKEY_CTX *ctx = rctx[keytype];
    443      1.1  christos     int expected = (keytype == TEST_KEYTYPE_X25519);
    444      1.1  christos 
    445      1.1  christos     TEST_note("%s %s", t->curve, encap ? "Encap" : "Decap");
    446      1.1  christos     if (!TEST_ptr(auth = new_raw_private_key(t->curve, t->rpriv,
    447  1.1.1.2  christos                       t->rprivlen, NULL, expected)))
    448      1.1  christos         goto err;
    449      1.1  christos 
    450      1.1  christos     if (encap) {
    451      1.1  christos         if (!TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, auth,
    452  1.1.1.2  christos                              opparam),
    453  1.1.1.2  christos                 expected))
    454      1.1  christos             goto err;
    455      1.1  christos     } else {
    456      1.1  christos         if (!TEST_int_eq(EVP_PKEY_auth_decapsulate_init(ctx, auth,
    457  1.1.1.2  christos                              opparam),
    458  1.1.1.2  christos                 expected))
    459      1.1  christos             goto err;
    460      1.1  christos     }
    461      1.1  christos     if (expected == 0
    462      1.1  christos         && !TEST_int_eq(ERR_GET_REASON(ERR_get_error()),
    463  1.1.1.2  christos             PROV_R_NOT_A_PUBLIC_KEY))
    464      1.1  christos         goto err;
    465      1.1  christos     ret = 1;
    466      1.1  christos err:
    467      1.1  christos     EVP_PKEY_free(auth);
    468      1.1  christos     return ret;
    469      1.1  christos }
    470      1.1  christos 
    471      1.1  christos /* EC specific tests */
    472      1.1  christos 
    473      1.1  christos /* Perform EC DHKEM KATs */
    474      1.1  christos static int test_ec_dhkem_derivekey(int tstid)
    475      1.1  christos {
    476      1.1  christos     int ret = 0;
    477      1.1  christos     EVP_PKEY *pkey = NULL;
    478      1.1  christos     OSSL_PARAM params[3];
    479      1.1  christos     EVP_PKEY_CTX *genctx = NULL;
    480      1.1  christos     const TEST_DERIVEKEY_DATA *t = &ec_derivekey_data[tstid];
    481      1.1  christos     unsigned char pubkey[133];
    482      1.1  christos     unsigned char privkey[66];
    483      1.1  christos     size_t pubkeylen = 0, privkeylen = 0;
    484      1.1  christos     BIGNUM *priv = NULL;
    485      1.1  christos 
    486      1.1  christos     params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
    487  1.1.1.2  christos         (char *)t->curvename, 0);
    488      1.1  christos     params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
    489  1.1.1.2  christos         (char *)t->ikm, t->ikmlen);
    490      1.1  christos     params[2] = OSSL_PARAM_construct_end();
    491      1.1  christos 
    492      1.1  christos     ret = TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL))
    493  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_keygen_init(genctx), 1)
    494  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
    495  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_generate(genctx, &pkey), 1)
    496  1.1.1.2  christos         && TEST_true(EVP_PKEY_get_octet_string_param(pkey,
    497  1.1.1.2  christos             OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
    498  1.1.1.2  christos             pubkey, sizeof(pubkey), &pubkeylen))
    499  1.1.1.2  christos         && TEST_true(EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
    500  1.1.1.2  christos             &priv))
    501  1.1.1.2  christos         && TEST_int_gt(privkeylen = BN_bn2bin(priv, privkey), 0)
    502  1.1.1.2  christos         && TEST_int_le(privkeylen, sizeof(privkey))
    503  1.1.1.2  christos         && TEST_mem_eq(privkey, privkeylen, t->priv, t->privlen)
    504  1.1.1.2  christos         && TEST_mem_eq(pubkey, pubkeylen, t->pub, t->publen);
    505      1.1  christos 
    506      1.1  christos     BN_free(priv);
    507      1.1  christos     EVP_PKEY_free(pkey);
    508      1.1  christos     EVP_PKEY_CTX_free(genctx);
    509      1.1  christos     return ret;
    510      1.1  christos }
    511      1.1  christos 
    512      1.1  christos /*
    513      1.1  christos  * Test that encapsulation uses a random seed if the ikm is not specified,
    514      1.1  christos  * and verify that the shared secret matches the decapsulate result.
    515      1.1  christos  */
    516      1.1  christos static int test_ec_noikme(int tstid)
    517      1.1  christos {
    518      1.1  christos     int ret = 0, auth = 0;
    519      1.1  christos     EVP_PKEY_CTX *ctx = NULL;
    520      1.1  christos     EVP_PKEY *recip = NULL;
    521      1.1  christos     EVP_PKEY *sender_auth = NULL;
    522      1.1  christos     unsigned char sender_secret[256];
    523      1.1  christos     unsigned char recip_secret[256];
    524      1.1  christos     unsigned char sender_pub[256];
    525      1.1  christos     size_t sender_secretlen = sizeof(sender_secret);
    526      1.1  christos     size_t recip_secretlen = sizeof(recip_secret);
    527      1.1  christos     size_t sender_publen = sizeof(sender_pub);
    528      1.1  christos     const char *curve;
    529      1.1  christos     int sz = OSSL_NELEM(dhkem_supported_curves);
    530      1.1  christos     const char *op = OSSL_KEM_PARAM_OPERATION_DHKEM;
    531      1.1  christos 
    532      1.1  christos     if (tstid >= sz) {
    533      1.1  christos         auth = 1;
    534      1.1  christos         tstid -= sz;
    535      1.1  christos     }
    536      1.1  christos     curve = dhkem_supported_curves[tstid];
    537      1.1  christos     TEST_note("testing encap/decap of curve %s%s\n", curve,
    538  1.1.1.2  christos         auth ? " with auth" : "");
    539      1.1  christos 
    540      1.1  christos     if (curve[0] == 'X') {
    541      1.1  christos         if (!TEST_ptr(recip = EVP_PKEY_Q_keygen(libctx, NULL, curve))
    542  1.1.1.2  christos             || (auth
    543  1.1.1.2  christos                 && !TEST_ptr(sender_auth = EVP_PKEY_Q_keygen(libctx, NULL,
    544  1.1.1.2  christos                                  curve))))
    545      1.1  christos             goto err;
    546      1.1  christos     } else {
    547      1.1  christos         if (!TEST_ptr(recip = EVP_PKEY_Q_keygen(libctx, NULL, "EC", curve))
    548  1.1.1.2  christos             || (auth
    549  1.1.1.2  christos                 && !TEST_ptr(sender_auth = EVP_PKEY_Q_keygen(libctx, NULL,
    550  1.1.1.2  christos                                  "EC", curve))))
    551      1.1  christos             goto err;
    552      1.1  christos     }
    553      1.1  christos 
    554      1.1  christos     ret = TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, recip, NULL))
    555  1.1.1.2  christos         && (sender_auth == NULL
    556  1.1.1.2  christos             || TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, sender_auth,
    557  1.1.1.2  christos                                NULL),
    558  1.1.1.2  christos                 1))
    559  1.1.1.2  christos         && (sender_auth != NULL
    560  1.1.1.2  christos             || TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1))
    561  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_CTX_set_kem_op(ctx, op), 1)
    562  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate(ctx, sender_pub, &sender_publen,
    563  1.1.1.2  christos                            sender_secret, &sender_secretlen),
    564  1.1.1.2  christos             1)
    565  1.1.1.2  christos         && (sender_auth == NULL
    566  1.1.1.2  christos             || TEST_int_eq(EVP_PKEY_auth_decapsulate_init(ctx, sender_auth,
    567  1.1.1.2  christos                                NULL),
    568  1.1.1.2  christos                 1))
    569  1.1.1.2  christos         && (sender_auth != NULL
    570  1.1.1.2  christos             || TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), 1))
    571  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_CTX_set_kem_op(ctx, op), 1)
    572  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate(ctx, recip_secret, &recip_secretlen,
    573  1.1.1.2  christos                            sender_pub, sender_publen),
    574  1.1.1.2  christos             1)
    575  1.1.1.2  christos         && TEST_mem_eq(recip_secret, recip_secretlen,
    576  1.1.1.2  christos             sender_secret, sender_secretlen);
    577      1.1  christos err:
    578      1.1  christos     EVP_PKEY_CTX_free(ctx);
    579      1.1  christos     EVP_PKEY_free(sender_auth);
    580      1.1  christos     EVP_PKEY_free(recip);
    581      1.1  christos     return ret;
    582      1.1  christos }
    583      1.1  christos 
    584      1.1  christos /* Test encap/decap init fail if the curve is invalid */
    585      1.1  christos static int do_ec_curve_failtest(const char *curve)
    586      1.1  christos {
    587      1.1  christos     int ret;
    588      1.1  christos     EVP_PKEY *key = NULL;
    589      1.1  christos     EVP_PKEY_CTX *ctx = NULL;
    590      1.1  christos 
    591      1.1  christos     ret = TEST_ptr(key = EVP_PKEY_Q_keygen(libctx, NULL, "EC", curve))
    592  1.1.1.2  christos         && TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL))
    593  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), -2)
    594  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), -2);
    595      1.1  christos     EVP_PKEY_free(key);
    596      1.1  christos     EVP_PKEY_CTX_free(ctx);
    597      1.1  christos     return ret;
    598      1.1  christos }
    599      1.1  christos 
    600      1.1  christos static int test_ec_curve_nonnist(void)
    601      1.1  christos {
    602      1.1  christos     return do_ec_curve_failtest("secp256k1");
    603      1.1  christos }
    604      1.1  christos 
    605      1.1  christos static int test_ec_curve_unsupported(void)
    606      1.1  christos {
    607      1.1  christos     return do_ec_curve_failtest("P-224");
    608      1.1  christos }
    609      1.1  christos 
    610      1.1  christos /* Test that passing a bad recipient public EC key fails during encap/decap */
    611      1.1  christos static int test_ec_badpublic(int tstid)
    612      1.1  christos {
    613      1.1  christos     int ret = 0;
    614      1.1  christos     EVP_PKEY *recippriv = NULL;
    615      1.1  christos     EVP_PKEY_CTX *ctx = NULL;
    616      1.1  christos     unsigned char secret[256];
    617      1.1  christos     unsigned char pub[256];
    618      1.1  christos     size_t secretlen = sizeof(secret);
    619      1.1  christos     int encap = ((tstid & 1) == 0);
    620      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[0];
    621      1.1  christos 
    622      1.1  christos     TEST_note("%s %s", t->curve, encap ? "Encap" : "Decap");
    623      1.1  christos     /* Set the recipient public key to the point at infinity */
    624      1.1  christos     pub[0] = 0;
    625      1.1  christos     if (!TEST_ptr(recippriv = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
    626  1.1.1.2  christos                       pub, 1)))
    627      1.1  christos         goto err;
    628      1.1  christos 
    629      1.1  christos     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, recippriv, NULL)))
    630      1.1  christos         goto err;
    631      1.1  christos 
    632      1.1  christos     if (encap) {
    633      1.1  christos         unsigned char enc[256];
    634      1.1  christos         size_t enclen = sizeof(enc);
    635      1.1  christos 
    636      1.1  christos         if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, opparam), 1))
    637      1.1  christos             goto err;
    638  1.1.1.2  christos         if (!TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc, &enclen,
    639  1.1.1.2  christos                              secret, &secretlen),
    640  1.1.1.2  christos                 0))
    641      1.1  christos             goto err;
    642      1.1  christos     } else {
    643      1.1  christos         if (!TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), 1))
    644      1.1  christos             goto err;
    645      1.1  christos         if (!TEST_int_eq(EVP_PKEY_decapsulate(ctx, secret, &secretlen,
    646  1.1.1.2  christos                              t->expected_enc,
    647  1.1.1.2  christos                              t->expected_enclen),
    648  1.1.1.2  christos                 0))
    649      1.1  christos             goto err;
    650      1.1  christos     }
    651      1.1  christos     if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), PROV_R_INVALID_KEY))
    652      1.1  christos         goto err;
    653      1.1  christos     ret = 1;
    654      1.1  christos err:
    655      1.1  christos     EVP_PKEY_free(recippriv);
    656      1.1  christos     EVP_PKEY_CTX_free(ctx);
    657      1.1  christos     return ret;
    658      1.1  christos }
    659      1.1  christos 
    660      1.1  christos static int test_ec_badauth(int tstid)
    661      1.1  christos {
    662      1.1  christos     int ret = 0;
    663      1.1  christos     EVP_PKEY *auth = NULL;
    664      1.1  christos     unsigned char enc[256];
    665      1.1  christos     unsigned char secret[256];
    666      1.1  christos     unsigned char pub[256];
    667      1.1  christos     size_t enclen = sizeof(enc);
    668      1.1  christos     size_t secretlen = sizeof(secret);
    669      1.1  christos     int encap = ((tstid & 1) == 0);
    670      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[TEST_KEYTYPE_P256];
    671      1.1  christos     EVP_PKEY_CTX *ctx = rctx[TEST_KEYTYPE_P256];
    672      1.1  christos 
    673      1.1  christos     TEST_note("%s %s", t->curve, encap ? "Encap" : "Decap");
    674      1.1  christos     /* Set the auth public key to the point at infinity */
    675      1.1  christos     pub[0] = 0;
    676      1.1  christos     if (!TEST_ptr(auth = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
    677  1.1.1.2  christos                       pub, 1)))
    678      1.1  christos         goto err;
    679      1.1  christos     if (encap) {
    680      1.1  christos         if (!TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, auth,
    681  1.1.1.2  christos                              opparam),
    682  1.1.1.2  christos                 1)
    683      1.1  christos             || !TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc, &enclen,
    684  1.1.1.2  christos                                 secret, &secretlen),
    685  1.1.1.2  christos                 0))
    686      1.1  christos             goto err;
    687      1.1  christos     } else {
    688      1.1  christos         if (!TEST_int_eq(EVP_PKEY_auth_decapsulate_init(ctx, auth, opparam), 1)
    689      1.1  christos             || !TEST_int_eq(EVP_PKEY_decapsulate(ctx, secret, &secretlen,
    690  1.1.1.2  christos                                 t->expected_enc,
    691  1.1.1.2  christos                                 t->expected_enclen),
    692  1.1.1.2  christos                 0))
    693      1.1  christos             goto err;
    694      1.1  christos     }
    695      1.1  christos     if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), PROV_R_INVALID_KEY))
    696      1.1  christos         goto err;
    697      1.1  christos     ret = 1;
    698      1.1  christos err:
    699      1.1  christos     EVP_PKEY_free(auth);
    700      1.1  christos     return ret;
    701      1.1  christos }
    702      1.1  christos 
    703      1.1  christos static int test_ec_invalid_decap_enc_buffer(void)
    704      1.1  christos {
    705      1.1  christos     const TEST_ENCAPDATA *t = &ec_encapdata[TEST_KEYTYPE_P256];
    706      1.1  christos     unsigned char enc[256];
    707      1.1  christos     unsigned char secret[256];
    708      1.1  christos     size_t secretlen = sizeof(secret);
    709      1.1  christos     EVP_PKEY_CTX *ctx = rctx[0];
    710      1.1  christos 
    711      1.1  christos     memcpy(enc, t->expected_enc, t->expected_enclen);
    712      1.1  christos     enc[0] = 0xFF;
    713      1.1  christos 
    714      1.1  christos     return TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), 1)
    715  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate(ctx, secret, &secretlen,
    716  1.1.1.2  christos                            enc, t->expected_enclen),
    717  1.1.1.2  christos             0);
    718      1.1  christos }
    719      1.1  christos 
    720      1.1  christos #ifndef OPENSSL_NO_ECX
    721      1.1  christos /* ECX specific tests */
    722      1.1  christos 
    723      1.1  christos /* Perform ECX DHKEM KATs */
    724      1.1  christos static int test_ecx_dhkem_derivekey(int tstid)
    725      1.1  christos {
    726      1.1  christos     int ret;
    727      1.1  christos     OSSL_PARAM params[2];
    728      1.1  christos     EVP_PKEY_CTX *genctx;
    729      1.1  christos     EVP_PKEY *pkey = NULL;
    730      1.1  christos     unsigned char pubkey[64];
    731      1.1  christos     unsigned char privkey[64];
    732      1.1  christos     unsigned char masked_priv[64];
    733      1.1  christos     size_t pubkeylen = 0, privkeylen = 0;
    734      1.1  christos     const TEST_DERIVEKEY_DATA *t = &ecx_derivekey_data[tstid];
    735      1.1  christos 
    736      1.1  christos     memcpy(masked_priv, t->priv, t->privlen);
    737      1.1  christos     if (OPENSSL_strcasecmp(t->curvename, "X25519") == 0) {
    738      1.1  christos         /*
    739      1.1  christos          * The RFC test vector seems incorrect since it is not in serialized form,
    740      1.1  christos          * So manually do the conversion here for now.
    741      1.1  christos          */
    742      1.1  christos         masked_priv[0] &= 248;
    743      1.1  christos         masked_priv[t->privlen - 1] &= 127;
    744      1.1  christos         masked_priv[t->privlen - 1] |= 64;
    745      1.1  christos     } else {
    746      1.1  christos         masked_priv[0] &= 252;
    747      1.1  christos         masked_priv[t->privlen - 1] |= 128;
    748      1.1  christos     }
    749      1.1  christos 
    750      1.1  christos     params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
    751  1.1.1.2  christos         (char *)t->ikm, t->ikmlen);
    752      1.1  christos     params[1] = OSSL_PARAM_construct_end();
    753      1.1  christos 
    754      1.1  christos     ret = TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, t->curvename, NULL))
    755  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_keygen_init(genctx), 1)
    756  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
    757  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_keygen(genctx, &pkey), 1)
    758  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_get_octet_string_param(pkey,
    759  1.1.1.2  christos                            OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
    760  1.1.1.2  christos                            pubkey, sizeof(pubkey), &pubkeylen),
    761  1.1.1.2  christos             1)
    762  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_get_octet_string_param(pkey,
    763  1.1.1.2  christos                            OSSL_PKEY_PARAM_PRIV_KEY,
    764  1.1.1.2  christos                            privkey, sizeof(privkey), &privkeylen),
    765  1.1.1.2  christos             1)
    766  1.1.1.2  christos         && TEST_mem_eq(t->pub, t->publen, pubkey, pubkeylen)
    767  1.1.1.2  christos         && TEST_mem_eq(masked_priv, t->privlen, privkey, privkeylen);
    768      1.1  christos 
    769      1.1  christos     EVP_PKEY_free(pkey);
    770      1.1  christos     EVP_PKEY_CTX_free(genctx);
    771      1.1  christos     return ret;
    772      1.1  christos }
    773      1.1  christos 
    774      1.1  christos /* Fail if the auth key has a different curve */
    775      1.1  christos static int test_ecx_auth_key_curve_mismatch(void)
    776      1.1  christos {
    777      1.1  christos     int ret = 0;
    778      1.1  christos     EVP_PKEY *auth = NULL;
    779      1.1  christos 
    780      1.1  christos     if (!TEST_ptr(auth = EVP_PKEY_Q_keygen(libctx, NULL, "X448")))
    781      1.1  christos         return 0;
    782      1.1  christos 
    783      1.1  christos     ret = TEST_int_eq(EVP_PKEY_auth_encapsulate_init(rctx[TEST_KEYTYPE_X25519],
    784  1.1.1.2  christos                           auth, opparam),
    785  1.1.1.2  christos         0);
    786      1.1  christos     EVP_PKEY_free(auth);
    787      1.1  christos     return ret;
    788      1.1  christos }
    789      1.1  christos 
    790      1.1  christos /* Fail if ED448 is used for DHKEM */
    791      1.1  christos static int test_ed_curve_unsupported(void)
    792      1.1  christos {
    793      1.1  christos     int ret;
    794      1.1  christos     EVP_PKEY *key = NULL;
    795      1.1  christos     EVP_PKEY_CTX *ctx = NULL;
    796      1.1  christos 
    797      1.1  christos     ret = TEST_ptr(key = EVP_PKEY_Q_keygen(libctx, NULL, "ED448"))
    798  1.1.1.2  christos         && TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL))
    799  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), -2)
    800  1.1.1.2  christos         && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), -2);
    801      1.1  christos     EVP_PKEY_free(key);
    802      1.1  christos     EVP_PKEY_CTX_free(ctx);
    803      1.1  christos     return ret;
    804      1.1  christos }
    805      1.1  christos #endif
    806      1.1  christos 
    807      1.1  christos int setup_tests(void)
    808      1.1  christos {
    809      1.1  christos     const char *prov_name = "default";
    810      1.1  christos     char *config_file = NULL;
    811      1.1  christos     char *op = OSSL_KEM_PARAM_OPERATION_DHKEM;
    812      1.1  christos 
    813      1.1  christos     if (!test_get_libctx(&libctx, &nullprov, config_file, &libprov, prov_name))
    814      1.1  christos         return 0;
    815      1.1  christos     opparam[0] = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION,
    816  1.1.1.2  christos         op, 0);
    817      1.1  christos     opparam[1] = OSSL_PARAM_construct_end();
    818      1.1  christos 
    819      1.1  christos     /* Create P256 and X25519 keys and ctxs */
    820      1.1  christos     if (!TEST_ptr(rkey[TEST_KEYTYPE_P256] = EVP_PKEY_Q_keygen(libctx, NULL,
    821  1.1.1.2  christos                       "EC", "P-256")))
    822      1.1  christos         goto err;
    823      1.1  christos #ifndef OPENSSL_NO_ECX
    824      1.1  christos     if (!TEST_ptr(rkey[TEST_KEYTYPE_X25519] = EVP_PKEY_Q_keygen(libctx, NULL,
    825  1.1.1.2  christos                       "X25519")))
    826      1.1  christos         goto err;
    827      1.1  christos #endif
    828  1.1.1.2  christos     if (!TEST_ptr(rctx[TEST_KEYTYPE_P256] = EVP_PKEY_CTX_new_from_pkey(libctx,
    829  1.1.1.2  christos                       rkey[TEST_KEYTYPE_P256], NULL)))
    830  1.1.1.2  christos         goto err;
    831      1.1  christos #ifndef OPENSSL_NO_ECX
    832  1.1.1.2  christos     if (!TEST_ptr(rctx[TEST_KEYTYPE_X25519] = EVP_PKEY_CTX_new_from_pkey(libctx,
    833  1.1.1.2  christos                       rkey[TEST_KEYTYPE_X25519], NULL)))
    834  1.1.1.2  christos         goto err;
    835      1.1  christos #endif
    836      1.1  christos 
    837      1.1  christos     ADD_ALL_TESTS(test_dhkem_encapsulate, OSSL_NELEM(ec_encapdata));
    838      1.1  christos     ADD_ALL_TESTS(test_dhkem_decapsulate, OSSL_NELEM(ec_encapdata));
    839      1.1  christos #ifndef OPENSSL_NO_ECX
    840      1.1  christos     ADD_ALL_TESTS(test_settables, TEST_KEYTYPES_P256_X25519);
    841      1.1  christos     ADD_ALL_TESTS(test_init_multiple, TEST_KEYTYPES_P256_X25519);
    842      1.1  christos 
    843      1.1  christos     ADD_ALL_TESTS(test_auth_key_type_mismatch, TEST_KEYTYPES_P256_X25519);
    844      1.1  christos     ADD_ALL_TESTS(test_no_operation_set, TEST_KEYTYPES_P256_X25519);
    845      1.1  christos     ADD_ALL_TESTS(test_ikm_small, TEST_KEYTYPES_P256_X25519);
    846      1.1  christos     ADD_ALL_TESTS(test_input_size_small, TEST_KEYTYPES_P256_X25519);
    847      1.1  christos     ADD_ALL_TESTS(test_null_params, TEST_KEYTYPES_P256_X25519);
    848      1.1  christos     ADD_ALL_TESTS(test_set_params, TEST_KEYTYPES_P256_X25519);
    849      1.1  christos     ADD_ALL_TESTS(test_nopublic,
    850  1.1.1.2  christos         TEST_KEM_ENCAP_DECAP * TEST_KEYTYPES_P256_X25519);
    851      1.1  christos     ADD_ALL_TESTS(test_noauthpublic,
    852  1.1.1.2  christos         TEST_KEM_ENCAP_DECAP * TEST_KEYTYPES_P256_X25519);
    853      1.1  christos #else
    854      1.1  christos     ADD_ALL_TESTS(test_settables, TEST_KEYTYPE_P256);
    855      1.1  christos     ADD_ALL_TESTS(test_init_multiple, TEST_KEYTYPE_P256);
    856      1.1  christos 
    857      1.1  christos     ADD_ALL_TESTS(test_auth_key_type_mismatch, TEST_KEYTYPE_P256);
    858      1.1  christos     ADD_ALL_TESTS(test_no_operation_set, TEST_KEYTYPE_P256);
    859      1.1  christos     ADD_ALL_TESTS(test_ikm_small, TEST_KEYTYPE_P256);
    860      1.1  christos     ADD_ALL_TESTS(test_input_size_small, TEST_KEYTYPE_P256);
    861      1.1  christos     ADD_ALL_TESTS(test_null_params, TEST_KEYTYPE_P256);
    862      1.1  christos     ADD_ALL_TESTS(test_set_params, TEST_KEYTYPE_P256);
    863      1.1  christos     ADD_ALL_TESTS(test_nopublic,
    864  1.1.1.2  christos         TEST_KEM_ENCAP_DECAP * TEST_KEYTYPE_P256);
    865      1.1  christos     ADD_ALL_TESTS(test_noauthpublic,
    866  1.1.1.2  christos         TEST_KEM_ENCAP_DECAP * TEST_KEYTYPE_P256);
    867      1.1  christos #endif
    868      1.1  christos     /* EC Specific tests */
    869      1.1  christos     ADD_ALL_TESTS(test_ec_dhkem_derivekey, OSSL_NELEM(ec_derivekey_data));
    870      1.1  christos     ADD_ALL_TESTS(test_ec_noikme,
    871  1.1.1.2  christos         TEST_TYPE_AUTH_NOAUTH * OSSL_NELEM(dhkem_supported_curves));
    872      1.1  christos     ADD_TEST(test_ec_auth_key_curve_mismatch);
    873      1.1  christos     ADD_TEST(test_ec_invalid_private_key);
    874      1.1  christos     ADD_TEST(test_ec_dhkem_derivekey_fail);
    875      1.1  christos     ADD_TEST(test_ec_curve_nonnist);
    876      1.1  christos     ADD_TEST(test_ec_curve_unsupported);
    877      1.1  christos     ADD_TEST(test_ec_invalid_decap_enc_buffer);
    878      1.1  christos     ADD_TEST(test_ec_public_key_infinity);
    879      1.1  christos     ADD_ALL_TESTS(test_ec_badpublic, TEST_KEM_ENCAP_DECAP);
    880      1.1  christos     ADD_ALL_TESTS(test_ec_badauth, TEST_KEM_ENCAP_DECAP);
    881      1.1  christos 
    882      1.1  christos     /* ECX specific tests */
    883      1.1  christos #ifndef OPENSSL_NO_ECX
    884      1.1  christos     ADD_ALL_TESTS(test_ecx_dhkem_derivekey, OSSL_NELEM(ecx_derivekey_data));
    885      1.1  christos     ADD_TEST(test_ecx_auth_key_curve_mismatch);
    886      1.1  christos     ADD_TEST(test_ed_curve_unsupported);
    887      1.1  christos #endif
    888      1.1  christos     return 1;
    889      1.1  christos err:
    890      1.1  christos     return 0;
    891      1.1  christos }
    892      1.1  christos 
    893      1.1  christos void cleanup_tests(void)
    894      1.1  christos {
    895      1.1  christos     EVP_PKEY_free(rkey[1]);
    896      1.1  christos     EVP_PKEY_free(rkey[0]);
    897      1.1  christos     EVP_PKEY_CTX_free(rctx[1]);
    898      1.1  christos     EVP_PKEY_CTX_free(rctx[0]);
    899      1.1  christos     OSSL_PROVIDER_unload(libprov);
    900      1.1  christos     OSSL_LIB_CTX_free(libctx);
    901      1.1  christos     OSSL_PROVIDER_unload(nullprov);
    902      1.1  christos }
    903