1 /* 2 * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* 11 * ECDH and ECDSA low level APIs are deprecated for public use, but still ok 12 * for internal use. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <stdio.h> 17 #include "internal/cryptlib.h" 18 #include <openssl/asn1t.h> 19 #include <openssl/x509.h> 20 #include <openssl/ec.h> 21 #include "ec_local.h" 22 #include <openssl/evp.h> 23 #include "crypto/evp.h" 24 25 /* EC pkey context structure */ 26 27 typedef struct { 28 /* Key and paramgen group */ 29 EC_GROUP *gen_group; 30 /* message digest */ 31 const EVP_MD *md; 32 /* Duplicate key if custom cofactor needed */ 33 EC_KEY *co_key; 34 /* Cofactor mode */ 35 signed char cofactor_mode; 36 /* KDF (if any) to use for ECDH */ 37 char kdf_type; 38 /* Message digest to use for key derivation */ 39 const EVP_MD *kdf_md; 40 /* User key material */ 41 unsigned char *kdf_ukm; 42 size_t kdf_ukmlen; 43 /* KDF output length */ 44 size_t kdf_outlen; 45 } EC_PKEY_CTX; 46 47 static int pkey_ec_init(EVP_PKEY_CTX *ctx) 48 { 49 EC_PKEY_CTX *dctx; 50 51 if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) { 52 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 53 return 0; 54 } 55 56 dctx->cofactor_mode = -1; 57 dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE; 58 ctx->data = dctx; 59 return 1; 60 } 61 62 static int pkey_ec_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) 63 { 64 EC_PKEY_CTX *dctx, *sctx; 65 if (!pkey_ec_init(dst)) 66 return 0; 67 sctx = src->data; 68 dctx = dst->data; 69 if (sctx->gen_group) { 70 dctx->gen_group = EC_GROUP_dup(sctx->gen_group); 71 if (!dctx->gen_group) 72 return 0; 73 } 74 dctx->md = sctx->md; 75 76 if (sctx->co_key) { 77 dctx->co_key = EC_KEY_dup(sctx->co_key); 78 if (!dctx->co_key) 79 return 0; 80 } 81 dctx->kdf_type = sctx->kdf_type; 82 dctx->kdf_md = sctx->kdf_md; 83 dctx->kdf_outlen = sctx->kdf_outlen; 84 if (sctx->kdf_ukm) { 85 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen); 86 if (!dctx->kdf_ukm) 87 return 0; 88 } else 89 dctx->kdf_ukm = NULL; 90 dctx->kdf_ukmlen = sctx->kdf_ukmlen; 91 return 1; 92 } 93 94 static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) 95 { 96 EC_PKEY_CTX *dctx = ctx->data; 97 if (dctx != NULL) { 98 EC_GROUP_free(dctx->gen_group); 99 EC_KEY_free(dctx->co_key); 100 OPENSSL_free(dctx->kdf_ukm); 101 OPENSSL_free(dctx); 102 ctx->data = NULL; 103 } 104 } 105 106 static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, 107 const unsigned char *tbs, size_t tbslen) 108 { 109 int ret, type; 110 unsigned int sltmp; 111 EC_PKEY_CTX *dctx = ctx->data; 112 /* 113 * Discard const. Its marked as const because this may be a cached copy of 114 * the "real" key. These calls don't make any modifications that need to 115 * be reflected back in the "original" key. 116 */ 117 EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); 118 const int sig_sz = ECDSA_size(ec); 119 120 /* ensure cast to size_t is safe */ 121 if (!ossl_assert(sig_sz > 0)) 122 return 0; 123 124 if (sig == NULL) { 125 *siglen = (size_t)sig_sz; 126 return 1; 127 } 128 129 if (*siglen < (size_t)sig_sz) { 130 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); 131 return 0; 132 } 133 134 type = (dctx->md != NULL) ? EVP_MD_get_type(dctx->md) : NID_sha1; 135 136 ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); 137 138 if (ret <= 0) 139 return ret; 140 *siglen = (size_t)sltmp; 141 return 1; 142 } 143 144 static int pkey_ec_verify(EVP_PKEY_CTX *ctx, 145 const unsigned char *sig, size_t siglen, 146 const unsigned char *tbs, size_t tbslen) 147 { 148 int ret, type; 149 EC_PKEY_CTX *dctx = ctx->data; 150 /* 151 * Discard const. Its marked as const because this may be a cached copy of 152 * the "real" key. These calls don't make any modifications that need to 153 * be reflected back in the "original" key. 154 */ 155 EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); 156 157 if (dctx->md) 158 type = EVP_MD_get_type(dctx->md); 159 else 160 type = NID_sha1; 161 162 ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); 163 164 return ret; 165 } 166 167 #ifndef OPENSSL_NO_EC 168 static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) 169 { 170 int ret; 171 size_t outlen; 172 const EC_POINT *pubkey = NULL; 173 EC_KEY *eckey; 174 const EC_KEY *eckeypub; 175 EC_PKEY_CTX *dctx = ctx->data; 176 177 if (ctx->pkey == NULL || ctx->peerkey == NULL) { 178 ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET); 179 return 0; 180 } 181 eckeypub = EVP_PKEY_get0_EC_KEY(ctx->peerkey); 182 if (eckeypub == NULL) { 183 ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET); 184 return 0; 185 } 186 187 eckey = dctx->co_key ? dctx->co_key 188 : (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); 189 190 if (!key) { 191 const EC_GROUP *group; 192 group = EC_KEY_get0_group(eckey); 193 194 if (group == NULL) 195 return 0; 196 *keylen = (EC_GROUP_get_degree(group) + 7) / 8; 197 return 1; 198 } 199 pubkey = EC_KEY_get0_public_key(eckeypub); 200 201 /* 202 * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not 203 * an error, the result is truncated. 204 */ 205 206 outlen = *keylen; 207 208 ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); 209 if (ret <= 0) 210 return 0; 211 *keylen = ret; 212 return 1; 213 } 214 215 static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, 216 unsigned char *key, size_t *keylen) 217 { 218 EC_PKEY_CTX *dctx = ctx->data; 219 unsigned char *ktmp = NULL; 220 size_t ktmplen; 221 int rv = 0; 222 if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE) 223 return pkey_ec_derive(ctx, key, keylen); 224 if (!key) { 225 *keylen = dctx->kdf_outlen; 226 return 1; 227 } 228 if (*keylen != dctx->kdf_outlen) 229 return 0; 230 if (!pkey_ec_derive(ctx, NULL, &ktmplen)) 231 return 0; 232 if ((ktmp = OPENSSL_malloc(ktmplen)) == NULL) { 233 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 234 return 0; 235 } 236 if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) 237 goto err; 238 /* Do KDF stuff */ 239 if (!ossl_ecdh_kdf_X9_63(key, *keylen, ktmp, ktmplen, 240 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md, 241 ctx->libctx, ctx->propquery)) 242 goto err; 243 rv = 1; 244 245 err: 246 OPENSSL_clear_free(ktmp, ktmplen); 247 return rv; 248 } 249 #endif 250 251 static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 252 { 253 EC_PKEY_CTX *dctx = ctx->data; 254 EC_GROUP *group; 255 switch (type) { 256 case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: 257 group = EC_GROUP_new_by_curve_name(p1); 258 if (group == NULL) { 259 ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); 260 return 0; 261 } 262 EC_GROUP_free(dctx->gen_group); 263 dctx->gen_group = group; 264 return 1; 265 266 case EVP_PKEY_CTRL_EC_PARAM_ENC: 267 if (!dctx->gen_group) { 268 ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET); 269 return 0; 270 } 271 EC_GROUP_set_asn1_flag(dctx->gen_group, p1); 272 return 1; 273 274 #ifndef OPENSSL_NO_EC 275 case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: 276 if (p1 == -2) { 277 if (dctx->cofactor_mode != -1) 278 return dctx->cofactor_mode; 279 else { 280 const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ctx->pkey); 281 return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0; 282 } 283 } else if (p1 < -1 || p1 > 1) 284 return -2; 285 dctx->cofactor_mode = p1; 286 if (p1 != -1) { 287 EC_KEY *ec_key = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); 288 289 /* 290 * We discarded the "const" above. This will only work if the key is 291 * a "real" legacy key, and not a cached copy of a provided key 292 */ 293 if (evp_pkey_is_provided(ctx->pkey)) { 294 ERR_raise(ERR_LIB_EC, ERR_R_UNSUPPORTED); 295 return 0; 296 } 297 if (!ec_key->group) 298 return -2; 299 /* If cofactor is 1 cofactor mode does nothing */ 300 if (BN_is_one(ec_key->group->cofactor)) 301 return 1; 302 if (!dctx->co_key) { 303 dctx->co_key = EC_KEY_dup(ec_key); 304 if (!dctx->co_key) 305 return 0; 306 } 307 if (p1) 308 EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); 309 else 310 EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); 311 } else { 312 EC_KEY_free(dctx->co_key); 313 dctx->co_key = NULL; 314 } 315 return 1; 316 #endif 317 318 case EVP_PKEY_CTRL_EC_KDF_TYPE: 319 if (p1 == -2) 320 return dctx->kdf_type; 321 if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_63) 322 return -2; 323 dctx->kdf_type = p1; 324 return 1; 325 326 case EVP_PKEY_CTRL_EC_KDF_MD: 327 dctx->kdf_md = p2; 328 return 1; 329 330 case EVP_PKEY_CTRL_GET_EC_KDF_MD: 331 *(const EVP_MD **)p2 = dctx->kdf_md; 332 return 1; 333 334 case EVP_PKEY_CTRL_EC_KDF_OUTLEN: 335 if (p1 <= 0) 336 return -2; 337 dctx->kdf_outlen = (size_t)p1; 338 return 1; 339 340 case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: 341 *(int *)p2 = dctx->kdf_outlen; 342 return 1; 343 344 case EVP_PKEY_CTRL_EC_KDF_UKM: 345 OPENSSL_free(dctx->kdf_ukm); 346 dctx->kdf_ukm = p2; 347 if (p2) 348 dctx->kdf_ukmlen = p1; 349 else 350 dctx->kdf_ukmlen = 0; 351 return 1; 352 353 case EVP_PKEY_CTRL_GET_EC_KDF_UKM: 354 *(unsigned char **)p2 = dctx->kdf_ukm; 355 return dctx->kdf_ukmlen; 356 357 case EVP_PKEY_CTRL_MD: 358 if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 && 359 EVP_MD_get_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && 360 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 && 361 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256 && 362 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha384 && 363 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha512 && 364 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_224 && 365 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_256 && 366 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_384 && 367 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_512 && 368 EVP_MD_get_type((const EVP_MD *)p2) != NID_sm3) { 369 ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE); 370 return 0; 371 } 372 dctx->md = p2; 373 return 1; 374 375 case EVP_PKEY_CTRL_GET_MD: 376 *(const EVP_MD **)p2 = dctx->md; 377 return 1; 378 379 case EVP_PKEY_CTRL_PEER_KEY: 380 /* Default behaviour is OK */ 381 case EVP_PKEY_CTRL_DIGESTINIT: 382 case EVP_PKEY_CTRL_PKCS7_SIGN: 383 case EVP_PKEY_CTRL_CMS_SIGN: 384 return 1; 385 386 default: 387 return -2; 388 389 } 390 } 391 392 static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, 393 const char *type, const char *value) 394 { 395 if (strcmp(type, "ec_paramgen_curve") == 0) { 396 int nid; 397 nid = EC_curve_nist2nid(value); 398 if (nid == NID_undef) 399 nid = OBJ_sn2nid(value); 400 if (nid == NID_undef) 401 nid = OBJ_ln2nid(value); 402 if (nid == NID_undef) { 403 ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); 404 return 0; 405 } 406 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); 407 } else if (strcmp(type, "ec_param_enc") == 0) { 408 int param_enc; 409 if (strcmp(value, "explicit") == 0) 410 param_enc = 0; 411 else if (strcmp(value, "named_curve") == 0) 412 param_enc = OPENSSL_EC_NAMED_CURVE; 413 else 414 return -2; 415 return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); 416 } else if (strcmp(type, "ecdh_kdf_md") == 0) { 417 const EVP_MD *md; 418 if ((md = EVP_get_digestbyname(value)) == NULL) { 419 ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST); 420 return 0; 421 } 422 return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md); 423 } else if (strcmp(type, "ecdh_cofactor_mode") == 0) { 424 int co_mode; 425 co_mode = atoi(value); 426 return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode); 427 } 428 429 return -2; 430 } 431 432 static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 433 { 434 EC_KEY *ec = NULL; 435 EC_PKEY_CTX *dctx = ctx->data; 436 int ret; 437 438 if (dctx->gen_group == NULL) { 439 ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET); 440 return 0; 441 } 442 ec = EC_KEY_new(); 443 if (ec == NULL) 444 return 0; 445 if (!(ret = EC_KEY_set_group(ec, dctx->gen_group)) 446 || !ossl_assert(ret = EVP_PKEY_assign_EC_KEY(pkey, ec))) 447 EC_KEY_free(ec); 448 return ret; 449 } 450 451 static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 452 { 453 EC_KEY *ec = NULL; 454 EC_PKEY_CTX *dctx = ctx->data; 455 int ret; 456 457 if (ctx->pkey == NULL && dctx->gen_group == NULL) { 458 ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET); 459 return 0; 460 } 461 ec = EC_KEY_new(); 462 if (ec == NULL) 463 return 0; 464 if (!ossl_assert(EVP_PKEY_assign_EC_KEY(pkey, ec))) { 465 EC_KEY_free(ec); 466 return 0; 467 } 468 /* Note: if error is returned, we count on caller to free pkey->pkey.ec */ 469 if (ctx->pkey != NULL) 470 ret = EVP_PKEY_copy_parameters(pkey, ctx->pkey); 471 else 472 ret = EC_KEY_set_group(ec, dctx->gen_group); 473 474 return ret ? EC_KEY_generate_key(ec) : 0; 475 } 476 477 static const EVP_PKEY_METHOD ec_pkey_meth = { 478 EVP_PKEY_EC, 479 0, 480 pkey_ec_init, 481 pkey_ec_copy, 482 pkey_ec_cleanup, 483 484 0, 485 pkey_ec_paramgen, 486 487 0, 488 pkey_ec_keygen, 489 490 0, 491 pkey_ec_sign, 492 493 0, 494 pkey_ec_verify, 495 496 0, 0, 497 498 0, 0, 0, 0, 499 500 0, 501 0, 502 503 0, 504 0, 505 506 0, 507 #ifndef OPENSSL_NO_EC 508 pkey_ec_kdf_derive, 509 #else 510 0, 511 #endif 512 pkey_ec_ctrl, 513 pkey_ec_ctrl_str 514 }; 515 516 const EVP_PKEY_METHOD *ossl_ec_pkey_method(void) 517 { 518 return &ec_pkey_meth; 519 } 520