2 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <openssl/evp.h>
11 #include <openssl/core_names.h>
12 #include <openssl/param_build.h>
13 #include <openssl/proverr.h>
14 #include "internal/nelem.h"
17 #define TEST_KEM_ENCAP 0
18 #define TEST_KEM_DECAP 1
19 #define TEST_KEM_ENCAP_DECAP 2
21 #define TEST_TYPE_AUTH 0
22 #define TEST_TYPE_NOAUTH 1
23 #define TEST_TYPE_AUTH_NOAUTH 2
25 #define TEST_KEYTYPE_P256 0
26 #define TEST_KEYTYPE_X25519 1
27 #define TEST_KEYTYPES_P256_X25519 2
29 static OSSL_LIB_CTX *libctx = NULL;
30 static OSSL_PROVIDER *nullprov = NULL;
31 static OSSL_PROVIDER *libprov = NULL;
32 static OSSL_PARAM opparam[2];
33 static EVP_PKEY *rkey[TEST_KEYTYPES_P256_X25519] = { NULL, NULL };
34 static EVP_PKEY_CTX *rctx[TEST_KEYTYPES_P256_X25519] = { NULL, NULL };
36 #include "dhkem_test.inc"
38 /* Perform encapsulate KAT's */
39 static int test_dhkem_encapsulate(int tstid)
42 EVP_PKEY *rpub = NULL, *spriv = NULL;
43 const TEST_ENCAPDATA *t = &ec_encapdata[tstid];
45 TEST_note("Test %s %s Decapsulate", t->curve,
46 t->spriv != NULL ? "Auth" : "");
48 if (!TEST_ptr(rpub = new_raw_public_key(t->curve, t->rpub, t->rpublen)))
51 if (t->spriv != NULL) {
52 if (!TEST_ptr(spriv = new_raw_private_key(t->curve,
53 t->spriv, t->sprivlen,
54 t->spub, t->spublen)))
57 ret = do_encap(t, rpub, spriv);
64 /* Perform decapsulate KAT's */
65 static int test_dhkem_decapsulate(int tstid)
68 EVP_PKEY *rpriv = NULL, *spub = NULL;
69 const TEST_ENCAPDATA *t = &ec_encapdata[tstid];
71 TEST_note("Test %s %s Decapsulate", t->curve, t->spub != NULL ? "Auth" : "");
73 if (!TEST_ptr(rpriv = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
74 t->rpub, t->rpublen)))
76 if (t->spub != NULL) {
77 if (!TEST_ptr(spub = new_raw_public_key(t->curve, t->spub, t->spublen)))
80 ret = do_decap(t, rpriv, spub);
87 /* Test that there are settables and they have correct data types */
88 static int test_settables(int tstid)
90 EVP_PKEY_CTX *ctx = rctx[tstid];
91 const OSSL_PARAM *settableparams;
94 return TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1)
95 && TEST_ptr(settableparams = EVP_PKEY_CTX_settable_params(ctx))
96 && TEST_ptr(p = OSSL_PARAM_locate_const(settableparams,
97 OSSL_KEM_PARAM_OPERATION))
98 && TEST_uint_eq(p->data_type, OSSL_PARAM_UTF8_STRING)
99 && TEST_ptr(p = OSSL_PARAM_locate_const(settableparams,
100 OSSL_KEM_PARAM_IKME))
101 && TEST_uint_eq(p->data_type, OSSL_PARAM_OCTET_STRING);
104 /* Test initing multiple times passes */
105 static int test_init_multiple(int tstid)
107 EVP_PKEY_CTX *ctx = rctx[tstid];
109 return TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1)
110 && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1)
111 && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), 1)
112 && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), 1);
115 /* Fail is various bad inputs are passed to the derivekey (keygen) operation */
116 static int test_ec_dhkem_derivekey_fail(void)
119 EVP_PKEY *pkey = NULL;
120 OSSL_PARAM params[3];
121 EVP_PKEY_CTX *genctx = NULL;
122 const TEST_DERIVEKEY_DATA *t = &ec_derivekey_data[0];
125 /* Check non nist curve fails */
126 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
128 params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
129 (char *)t->ikm, t->ikmlen);
130 params[2] = OSSL_PARAM_construct_end();
132 if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL))
133 || !TEST_int_eq(EVP_PKEY_keygen_init(genctx), 1)
134 || !TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
135 || !TEST_int_eq(EVP_PKEY_generate(genctx, &pkey),0))
138 /* Fail if curve is not one of P-256, P-384 or P-521 */
139 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
141 params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
142 (char *)t->ikm, t->ikmlen);
143 params[2] = OSSL_PARAM_construct_end();
144 if (!TEST_int_eq(EVP_PKEY_keygen_init(genctx), 1)
145 || !TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
146 || !TEST_int_eq(EVP_PKEY_generate(genctx, &pkey), 0))
149 /* Fail if ikm len is too small*/
150 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
152 params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
153 (char *)t->ikm, t->ikmlen - 1);
154 params[2] = OSSL_PARAM_construct_end();
155 if (!TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
156 || !TEST_int_eq(EVP_PKEY_generate(genctx, &pkey), 0))
163 EVP_PKEY_CTX_free(genctx);
167 /* Fail if the operation parameter is not set */
168 static int test_no_operation_set(int tstid)
170 EVP_PKEY_CTX *ctx = rctx[tstid];
171 const TEST_ENCAPDATA *t = &ec_encapdata[tstid];
174 return TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1)
175 && TEST_int_eq(EVP_PKEY_encapsulate(ctx, NULL, &len, NULL, NULL), -2)
176 && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), 1)
177 && TEST_int_eq(EVP_PKEY_decapsulate(ctx, NULL, &len,
179 t->expected_enclen), -2);
182 /* Fail if the ikm is too small */
183 static int test_ikm_small(int tstid)
185 unsigned char tmp[16] = { 0 };
186 unsigned char secret[256];
187 unsigned char enc[256];
188 size_t secretlen = sizeof(secret);
189 size_t enclen = sizeof(enc);
190 OSSL_PARAM params[3];
191 EVP_PKEY_CTX *ctx = rctx[tstid];
193 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION,
194 OSSL_KEM_PARAM_OPERATION_DHKEM,
196 params[1] = OSSL_PARAM_construct_octet_string(OSSL_KEM_PARAM_IKME,
198 params[2] = OSSL_PARAM_construct_end();
200 return TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, params), 1)
201 && TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc, &enclen,
202 secret, &secretlen), 0);
205 /* Fail if buffers lengths are too small to hold returned data */
206 static int test_input_size_small(int tstid)
209 unsigned char sec[256];
210 unsigned char enc[256];
211 size_t seclen = sizeof(sec);
212 size_t enclen = sizeof(enc);
213 EVP_PKEY_CTX *ctx = rctx[tstid];
215 if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, opparam), 1)
216 || !TEST_int_eq(EVP_PKEY_encapsulate(ctx, NULL, &enclen,
220 /* buffer too small for enc */
222 if (!TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc, &enclen, sec, &seclen),
226 /* buffer too small for secret */
228 if (!TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc, &enclen, sec, &seclen), 0))
231 if (!TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), 1))
233 /* buffer too small for decapsulate secret */
235 if (!TEST_int_eq(EVP_PKEY_decapsulate(ctx, sec, &seclen, enc, enclen), 0))
238 /* incorrect enclen passed to decap */
240 ret = TEST_int_eq(EVP_PKEY_decapsulate(ctx, sec, &seclen, enc, enclen), 0);
245 /* Fail if the auth key has a different curve */
246 static int test_ec_auth_key_curve_mismatch(void)
249 EVP_PKEY *auth = NULL;
251 if (!TEST_ptr(auth = EVP_PKEY_Q_keygen(libctx, NULL, "EC", "P-521")))
254 ret = TEST_int_eq(EVP_PKEY_auth_encapsulate_init(rctx[0], auth, opparam), 0);
259 /* Fail if the auth key has a different key type to the recipient */
260 static int test_auth_key_type_mismatch(int tstid)
265 return TEST_int_eq(EVP_PKEY_auth_encapsulate_init(rctx[id1],
266 rkey[id2], opparam), 0);
269 static int test_ec_invalid_private_key(void)
272 EVP_PKEY *priv = NULL;
273 EVP_PKEY_CTX *ctx = NULL;
274 const TEST_ENCAPDATA *t = &ec_encapdata[0];
275 static const unsigned char order[] = {
276 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
277 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
278 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
281 ret = TEST_ptr(priv = new_raw_private_key("P-256", order, sizeof(order),
282 t->rpub, t->rpublen))
283 && TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, priv, NULL))
284 && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 0);
286 EVP_PKEY_CTX_free(ctx);
290 static int test_ec_public_key_infinity(void)
293 EVP_PKEY *key = NULL;
294 EVP_PKEY_CTX *keyctx = NULL;
295 unsigned char s[256];
296 unsigned char e[256];
297 size_t slen = sizeof(s);
298 size_t elen = sizeof(e);
299 unsigned char tmp[1] = { 0 }; /* The encoding for an EC point at infinity */
300 EVP_PKEY_CTX *ctx = rctx[0];
301 const TEST_ENCAPDATA *t = &ec_encapdata[0];
303 ret = TEST_ptr(key = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
305 && TEST_ptr(keyctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL))
306 /* Fail if the recipient public key is invalid */
307 && TEST_int_eq(EVP_PKEY_encapsulate_init(keyctx, opparam), 1)
308 && TEST_int_eq(EVP_PKEY_encapsulate(keyctx, e, &elen, s, &slen), 0)
309 /* Fail the decap if the recipient public key is invalid */
310 && TEST_int_eq(EVP_PKEY_decapsulate_init(keyctx, opparam), 1)
311 && TEST_int_eq(EVP_PKEY_decapsulate(keyctx, s, &slen,
313 t->expected_enclen), 0)
314 /* Fail if the auth key has a bad public key */
315 && TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, key, opparam), 1)
316 && TEST_int_eq(EVP_PKEY_encapsulate(ctx, e, &elen, s, &slen), 0);
319 EVP_PKEY_CTX_free(keyctx);
323 /* Test incorrectly passing NULL values fail */
324 static int test_null_params(int tstid)
326 EVP_PKEY_CTX *ctx = rctx[tstid];
327 const TEST_ENCAPDATA *t = &ec_encapdata[tstid];
329 /* auth_encap/decap init must be passed a non NULL value */
330 return TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, NULL, opparam), 0)
331 && TEST_int_eq(EVP_PKEY_auth_decapsulate_init(ctx, NULL, opparam), 0)
332 /* Check decap fails if NULL params are passed */
333 && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), 1)
334 && TEST_int_eq(EVP_PKEY_decapsulate(ctx, NULL, NULL,
336 t->expected_enclen), 0)
337 /* Check encap fails if NULL params are passed */
338 && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, opparam), 1)
339 && TEST_int_eq(EVP_PKEY_encapsulate(ctx, NULL, NULL,
343 static int test_set_params(int tstid)
346 EVP_PKEY_CTX *ctx = rctx[tstid];
347 OSSL_PARAM badparams[4];
350 /* wrong data type for operation param */
351 badparams[0] = OSSL_PARAM_construct_int(OSSL_KEM_PARAM_OPERATION, &val);
352 badparams[1] = OSSL_PARAM_construct_end();
353 if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 0))
355 /* unknown string used for the operation param */
356 badparams[0] = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION,
358 badparams[1] = OSSL_PARAM_construct_end();
359 if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 0))
362 /* NULL string set for the operation param */
363 badparams[0] = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION,
365 badparams[1] = OSSL_PARAM_construct_end();
366 if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 0))
369 /* wrong data type for ikme param */
370 badparams[0] = OSSL_PARAM_construct_int(OSSL_KEM_PARAM_IKME, &val);
371 badparams[1] = OSSL_PARAM_construct_end();
372 if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 0))
375 /* Setting the ikme to NULL is allowed */
376 badparams[0] = OSSL_PARAM_construct_octet_string(OSSL_KEM_PARAM_IKME, NULL, 0);
377 badparams[1] = OSSL_PARAM_construct_end();
378 if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 1))
381 /* Test that unknown params are ignored */
382 badparams[0] = OSSL_PARAM_construct_int("unknownparam", &val);
383 badparams[1] = OSSL_PARAM_construct_end();
384 ret = TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, badparams), 1);
390 * ECX keys autogen the public key if a private key is loaded,
391 * So this test passes for ECX, but fails for EC
393 static int test_nopublic(int tstid)
396 EVP_PKEY_CTX *ctx = NULL;
397 EVP_PKEY *priv = NULL;
398 int encap = ((tstid & 1) == 0);
399 int keytype = tstid >= TEST_KEM_ENCAP_DECAP;
400 const TEST_ENCAPDATA *t = &ec_encapdata[keytype];
401 int expected = (keytype == TEST_KEYTYPE_X25519);
403 TEST_note("%s %s", t->curve, encap ? "Encap" : "Decap");
404 if (!TEST_ptr(priv = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
407 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, priv, NULL)))
411 if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, opparam), expected))
414 if (!TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), expected))
418 && !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), PROV_R_NOT_A_PUBLIC_KEY))
423 EVP_PKEY_CTX_free(ctx);
427 /* Test that not setting the auth public key fails the auth encap/decap init */
428 static int test_noauthpublic(int tstid)
431 EVP_PKEY *auth = NULL;
432 int encap = ((tstid & 1) == 0);
433 int keytype = tstid >= TEST_KEM_ENCAP_DECAP;
434 const TEST_ENCAPDATA *t = &ec_encapdata[keytype];
435 EVP_PKEY_CTX *ctx = rctx[keytype];
436 int expected = (keytype == TEST_KEYTYPE_X25519);
438 TEST_note("%s %s", t->curve, encap ? "Encap" : "Decap");
439 if (!TEST_ptr(auth = new_raw_private_key(t->curve, t->rpriv,
440 t->rprivlen, NULL, expected)))
444 if (!TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, auth,
448 if (!TEST_int_eq(EVP_PKEY_auth_decapsulate_init(ctx, auth,
453 && !TEST_int_eq(ERR_GET_REASON(ERR_get_error()),
454 PROV_R_NOT_A_PUBLIC_KEY))
462 /* EC specific tests */
464 /* Perform EC DHKEM KATs */
465 static int test_ec_dhkem_derivekey(int tstid)
468 EVP_PKEY *pkey = NULL;
469 OSSL_PARAM params[3];
470 EVP_PKEY_CTX *genctx = NULL;
471 const TEST_DERIVEKEY_DATA *t = &ec_derivekey_data[tstid];
472 unsigned char pubkey[133];
473 unsigned char privkey[66];
474 size_t pubkeylen = 0, privkeylen = 0;
477 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
478 (char *)t->curvename, 0);
479 params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
480 (char *)t->ikm, t->ikmlen);
481 params[2] = OSSL_PARAM_construct_end();
483 ret = TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL))
484 && TEST_int_eq(EVP_PKEY_keygen_init(genctx), 1)
485 && TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
486 && TEST_int_eq(EVP_PKEY_generate(genctx, &pkey), 1)
487 && TEST_true(EVP_PKEY_get_octet_string_param(pkey,
488 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
489 pubkey, sizeof(pubkey), &pubkeylen))
490 && TEST_true(EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
492 && TEST_int_gt(privkeylen = BN_bn2bin(priv, privkey), 0)
493 && TEST_int_le(privkeylen, sizeof(privkey))
494 && TEST_mem_eq(privkey, privkeylen, t->priv, t->privlen)
495 && TEST_mem_eq(pubkey, pubkeylen, t->pub, t->publen);
499 EVP_PKEY_CTX_free(genctx);
504 * Test that encapsulation uses a random seed if the ikm is not specified,
505 * and verify that the shared secret matches the decapsulate result.
507 static int test_ec_noikme(int tstid)
509 int ret = 0, auth = 0;
510 EVP_PKEY_CTX *ctx = NULL;
511 EVP_PKEY *recip = NULL;
512 EVP_PKEY *sender_auth = NULL;
513 unsigned char sender_secret[256];
514 unsigned char recip_secret[256];
515 unsigned char sender_pub[256];
516 size_t sender_secretlen = sizeof(sender_secret);
517 size_t recip_secretlen = sizeof(recip_secret);
518 size_t sender_publen = sizeof(sender_pub);
520 int sz = OSSL_NELEM(dhkem_supported_curves);
521 const char *op = OSSL_KEM_PARAM_OPERATION_DHKEM;
527 curve = dhkem_supported_curves[tstid];
528 TEST_note("testing encap/decap of curve %s%s\n", curve,
529 auth ? " with auth" : "");
531 if (curve[0] == 'X') {
532 if (!TEST_ptr(recip = EVP_PKEY_Q_keygen(libctx, NULL, curve))
534 && !TEST_ptr(sender_auth = EVP_PKEY_Q_keygen(libctx, NULL,
538 if (!TEST_ptr(recip = EVP_PKEY_Q_keygen(libctx, NULL, "EC", curve))
540 && !TEST_ptr(sender_auth = EVP_PKEY_Q_keygen(libctx, NULL,
545 ret = TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, recip, NULL))
546 && (sender_auth == NULL
547 || TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, sender_auth,
549 && (sender_auth != NULL
550 || TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1))
551 && TEST_int_eq(EVP_PKEY_CTX_set_kem_op(ctx, op), 1)
552 && TEST_int_eq(EVP_PKEY_encapsulate(ctx, sender_pub, &sender_publen,
553 sender_secret, &sender_secretlen), 1)
554 && (sender_auth == NULL
555 || TEST_int_eq(EVP_PKEY_auth_decapsulate_init(ctx, sender_auth,
557 && (sender_auth != NULL
558 || TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), 1))
559 && TEST_int_eq(EVP_PKEY_CTX_set_kem_op(ctx, op), 1)
560 && TEST_int_eq(EVP_PKEY_decapsulate(ctx, recip_secret, &recip_secretlen,
561 sender_pub, sender_publen), 1)
562 && TEST_mem_eq(recip_secret, recip_secretlen,
563 sender_secret, sender_secretlen);
565 EVP_PKEY_CTX_free(ctx);
566 EVP_PKEY_free(sender_auth);
567 EVP_PKEY_free(recip);
571 /* Test encap/decap init fail if the curve is invalid */
572 static int do_ec_curve_failtest(const char *curve)
575 EVP_PKEY *key = NULL;
576 EVP_PKEY_CTX *ctx = NULL;
578 ret = TEST_ptr(key = EVP_PKEY_Q_keygen(libctx, NULL, "EC", curve))
579 && TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL))
580 && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), -2)
581 && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), -2);
583 EVP_PKEY_CTX_free(ctx);
587 static int test_ec_curve_nonnist(void)
589 return do_ec_curve_failtest("secp256k1");
592 static int test_ec_curve_unsupported(void)
594 return do_ec_curve_failtest("P-224");
597 /* Test that passing a bad recipient public EC key fails during encap/decap */
598 static int test_ec_badpublic(int tstid)
601 EVP_PKEY *recippriv = NULL;
602 EVP_PKEY_CTX *ctx = NULL;
603 unsigned char secret[256];
604 unsigned char pub[256];
605 size_t secretlen = sizeof(secret);
606 int encap = ((tstid & 1) == 0);
607 const TEST_ENCAPDATA *t = &ec_encapdata[0];
609 TEST_note("%s %s", t->curve, encap ? "Encap" : "Decap");
610 /* Set the recipient public key to the point at infinity */
612 if (!TEST_ptr(recippriv = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
616 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, recippriv, NULL)))
620 unsigned char enc[256];
621 size_t enclen = sizeof(enc);
623 if (!TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, opparam), 1))
625 if (!TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc , &enclen,
626 secret, &secretlen), 0 ))
629 if (!TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), 1))
631 if (!TEST_int_eq(EVP_PKEY_decapsulate(ctx, secret, &secretlen,
637 if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), PROV_R_INVALID_KEY))
641 EVP_PKEY_free(recippriv);
642 EVP_PKEY_CTX_free(ctx);
646 static int test_ec_badauth(int tstid)
649 EVP_PKEY *auth = NULL;
650 unsigned char enc[256];
651 unsigned char secret[256];
652 unsigned char pub[256];
653 size_t enclen = sizeof(enc);
654 size_t secretlen = sizeof(secret);
655 int encap = ((tstid & 1) == 0);
656 const TEST_ENCAPDATA *t = &ec_encapdata[TEST_KEYTYPE_P256];
657 EVP_PKEY_CTX *ctx = rctx[TEST_KEYTYPE_P256];
659 TEST_note("%s %s", t->curve, encap ? "Encap" : "Decap");
660 /* Set the auth public key to the point at infinity */
662 if (!TEST_ptr(auth = new_raw_private_key(t->curve, t->rpriv, t->rprivlen,
666 if (!TEST_int_eq(EVP_PKEY_auth_encapsulate_init(ctx, auth,
668 || !TEST_int_eq(EVP_PKEY_encapsulate(ctx, enc, &enclen,
669 secret, &secretlen), 0))
672 if (!TEST_int_eq(EVP_PKEY_auth_decapsulate_init(ctx, auth, opparam), 1)
673 || !TEST_int_eq(EVP_PKEY_decapsulate(ctx, secret, &secretlen,
675 t->expected_enclen), 0))
678 if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), PROV_R_INVALID_KEY))
686 static int test_ec_invalid_decap_enc_buffer(void)
688 const TEST_ENCAPDATA *t = &ec_encapdata[TEST_KEYTYPE_P256];
689 unsigned char enc[256];
690 unsigned char secret[256];
691 size_t secretlen = sizeof(secret);
692 EVP_PKEY_CTX *ctx = rctx[0];
694 memcpy(enc, t->expected_enc, t->expected_enclen);
697 return TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, opparam), 1)
698 && TEST_int_eq(EVP_PKEY_decapsulate(ctx, secret, &secretlen,
699 enc, t->expected_enclen), 0);
702 /* ECX specific tests */
704 /* Perform ECX DHKEM KATs */
705 static int test_ecx_dhkem_derivekey(int tstid)
708 OSSL_PARAM params[2];
709 EVP_PKEY_CTX *genctx;
710 EVP_PKEY *pkey = NULL;
711 unsigned char pubkey[64];
712 unsigned char privkey[64];
713 unsigned char masked_priv[64];
714 size_t pubkeylen = 0, privkeylen = 0;
715 const TEST_DERIVEKEY_DATA *t = &ecx_derivekey_data[tstid];
717 memcpy(masked_priv, t->priv, t->privlen);
718 if (OPENSSL_strcasecmp(t->curvename, "X25519") == 0) {
720 * The RFC test vector seems incorrect since it is not in serialized form,
721 * So manually do the conversion here for now.
723 masked_priv[0] &= 248;
724 masked_priv[t->privlen - 1] &= 127;
725 masked_priv[t->privlen - 1] |= 64;
727 masked_priv[0] &= 252;
728 masked_priv[t->privlen - 1] |= 128;
731 params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM,
732 (char *)t->ikm, t->ikmlen);
733 params[1] = OSSL_PARAM_construct_end();
735 ret = TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, t->curvename, NULL))
736 && TEST_int_eq(EVP_PKEY_keygen_init(genctx), 1)
737 && TEST_int_eq(EVP_PKEY_CTX_set_params(genctx, params), 1)
738 && TEST_int_eq(EVP_PKEY_keygen(genctx, &pkey), 1)
739 && TEST_int_eq(EVP_PKEY_get_octet_string_param(pkey,
740 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
741 pubkey, sizeof(pubkey), &pubkeylen), 1)
742 && TEST_int_eq(EVP_PKEY_get_octet_string_param(pkey,
743 OSSL_PKEY_PARAM_PRIV_KEY,
744 privkey, sizeof(privkey), &privkeylen), 1)
745 && TEST_mem_eq(t->pub, t->publen, pubkey, pubkeylen)
746 && TEST_mem_eq(masked_priv, t->privlen, privkey, privkeylen);
749 EVP_PKEY_CTX_free(genctx);
753 /* Fail if the auth key has a different curve */
754 static int test_ecx_auth_key_curve_mismatch(void)
757 EVP_PKEY *auth = NULL;
759 if (!TEST_ptr(auth = EVP_PKEY_Q_keygen(libctx, NULL, "X448")))
762 ret = TEST_int_eq(EVP_PKEY_auth_encapsulate_init(rctx[TEST_KEYTYPE_X25519],
768 /* Fail if ED448 is used for DHKEM */
769 static int test_ed_curve_unsupported(void)
772 EVP_PKEY *key = NULL;
773 EVP_PKEY_CTX *ctx = NULL;
775 ret = TEST_ptr(key = EVP_PKEY_Q_keygen(libctx, NULL, "ED448"))
776 && TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL))
777 && TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), -2)
778 && TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), -2);
780 EVP_PKEY_CTX_free(ctx);
784 int setup_tests(void)
786 const char *prov_name = "default";
787 char *config_file = NULL;
788 char *op = OSSL_KEM_PARAM_OPERATION_DHKEM;
790 if (!test_get_libctx(&libctx, &nullprov, config_file, &libprov, prov_name))
792 opparam[0] = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION,
794 opparam[1] = OSSL_PARAM_construct_end();
796 /* Create P256 and X25519 keys and ctxs */
797 if (!TEST_ptr(rkey[TEST_KEYTYPE_P256] = EVP_PKEY_Q_keygen(libctx, NULL,
800 if (!TEST_ptr(rkey[TEST_KEYTYPE_X25519] = EVP_PKEY_Q_keygen(libctx, NULL,
803 if (!TEST_ptr(rctx[TEST_KEYTYPE_P256] =
804 EVP_PKEY_CTX_new_from_pkey(libctx,
805 rkey[TEST_KEYTYPE_P256], NULL)))
807 if (!TEST_ptr(rctx[TEST_KEYTYPE_X25519] =
808 EVP_PKEY_CTX_new_from_pkey(libctx,
809 rkey[TEST_KEYTYPE_X25519], NULL)))
812 ADD_ALL_TESTS(test_dhkem_encapsulate, OSSL_NELEM(ec_encapdata));
813 ADD_ALL_TESTS(test_dhkem_decapsulate, OSSL_NELEM(ec_encapdata));
814 ADD_ALL_TESTS(test_settables, TEST_KEYTYPES_P256_X25519);
815 ADD_ALL_TESTS(test_init_multiple, TEST_KEYTYPES_P256_X25519);
817 ADD_ALL_TESTS(test_auth_key_type_mismatch, TEST_KEYTYPES_P256_X25519);
818 ADD_ALL_TESTS(test_no_operation_set, TEST_KEYTYPES_P256_X25519);
819 ADD_ALL_TESTS(test_ikm_small, TEST_KEYTYPES_P256_X25519);
820 ADD_ALL_TESTS(test_input_size_small, TEST_KEYTYPES_P256_X25519);
821 ADD_ALL_TESTS(test_null_params, TEST_KEYTYPES_P256_X25519);
822 ADD_ALL_TESTS(test_set_params, TEST_KEYTYPES_P256_X25519);
823 ADD_ALL_TESTS(test_nopublic,
824 TEST_KEM_ENCAP_DECAP * TEST_KEYTYPES_P256_X25519);
825 ADD_ALL_TESTS(test_noauthpublic,
826 TEST_KEM_ENCAP_DECAP * TEST_KEYTYPES_P256_X25519);
828 /* EC Specific tests */
829 ADD_ALL_TESTS(test_ec_dhkem_derivekey, OSSL_NELEM(ec_derivekey_data));
830 ADD_ALL_TESTS(test_ec_noikme,
831 TEST_TYPE_AUTH_NOAUTH * OSSL_NELEM(dhkem_supported_curves));
832 ADD_TEST(test_ec_auth_key_curve_mismatch);
833 ADD_TEST(test_ec_invalid_private_key);
834 ADD_TEST(test_ec_dhkem_derivekey_fail);
835 ADD_TEST(test_ec_curve_nonnist);
836 ADD_TEST(test_ec_curve_unsupported);
837 ADD_TEST(test_ec_invalid_decap_enc_buffer);
838 ADD_TEST(test_ec_public_key_infinity);
839 ADD_ALL_TESTS(test_ec_badpublic, TEST_KEM_ENCAP_DECAP);
840 ADD_ALL_TESTS(test_ec_badauth, TEST_KEM_ENCAP_DECAP);
842 /* ECX specific tests */
843 ADD_ALL_TESTS(test_ecx_dhkem_derivekey, OSSL_NELEM(ecx_derivekey_data));
844 ADD_TEST(test_ecx_auth_key_curve_mismatch);
845 ADD_TEST(test_ed_curve_unsupported);
851 void cleanup_tests(void)
853 EVP_PKEY_free(rkey[1]);
854 EVP_PKEY_free(rkey[0]);
855 EVP_PKEY_CTX_free(rctx[1]);
856 EVP_PKEY_CTX_free(rctx[0]);
857 OSSL_PROVIDER_unload(libprov);
858 OSSL_LIB_CTX_free(libctx);
859 OSSL_PROVIDER_unload(nullprov);