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