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