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