1/* 2 * Copyright 2006-2022 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/x509.h> 19#include <openssl/ec.h> 20#include <openssl/bn.h> 21#include <openssl/asn1t.h> 22#include "crypto/asn1.h" 23#include "crypto/evp.h" 24#include "crypto/x509.h" 25#include <openssl/core_names.h> 26#include <openssl/param_build.h> 27#include "ec_local.h" 28 29static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key) 30{ 31 const EC_GROUP *group; 32 int nid; 33 34 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { 35 ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); 36 return 0; 37 } 38 if (EC_GROUP_get_asn1_flag(group) 39 && (nid = EC_GROUP_get_curve_name(group))) 40 /* we have a 'named curve' => just set the OID */ 41 { 42 ASN1_OBJECT *asn1obj = OBJ_nid2obj(nid); 43 44 if (asn1obj == NULL || OBJ_length(asn1obj) == 0) { 45 ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID); 46 return 0; 47 } 48 *ppval = asn1obj; 49 *pptype = V_ASN1_OBJECT; 50 } else { /* explicit parameters */ 51 52 ASN1_STRING *pstr = NULL; 53 pstr = ASN1_STRING_new(); 54 if (pstr == NULL) 55 return 0; 56 pstr->length = i2d_ECParameters(ec_key, &pstr->data); 57 if (pstr->length <= 0) { 58 ASN1_STRING_free(pstr); 59 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 60 return 0; 61 } 62 *ppval = pstr; 63 *pptype = V_ASN1_SEQUENCE; 64 } 65 return 1; 66} 67 68static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 69{ 70 const EC_KEY *ec_key = pkey->pkey.ec; 71 void *pval = NULL; 72 int ptype; 73 unsigned char *penc = NULL, *p; 74 int penclen; 75 76 if (!eckey_param2type(&ptype, &pval, ec_key)) { 77 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 78 return 0; 79 } 80 penclen = i2o_ECPublicKey(ec_key, NULL); 81 if (penclen <= 0) 82 goto err; 83 penc = OPENSSL_malloc(penclen); 84 if (penc == NULL) 85 goto err; 86 p = penc; 87 penclen = i2o_ECPublicKey(ec_key, &p); 88 if (penclen <= 0) 89 goto err; 90 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), 91 ptype, pval, penc, penclen)) 92 return 1; 93 err: 94 if (ptype == V_ASN1_SEQUENCE) 95 ASN1_STRING_free(pval); 96 OPENSSL_free(penc); 97 return 0; 98} 99 100static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) 101{ 102 const unsigned char *p = NULL; 103 int pklen; 104 EC_KEY *eckey = NULL; 105 X509_ALGOR *palg; 106 OSSL_LIB_CTX *libctx = NULL; 107 const char *propq = NULL; 108 109 if (!ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey) 110 || !X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 111 return 0; 112 eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq); 113 114 if (!eckey) 115 return 0; 116 117 /* We have parameters now set public key */ 118 if (!o2i_ECPublicKey(&eckey, &p, pklen)) { 119 ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); 120 goto ecerr; 121 } 122 123 EVP_PKEY_assign_EC_KEY(pkey, eckey); 124 return 1; 125 126 ecerr: 127 EC_KEY_free(eckey); 128 return 0; 129} 130 131static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 132{ 133 int r; 134 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); 135 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), 136 *pb = EC_KEY_get0_public_key(b->pkey.ec); 137 138 if (group == NULL || pa == NULL || pb == NULL) 139 return -2; 140 r = EC_POINT_cmp(group, pa, pb, NULL); 141 if (r == 0) 142 return 1; 143 if (r == 1) 144 return 0; 145 return -2; 146} 147 148static int eckey_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8, 149 OSSL_LIB_CTX *libctx, const char *propq) 150{ 151 int ret = 0; 152 EC_KEY *eckey = ossl_ec_key_from_pkcs8(p8, libctx, propq); 153 154 if (eckey != NULL) { 155 ret = 1; 156 EVP_PKEY_assign_EC_KEY(pkey, eckey); 157 } 158 159 return ret; 160} 161 162static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 163{ 164 EC_KEY ec_key = *(pkey->pkey.ec); 165 unsigned char *ep = NULL; 166 int eplen, ptype; 167 void *pval; 168 unsigned int old_flags; 169 170 if (!eckey_param2type(&ptype, &pval, &ec_key)) { 171 ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); 172 return 0; 173 } 174 175 /* set the private key */ 176 177 /* 178 * do not include the parameters in the SEC1 private key see PKCS#11 179 * 12.11 180 */ 181 old_flags = EC_KEY_get_enc_flags(&ec_key); 182 EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS); 183 184 eplen = i2d_ECPrivateKey(&ec_key, &ep); 185 if (eplen <= 0) { 186 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 187 goto err; 188 } 189 190 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, 191 ptype, pval, ep, eplen)) { 192 ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 193 OPENSSL_clear_free(ep, eplen); 194 goto err; 195 } 196 197 return 1; 198 199 err: 200 if (ptype == V_ASN1_SEQUENCE) 201 ASN1_STRING_free(pval); 202 return 0; 203} 204 205static int int_ec_size(const EVP_PKEY *pkey) 206{ 207 return ECDSA_size(pkey->pkey.ec); 208} 209 210static int ec_bits(const EVP_PKEY *pkey) 211{ 212 return EC_GROUP_order_bits(EC_KEY_get0_group(pkey->pkey.ec)); 213} 214 215static int ec_security_bits(const EVP_PKEY *pkey) 216{ 217 int ecbits = ec_bits(pkey); 218 219 if (ecbits >= 512) 220 return 256; 221 if (ecbits >= 384) 222 return 192; 223 if (ecbits >= 256) 224 return 128; 225 if (ecbits >= 224) 226 return 112; 227 if (ecbits >= 160) 228 return 80; 229 return ecbits / 2; 230} 231 232static int ec_missing_parameters(const EVP_PKEY *pkey) 233{ 234 if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL) 235 return 1; 236 return 0; 237} 238 239static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 240{ 241 EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); 242 243 if (group == NULL) 244 return 0; 245 if (to->pkey.ec == NULL) { 246 to->pkey.ec = EC_KEY_new(); 247 if (to->pkey.ec == NULL) 248 goto err; 249 } 250 if (EC_KEY_set_group(to->pkey.ec, group) == 0) 251 goto err; 252 EC_GROUP_free(group); 253 return 1; 254 err: 255 EC_GROUP_free(group); 256 return 0; 257} 258 259static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 260{ 261 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), 262 *group_b = EC_KEY_get0_group(b->pkey.ec); 263 264 if (group_a == NULL || group_b == NULL) 265 return -2; 266 if (EC_GROUP_cmp(group_a, group_b, NULL)) 267 return 0; 268 else 269 return 1; 270} 271 272static void int_ec_free(EVP_PKEY *pkey) 273{ 274 EC_KEY_free(pkey->pkey.ec); 275} 276 277typedef enum { 278 EC_KEY_PRINT_PRIVATE, 279 EC_KEY_PRINT_PUBLIC, 280 EC_KEY_PRINT_PARAM 281} ec_print_t; 282 283static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype) 284{ 285 const char *ecstr; 286 unsigned char *priv = NULL, *pub = NULL; 287 size_t privlen = 0, publen = 0; 288 int ret = 0; 289 const EC_GROUP *group; 290 291 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { 292 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 293 return 0; 294 } 295 296 if (ktype != EC_KEY_PRINT_PARAM && EC_KEY_get0_public_key(x) != NULL) { 297 publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL); 298 if (publen == 0) 299 goto err; 300 } 301 302 if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) { 303 privlen = EC_KEY_priv2buf(x, &priv); 304 if (privlen == 0) 305 goto err; 306 } 307 308 if (ktype == EC_KEY_PRINT_PRIVATE) 309 ecstr = "Private-Key"; 310 else if (ktype == EC_KEY_PRINT_PUBLIC) 311 ecstr = "Public-Key"; 312 else 313 ecstr = "ECDSA-Parameters"; 314 315 if (!BIO_indent(bp, off, 128)) 316 goto err; 317 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, 318 EC_GROUP_order_bits(group)) <= 0) 319 goto err; 320 321 if (privlen != 0) { 322 if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0) 323 goto err; 324 if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0) 325 goto err; 326 } 327 328 if (publen != 0) { 329 if (BIO_printf(bp, "%*spub:\n", off, "") <= 0) 330 goto err; 331 if (ASN1_buf_print(bp, pub, publen, off + 4) == 0) 332 goto err; 333 } 334 335 if (!ECPKParameters_print(bp, group, off)) 336 goto err; 337 ret = 1; 338 err: 339 if (!ret) 340 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 341 OPENSSL_clear_free(priv, privlen); 342 OPENSSL_free(pub); 343 return ret; 344} 345 346static int eckey_param_decode(EVP_PKEY *pkey, 347 const unsigned char **pder, int derlen) 348{ 349 EC_KEY *eckey; 350 351 if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) 352 return 0; 353 EVP_PKEY_assign_EC_KEY(pkey, eckey); 354 return 1; 355} 356 357static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 358{ 359 return i2d_ECParameters(pkey->pkey.ec, pder); 360} 361 362static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, 363 ASN1_PCTX *ctx) 364{ 365 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PARAM); 366} 367 368static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 369 ASN1_PCTX *ctx) 370{ 371 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PUBLIC); 372} 373 374static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 375 ASN1_PCTX *ctx) 376{ 377 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PRIVATE); 378} 379 380static int old_ec_priv_decode(EVP_PKEY *pkey, 381 const unsigned char **pder, int derlen) 382{ 383 EC_KEY *ec; 384 385 if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) 386 return 0; 387 EVP_PKEY_assign_EC_KEY(pkey, ec); 388 return 1; 389} 390 391static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) 392{ 393 return i2d_ECPrivateKey(pkey->pkey.ec, pder); 394} 395 396static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 397{ 398 switch (op) { 399 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 400 if (EVP_PKEY_get_id(pkey) == EVP_PKEY_SM2) { 401 /* For SM2, the only valid digest-alg is SM3 */ 402 *(int *)arg2 = NID_sm3; 403 return 2; /* Make it mandatory */ 404 } 405 *(int *)arg2 = NID_sha256; 406 return 1; 407 408 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: 409 /* We should only be here if we have a legacy key */ 410 if (!ossl_assert(evp_pkey_is_legacy(pkey))) 411 return 0; 412 return EC_KEY_oct2key(evp_pkey_get0_EC_KEY_int(pkey), arg2, arg1, NULL); 413 414 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: 415 return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey), 416 POINT_CONVERSION_UNCOMPRESSED, arg2, NULL); 417 418 default: 419 return -2; 420 } 421} 422 423static int ec_pkey_check(const EVP_PKEY *pkey) 424{ 425 EC_KEY *eckey = pkey->pkey.ec; 426 427 /* stay consistent to what EVP_PKEY_check demands */ 428 if (eckey->priv_key == NULL) { 429 ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY); 430 return 0; 431 } 432 433 return EC_KEY_check_key(eckey); 434} 435 436static int ec_pkey_public_check(const EVP_PKEY *pkey) 437{ 438 EC_KEY *eckey = pkey->pkey.ec; 439 440 /* 441 * Note: it unnecessary to check eckey->pub_key here since 442 * it will be checked in EC_KEY_check_key(). In fact, the 443 * EC_KEY_check_key() mainly checks the public key, and checks 444 * the private key optionally (only if there is one). So if 445 * someone passes a whole EC key (public + private), this 446 * will also work... 447 */ 448 449 return EC_KEY_check_key(eckey); 450} 451 452static int ec_pkey_param_check(const EVP_PKEY *pkey) 453{ 454 EC_KEY *eckey = pkey->pkey.ec; 455 456 /* stay consistent to what EVP_PKEY_check demands */ 457 if (eckey->group == NULL) { 458 ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); 459 return 0; 460 } 461 462 return EC_GROUP_check(eckey->group, NULL); 463} 464 465static 466size_t ec_pkey_dirty_cnt(const EVP_PKEY *pkey) 467{ 468 return pkey->pkey.ec->dirty_cnt; 469} 470 471static 472int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata, 473 OSSL_FUNC_keymgmt_import_fn *importer, 474 OSSL_LIB_CTX *libctx, const char *propq) 475{ 476 const EC_KEY *eckey = NULL; 477 const EC_GROUP *ecg = NULL; 478 unsigned char *pub_key_buf = NULL, *gen_buf = NULL; 479 size_t pub_key_buflen; 480 OSSL_PARAM_BLD *tmpl; 481 OSSL_PARAM *params = NULL; 482 const BIGNUM *priv_key = NULL; 483 const EC_POINT *pub_point = NULL; 484 int selection = 0; 485 int rv = 0; 486 BN_CTX *bnctx = NULL; 487 488 if (from == NULL 489 || (eckey = from->pkey.ec) == NULL 490 || (ecg = EC_KEY_get0_group(eckey)) == NULL) 491 return 0; 492 493 tmpl = OSSL_PARAM_BLD_new(); 494 if (tmpl == NULL) 495 return 0; 496 497 /* 498 * EC_POINT_point2buf() can generate random numbers in some 499 * implementations so we need to ensure we use the correct libctx. 500 */ 501 bnctx = BN_CTX_new_ex(libctx); 502 if (bnctx == NULL) 503 goto err; 504 BN_CTX_start(bnctx); 505 506 /* export the domain parameters */ 507 if (!ossl_ec_group_todata(ecg, tmpl, NULL, libctx, propq, bnctx, &gen_buf)) 508 goto err; 509 selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS; 510 511 priv_key = EC_KEY_get0_private_key(eckey); 512 pub_point = EC_KEY_get0_public_key(eckey); 513 514 if (pub_point != NULL) { 515 /* convert pub_point to a octet string according to the SECG standard */ 516 point_conversion_form_t format = EC_KEY_get_conv_form(eckey); 517 518 if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point, 519 format, 520 &pub_key_buf, bnctx)) == 0 521 || !OSSL_PARAM_BLD_push_octet_string(tmpl, 522 OSSL_PKEY_PARAM_PUB_KEY, 523 pub_key_buf, 524 pub_key_buflen)) 525 goto err; 526 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; 527 } 528 529 if (priv_key != NULL) { 530 size_t sz; 531 int ecbits; 532 int ecdh_cofactor_mode; 533 534 /* 535 * Key import/export should never leak the bit length of the secret 536 * scalar in the key. 537 * 538 * For this reason, on export we use padded BIGNUMs with fixed length. 539 * 540 * When importing we also should make sure that, even if short lived, 541 * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as 542 * soon as possible, so that any processing of this BIGNUM might opt for 543 * constant time implementations in the backend. 544 * 545 * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have 546 * to preallocate the BIGNUM internal buffer to a fixed public size big 547 * enough that operations performed during the processing never trigger 548 * a realloc which would leak the size of the scalar through memory 549 * accesses. 550 * 551 * Fixed Length 552 * ------------ 553 * 554 * The order of the large prime subgroup of the curve is our choice for 555 * a fixed public size, as that is generally the upper bound for 556 * generating a private key in EC cryptosystems and should fit all valid 557 * secret scalars. 558 * 559 * For padding on export we just use the bit length of the order 560 * converted to bytes (rounding up). 561 * 562 * For preallocating the BIGNUM storage we look at the number of "words" 563 * required for the internal representation of the order, and we 564 * preallocate 2 extra "words" in case any of the subsequent processing 565 * might temporarily overflow the order length. 566 */ 567 ecbits = EC_GROUP_order_bits(ecg); 568 if (ecbits <= 0) 569 goto err; 570 571 sz = (ecbits + 7 ) / 8; 572 if (!OSSL_PARAM_BLD_push_BN_pad(tmpl, 573 OSSL_PKEY_PARAM_PRIV_KEY, 574 priv_key, sz)) 575 goto err; 576 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY; 577 578 /* 579 * The ECDH Cofactor Mode is defined only if the EC_KEY actually 580 * contains a private key, so we check for the flag and export it only 581 * in this case. 582 */ 583 ecdh_cofactor_mode = 584 (EC_KEY_get_flags(eckey) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; 585 586 /* Export the ECDH_COFACTOR_MODE parameter */ 587 if (!OSSL_PARAM_BLD_push_int(tmpl, 588 OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, 589 ecdh_cofactor_mode)) 590 goto err; 591 selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS; 592 } 593 594 params = OSSL_PARAM_BLD_to_param(tmpl); 595 596 /* We export, the provider imports */ 597 rv = importer(to_keydata, selection, params); 598 599 err: 600 OSSL_PARAM_BLD_free(tmpl); 601 OSSL_PARAM_free(params); 602 OPENSSL_free(pub_key_buf); 603 OPENSSL_free(gen_buf); 604 BN_CTX_end(bnctx); 605 BN_CTX_free(bnctx); 606 return rv; 607} 608 609static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx) 610{ 611 EVP_PKEY_CTX *pctx = vpctx; 612 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); 613 EC_KEY *ec = EC_KEY_new_ex(pctx->libctx, pctx->propquery); 614 615 if (ec == NULL) { 616 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); 617 return 0; 618 } 619 620 if (!ossl_ec_group_fromdata(ec, params) 621 || !ossl_ec_key_otherparams_fromdata(ec, params) 622 || !ossl_ec_key_fromdata(ec, params, 1) 623 || !EVP_PKEY_assign_EC_KEY(pkey, ec)) { 624 EC_KEY_free(ec); 625 return 0; 626 } 627 return 1; 628} 629 630static int ec_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) 631{ 632 EC_KEY *eckey = from->pkey.ec; 633 EC_KEY *dupkey = NULL; 634 int ret; 635 636 if (eckey != NULL) { 637 dupkey = EC_KEY_dup(eckey); 638 if (dupkey == NULL) 639 return 0; 640 } else { 641 /* necessary to properly copy empty SM2 keys */ 642 return EVP_PKEY_set_type(to, from->type); 643 } 644 645 ret = EVP_PKEY_assign_EC_KEY(to, dupkey); 646 if (!ret) 647 EC_KEY_free(dupkey); 648 return ret; 649} 650 651const EVP_PKEY_ASN1_METHOD ossl_eckey_asn1_meth = { 652 EVP_PKEY_EC, 653 EVP_PKEY_EC, 654 0, 655 "EC", 656 "OpenSSL EC algorithm", 657 658 eckey_pub_decode, 659 eckey_pub_encode, 660 eckey_pub_cmp, 661 eckey_pub_print, 662 663 NULL, 664 eckey_priv_encode, 665 eckey_priv_print, 666 667 int_ec_size, 668 ec_bits, 669 ec_security_bits, 670 671 eckey_param_decode, 672 eckey_param_encode, 673 ec_missing_parameters, 674 ec_copy_parameters, 675 ec_cmp_parameters, 676 eckey_param_print, 677 0, 678 679 int_ec_free, 680 ec_pkey_ctrl, 681 old_ec_priv_decode, 682 old_ec_priv_encode, 683 684 0, 0, 0, 685 686 ec_pkey_check, 687 ec_pkey_public_check, 688 ec_pkey_param_check, 689 690 0, /* set_priv_key */ 691 0, /* set_pub_key */ 692 0, /* get_priv_key */ 693 0, /* get_pub_key */ 694 695 ec_pkey_dirty_cnt, 696 ec_pkey_export_to, 697 ec_pkey_import_from, 698 ec_pkey_copy, 699 eckey_priv_decode_ex 700}; 701 702#if !defined(OPENSSL_NO_SM2) 703const EVP_PKEY_ASN1_METHOD ossl_sm2_asn1_meth = { 704 EVP_PKEY_SM2, 705 EVP_PKEY_EC, 706 ASN1_PKEY_ALIAS 707}; 708#endif 709 710int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) 711{ 712 int private = EC_KEY_get0_private_key(x) != NULL; 713 714 return do_EC_KEY_print(bp, x, off, 715 private ? EC_KEY_PRINT_PRIVATE : EC_KEY_PRINT_PUBLIC); 716} 717 718int ECParameters_print(BIO *bp, const EC_KEY *x) 719{ 720 return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM); 721} 722