1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2020-2023 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/ECDSA low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <string.h> 17e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 18e1051a39Sopenharmony_ci#include <openssl/core_names.h> 19e1051a39Sopenharmony_ci#include <openssl/bn.h> 20e1051a39Sopenharmony_ci#include <openssl/err.h> 21e1051a39Sopenharmony_ci#include <openssl/objects.h> 22e1051a39Sopenharmony_ci#include <openssl/proverr.h> 23e1051a39Sopenharmony_ci#include "crypto/bn.h" 24e1051a39Sopenharmony_ci#include "crypto/ec.h" 25e1051a39Sopenharmony_ci#include "prov/implementations.h" 26e1051a39Sopenharmony_ci#include "prov/providercommon.h" 27e1051a39Sopenharmony_ci#include "prov/provider_ctx.h" 28e1051a39Sopenharmony_ci#include "internal/param_build_set.h" 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 31e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 32e1051a39Sopenharmony_ci# include "crypto/sm2.h" 33e1051a39Sopenharmony_ci# endif 34e1051a39Sopenharmony_ci#endif 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_new_fn ec_newdata; 37e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gen_init_fn ec_gen_init; 38e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gen_set_template_fn ec_gen_set_template; 39e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gen_set_params_fn ec_gen_set_params; 40e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gen_settable_params_fn ec_gen_settable_params; 41e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gen_fn ec_gen; 42e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gen_cleanup_fn ec_gen_cleanup; 43e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_load_fn ec_load; 44e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_free_fn ec_freedata; 45e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_get_params_fn ec_get_params; 46e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gettable_params_fn ec_gettable_params; 47e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_set_params_fn ec_set_params; 48e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_settable_params_fn ec_settable_params; 49e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_has_fn ec_has; 50e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_match_fn ec_match; 51e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_validate_fn ec_validate; 52e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_import_fn ec_import; 53e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_import_types_fn ec_import_types; 54e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_export_fn ec_export; 55e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_export_types_fn ec_export_types; 56e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_query_operation_name_fn ec_query_operation_name; 57e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_dup_fn ec_dup; 58e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 59e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 60e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_new_fn sm2_newdata; 61e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gen_init_fn sm2_gen_init; 62e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gen_fn sm2_gen; 63e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_get_params_fn sm2_get_params; 64e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_gettable_params_fn sm2_gettable_params; 65e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_settable_params_fn sm2_settable_params; 66e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_import_fn sm2_import; 67e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_query_operation_name_fn sm2_query_operation_name; 68e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_validate_fn sm2_validate; 69e1051a39Sopenharmony_ci# endif 70e1051a39Sopenharmony_ci#endif 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci#define EC_DEFAULT_MD "SHA256" 73e1051a39Sopenharmony_ci#define EC_POSSIBLE_SELECTIONS \ 74e1051a39Sopenharmony_ci (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) 75e1051a39Sopenharmony_ci#define SM2_DEFAULT_MD "SM3" 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_cistatic 78e1051a39Sopenharmony_ciconst char *ec_query_operation_name(int operation_id) 79e1051a39Sopenharmony_ci{ 80e1051a39Sopenharmony_ci switch (operation_id) { 81e1051a39Sopenharmony_ci case OSSL_OP_KEYEXCH: 82e1051a39Sopenharmony_ci return "ECDH"; 83e1051a39Sopenharmony_ci case OSSL_OP_SIGNATURE: 84e1051a39Sopenharmony_ci return "ECDSA"; 85e1051a39Sopenharmony_ci } 86e1051a39Sopenharmony_ci return NULL; 87e1051a39Sopenharmony_ci} 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 90e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 91e1051a39Sopenharmony_cistatic 92e1051a39Sopenharmony_ciconst char *sm2_query_operation_name(int operation_id) 93e1051a39Sopenharmony_ci{ 94e1051a39Sopenharmony_ci switch (operation_id) { 95e1051a39Sopenharmony_ci case OSSL_OP_SIGNATURE: 96e1051a39Sopenharmony_ci return "SM2"; 97e1051a39Sopenharmony_ci } 98e1051a39Sopenharmony_ci return NULL; 99e1051a39Sopenharmony_ci} 100e1051a39Sopenharmony_ci# endif 101e1051a39Sopenharmony_ci#endif 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_ci/* 104e1051a39Sopenharmony_ci * Callers of key_to_params MUST make sure that domparams_to_params is also 105e1051a39Sopenharmony_ci * called! 106e1051a39Sopenharmony_ci * 107e1051a39Sopenharmony_ci * This function only exports the bare keypair, domain parameters and other 108e1051a39Sopenharmony_ci * parameters are exported separately. 109e1051a39Sopenharmony_ci */ 110e1051a39Sopenharmony_cistatic ossl_inline 111e1051a39Sopenharmony_ciint key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, 112e1051a39Sopenharmony_ci OSSL_PARAM params[], int include_private, 113e1051a39Sopenharmony_ci unsigned char **pub_key) 114e1051a39Sopenharmony_ci{ 115e1051a39Sopenharmony_ci BIGNUM *x = NULL, *y = NULL; 116e1051a39Sopenharmony_ci const BIGNUM *priv_key = NULL; 117e1051a39Sopenharmony_ci const EC_POINT *pub_point = NULL; 118e1051a39Sopenharmony_ci const EC_GROUP *ecg = NULL; 119e1051a39Sopenharmony_ci size_t pub_key_len = 0; 120e1051a39Sopenharmony_ci int ret = 0; 121e1051a39Sopenharmony_ci BN_CTX *bnctx = NULL; 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci if (eckey == NULL 124e1051a39Sopenharmony_ci || (ecg = EC_KEY_get0_group(eckey)) == NULL) 125e1051a39Sopenharmony_ci return 0; 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci priv_key = EC_KEY_get0_private_key(eckey); 128e1051a39Sopenharmony_ci pub_point = EC_KEY_get0_public_key(eckey); 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_ci if (pub_point != NULL) { 131e1051a39Sopenharmony_ci OSSL_PARAM *p = NULL, *px = NULL, *py = NULL; 132e1051a39Sopenharmony_ci /* 133e1051a39Sopenharmony_ci * EC_POINT_point2buf() can generate random numbers in some 134e1051a39Sopenharmony_ci * implementations so we need to ensure we use the correct libctx. 135e1051a39Sopenharmony_ci */ 136e1051a39Sopenharmony_ci bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eckey)); 137e1051a39Sopenharmony_ci if (bnctx == NULL) 138e1051a39Sopenharmony_ci goto err; 139e1051a39Sopenharmony_ci 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci /* If we are doing a get then check first before decoding the point */ 142e1051a39Sopenharmony_ci if (tmpl == NULL) { 143e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY); 144e1051a39Sopenharmony_ci px = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X); 145e1051a39Sopenharmony_ci py = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y); 146e1051a39Sopenharmony_ci } 147e1051a39Sopenharmony_ci 148e1051a39Sopenharmony_ci if (p != NULL || tmpl != NULL) { 149e1051a39Sopenharmony_ci /* convert pub_point to a octet string according to the SECG standard */ 150e1051a39Sopenharmony_ci point_conversion_form_t format = EC_KEY_get_conv_form(eckey); 151e1051a39Sopenharmony_ci 152e1051a39Sopenharmony_ci if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point, 153e1051a39Sopenharmony_ci format, 154e1051a39Sopenharmony_ci pub_key, bnctx)) == 0 155e1051a39Sopenharmony_ci || !ossl_param_build_set_octet_string(tmpl, p, 156e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_PUB_KEY, 157e1051a39Sopenharmony_ci *pub_key, pub_key_len)) 158e1051a39Sopenharmony_ci goto err; 159e1051a39Sopenharmony_ci } 160e1051a39Sopenharmony_ci if (px != NULL || py != NULL) { 161e1051a39Sopenharmony_ci if (px != NULL) { 162e1051a39Sopenharmony_ci x = BN_CTX_get(bnctx); 163e1051a39Sopenharmony_ci if (x == NULL) 164e1051a39Sopenharmony_ci goto err; 165e1051a39Sopenharmony_ci } 166e1051a39Sopenharmony_ci if (py != NULL) { 167e1051a39Sopenharmony_ci y = BN_CTX_get(bnctx); 168e1051a39Sopenharmony_ci if (y == NULL) 169e1051a39Sopenharmony_ci goto err; 170e1051a39Sopenharmony_ci } 171e1051a39Sopenharmony_ci 172e1051a39Sopenharmony_ci if (!EC_POINT_get_affine_coordinates(ecg, pub_point, x, y, bnctx)) 173e1051a39Sopenharmony_ci goto err; 174e1051a39Sopenharmony_ci if (px != NULL 175e1051a39Sopenharmony_ci && !ossl_param_build_set_bn(tmpl, px, 176e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_PUB_X, x)) 177e1051a39Sopenharmony_ci goto err; 178e1051a39Sopenharmony_ci if (py != NULL 179e1051a39Sopenharmony_ci && !ossl_param_build_set_bn(tmpl, py, 180e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_PUB_Y, y)) 181e1051a39Sopenharmony_ci goto err; 182e1051a39Sopenharmony_ci } 183e1051a39Sopenharmony_ci } 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ci if (priv_key != NULL && include_private) { 186e1051a39Sopenharmony_ci size_t sz; 187e1051a39Sopenharmony_ci int ecbits; 188e1051a39Sopenharmony_ci 189e1051a39Sopenharmony_ci /* 190e1051a39Sopenharmony_ci * Key import/export should never leak the bit length of the secret 191e1051a39Sopenharmony_ci * scalar in the key. 192e1051a39Sopenharmony_ci * 193e1051a39Sopenharmony_ci * For this reason, on export we use padded BIGNUMs with fixed length. 194e1051a39Sopenharmony_ci * 195e1051a39Sopenharmony_ci * When importing we also should make sure that, even if short lived, 196e1051a39Sopenharmony_ci * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as 197e1051a39Sopenharmony_ci * soon as possible, so that any processing of this BIGNUM might opt for 198e1051a39Sopenharmony_ci * constant time implementations in the backend. 199e1051a39Sopenharmony_ci * 200e1051a39Sopenharmony_ci * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have 201e1051a39Sopenharmony_ci * to preallocate the BIGNUM internal buffer to a fixed public size big 202e1051a39Sopenharmony_ci * enough that operations performed during the processing never trigger 203e1051a39Sopenharmony_ci * a realloc which would leak the size of the scalar through memory 204e1051a39Sopenharmony_ci * accesses. 205e1051a39Sopenharmony_ci * 206e1051a39Sopenharmony_ci * Fixed Length 207e1051a39Sopenharmony_ci * ------------ 208e1051a39Sopenharmony_ci * 209e1051a39Sopenharmony_ci * The order of the large prime subgroup of the curve is our choice for 210e1051a39Sopenharmony_ci * a fixed public size, as that is generally the upper bound for 211e1051a39Sopenharmony_ci * generating a private key in EC cryptosystems and should fit all valid 212e1051a39Sopenharmony_ci * secret scalars. 213e1051a39Sopenharmony_ci * 214e1051a39Sopenharmony_ci * For padding on export we just use the bit length of the order 215e1051a39Sopenharmony_ci * converted to bytes (rounding up). 216e1051a39Sopenharmony_ci * 217e1051a39Sopenharmony_ci * For preallocating the BIGNUM storage we look at the number of "words" 218e1051a39Sopenharmony_ci * required for the internal representation of the order, and we 219e1051a39Sopenharmony_ci * preallocate 2 extra "words" in case any of the subsequent processing 220e1051a39Sopenharmony_ci * might temporarily overflow the order length. 221e1051a39Sopenharmony_ci */ 222e1051a39Sopenharmony_ci ecbits = EC_GROUP_order_bits(ecg); 223e1051a39Sopenharmony_ci if (ecbits <= 0) 224e1051a39Sopenharmony_ci goto err; 225e1051a39Sopenharmony_ci sz = (ecbits + 7 ) / 8; 226e1051a39Sopenharmony_ci 227e1051a39Sopenharmony_ci if (!ossl_param_build_set_bn_pad(tmpl, params, 228e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_PRIV_KEY, 229e1051a39Sopenharmony_ci priv_key, sz)) 230e1051a39Sopenharmony_ci goto err; 231e1051a39Sopenharmony_ci } 232e1051a39Sopenharmony_ci ret = 1; 233e1051a39Sopenharmony_ci err: 234e1051a39Sopenharmony_ci BN_CTX_free(bnctx); 235e1051a39Sopenharmony_ci return ret; 236e1051a39Sopenharmony_ci} 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_cistatic ossl_inline 239e1051a39Sopenharmony_ciint otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl, 240e1051a39Sopenharmony_ci OSSL_PARAM params[]) 241e1051a39Sopenharmony_ci{ 242e1051a39Sopenharmony_ci int ecdh_cofactor_mode = 0, group_check = 0; 243e1051a39Sopenharmony_ci const char *name = NULL; 244e1051a39Sopenharmony_ci point_conversion_form_t format; 245e1051a39Sopenharmony_ci 246e1051a39Sopenharmony_ci if (ec == NULL) 247e1051a39Sopenharmony_ci return 0; 248e1051a39Sopenharmony_ci 249e1051a39Sopenharmony_ci format = EC_KEY_get_conv_form(ec); 250e1051a39Sopenharmony_ci name = ossl_ec_pt_format_id2name((int)format); 251e1051a39Sopenharmony_ci if (name != NULL 252e1051a39Sopenharmony_ci && !ossl_param_build_set_utf8_string(tmpl, params, 253e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, 254e1051a39Sopenharmony_ci name)) 255e1051a39Sopenharmony_ci return 0; 256e1051a39Sopenharmony_ci 257e1051a39Sopenharmony_ci group_check = EC_KEY_get_flags(ec) & EC_FLAG_CHECK_NAMED_GROUP_MASK; 258e1051a39Sopenharmony_ci name = ossl_ec_check_group_type_id2name(group_check); 259e1051a39Sopenharmony_ci if (name != NULL 260e1051a39Sopenharmony_ci && !ossl_param_build_set_utf8_string(tmpl, params, 261e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, 262e1051a39Sopenharmony_ci name)) 263e1051a39Sopenharmony_ci return 0; 264e1051a39Sopenharmony_ci 265e1051a39Sopenharmony_ci if ((EC_KEY_get_enc_flags(ec) & EC_PKEY_NO_PUBKEY) != 0 266e1051a39Sopenharmony_ci && !ossl_param_build_set_int(tmpl, params, 267e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 0)) 268e1051a39Sopenharmony_ci return 0; 269e1051a39Sopenharmony_ci 270e1051a39Sopenharmony_ci ecdh_cofactor_mode = 271e1051a39Sopenharmony_ci (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; 272e1051a39Sopenharmony_ci return ossl_param_build_set_int(tmpl, params, 273e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, 274e1051a39Sopenharmony_ci ecdh_cofactor_mode); 275e1051a39Sopenharmony_ci} 276e1051a39Sopenharmony_ci 277e1051a39Sopenharmony_cistatic 278e1051a39Sopenharmony_civoid *ec_newdata(void *provctx) 279e1051a39Sopenharmony_ci{ 280e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 281e1051a39Sopenharmony_ci return NULL; 282e1051a39Sopenharmony_ci return EC_KEY_new_ex(PROV_LIBCTX_OF(provctx), NULL); 283e1051a39Sopenharmony_ci} 284e1051a39Sopenharmony_ci 285e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 286e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 287e1051a39Sopenharmony_cistatic 288e1051a39Sopenharmony_civoid *sm2_newdata(void *provctx) 289e1051a39Sopenharmony_ci{ 290e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 291e1051a39Sopenharmony_ci return NULL; 292e1051a39Sopenharmony_ci return EC_KEY_new_by_curve_name_ex(PROV_LIBCTX_OF(provctx), NULL, NID_sm2); 293e1051a39Sopenharmony_ci} 294e1051a39Sopenharmony_ci# endif 295e1051a39Sopenharmony_ci#endif 296e1051a39Sopenharmony_ci 297e1051a39Sopenharmony_cistatic 298e1051a39Sopenharmony_civoid ec_freedata(void *keydata) 299e1051a39Sopenharmony_ci{ 300e1051a39Sopenharmony_ci EC_KEY_free(keydata); 301e1051a39Sopenharmony_ci} 302e1051a39Sopenharmony_ci 303e1051a39Sopenharmony_cistatic 304e1051a39Sopenharmony_ciint ec_has(const void *keydata, int selection) 305e1051a39Sopenharmony_ci{ 306e1051a39Sopenharmony_ci const EC_KEY *ec = keydata; 307e1051a39Sopenharmony_ci int ok = 1; 308e1051a39Sopenharmony_ci 309e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || ec == NULL) 310e1051a39Sopenharmony_ci return 0; 311e1051a39Sopenharmony_ci if ((selection & EC_POSSIBLE_SELECTIONS) == 0) 312e1051a39Sopenharmony_ci return 1; /* the selection is not missing */ 313e1051a39Sopenharmony_ci 314e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 315e1051a39Sopenharmony_ci ok = ok && (EC_KEY_get0_public_key(ec) != NULL); 316e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 317e1051a39Sopenharmony_ci ok = ok && (EC_KEY_get0_private_key(ec) != NULL); 318e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 319e1051a39Sopenharmony_ci ok = ok && (EC_KEY_get0_group(ec) != NULL); 320e1051a39Sopenharmony_ci /* 321e1051a39Sopenharmony_ci * We consider OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS to always be 322e1051a39Sopenharmony_ci * available, so no extra check is needed other than the previous one 323e1051a39Sopenharmony_ci * against EC_POSSIBLE_SELECTIONS. 324e1051a39Sopenharmony_ci */ 325e1051a39Sopenharmony_ci return ok; 326e1051a39Sopenharmony_ci} 327e1051a39Sopenharmony_ci 328e1051a39Sopenharmony_cistatic int ec_match(const void *keydata1, const void *keydata2, int selection) 329e1051a39Sopenharmony_ci{ 330e1051a39Sopenharmony_ci const EC_KEY *ec1 = keydata1; 331e1051a39Sopenharmony_ci const EC_KEY *ec2 = keydata2; 332e1051a39Sopenharmony_ci const EC_GROUP *group_a = EC_KEY_get0_group(ec1); 333e1051a39Sopenharmony_ci const EC_GROUP *group_b = EC_KEY_get0_group(ec2); 334e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 335e1051a39Sopenharmony_ci int ok = 1; 336e1051a39Sopenharmony_ci 337e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 338e1051a39Sopenharmony_ci return 0; 339e1051a39Sopenharmony_ci 340e1051a39Sopenharmony_ci ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec1)); 341e1051a39Sopenharmony_ci if (ctx == NULL) 342e1051a39Sopenharmony_ci return 0; 343e1051a39Sopenharmony_ci 344e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 345e1051a39Sopenharmony_ci ok = ok && group_a != NULL && group_b != NULL 346e1051a39Sopenharmony_ci && EC_GROUP_cmp(group_a, group_b, ctx) == 0; 347e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 348e1051a39Sopenharmony_ci int key_checked = 0; 349e1051a39Sopenharmony_ci 350e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 351e1051a39Sopenharmony_ci const EC_POINT *pa = EC_KEY_get0_public_key(ec1); 352e1051a39Sopenharmony_ci const EC_POINT *pb = EC_KEY_get0_public_key(ec2); 353e1051a39Sopenharmony_ci 354e1051a39Sopenharmony_ci if (pa != NULL && pb != NULL) { 355e1051a39Sopenharmony_ci ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0; 356e1051a39Sopenharmony_ci key_checked = 1; 357e1051a39Sopenharmony_ci } 358e1051a39Sopenharmony_ci } 359e1051a39Sopenharmony_ci if (!key_checked 360e1051a39Sopenharmony_ci && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 361e1051a39Sopenharmony_ci const BIGNUM *pa = EC_KEY_get0_private_key(ec1); 362e1051a39Sopenharmony_ci const BIGNUM *pb = EC_KEY_get0_private_key(ec2); 363e1051a39Sopenharmony_ci 364e1051a39Sopenharmony_ci if (pa != NULL && pb != NULL) { 365e1051a39Sopenharmony_ci ok = ok && BN_cmp(pa, pb) == 0; 366e1051a39Sopenharmony_ci key_checked = 1; 367e1051a39Sopenharmony_ci } 368e1051a39Sopenharmony_ci } 369e1051a39Sopenharmony_ci ok = ok && key_checked; 370e1051a39Sopenharmony_ci } 371e1051a39Sopenharmony_ci BN_CTX_free(ctx); 372e1051a39Sopenharmony_ci return ok; 373e1051a39Sopenharmony_ci} 374e1051a39Sopenharmony_ci 375e1051a39Sopenharmony_cistatic int common_check_sm2(const EC_KEY *ec, int sm2_wanted) 376e1051a39Sopenharmony_ci{ 377e1051a39Sopenharmony_ci const EC_GROUP *ecg = NULL; 378e1051a39Sopenharmony_ci 379e1051a39Sopenharmony_ci /* 380e1051a39Sopenharmony_ci * sm2_wanted: import the keys or domparams only on SM2 Curve 381e1051a39Sopenharmony_ci * !sm2_wanted: import the keys or domparams only not on SM2 Curve 382e1051a39Sopenharmony_ci */ 383e1051a39Sopenharmony_ci if ((ecg = EC_KEY_get0_group(ec)) == NULL 384e1051a39Sopenharmony_ci || (sm2_wanted ^ (EC_GROUP_get_curve_name(ecg) == NID_sm2))) 385e1051a39Sopenharmony_ci return 0; 386e1051a39Sopenharmony_ci return 1; 387e1051a39Sopenharmony_ci} 388e1051a39Sopenharmony_ci 389e1051a39Sopenharmony_cistatic 390e1051a39Sopenharmony_ciint common_import(void *keydata, int selection, const OSSL_PARAM params[], 391e1051a39Sopenharmony_ci int sm2_wanted) 392e1051a39Sopenharmony_ci{ 393e1051a39Sopenharmony_ci EC_KEY *ec = keydata; 394e1051a39Sopenharmony_ci int ok = 1; 395e1051a39Sopenharmony_ci 396e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || ec == NULL) 397e1051a39Sopenharmony_ci return 0; 398e1051a39Sopenharmony_ci 399e1051a39Sopenharmony_ci /* 400e1051a39Sopenharmony_ci * In this implementation, we can export/import only keydata in the 401e1051a39Sopenharmony_ci * following combinations: 402e1051a39Sopenharmony_ci * - domain parameters (+optional other params) 403e1051a39Sopenharmony_ci * - public key with associated domain parameters (+optional other params) 404e1051a39Sopenharmony_ci * - private key with associated domain parameters and optional public key 405e1051a39Sopenharmony_ci * (+optional other params) 406e1051a39Sopenharmony_ci * 407e1051a39Sopenharmony_ci * This means: 408e1051a39Sopenharmony_ci * - domain parameters must always be requested 409e1051a39Sopenharmony_ci * - private key must be requested alongside public key 410e1051a39Sopenharmony_ci * - other parameters are always optional 411e1051a39Sopenharmony_ci */ 412e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0) 413e1051a39Sopenharmony_ci return 0; 414e1051a39Sopenharmony_ci 415e1051a39Sopenharmony_ci ok = ok && ossl_ec_group_fromdata(ec, params); 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_ci if (!common_check_sm2(ec, sm2_wanted)) 418e1051a39Sopenharmony_ci return 0; 419e1051a39Sopenharmony_ci 420e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 421e1051a39Sopenharmony_ci int include_private = 422e1051a39Sopenharmony_ci selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; 423e1051a39Sopenharmony_ci 424e1051a39Sopenharmony_ci ok = ok && ossl_ec_key_fromdata(ec, params, include_private); 425e1051a39Sopenharmony_ci } 426e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) 427e1051a39Sopenharmony_ci ok = ok && ossl_ec_key_otherparams_fromdata(ec, params); 428e1051a39Sopenharmony_ci 429e1051a39Sopenharmony_ci return ok; 430e1051a39Sopenharmony_ci} 431e1051a39Sopenharmony_ci 432e1051a39Sopenharmony_cistatic 433e1051a39Sopenharmony_ciint ec_import(void *keydata, int selection, const OSSL_PARAM params[]) 434e1051a39Sopenharmony_ci{ 435e1051a39Sopenharmony_ci return common_import(keydata, selection, params, 0); 436e1051a39Sopenharmony_ci} 437e1051a39Sopenharmony_ci 438e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 439e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 440e1051a39Sopenharmony_cistatic 441e1051a39Sopenharmony_ciint sm2_import(void *keydata, int selection, const OSSL_PARAM params[]) 442e1051a39Sopenharmony_ci{ 443e1051a39Sopenharmony_ci return common_import(keydata, selection, params, 1); 444e1051a39Sopenharmony_ci} 445e1051a39Sopenharmony_ci# endif 446e1051a39Sopenharmony_ci#endif 447e1051a39Sopenharmony_ci 448e1051a39Sopenharmony_cistatic 449e1051a39Sopenharmony_ciint ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, 450e1051a39Sopenharmony_ci void *cbarg) 451e1051a39Sopenharmony_ci{ 452e1051a39Sopenharmony_ci EC_KEY *ec = keydata; 453e1051a39Sopenharmony_ci OSSL_PARAM_BLD *tmpl = NULL; 454e1051a39Sopenharmony_ci OSSL_PARAM *params = NULL; 455e1051a39Sopenharmony_ci unsigned char *pub_key = NULL, *genbuf = NULL; 456e1051a39Sopenharmony_ci BN_CTX *bnctx = NULL; 457e1051a39Sopenharmony_ci int ok = 1; 458e1051a39Sopenharmony_ci 459e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || ec == NULL) 460e1051a39Sopenharmony_ci return 0; 461e1051a39Sopenharmony_ci 462e1051a39Sopenharmony_ci /* 463e1051a39Sopenharmony_ci * In this implementation, we can export/import only keydata in the 464e1051a39Sopenharmony_ci * following combinations: 465e1051a39Sopenharmony_ci * - domain parameters (+optional other params) 466e1051a39Sopenharmony_ci * - public key with associated domain parameters (+optional other params) 467e1051a39Sopenharmony_ci * - private key with associated public key and domain parameters 468e1051a39Sopenharmony_ci * (+optional other params) 469e1051a39Sopenharmony_ci * 470e1051a39Sopenharmony_ci * This means: 471e1051a39Sopenharmony_ci * - domain parameters must always be requested 472e1051a39Sopenharmony_ci * - private key must be requested alongside public key 473e1051a39Sopenharmony_ci * - other parameters are always optional 474e1051a39Sopenharmony_ci */ 475e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0) 476e1051a39Sopenharmony_ci return 0; 477e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 478e1051a39Sopenharmony_ci && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0) 479e1051a39Sopenharmony_ci return 0; 480e1051a39Sopenharmony_ci 481e1051a39Sopenharmony_ci tmpl = OSSL_PARAM_BLD_new(); 482e1051a39Sopenharmony_ci if (tmpl == NULL) 483e1051a39Sopenharmony_ci return 0; 484e1051a39Sopenharmony_ci 485e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 486e1051a39Sopenharmony_ci bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec)); 487e1051a39Sopenharmony_ci if (bnctx == NULL) { 488e1051a39Sopenharmony_ci ok = 0; 489e1051a39Sopenharmony_ci goto end; 490e1051a39Sopenharmony_ci } 491e1051a39Sopenharmony_ci BN_CTX_start(bnctx); 492e1051a39Sopenharmony_ci ok = ok && ossl_ec_group_todata(EC_KEY_get0_group(ec), tmpl, NULL, 493e1051a39Sopenharmony_ci ossl_ec_key_get_libctx(ec), 494e1051a39Sopenharmony_ci ossl_ec_key_get0_propq(ec), 495e1051a39Sopenharmony_ci bnctx, &genbuf); 496e1051a39Sopenharmony_ci } 497e1051a39Sopenharmony_ci 498e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 499e1051a39Sopenharmony_ci int include_private = 500e1051a39Sopenharmony_ci selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; 501e1051a39Sopenharmony_ci 502e1051a39Sopenharmony_ci ok = ok && key_to_params(ec, tmpl, NULL, include_private, &pub_key); 503e1051a39Sopenharmony_ci } 504e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) 505e1051a39Sopenharmony_ci ok = ok && otherparams_to_params(ec, tmpl, NULL); 506e1051a39Sopenharmony_ci 507e1051a39Sopenharmony_ci if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) { 508e1051a39Sopenharmony_ci ok = 0; 509e1051a39Sopenharmony_ci goto end; 510e1051a39Sopenharmony_ci } 511e1051a39Sopenharmony_ci 512e1051a39Sopenharmony_ci ok = param_cb(params, cbarg); 513e1051a39Sopenharmony_ci OSSL_PARAM_free(params); 514e1051a39Sopenharmony_ciend: 515e1051a39Sopenharmony_ci OSSL_PARAM_BLD_free(tmpl); 516e1051a39Sopenharmony_ci OPENSSL_free(pub_key); 517e1051a39Sopenharmony_ci OPENSSL_free(genbuf); 518e1051a39Sopenharmony_ci BN_CTX_end(bnctx); 519e1051a39Sopenharmony_ci BN_CTX_free(bnctx); 520e1051a39Sopenharmony_ci return ok; 521e1051a39Sopenharmony_ci} 522e1051a39Sopenharmony_ci 523e1051a39Sopenharmony_ci/* IMEXPORT = IMPORT + EXPORT */ 524e1051a39Sopenharmony_ci 525e1051a39Sopenharmony_ci# define EC_IMEXPORTABLE_DOM_PARAMETERS \ 526e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), \ 527e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), \ 528e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0),\ 529e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0), \ 530e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0), \ 531e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0), \ 532e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0), \ 533e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), \ 534e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), \ 535e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), \ 536e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), \ 537e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL) 538e1051a39Sopenharmony_ci 539e1051a39Sopenharmony_ci# define EC_IMEXPORTABLE_PUBLIC_KEY \ 540e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) 541e1051a39Sopenharmony_ci# define EC_IMEXPORTABLE_PRIVATE_KEY \ 542e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) 543e1051a39Sopenharmony_ci# define EC_IMEXPORTABLE_OTHER_PARAMETERS \ 544e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), \ 545e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, NULL) 546e1051a39Sopenharmony_ci 547e1051a39Sopenharmony_ci/* 548e1051a39Sopenharmony_ci * Include all the possible combinations of OSSL_PARAM arrays for 549e1051a39Sopenharmony_ci * ec_imexport_types(). 550e1051a39Sopenharmony_ci * 551e1051a39Sopenharmony_ci * They are in a separate file as it is ~100 lines of unreadable and 552e1051a39Sopenharmony_ci * uninteresting machine generated stuff. 553e1051a39Sopenharmony_ci */ 554e1051a39Sopenharmony_ci#include "ec_kmgmt_imexport.inc" 555e1051a39Sopenharmony_ci 556e1051a39Sopenharmony_cistatic ossl_inline 557e1051a39Sopenharmony_ciconst OSSL_PARAM *ec_imexport_types(int selection) 558e1051a39Sopenharmony_ci{ 559e1051a39Sopenharmony_ci int type_select = 0; 560e1051a39Sopenharmony_ci 561e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 562e1051a39Sopenharmony_ci type_select += 1; 563e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 564e1051a39Sopenharmony_ci type_select += 2; 565e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 566e1051a39Sopenharmony_ci type_select += 4; 567e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) 568e1051a39Sopenharmony_ci type_select += 8; 569e1051a39Sopenharmony_ci return ec_types[type_select]; 570e1051a39Sopenharmony_ci} 571e1051a39Sopenharmony_ci 572e1051a39Sopenharmony_cistatic 573e1051a39Sopenharmony_ciconst OSSL_PARAM *ec_import_types(int selection) 574e1051a39Sopenharmony_ci{ 575e1051a39Sopenharmony_ci return ec_imexport_types(selection); 576e1051a39Sopenharmony_ci} 577e1051a39Sopenharmony_ci 578e1051a39Sopenharmony_cistatic 579e1051a39Sopenharmony_ciconst OSSL_PARAM *ec_export_types(int selection) 580e1051a39Sopenharmony_ci{ 581e1051a39Sopenharmony_ci return ec_imexport_types(selection); 582e1051a39Sopenharmony_ci} 583e1051a39Sopenharmony_ci 584e1051a39Sopenharmony_cistatic int ec_get_ecm_params(const EC_GROUP *group, OSSL_PARAM params[]) 585e1051a39Sopenharmony_ci{ 586e1051a39Sopenharmony_ci#ifdef OPENSSL_NO_EC2M 587e1051a39Sopenharmony_ci return 1; 588e1051a39Sopenharmony_ci#else 589e1051a39Sopenharmony_ci int ret = 0, m; 590e1051a39Sopenharmony_ci unsigned int k1 = 0, k2 = 0, k3 = 0; 591e1051a39Sopenharmony_ci int basis_nid; 592e1051a39Sopenharmony_ci const char *basis_name = NULL; 593e1051a39Sopenharmony_ci int fid = EC_GROUP_get_field_type(group); 594e1051a39Sopenharmony_ci 595e1051a39Sopenharmony_ci if (fid != NID_X9_62_characteristic_two_field) 596e1051a39Sopenharmony_ci return 1; 597e1051a39Sopenharmony_ci 598e1051a39Sopenharmony_ci basis_nid = EC_GROUP_get_basis_type(group); 599e1051a39Sopenharmony_ci if (basis_nid == NID_X9_62_tpBasis) 600e1051a39Sopenharmony_ci basis_name = SN_X9_62_tpBasis; 601e1051a39Sopenharmony_ci else if (basis_nid == NID_X9_62_ppBasis) 602e1051a39Sopenharmony_ci basis_name = SN_X9_62_ppBasis; 603e1051a39Sopenharmony_ci else 604e1051a39Sopenharmony_ci goto err; 605e1051a39Sopenharmony_ci 606e1051a39Sopenharmony_ci m = EC_GROUP_get_degree(group); 607e1051a39Sopenharmony_ci if (!ossl_param_build_set_int(NULL, params, OSSL_PKEY_PARAM_EC_CHAR2_M, m) 608e1051a39Sopenharmony_ci || !ossl_param_build_set_utf8_string(NULL, params, 609e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_CHAR2_TYPE, 610e1051a39Sopenharmony_ci basis_name)) 611e1051a39Sopenharmony_ci goto err; 612e1051a39Sopenharmony_ci 613e1051a39Sopenharmony_ci if (basis_nid == NID_X9_62_tpBasis) { 614e1051a39Sopenharmony_ci if (!EC_GROUP_get_trinomial_basis(group, &k1) 615e1051a39Sopenharmony_ci || !ossl_param_build_set_int(NULL, params, 616e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, 617e1051a39Sopenharmony_ci (int)k1)) 618e1051a39Sopenharmony_ci goto err; 619e1051a39Sopenharmony_ci } else { 620e1051a39Sopenharmony_ci if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3) 621e1051a39Sopenharmony_ci || !ossl_param_build_set_int(NULL, params, 622e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, (int)k1) 623e1051a39Sopenharmony_ci || !ossl_param_build_set_int(NULL, params, 624e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, (int)k2) 625e1051a39Sopenharmony_ci || !ossl_param_build_set_int(NULL, params, 626e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, (int)k3)) 627e1051a39Sopenharmony_ci goto err; 628e1051a39Sopenharmony_ci } 629e1051a39Sopenharmony_ci ret = 1; 630e1051a39Sopenharmony_cierr: 631e1051a39Sopenharmony_ci return ret; 632e1051a39Sopenharmony_ci#endif /* OPENSSL_NO_EC2M */ 633e1051a39Sopenharmony_ci} 634e1051a39Sopenharmony_ci 635e1051a39Sopenharmony_cistatic 636e1051a39Sopenharmony_ciint common_get_params(void *key, OSSL_PARAM params[], int sm2) 637e1051a39Sopenharmony_ci{ 638e1051a39Sopenharmony_ci int ret = 0; 639e1051a39Sopenharmony_ci EC_KEY *eck = key; 640e1051a39Sopenharmony_ci const EC_GROUP *ecg = NULL; 641e1051a39Sopenharmony_ci OSSL_PARAM *p; 642e1051a39Sopenharmony_ci unsigned char *pub_key = NULL, *genbuf = NULL; 643e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx; 644e1051a39Sopenharmony_ci const char *propq; 645e1051a39Sopenharmony_ci BN_CTX *bnctx = NULL; 646e1051a39Sopenharmony_ci 647e1051a39Sopenharmony_ci ecg = EC_KEY_get0_group(eck); 648e1051a39Sopenharmony_ci if (ecg == NULL) { 649e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET); 650e1051a39Sopenharmony_ci return 0; 651e1051a39Sopenharmony_ci } 652e1051a39Sopenharmony_ci 653e1051a39Sopenharmony_ci libctx = ossl_ec_key_get_libctx(eck); 654e1051a39Sopenharmony_ci propq = ossl_ec_key_get0_propq(eck); 655e1051a39Sopenharmony_ci 656e1051a39Sopenharmony_ci bnctx = BN_CTX_new_ex(libctx); 657e1051a39Sopenharmony_ci if (bnctx == NULL) 658e1051a39Sopenharmony_ci return 0; 659e1051a39Sopenharmony_ci BN_CTX_start(bnctx); 660e1051a39Sopenharmony_ci 661e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL 662e1051a39Sopenharmony_ci && !OSSL_PARAM_set_int(p, ECDSA_size(eck))) 663e1051a39Sopenharmony_ci goto err; 664e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL 665e1051a39Sopenharmony_ci && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg))) 666e1051a39Sopenharmony_ci goto err; 667e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL) { 668e1051a39Sopenharmony_ci int ecbits, sec_bits; 669e1051a39Sopenharmony_ci 670e1051a39Sopenharmony_ci ecbits = EC_GROUP_order_bits(ecg); 671e1051a39Sopenharmony_ci 672e1051a39Sopenharmony_ci /* 673e1051a39Sopenharmony_ci * The following estimates are based on the values published 674e1051a39Sopenharmony_ci * in Table 2 of "NIST Special Publication 800-57 Part 1 Revision 4" 675e1051a39Sopenharmony_ci * at http://dx.doi.org/10.6028/NIST.SP.800-57pt1r4 . 676e1051a39Sopenharmony_ci * 677e1051a39Sopenharmony_ci * Note that the above reference explicitly categorizes algorithms in a 678e1051a39Sopenharmony_ci * discrete set of values {80, 112, 128, 192, 256}, and that it is 679e1051a39Sopenharmony_ci * relevant only for NIST approved Elliptic Curves, while OpenSSL 680e1051a39Sopenharmony_ci * applies the same logic also to other curves. 681e1051a39Sopenharmony_ci * 682e1051a39Sopenharmony_ci * Classifications produced by other standardazing bodies might differ, 683e1051a39Sopenharmony_ci * so the results provided for "bits of security" by this provider are 684e1051a39Sopenharmony_ci * to be considered merely indicative, and it is the users' 685e1051a39Sopenharmony_ci * responsibility to compare these values against the normative 686e1051a39Sopenharmony_ci * references that may be relevant for their intent and purposes. 687e1051a39Sopenharmony_ci */ 688e1051a39Sopenharmony_ci if (ecbits >= 512) 689e1051a39Sopenharmony_ci sec_bits = 256; 690e1051a39Sopenharmony_ci else if (ecbits >= 384) 691e1051a39Sopenharmony_ci sec_bits = 192; 692e1051a39Sopenharmony_ci else if (ecbits >= 256) 693e1051a39Sopenharmony_ci sec_bits = 128; 694e1051a39Sopenharmony_ci else if (ecbits >= 224) 695e1051a39Sopenharmony_ci sec_bits = 112; 696e1051a39Sopenharmony_ci else if (ecbits >= 160) 697e1051a39Sopenharmony_ci sec_bits = 80; 698e1051a39Sopenharmony_ci else 699e1051a39Sopenharmony_ci sec_bits = ecbits / 2; 700e1051a39Sopenharmony_ci 701e1051a39Sopenharmony_ci if (!OSSL_PARAM_set_int(p, sec_bits)) 702e1051a39Sopenharmony_ci goto err; 703e1051a39Sopenharmony_ci } 704e1051a39Sopenharmony_ci 705e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, 706e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS)) 707e1051a39Sopenharmony_ci != NULL) { 708e1051a39Sopenharmony_ci int explicitparams = EC_KEY_decoded_from_explicit_params(eck); 709e1051a39Sopenharmony_ci 710e1051a39Sopenharmony_ci if (explicitparams < 0 711e1051a39Sopenharmony_ci || !OSSL_PARAM_set_int(p, explicitparams)) 712e1051a39Sopenharmony_ci goto err; 713e1051a39Sopenharmony_ci } 714e1051a39Sopenharmony_ci 715e1051a39Sopenharmony_ci if (!sm2) { 716e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL 717e1051a39Sopenharmony_ci && !OSSL_PARAM_set_utf8_string(p, EC_DEFAULT_MD)) 718e1051a39Sopenharmony_ci goto err; 719e1051a39Sopenharmony_ci } else { 720e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL 721e1051a39Sopenharmony_ci && !OSSL_PARAM_set_utf8_string(p, SM2_DEFAULT_MD)) 722e1051a39Sopenharmony_ci goto err; 723e1051a39Sopenharmony_ci } 724e1051a39Sopenharmony_ci 725e1051a39Sopenharmony_ci /* SM2 doesn't support this PARAM */ 726e1051a39Sopenharmony_ci if (!sm2) { 727e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH); 728e1051a39Sopenharmony_ci if (p != NULL) { 729e1051a39Sopenharmony_ci int ecdh_cofactor_mode = 0; 730e1051a39Sopenharmony_ci 731e1051a39Sopenharmony_ci ecdh_cofactor_mode = 732e1051a39Sopenharmony_ci (EC_KEY_get_flags(eck) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; 733e1051a39Sopenharmony_ci 734e1051a39Sopenharmony_ci if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode)) 735e1051a39Sopenharmony_ci goto err; 736e1051a39Sopenharmony_ci } 737e1051a39Sopenharmony_ci } 738e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, 739e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) { 740e1051a39Sopenharmony_ci const EC_POINT *ecp = EC_KEY_get0_public_key(key); 741e1051a39Sopenharmony_ci 742e1051a39Sopenharmony_ci if (ecp == NULL) { 743e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 744e1051a39Sopenharmony_ci goto err; 745e1051a39Sopenharmony_ci } 746e1051a39Sopenharmony_ci p->return_size = EC_POINT_point2oct(ecg, ecp, 747e1051a39Sopenharmony_ci POINT_CONVERSION_UNCOMPRESSED, 748e1051a39Sopenharmony_ci p->data, p->data_size, bnctx); 749e1051a39Sopenharmony_ci if (p->return_size == 0) 750e1051a39Sopenharmony_ci goto err; 751e1051a39Sopenharmony_ci } 752e1051a39Sopenharmony_ci 753e1051a39Sopenharmony_ci ret = ec_get_ecm_params(ecg, params) 754e1051a39Sopenharmony_ci && ossl_ec_group_todata(ecg, NULL, params, libctx, propq, bnctx, 755e1051a39Sopenharmony_ci &genbuf) 756e1051a39Sopenharmony_ci && key_to_params(eck, NULL, params, 1, &pub_key) 757e1051a39Sopenharmony_ci && otherparams_to_params(eck, NULL, params); 758e1051a39Sopenharmony_cierr: 759e1051a39Sopenharmony_ci OPENSSL_free(genbuf); 760e1051a39Sopenharmony_ci OPENSSL_free(pub_key); 761e1051a39Sopenharmony_ci BN_CTX_end(bnctx); 762e1051a39Sopenharmony_ci BN_CTX_free(bnctx); 763e1051a39Sopenharmony_ci return ret; 764e1051a39Sopenharmony_ci} 765e1051a39Sopenharmony_ci 766e1051a39Sopenharmony_cistatic 767e1051a39Sopenharmony_ciint ec_get_params(void *key, OSSL_PARAM params[]) 768e1051a39Sopenharmony_ci{ 769e1051a39Sopenharmony_ci return common_get_params(key, params, 0); 770e1051a39Sopenharmony_ci} 771e1051a39Sopenharmony_ci 772e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M 773e1051a39Sopenharmony_ci# define EC2M_GETTABLE_DOM_PARAMS \ 774e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_M, NULL), \ 775e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_CHAR2_TYPE, NULL, 0), \ 776e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, NULL), \ 777e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, NULL), \ 778e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, NULL), \ 779e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, NULL), 780e1051a39Sopenharmony_ci#else 781e1051a39Sopenharmony_ci# define EC2M_GETTABLE_DOM_PARAMS 782e1051a39Sopenharmony_ci#endif 783e1051a39Sopenharmony_ci 784e1051a39Sopenharmony_cistatic const OSSL_PARAM ec_known_gettable_params[] = { 785e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), 786e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), 787e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), 788e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0), 789e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 790e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL), 791e1051a39Sopenharmony_ci EC_IMEXPORTABLE_DOM_PARAMETERS, 792e1051a39Sopenharmony_ci EC2M_GETTABLE_DOM_PARAMS 793e1051a39Sopenharmony_ci EC_IMEXPORTABLE_PUBLIC_KEY, 794e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0), 795e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0), 796e1051a39Sopenharmony_ci EC_IMEXPORTABLE_PRIVATE_KEY, 797e1051a39Sopenharmony_ci EC_IMEXPORTABLE_OTHER_PARAMETERS, 798e1051a39Sopenharmony_ci OSSL_PARAM_END 799e1051a39Sopenharmony_ci}; 800e1051a39Sopenharmony_ci 801e1051a39Sopenharmony_cistatic 802e1051a39Sopenharmony_ciconst OSSL_PARAM *ec_gettable_params(void *provctx) 803e1051a39Sopenharmony_ci{ 804e1051a39Sopenharmony_ci return ec_known_gettable_params; 805e1051a39Sopenharmony_ci} 806e1051a39Sopenharmony_ci 807e1051a39Sopenharmony_cistatic const OSSL_PARAM ec_known_settable_params[] = { 808e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), 809e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 810e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), 811e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0), 812e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), 813e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, NULL), 814e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, NULL, 0), 815e1051a39Sopenharmony_ci OSSL_PARAM_END 816e1051a39Sopenharmony_ci}; 817e1051a39Sopenharmony_ci 818e1051a39Sopenharmony_cistatic 819e1051a39Sopenharmony_ciconst OSSL_PARAM *ec_settable_params(void *provctx) 820e1051a39Sopenharmony_ci{ 821e1051a39Sopenharmony_ci return ec_known_settable_params; 822e1051a39Sopenharmony_ci} 823e1051a39Sopenharmony_ci 824e1051a39Sopenharmony_cistatic 825e1051a39Sopenharmony_ciint ec_set_params(void *key, const OSSL_PARAM params[]) 826e1051a39Sopenharmony_ci{ 827e1051a39Sopenharmony_ci EC_KEY *eck = key; 828e1051a39Sopenharmony_ci const OSSL_PARAM *p; 829e1051a39Sopenharmony_ci 830e1051a39Sopenharmony_ci if (key == NULL) 831e1051a39Sopenharmony_ci return 0; 832e1051a39Sopenharmony_ci if (params == NULL) 833e1051a39Sopenharmony_ci return 1; 834e1051a39Sopenharmony_ci 835e1051a39Sopenharmony_ci 836e1051a39Sopenharmony_ci if (!ossl_ec_group_set_params((EC_GROUP *)EC_KEY_get0_group(key), params)) 837e1051a39Sopenharmony_ci return 0; 838e1051a39Sopenharmony_ci 839e1051a39Sopenharmony_ci p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); 840e1051a39Sopenharmony_ci if (p != NULL) { 841e1051a39Sopenharmony_ci BN_CTX *ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key)); 842e1051a39Sopenharmony_ci int ret = 1; 843e1051a39Sopenharmony_ci 844e1051a39Sopenharmony_ci if (ctx == NULL 845e1051a39Sopenharmony_ci || p->data_type != OSSL_PARAM_OCTET_STRING 846e1051a39Sopenharmony_ci || !EC_KEY_oct2key(key, p->data, p->data_size, ctx)) 847e1051a39Sopenharmony_ci ret = 0; 848e1051a39Sopenharmony_ci BN_CTX_free(ctx); 849e1051a39Sopenharmony_ci if (!ret) 850e1051a39Sopenharmony_ci return 0; 851e1051a39Sopenharmony_ci } 852e1051a39Sopenharmony_ci 853e1051a39Sopenharmony_ci return ossl_ec_key_otherparams_fromdata(eck, params); 854e1051a39Sopenharmony_ci} 855e1051a39Sopenharmony_ci 856e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 857e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 858e1051a39Sopenharmony_cistatic 859e1051a39Sopenharmony_ciint sm2_get_params(void *key, OSSL_PARAM params[]) 860e1051a39Sopenharmony_ci{ 861e1051a39Sopenharmony_ci return common_get_params(key, params, 1); 862e1051a39Sopenharmony_ci} 863e1051a39Sopenharmony_ci 864e1051a39Sopenharmony_cistatic const OSSL_PARAM sm2_known_gettable_params[] = { 865e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), 866e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), 867e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), 868e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0), 869e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 870e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL), 871e1051a39Sopenharmony_ci EC_IMEXPORTABLE_DOM_PARAMETERS, 872e1051a39Sopenharmony_ci EC_IMEXPORTABLE_PUBLIC_KEY, 873e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0), 874e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0), 875e1051a39Sopenharmony_ci EC_IMEXPORTABLE_PRIVATE_KEY, 876e1051a39Sopenharmony_ci OSSL_PARAM_END 877e1051a39Sopenharmony_ci}; 878e1051a39Sopenharmony_ci 879e1051a39Sopenharmony_cistatic 880e1051a39Sopenharmony_ciconst OSSL_PARAM *sm2_gettable_params(ossl_unused void *provctx) 881e1051a39Sopenharmony_ci{ 882e1051a39Sopenharmony_ci return sm2_known_gettable_params; 883e1051a39Sopenharmony_ci} 884e1051a39Sopenharmony_ci 885e1051a39Sopenharmony_cistatic const OSSL_PARAM sm2_known_settable_params[] = { 886e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 887e1051a39Sopenharmony_ci OSSL_PARAM_END 888e1051a39Sopenharmony_ci}; 889e1051a39Sopenharmony_ci 890e1051a39Sopenharmony_cistatic 891e1051a39Sopenharmony_ciconst OSSL_PARAM *sm2_settable_params(ossl_unused void *provctx) 892e1051a39Sopenharmony_ci{ 893e1051a39Sopenharmony_ci return sm2_known_settable_params; 894e1051a39Sopenharmony_ci} 895e1051a39Sopenharmony_ci 896e1051a39Sopenharmony_cistatic 897e1051a39Sopenharmony_ciint sm2_validate(const void *keydata, int selection, int checktype) 898e1051a39Sopenharmony_ci{ 899e1051a39Sopenharmony_ci const EC_KEY *eck = keydata; 900e1051a39Sopenharmony_ci int ok = 1; 901e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 902e1051a39Sopenharmony_ci 903e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 904e1051a39Sopenharmony_ci return 0; 905e1051a39Sopenharmony_ci 906e1051a39Sopenharmony_ci if ((selection & EC_POSSIBLE_SELECTIONS) == 0) 907e1051a39Sopenharmony_ci return 1; /* nothing to validate */ 908e1051a39Sopenharmony_ci 909e1051a39Sopenharmony_ci ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck)); 910e1051a39Sopenharmony_ci if (ctx == NULL) 911e1051a39Sopenharmony_ci return 0; 912e1051a39Sopenharmony_ci 913e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 914e1051a39Sopenharmony_ci ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx); 915e1051a39Sopenharmony_ci 916e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 917e1051a39Sopenharmony_ci if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK) 918e1051a39Sopenharmony_ci ok = ok && ossl_ec_key_public_check_quick(eck, ctx); 919e1051a39Sopenharmony_ci else 920e1051a39Sopenharmony_ci ok = ok && ossl_ec_key_public_check(eck, ctx); 921e1051a39Sopenharmony_ci } 922e1051a39Sopenharmony_ci 923e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 924e1051a39Sopenharmony_ci ok = ok && ossl_sm2_key_private_check(eck); 925e1051a39Sopenharmony_ci 926e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR) 927e1051a39Sopenharmony_ci ok = ok && ossl_ec_key_pairwise_check(eck, ctx); 928e1051a39Sopenharmony_ci 929e1051a39Sopenharmony_ci BN_CTX_free(ctx); 930e1051a39Sopenharmony_ci return ok; 931e1051a39Sopenharmony_ci} 932e1051a39Sopenharmony_ci# endif 933e1051a39Sopenharmony_ci#endif 934e1051a39Sopenharmony_ci 935e1051a39Sopenharmony_cistatic 936e1051a39Sopenharmony_ciint ec_validate(const void *keydata, int selection, int checktype) 937e1051a39Sopenharmony_ci{ 938e1051a39Sopenharmony_ci const EC_KEY *eck = keydata; 939e1051a39Sopenharmony_ci int ok = 1; 940e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 941e1051a39Sopenharmony_ci 942e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 943e1051a39Sopenharmony_ci return 0; 944e1051a39Sopenharmony_ci 945e1051a39Sopenharmony_ci if ((selection & EC_POSSIBLE_SELECTIONS) == 0) 946e1051a39Sopenharmony_ci return 1; /* nothing to validate */ 947e1051a39Sopenharmony_ci 948e1051a39Sopenharmony_ci ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck)); 949e1051a39Sopenharmony_ci if (ctx == NULL) 950e1051a39Sopenharmony_ci return 0; 951e1051a39Sopenharmony_ci 952e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 953e1051a39Sopenharmony_ci int flags = EC_KEY_get_flags(eck); 954e1051a39Sopenharmony_ci 955e1051a39Sopenharmony_ci if ((flags & EC_FLAG_CHECK_NAMED_GROUP) != 0) 956e1051a39Sopenharmony_ci ok = ok && EC_GROUP_check_named_curve(EC_KEY_get0_group(eck), 957e1051a39Sopenharmony_ci (flags & EC_FLAG_CHECK_NAMED_GROUP_NIST) != 0, ctx) > 0; 958e1051a39Sopenharmony_ci else 959e1051a39Sopenharmony_ci ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx); 960e1051a39Sopenharmony_ci } 961e1051a39Sopenharmony_ci 962e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 963e1051a39Sopenharmony_ci if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK) 964e1051a39Sopenharmony_ci ok = ok && ossl_ec_key_public_check_quick(eck, ctx); 965e1051a39Sopenharmony_ci else 966e1051a39Sopenharmony_ci ok = ok && ossl_ec_key_public_check(eck, ctx); 967e1051a39Sopenharmony_ci } 968e1051a39Sopenharmony_ci 969e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 970e1051a39Sopenharmony_ci ok = ok && ossl_ec_key_private_check(eck); 971e1051a39Sopenharmony_ci 972e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR) 973e1051a39Sopenharmony_ci ok = ok && ossl_ec_key_pairwise_check(eck, ctx); 974e1051a39Sopenharmony_ci 975e1051a39Sopenharmony_ci BN_CTX_free(ctx); 976e1051a39Sopenharmony_ci return ok; 977e1051a39Sopenharmony_ci} 978e1051a39Sopenharmony_ci 979e1051a39Sopenharmony_cistruct ec_gen_ctx { 980e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx; 981e1051a39Sopenharmony_ci char *group_name; 982e1051a39Sopenharmony_ci char *encoding; 983e1051a39Sopenharmony_ci char *pt_format; 984e1051a39Sopenharmony_ci char *group_check; 985e1051a39Sopenharmony_ci char *field_type; 986e1051a39Sopenharmony_ci BIGNUM *p, *a, *b, *order, *cofactor; 987e1051a39Sopenharmony_ci unsigned char *gen, *seed; 988e1051a39Sopenharmony_ci size_t gen_len, seed_len; 989e1051a39Sopenharmony_ci int selection; 990e1051a39Sopenharmony_ci int ecdh_mode; 991e1051a39Sopenharmony_ci EC_GROUP *gen_group; 992e1051a39Sopenharmony_ci}; 993e1051a39Sopenharmony_ci 994e1051a39Sopenharmony_cistatic void *ec_gen_init(void *provctx, int selection, 995e1051a39Sopenharmony_ci const OSSL_PARAM params[]) 996e1051a39Sopenharmony_ci{ 997e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); 998e1051a39Sopenharmony_ci struct ec_gen_ctx *gctx = NULL; 999e1051a39Sopenharmony_ci 1000e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || (selection & (EC_POSSIBLE_SELECTIONS)) == 0) 1001e1051a39Sopenharmony_ci return NULL; 1002e1051a39Sopenharmony_ci 1003e1051a39Sopenharmony_ci if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { 1004e1051a39Sopenharmony_ci gctx->libctx = libctx; 1005e1051a39Sopenharmony_ci gctx->selection = selection; 1006e1051a39Sopenharmony_ci gctx->ecdh_mode = 0; 1007e1051a39Sopenharmony_ci if (!ec_gen_set_params(gctx, params)) { 1008e1051a39Sopenharmony_ci OPENSSL_free(gctx); 1009e1051a39Sopenharmony_ci gctx = NULL; 1010e1051a39Sopenharmony_ci } 1011e1051a39Sopenharmony_ci } 1012e1051a39Sopenharmony_ci return gctx; 1013e1051a39Sopenharmony_ci} 1014e1051a39Sopenharmony_ci 1015e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1016e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 1017e1051a39Sopenharmony_cistatic void *sm2_gen_init(void *provctx, int selection, 1018e1051a39Sopenharmony_ci const OSSL_PARAM params[]) 1019e1051a39Sopenharmony_ci{ 1020e1051a39Sopenharmony_ci struct ec_gen_ctx *gctx = ec_gen_init(provctx, selection, params); 1021e1051a39Sopenharmony_ci 1022e1051a39Sopenharmony_ci if (gctx != NULL) { 1023e1051a39Sopenharmony_ci if (gctx->group_name != NULL) 1024e1051a39Sopenharmony_ci return gctx; 1025e1051a39Sopenharmony_ci if ((gctx->group_name = OPENSSL_strdup("sm2")) != NULL) 1026e1051a39Sopenharmony_ci return gctx; 1027e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 1028e1051a39Sopenharmony_ci ec_gen_cleanup(gctx); 1029e1051a39Sopenharmony_ci } 1030e1051a39Sopenharmony_ci return NULL; 1031e1051a39Sopenharmony_ci} 1032e1051a39Sopenharmony_ci# endif 1033e1051a39Sopenharmony_ci#endif 1034e1051a39Sopenharmony_ci 1035e1051a39Sopenharmony_cistatic int ec_gen_set_group(void *genctx, const EC_GROUP *src) 1036e1051a39Sopenharmony_ci{ 1037e1051a39Sopenharmony_ci struct ec_gen_ctx *gctx = genctx; 1038e1051a39Sopenharmony_ci EC_GROUP *group; 1039e1051a39Sopenharmony_ci 1040e1051a39Sopenharmony_ci group = EC_GROUP_dup(src); 1041e1051a39Sopenharmony_ci if (group == NULL) { 1042e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); 1043e1051a39Sopenharmony_ci return 0; 1044e1051a39Sopenharmony_ci } 1045e1051a39Sopenharmony_ci EC_GROUP_free(gctx->gen_group); 1046e1051a39Sopenharmony_ci gctx->gen_group = group; 1047e1051a39Sopenharmony_ci return 1; 1048e1051a39Sopenharmony_ci} 1049e1051a39Sopenharmony_ci 1050e1051a39Sopenharmony_cistatic int ec_gen_set_template(void *genctx, void *templ) 1051e1051a39Sopenharmony_ci{ 1052e1051a39Sopenharmony_ci struct ec_gen_ctx *gctx = genctx; 1053e1051a39Sopenharmony_ci EC_KEY *ec = templ; 1054e1051a39Sopenharmony_ci const EC_GROUP *ec_group; 1055e1051a39Sopenharmony_ci 1056e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || gctx == NULL || ec == NULL) 1057e1051a39Sopenharmony_ci return 0; 1058e1051a39Sopenharmony_ci if ((ec_group = EC_KEY_get0_group(ec)) == NULL) 1059e1051a39Sopenharmony_ci return 0; 1060e1051a39Sopenharmony_ci return ec_gen_set_group(gctx, ec_group); 1061e1051a39Sopenharmony_ci} 1062e1051a39Sopenharmony_ci 1063e1051a39Sopenharmony_ci#define COPY_INT_PARAM(params, key, val) \ 1064e1051a39Sopenharmony_cip = OSSL_PARAM_locate_const(params, key); \ 1065e1051a39Sopenharmony_ciif (p != NULL && !OSSL_PARAM_get_int(p, &val)) \ 1066e1051a39Sopenharmony_ci goto err; 1067e1051a39Sopenharmony_ci 1068e1051a39Sopenharmony_ci#define COPY_UTF8_PARAM(params, key, val) \ 1069e1051a39Sopenharmony_cip = OSSL_PARAM_locate_const(params, key); \ 1070e1051a39Sopenharmony_ciif (p != NULL) { \ 1071e1051a39Sopenharmony_ci if (p->data_type != OSSL_PARAM_UTF8_STRING) \ 1072e1051a39Sopenharmony_ci goto err; \ 1073e1051a39Sopenharmony_ci OPENSSL_free(val); \ 1074e1051a39Sopenharmony_ci val = OPENSSL_strdup(p->data); \ 1075e1051a39Sopenharmony_ci if (val == NULL) \ 1076e1051a39Sopenharmony_ci goto err; \ 1077e1051a39Sopenharmony_ci} 1078e1051a39Sopenharmony_ci 1079e1051a39Sopenharmony_ci#define COPY_OCTET_PARAM(params, key, val, len) \ 1080e1051a39Sopenharmony_cip = OSSL_PARAM_locate_const(params, key); \ 1081e1051a39Sopenharmony_ciif (p != NULL) { \ 1082e1051a39Sopenharmony_ci if (p->data_type != OSSL_PARAM_OCTET_STRING) \ 1083e1051a39Sopenharmony_ci goto err; \ 1084e1051a39Sopenharmony_ci OPENSSL_free(val); \ 1085e1051a39Sopenharmony_ci len = p->data_size; \ 1086e1051a39Sopenharmony_ci val = OPENSSL_memdup(p->data, p->data_size); \ 1087e1051a39Sopenharmony_ci if (val == NULL) \ 1088e1051a39Sopenharmony_ci goto err; \ 1089e1051a39Sopenharmony_ci} 1090e1051a39Sopenharmony_ci 1091e1051a39Sopenharmony_ci#define COPY_BN_PARAM(params, key, bn) \ 1092e1051a39Sopenharmony_cip = OSSL_PARAM_locate_const(params, key); \ 1093e1051a39Sopenharmony_ciif (p != NULL) { \ 1094e1051a39Sopenharmony_ci if (bn == NULL) \ 1095e1051a39Sopenharmony_ci bn = BN_new(); \ 1096e1051a39Sopenharmony_ci if (bn == NULL || !OSSL_PARAM_get_BN(p, &bn)) \ 1097e1051a39Sopenharmony_ci goto err; \ 1098e1051a39Sopenharmony_ci} 1099e1051a39Sopenharmony_ci 1100e1051a39Sopenharmony_cistatic int ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) 1101e1051a39Sopenharmony_ci{ 1102e1051a39Sopenharmony_ci int ret = 0; 1103e1051a39Sopenharmony_ci struct ec_gen_ctx *gctx = genctx; 1104e1051a39Sopenharmony_ci const OSSL_PARAM *p; 1105e1051a39Sopenharmony_ci EC_GROUP *group = NULL; 1106e1051a39Sopenharmony_ci 1107e1051a39Sopenharmony_ci COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode); 1108e1051a39Sopenharmony_ci 1109e1051a39Sopenharmony_ci COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name); 1110e1051a39Sopenharmony_ci COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type); 1111e1051a39Sopenharmony_ci COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding); 1112e1051a39Sopenharmony_ci COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, gctx->pt_format); 1113e1051a39Sopenharmony_ci COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, gctx->group_check); 1114e1051a39Sopenharmony_ci 1115e1051a39Sopenharmony_ci COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_P, gctx->p); 1116e1051a39Sopenharmony_ci COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_A, gctx->a); 1117e1051a39Sopenharmony_ci COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_B, gctx->b); 1118e1051a39Sopenharmony_ci COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_ORDER, gctx->order); 1119e1051a39Sopenharmony_ci COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor); 1120e1051a39Sopenharmony_ci 1121e1051a39Sopenharmony_ci COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len); 1122e1051a39Sopenharmony_ci COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen, 1123e1051a39Sopenharmony_ci gctx->gen_len); 1124e1051a39Sopenharmony_ci 1125e1051a39Sopenharmony_ci ret = 1; 1126e1051a39Sopenharmony_cierr: 1127e1051a39Sopenharmony_ci EC_GROUP_free(group); 1128e1051a39Sopenharmony_ci return ret; 1129e1051a39Sopenharmony_ci} 1130e1051a39Sopenharmony_ci 1131e1051a39Sopenharmony_cistatic int ec_gen_set_group_from_params(struct ec_gen_ctx *gctx) 1132e1051a39Sopenharmony_ci{ 1133e1051a39Sopenharmony_ci int ret = 0; 1134e1051a39Sopenharmony_ci OSSL_PARAM_BLD *bld; 1135e1051a39Sopenharmony_ci OSSL_PARAM *params = NULL; 1136e1051a39Sopenharmony_ci EC_GROUP *group = NULL; 1137e1051a39Sopenharmony_ci 1138e1051a39Sopenharmony_ci bld = OSSL_PARAM_BLD_new(); 1139e1051a39Sopenharmony_ci if (bld == NULL) 1140e1051a39Sopenharmony_ci return 0; 1141e1051a39Sopenharmony_ci 1142e1051a39Sopenharmony_ci if (gctx->encoding != NULL 1143e1051a39Sopenharmony_ci && !OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_ENCODING, 1144e1051a39Sopenharmony_ci gctx->encoding, 0)) 1145e1051a39Sopenharmony_ci goto err; 1146e1051a39Sopenharmony_ci 1147e1051a39Sopenharmony_ci if (gctx->pt_format != NULL 1148e1051a39Sopenharmony_ci && !OSSL_PARAM_BLD_push_utf8_string(bld, 1149e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, 1150e1051a39Sopenharmony_ci gctx->pt_format, 0)) 1151e1051a39Sopenharmony_ci goto err; 1152e1051a39Sopenharmony_ci 1153e1051a39Sopenharmony_ci if (gctx->group_name != NULL) { 1154e1051a39Sopenharmony_ci if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, 1155e1051a39Sopenharmony_ci gctx->group_name, 0)) 1156e1051a39Sopenharmony_ci goto err; 1157e1051a39Sopenharmony_ci /* Ignore any other parameters if there is a group name */ 1158e1051a39Sopenharmony_ci goto build; 1159e1051a39Sopenharmony_ci } else if (gctx->field_type != NULL) { 1160e1051a39Sopenharmony_ci if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_FIELD_TYPE, 1161e1051a39Sopenharmony_ci gctx->field_type, 0)) 1162e1051a39Sopenharmony_ci goto err; 1163e1051a39Sopenharmony_ci } else { 1164e1051a39Sopenharmony_ci goto err; 1165e1051a39Sopenharmony_ci } 1166e1051a39Sopenharmony_ci if (gctx->p == NULL 1167e1051a39Sopenharmony_ci || gctx->a == NULL 1168e1051a39Sopenharmony_ci || gctx->b == NULL 1169e1051a39Sopenharmony_ci || gctx->order == NULL 1170e1051a39Sopenharmony_ci || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, gctx->p) 1171e1051a39Sopenharmony_ci || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, gctx->a) 1172e1051a39Sopenharmony_ci || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, gctx->b) 1173e1051a39Sopenharmony_ci || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER, gctx->order)) 1174e1051a39Sopenharmony_ci goto err; 1175e1051a39Sopenharmony_ci 1176e1051a39Sopenharmony_ci if (gctx->cofactor != NULL 1177e1051a39Sopenharmony_ci && !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR, 1178e1051a39Sopenharmony_ci gctx->cofactor)) 1179e1051a39Sopenharmony_ci goto err; 1180e1051a39Sopenharmony_ci 1181e1051a39Sopenharmony_ci if (gctx->seed != NULL 1182e1051a39Sopenharmony_ci && !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_SEED, 1183e1051a39Sopenharmony_ci gctx->seed, gctx->seed_len)) 1184e1051a39Sopenharmony_ci goto err; 1185e1051a39Sopenharmony_ci 1186e1051a39Sopenharmony_ci if (gctx->gen == NULL 1187e1051a39Sopenharmony_ci || !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_GENERATOR, 1188e1051a39Sopenharmony_ci gctx->gen, gctx->gen_len)) 1189e1051a39Sopenharmony_ci goto err; 1190e1051a39Sopenharmony_cibuild: 1191e1051a39Sopenharmony_ci params = OSSL_PARAM_BLD_to_param(bld); 1192e1051a39Sopenharmony_ci if (params == NULL) 1193e1051a39Sopenharmony_ci goto err; 1194e1051a39Sopenharmony_ci group = EC_GROUP_new_from_params(params, gctx->libctx, NULL); 1195e1051a39Sopenharmony_ci if (group == NULL) 1196e1051a39Sopenharmony_ci goto err; 1197e1051a39Sopenharmony_ci 1198e1051a39Sopenharmony_ci EC_GROUP_free(gctx->gen_group); 1199e1051a39Sopenharmony_ci gctx->gen_group = group; 1200e1051a39Sopenharmony_ci 1201e1051a39Sopenharmony_ci ret = 1; 1202e1051a39Sopenharmony_cierr: 1203e1051a39Sopenharmony_ci OSSL_PARAM_free(params); 1204e1051a39Sopenharmony_ci OSSL_PARAM_BLD_free(bld); 1205e1051a39Sopenharmony_ci return ret; 1206e1051a39Sopenharmony_ci} 1207e1051a39Sopenharmony_ci 1208e1051a39Sopenharmony_cistatic const OSSL_PARAM *ec_gen_settable_params(ossl_unused void *genctx, 1209e1051a39Sopenharmony_ci ossl_unused void *provctx) 1210e1051a39Sopenharmony_ci{ 1211e1051a39Sopenharmony_ci static OSSL_PARAM settable[] = { 1212e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), 1213e1051a39Sopenharmony_ci OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), 1214e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), 1215e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0), 1216e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0), 1217e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0), 1218e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0), 1219e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0), 1220e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), 1221e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), 1222e1051a39Sopenharmony_ci OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), 1223e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), 1224e1051a39Sopenharmony_ci OSSL_PARAM_END 1225e1051a39Sopenharmony_ci }; 1226e1051a39Sopenharmony_ci 1227e1051a39Sopenharmony_ci return settable; 1228e1051a39Sopenharmony_ci} 1229e1051a39Sopenharmony_ci 1230e1051a39Sopenharmony_cistatic int ec_gen_assign_group(EC_KEY *ec, EC_GROUP *group) 1231e1051a39Sopenharmony_ci{ 1232e1051a39Sopenharmony_ci if (group == NULL) { 1233e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET); 1234e1051a39Sopenharmony_ci return 0; 1235e1051a39Sopenharmony_ci } 1236e1051a39Sopenharmony_ci return EC_KEY_set_group(ec, group) > 0; 1237e1051a39Sopenharmony_ci} 1238e1051a39Sopenharmony_ci 1239e1051a39Sopenharmony_ci/* 1240e1051a39Sopenharmony_ci * The callback arguments (osslcb & cbarg) are not used by EC_KEY generation 1241e1051a39Sopenharmony_ci */ 1242e1051a39Sopenharmony_cistatic void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) 1243e1051a39Sopenharmony_ci{ 1244e1051a39Sopenharmony_ci struct ec_gen_ctx *gctx = genctx; 1245e1051a39Sopenharmony_ci EC_KEY *ec = NULL; 1246e1051a39Sopenharmony_ci int ret = 0; 1247e1051a39Sopenharmony_ci 1248e1051a39Sopenharmony_ci if (!ossl_prov_is_running() 1249e1051a39Sopenharmony_ci || gctx == NULL 1250e1051a39Sopenharmony_ci || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL) 1251e1051a39Sopenharmony_ci return NULL; 1252e1051a39Sopenharmony_ci 1253e1051a39Sopenharmony_ci if (gctx->gen_group == NULL) { 1254e1051a39Sopenharmony_ci if (!ec_gen_set_group_from_params(gctx)) 1255e1051a39Sopenharmony_ci goto err; 1256e1051a39Sopenharmony_ci } else { 1257e1051a39Sopenharmony_ci if (gctx->encoding != NULL) { 1258e1051a39Sopenharmony_ci int flags = ossl_ec_encoding_name2id(gctx->encoding); 1259e1051a39Sopenharmony_ci 1260e1051a39Sopenharmony_ci if (flags < 0) 1261e1051a39Sopenharmony_ci goto err; 1262e1051a39Sopenharmony_ci EC_GROUP_set_asn1_flag(gctx->gen_group, flags); 1263e1051a39Sopenharmony_ci } 1264e1051a39Sopenharmony_ci if (gctx->pt_format != NULL) { 1265e1051a39Sopenharmony_ci int format = ossl_ec_pt_format_name2id(gctx->pt_format); 1266e1051a39Sopenharmony_ci 1267e1051a39Sopenharmony_ci if (format < 0) 1268e1051a39Sopenharmony_ci goto err; 1269e1051a39Sopenharmony_ci EC_GROUP_set_point_conversion_form(gctx->gen_group, format); 1270e1051a39Sopenharmony_ci } 1271e1051a39Sopenharmony_ci } 1272e1051a39Sopenharmony_ci 1273e1051a39Sopenharmony_ci /* We must always assign a group, no matter what */ 1274e1051a39Sopenharmony_ci ret = ec_gen_assign_group(ec, gctx->gen_group); 1275e1051a39Sopenharmony_ci 1276e1051a39Sopenharmony_ci /* Whether you want it or not, you get a keypair, not just one half */ 1277e1051a39Sopenharmony_ci if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) 1278e1051a39Sopenharmony_ci ret = ret && EC_KEY_generate_key(ec); 1279e1051a39Sopenharmony_ci 1280e1051a39Sopenharmony_ci if (gctx->ecdh_mode != -1) 1281e1051a39Sopenharmony_ci ret = ret && ossl_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode); 1282e1051a39Sopenharmony_ci 1283e1051a39Sopenharmony_ci if (gctx->group_check != NULL) 1284e1051a39Sopenharmony_ci ret = ret && ossl_ec_set_check_group_type_from_name(ec, gctx->group_check); 1285e1051a39Sopenharmony_ci if (ret) 1286e1051a39Sopenharmony_ci return ec; 1287e1051a39Sopenharmony_cierr: 1288e1051a39Sopenharmony_ci /* Something went wrong, throw the key away */ 1289e1051a39Sopenharmony_ci EC_KEY_free(ec); 1290e1051a39Sopenharmony_ci return NULL; 1291e1051a39Sopenharmony_ci} 1292e1051a39Sopenharmony_ci 1293e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1294e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 1295e1051a39Sopenharmony_ci/* 1296e1051a39Sopenharmony_ci * The callback arguments (osslcb & cbarg) are not used by EC_KEY generation 1297e1051a39Sopenharmony_ci */ 1298e1051a39Sopenharmony_cistatic void *sm2_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) 1299e1051a39Sopenharmony_ci{ 1300e1051a39Sopenharmony_ci struct ec_gen_ctx *gctx = genctx; 1301e1051a39Sopenharmony_ci EC_KEY *ec = NULL; 1302e1051a39Sopenharmony_ci int ret = 1; 1303e1051a39Sopenharmony_ci 1304e1051a39Sopenharmony_ci if (gctx == NULL 1305e1051a39Sopenharmony_ci || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL) 1306e1051a39Sopenharmony_ci return NULL; 1307e1051a39Sopenharmony_ci 1308e1051a39Sopenharmony_ci if (gctx->gen_group == NULL) { 1309e1051a39Sopenharmony_ci if (!ec_gen_set_group_from_params(gctx)) 1310e1051a39Sopenharmony_ci goto err; 1311e1051a39Sopenharmony_ci } else { 1312e1051a39Sopenharmony_ci if (gctx->encoding) { 1313e1051a39Sopenharmony_ci int flags = ossl_ec_encoding_name2id(gctx->encoding); 1314e1051a39Sopenharmony_ci 1315e1051a39Sopenharmony_ci if (flags < 0) 1316e1051a39Sopenharmony_ci goto err; 1317e1051a39Sopenharmony_ci EC_GROUP_set_asn1_flag(gctx->gen_group, flags); 1318e1051a39Sopenharmony_ci } 1319e1051a39Sopenharmony_ci if (gctx->pt_format != NULL) { 1320e1051a39Sopenharmony_ci int format = ossl_ec_pt_format_name2id(gctx->pt_format); 1321e1051a39Sopenharmony_ci 1322e1051a39Sopenharmony_ci if (format < 0) 1323e1051a39Sopenharmony_ci goto err; 1324e1051a39Sopenharmony_ci EC_GROUP_set_point_conversion_form(gctx->gen_group, format); 1325e1051a39Sopenharmony_ci } 1326e1051a39Sopenharmony_ci } 1327e1051a39Sopenharmony_ci 1328e1051a39Sopenharmony_ci /* We must always assign a group, no matter what */ 1329e1051a39Sopenharmony_ci ret = ec_gen_assign_group(ec, gctx->gen_group); 1330e1051a39Sopenharmony_ci 1331e1051a39Sopenharmony_ci /* Whether you want it or not, you get a keypair, not just one half */ 1332e1051a39Sopenharmony_ci if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) 1333e1051a39Sopenharmony_ci ret = ret && EC_KEY_generate_key(ec); 1334e1051a39Sopenharmony_ci 1335e1051a39Sopenharmony_ci if (ret) 1336e1051a39Sopenharmony_ci return ec; 1337e1051a39Sopenharmony_cierr: 1338e1051a39Sopenharmony_ci /* Something went wrong, throw the key away */ 1339e1051a39Sopenharmony_ci EC_KEY_free(ec); 1340e1051a39Sopenharmony_ci return NULL; 1341e1051a39Sopenharmony_ci} 1342e1051a39Sopenharmony_ci# endif 1343e1051a39Sopenharmony_ci#endif 1344e1051a39Sopenharmony_ci 1345e1051a39Sopenharmony_cistatic void ec_gen_cleanup(void *genctx) 1346e1051a39Sopenharmony_ci{ 1347e1051a39Sopenharmony_ci struct ec_gen_ctx *gctx = genctx; 1348e1051a39Sopenharmony_ci 1349e1051a39Sopenharmony_ci if (gctx == NULL) 1350e1051a39Sopenharmony_ci return; 1351e1051a39Sopenharmony_ci 1352e1051a39Sopenharmony_ci EC_GROUP_free(gctx->gen_group); 1353e1051a39Sopenharmony_ci BN_free(gctx->p); 1354e1051a39Sopenharmony_ci BN_free(gctx->a); 1355e1051a39Sopenharmony_ci BN_free(gctx->b); 1356e1051a39Sopenharmony_ci BN_free(gctx->order); 1357e1051a39Sopenharmony_ci BN_free(gctx->cofactor); 1358e1051a39Sopenharmony_ci OPENSSL_free(gctx->group_name); 1359e1051a39Sopenharmony_ci OPENSSL_free(gctx->field_type); 1360e1051a39Sopenharmony_ci OPENSSL_free(gctx->pt_format); 1361e1051a39Sopenharmony_ci OPENSSL_free(gctx->encoding); 1362e1051a39Sopenharmony_ci OPENSSL_free(gctx->seed); 1363e1051a39Sopenharmony_ci OPENSSL_free(gctx->gen); 1364e1051a39Sopenharmony_ci OPENSSL_free(gctx); 1365e1051a39Sopenharmony_ci} 1366e1051a39Sopenharmony_ci 1367e1051a39Sopenharmony_cistatic void *common_load(const void *reference, size_t reference_sz, 1368e1051a39Sopenharmony_ci int sm2_wanted) 1369e1051a39Sopenharmony_ci{ 1370e1051a39Sopenharmony_ci EC_KEY *ec = NULL; 1371e1051a39Sopenharmony_ci 1372e1051a39Sopenharmony_ci if (ossl_prov_is_running() && reference_sz == sizeof(ec)) { 1373e1051a39Sopenharmony_ci /* The contents of the reference is the address to our object */ 1374e1051a39Sopenharmony_ci ec = *(EC_KEY **)reference; 1375e1051a39Sopenharmony_ci 1376e1051a39Sopenharmony_ci if (!common_check_sm2(ec, sm2_wanted)) 1377e1051a39Sopenharmony_ci return NULL; 1378e1051a39Sopenharmony_ci 1379e1051a39Sopenharmony_ci /* We grabbed, so we detach it */ 1380e1051a39Sopenharmony_ci *(EC_KEY **)reference = NULL; 1381e1051a39Sopenharmony_ci return ec; 1382e1051a39Sopenharmony_ci } 1383e1051a39Sopenharmony_ci return NULL; 1384e1051a39Sopenharmony_ci} 1385e1051a39Sopenharmony_ci 1386e1051a39Sopenharmony_cistatic void *ec_load(const void *reference, size_t reference_sz) 1387e1051a39Sopenharmony_ci{ 1388e1051a39Sopenharmony_ci return common_load(reference, reference_sz, 0); 1389e1051a39Sopenharmony_ci} 1390e1051a39Sopenharmony_ci 1391e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1392e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 1393e1051a39Sopenharmony_cistatic void *sm2_load(const void *reference, size_t reference_sz) 1394e1051a39Sopenharmony_ci{ 1395e1051a39Sopenharmony_ci return common_load(reference, reference_sz, 1); 1396e1051a39Sopenharmony_ci} 1397e1051a39Sopenharmony_ci# endif 1398e1051a39Sopenharmony_ci#endif 1399e1051a39Sopenharmony_ci 1400e1051a39Sopenharmony_cistatic void *ec_dup(const void *keydata_from, int selection) 1401e1051a39Sopenharmony_ci{ 1402e1051a39Sopenharmony_ci if (ossl_prov_is_running()) 1403e1051a39Sopenharmony_ci return ossl_ec_key_dup(keydata_from, selection); 1404e1051a39Sopenharmony_ci return NULL; 1405e1051a39Sopenharmony_ci} 1406e1051a39Sopenharmony_ci 1407e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_ec_keymgmt_functions[] = { 1408e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata }, 1409e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init }, 1410e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, 1411e1051a39Sopenharmony_ci (void (*)(void))ec_gen_set_template }, 1412e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params }, 1413e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, 1414e1051a39Sopenharmony_ci (void (*)(void))ec_gen_settable_params }, 1415e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))ec_gen }, 1416e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup }, 1417e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ec_load }, 1418e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata }, 1419e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))ec_get_params }, 1420e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))ec_gettable_params }, 1421e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))ec_set_params }, 1422e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))ec_settable_params }, 1423e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has }, 1424e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match }, 1425e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))ec_validate }, 1426e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ec_import }, 1427e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types }, 1428e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export }, 1429e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types }, 1430e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, 1431e1051a39Sopenharmony_ci (void (*)(void))ec_query_operation_name }, 1432e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup }, 1433e1051a39Sopenharmony_ci { 0, NULL } 1434e1051a39Sopenharmony_ci}; 1435e1051a39Sopenharmony_ci 1436e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1437e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 1438e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_sm2_keymgmt_functions[] = { 1439e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))sm2_newdata }, 1440e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))sm2_gen_init }, 1441e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, 1442e1051a39Sopenharmony_ci (void (*)(void))ec_gen_set_template }, 1443e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params }, 1444e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, 1445e1051a39Sopenharmony_ci (void (*)(void))ec_gen_settable_params }, 1446e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))sm2_gen }, 1447e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup }, 1448e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))sm2_load }, 1449e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata }, 1450e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))sm2_get_params }, 1451e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))sm2_gettable_params }, 1452e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))ec_set_params }, 1453e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))sm2_settable_params }, 1454e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has }, 1455e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match }, 1456e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))sm2_validate }, 1457e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sm2_import }, 1458e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types }, 1459e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export }, 1460e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types }, 1461e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, 1462e1051a39Sopenharmony_ci (void (*)(void))sm2_query_operation_name }, 1463e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup }, 1464e1051a39Sopenharmony_ci { 0, NULL } 1465e1051a39Sopenharmony_ci}; 1466e1051a39Sopenharmony_ci# endif 1467e1051a39Sopenharmony_ci#endif 1468