1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2015-2021 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 <string.h> 17e1051a39Sopenharmony_ci#include <openssl/ec.h> 18e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 19e1051a39Sopenharmony_ci# include <openssl/engine.h> 20e1051a39Sopenharmony_ci#endif 21e1051a39Sopenharmony_ci#include <openssl/err.h> 22e1051a39Sopenharmony_ci#include "ec_local.h" 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ci 25e1051a39Sopenharmony_cistatic const EC_KEY_METHOD openssl_ec_key_method = { 26e1051a39Sopenharmony_ci "OpenSSL EC_KEY method", 27e1051a39Sopenharmony_ci 0, 28e1051a39Sopenharmony_ci 0,0,0,0,0,0, 29e1051a39Sopenharmony_ci ossl_ec_key_gen, 30e1051a39Sopenharmony_ci ossl_ecdh_compute_key, 31e1051a39Sopenharmony_ci ossl_ecdsa_sign, 32e1051a39Sopenharmony_ci ossl_ecdsa_sign_setup, 33e1051a39Sopenharmony_ci ossl_ecdsa_sign_sig, 34e1051a39Sopenharmony_ci ossl_ecdsa_verify, 35e1051a39Sopenharmony_ci ossl_ecdsa_verify_sig 36e1051a39Sopenharmony_ci}; 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_cistatic const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method; 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ciconst EC_KEY_METHOD *EC_KEY_OpenSSL(void) 41e1051a39Sopenharmony_ci{ 42e1051a39Sopenharmony_ci return &openssl_ec_key_method; 43e1051a39Sopenharmony_ci} 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ciconst EC_KEY_METHOD *EC_KEY_get_default_method(void) 46e1051a39Sopenharmony_ci{ 47e1051a39Sopenharmony_ci return default_ec_key_meth; 48e1051a39Sopenharmony_ci} 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_civoid EC_KEY_set_default_method(const EC_KEY_METHOD *meth) 51e1051a39Sopenharmony_ci{ 52e1051a39Sopenharmony_ci if (meth == NULL) 53e1051a39Sopenharmony_ci default_ec_key_meth = &openssl_ec_key_method; 54e1051a39Sopenharmony_ci else 55e1051a39Sopenharmony_ci default_ec_key_meth = meth; 56e1051a39Sopenharmony_ci} 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ciconst EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key) 59e1051a39Sopenharmony_ci{ 60e1051a39Sopenharmony_ci return key->meth; 61e1051a39Sopenharmony_ci} 62e1051a39Sopenharmony_ci 63e1051a39Sopenharmony_ciint EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) 64e1051a39Sopenharmony_ci{ 65e1051a39Sopenharmony_ci void (*finish)(EC_KEY *key) = key->meth->finish; 66e1051a39Sopenharmony_ci 67e1051a39Sopenharmony_ci if (finish != NULL) 68e1051a39Sopenharmony_ci finish(key); 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 71e1051a39Sopenharmony_ci ENGINE_finish(key->engine); 72e1051a39Sopenharmony_ci key->engine = NULL; 73e1051a39Sopenharmony_ci#endif 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci key->meth = meth; 76e1051a39Sopenharmony_ci if (meth->init != NULL) 77e1051a39Sopenharmony_ci return meth->init(key); 78e1051a39Sopenharmony_ci return 1; 79e1051a39Sopenharmony_ci} 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_ciEC_KEY *ossl_ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq, 82e1051a39Sopenharmony_ci ENGINE *engine) 83e1051a39Sopenharmony_ci{ 84e1051a39Sopenharmony_ci EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci if (ret == NULL) { 87e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 88e1051a39Sopenharmony_ci return NULL; 89e1051a39Sopenharmony_ci } 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci ret->libctx = libctx; 92e1051a39Sopenharmony_ci if (propq != NULL) { 93e1051a39Sopenharmony_ci ret->propq = OPENSSL_strdup(propq); 94e1051a39Sopenharmony_ci if (ret->propq == NULL) { 95e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 96e1051a39Sopenharmony_ci goto err; 97e1051a39Sopenharmony_ci } 98e1051a39Sopenharmony_ci } 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_ci ret->references = 1; 101e1051a39Sopenharmony_ci ret->lock = CRYPTO_THREAD_lock_new(); 102e1051a39Sopenharmony_ci if (ret->lock == NULL) { 103e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 104e1051a39Sopenharmony_ci goto err; 105e1051a39Sopenharmony_ci } 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ci ret->meth = EC_KEY_get_default_method(); 108e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 109e1051a39Sopenharmony_ci if (engine != NULL) { 110e1051a39Sopenharmony_ci if (!ENGINE_init(engine)) { 111e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB); 112e1051a39Sopenharmony_ci goto err; 113e1051a39Sopenharmony_ci } 114e1051a39Sopenharmony_ci ret->engine = engine; 115e1051a39Sopenharmony_ci } else 116e1051a39Sopenharmony_ci ret->engine = ENGINE_get_default_EC(); 117e1051a39Sopenharmony_ci if (ret->engine != NULL) { 118e1051a39Sopenharmony_ci ret->meth = ENGINE_get_EC(ret->engine); 119e1051a39Sopenharmony_ci if (ret->meth == NULL) { 120e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB); 121e1051a39Sopenharmony_ci goto err; 122e1051a39Sopenharmony_ci } 123e1051a39Sopenharmony_ci } 124e1051a39Sopenharmony_ci#endif 125e1051a39Sopenharmony_ci 126e1051a39Sopenharmony_ci ret->version = 1; 127e1051a39Sopenharmony_ci ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ci/* No ex_data inside the FIPS provider */ 130e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 131e1051a39Sopenharmony_ci if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) { 132e1051a39Sopenharmony_ci goto err; 133e1051a39Sopenharmony_ci } 134e1051a39Sopenharmony_ci#endif 135e1051a39Sopenharmony_ci 136e1051a39Sopenharmony_ci if (ret->meth->init != NULL && ret->meth->init(ret) == 0) { 137e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_INIT_FAIL); 138e1051a39Sopenharmony_ci goto err; 139e1051a39Sopenharmony_ci } 140e1051a39Sopenharmony_ci return ret; 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci err: 143e1051a39Sopenharmony_ci EC_KEY_free(ret); 144e1051a39Sopenharmony_ci return NULL; 145e1051a39Sopenharmony_ci} 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 148e1051a39Sopenharmony_ciEC_KEY *EC_KEY_new_method(ENGINE *engine) 149e1051a39Sopenharmony_ci{ 150e1051a39Sopenharmony_ci return ossl_ec_key_new_method_int(NULL, NULL, engine); 151e1051a39Sopenharmony_ci} 152e1051a39Sopenharmony_ci#endif 153e1051a39Sopenharmony_ci 154e1051a39Sopenharmony_ciint ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, 155e1051a39Sopenharmony_ci const EC_KEY *eckey, 156e1051a39Sopenharmony_ci void *(*KDF) (const void *in, size_t inlen, void *out, 157e1051a39Sopenharmony_ci size_t *outlen)) 158e1051a39Sopenharmony_ci{ 159e1051a39Sopenharmony_ci unsigned char *sec = NULL; 160e1051a39Sopenharmony_ci size_t seclen; 161e1051a39Sopenharmony_ci if (eckey->meth->compute_key == NULL) { 162e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); 163e1051a39Sopenharmony_ci return 0; 164e1051a39Sopenharmony_ci } 165e1051a39Sopenharmony_ci if (outlen > INT_MAX) { 166e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH); 167e1051a39Sopenharmony_ci return 0; 168e1051a39Sopenharmony_ci } 169e1051a39Sopenharmony_ci if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey)) 170e1051a39Sopenharmony_ci return 0; 171e1051a39Sopenharmony_ci if (KDF != NULL) { 172e1051a39Sopenharmony_ci KDF(sec, seclen, out, &outlen); 173e1051a39Sopenharmony_ci } else { 174e1051a39Sopenharmony_ci if (outlen > seclen) 175e1051a39Sopenharmony_ci outlen = seclen; 176e1051a39Sopenharmony_ci memcpy(out, sec, outlen); 177e1051a39Sopenharmony_ci } 178e1051a39Sopenharmony_ci OPENSSL_clear_free(sec, seclen); 179e1051a39Sopenharmony_ci return outlen; 180e1051a39Sopenharmony_ci} 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_ciEC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth) 183e1051a39Sopenharmony_ci{ 184e1051a39Sopenharmony_ci EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth)); 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_ci if (ret == NULL) 187e1051a39Sopenharmony_ci return NULL; 188e1051a39Sopenharmony_ci if (meth != NULL) 189e1051a39Sopenharmony_ci *ret = *meth; 190e1051a39Sopenharmony_ci ret->flags |= EC_KEY_METHOD_DYNAMIC; 191e1051a39Sopenharmony_ci return ret; 192e1051a39Sopenharmony_ci} 193e1051a39Sopenharmony_ci 194e1051a39Sopenharmony_civoid EC_KEY_METHOD_free(EC_KEY_METHOD *meth) 195e1051a39Sopenharmony_ci{ 196e1051a39Sopenharmony_ci if (meth->flags & EC_KEY_METHOD_DYNAMIC) 197e1051a39Sopenharmony_ci OPENSSL_free(meth); 198e1051a39Sopenharmony_ci} 199e1051a39Sopenharmony_ci 200e1051a39Sopenharmony_civoid EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, 201e1051a39Sopenharmony_ci int (*init)(EC_KEY *key), 202e1051a39Sopenharmony_ci void (*finish)(EC_KEY *key), 203e1051a39Sopenharmony_ci int (*copy)(EC_KEY *dest, const EC_KEY *src), 204e1051a39Sopenharmony_ci int (*set_group)(EC_KEY *key, const EC_GROUP *grp), 205e1051a39Sopenharmony_ci int (*set_private)(EC_KEY *key, 206e1051a39Sopenharmony_ci const BIGNUM *priv_key), 207e1051a39Sopenharmony_ci int (*set_public)(EC_KEY *key, 208e1051a39Sopenharmony_ci const EC_POINT *pub_key)) 209e1051a39Sopenharmony_ci{ 210e1051a39Sopenharmony_ci meth->init = init; 211e1051a39Sopenharmony_ci meth->finish = finish; 212e1051a39Sopenharmony_ci meth->copy = copy; 213e1051a39Sopenharmony_ci meth->set_group = set_group; 214e1051a39Sopenharmony_ci meth->set_private = set_private; 215e1051a39Sopenharmony_ci meth->set_public = set_public; 216e1051a39Sopenharmony_ci} 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_civoid EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, 219e1051a39Sopenharmony_ci int (*keygen)(EC_KEY *key)) 220e1051a39Sopenharmony_ci{ 221e1051a39Sopenharmony_ci meth->keygen = keygen; 222e1051a39Sopenharmony_ci} 223e1051a39Sopenharmony_ci 224e1051a39Sopenharmony_civoid EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, 225e1051a39Sopenharmony_ci int (*ckey)(unsigned char **psec, 226e1051a39Sopenharmony_ci size_t *pseclen, 227e1051a39Sopenharmony_ci const EC_POINT *pub_key, 228e1051a39Sopenharmony_ci const EC_KEY *ecdh)) 229e1051a39Sopenharmony_ci{ 230e1051a39Sopenharmony_ci meth->compute_key = ckey; 231e1051a39Sopenharmony_ci} 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_civoid EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, 234e1051a39Sopenharmony_ci int (*sign)(int type, const unsigned char *dgst, 235e1051a39Sopenharmony_ci int dlen, unsigned char *sig, 236e1051a39Sopenharmony_ci unsigned int *siglen, 237e1051a39Sopenharmony_ci const BIGNUM *kinv, const BIGNUM *r, 238e1051a39Sopenharmony_ci EC_KEY *eckey), 239e1051a39Sopenharmony_ci int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, 240e1051a39Sopenharmony_ci BIGNUM **kinvp, BIGNUM **rp), 241e1051a39Sopenharmony_ci ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, 242e1051a39Sopenharmony_ci int dgst_len, 243e1051a39Sopenharmony_ci const BIGNUM *in_kinv, 244e1051a39Sopenharmony_ci const BIGNUM *in_r, 245e1051a39Sopenharmony_ci EC_KEY *eckey)) 246e1051a39Sopenharmony_ci{ 247e1051a39Sopenharmony_ci meth->sign = sign; 248e1051a39Sopenharmony_ci meth->sign_setup = sign_setup; 249e1051a39Sopenharmony_ci meth->sign_sig = sign_sig; 250e1051a39Sopenharmony_ci} 251e1051a39Sopenharmony_ci 252e1051a39Sopenharmony_civoid EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, 253e1051a39Sopenharmony_ci int (*verify)(int type, const unsigned 254e1051a39Sopenharmony_ci char *dgst, int dgst_len, 255e1051a39Sopenharmony_ci const unsigned char *sigbuf, 256e1051a39Sopenharmony_ci int sig_len, EC_KEY *eckey), 257e1051a39Sopenharmony_ci int (*verify_sig)(const unsigned char *dgst, 258e1051a39Sopenharmony_ci int dgst_len, 259e1051a39Sopenharmony_ci const ECDSA_SIG *sig, 260e1051a39Sopenharmony_ci EC_KEY *eckey)) 261e1051a39Sopenharmony_ci{ 262e1051a39Sopenharmony_ci meth->verify = verify; 263e1051a39Sopenharmony_ci meth->verify_sig = verify_sig; 264e1051a39Sopenharmony_ci} 265e1051a39Sopenharmony_ci 266e1051a39Sopenharmony_civoid EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth, 267e1051a39Sopenharmony_ci int (**pinit)(EC_KEY *key), 268e1051a39Sopenharmony_ci void (**pfinish)(EC_KEY *key), 269e1051a39Sopenharmony_ci int (**pcopy)(EC_KEY *dest, const EC_KEY *src), 270e1051a39Sopenharmony_ci int (**pset_group)(EC_KEY *key, 271e1051a39Sopenharmony_ci const EC_GROUP *grp), 272e1051a39Sopenharmony_ci int (**pset_private)(EC_KEY *key, 273e1051a39Sopenharmony_ci const BIGNUM *priv_key), 274e1051a39Sopenharmony_ci int (**pset_public)(EC_KEY *key, 275e1051a39Sopenharmony_ci const EC_POINT *pub_key)) 276e1051a39Sopenharmony_ci{ 277e1051a39Sopenharmony_ci if (pinit != NULL) 278e1051a39Sopenharmony_ci *pinit = meth->init; 279e1051a39Sopenharmony_ci if (pfinish != NULL) 280e1051a39Sopenharmony_ci *pfinish = meth->finish; 281e1051a39Sopenharmony_ci if (pcopy != NULL) 282e1051a39Sopenharmony_ci *pcopy = meth->copy; 283e1051a39Sopenharmony_ci if (pset_group != NULL) 284e1051a39Sopenharmony_ci *pset_group = meth->set_group; 285e1051a39Sopenharmony_ci if (pset_private != NULL) 286e1051a39Sopenharmony_ci *pset_private = meth->set_private; 287e1051a39Sopenharmony_ci if (pset_public != NULL) 288e1051a39Sopenharmony_ci *pset_public = meth->set_public; 289e1051a39Sopenharmony_ci} 290e1051a39Sopenharmony_ci 291e1051a39Sopenharmony_civoid EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, 292e1051a39Sopenharmony_ci int (**pkeygen)(EC_KEY *key)) 293e1051a39Sopenharmony_ci{ 294e1051a39Sopenharmony_ci if (pkeygen != NULL) 295e1051a39Sopenharmony_ci *pkeygen = meth->keygen; 296e1051a39Sopenharmony_ci} 297e1051a39Sopenharmony_ci 298e1051a39Sopenharmony_civoid EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, 299e1051a39Sopenharmony_ci int (**pck)(unsigned char **pout, 300e1051a39Sopenharmony_ci size_t *poutlen, 301e1051a39Sopenharmony_ci const EC_POINT *pub_key, 302e1051a39Sopenharmony_ci const EC_KEY *ecdh)) 303e1051a39Sopenharmony_ci{ 304e1051a39Sopenharmony_ci if (pck != NULL) 305e1051a39Sopenharmony_ci *pck = meth->compute_key; 306e1051a39Sopenharmony_ci} 307e1051a39Sopenharmony_ci 308e1051a39Sopenharmony_civoid EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, 309e1051a39Sopenharmony_ci int (**psign)(int type, const unsigned char *dgst, 310e1051a39Sopenharmony_ci int dlen, unsigned char *sig, 311e1051a39Sopenharmony_ci unsigned int *siglen, 312e1051a39Sopenharmony_ci const BIGNUM *kinv, const BIGNUM *r, 313e1051a39Sopenharmony_ci EC_KEY *eckey), 314e1051a39Sopenharmony_ci int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, 315e1051a39Sopenharmony_ci BIGNUM **kinvp, BIGNUM **rp), 316e1051a39Sopenharmony_ci ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, 317e1051a39Sopenharmony_ci int dgst_len, 318e1051a39Sopenharmony_ci const BIGNUM *in_kinv, 319e1051a39Sopenharmony_ci const BIGNUM *in_r, 320e1051a39Sopenharmony_ci EC_KEY *eckey)) 321e1051a39Sopenharmony_ci{ 322e1051a39Sopenharmony_ci if (psign != NULL) 323e1051a39Sopenharmony_ci *psign = meth->sign; 324e1051a39Sopenharmony_ci if (psign_setup != NULL) 325e1051a39Sopenharmony_ci *psign_setup = meth->sign_setup; 326e1051a39Sopenharmony_ci if (psign_sig != NULL) 327e1051a39Sopenharmony_ci *psign_sig = meth->sign_sig; 328e1051a39Sopenharmony_ci} 329e1051a39Sopenharmony_ci 330e1051a39Sopenharmony_civoid EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, 331e1051a39Sopenharmony_ci int (**pverify)(int type, const unsigned 332e1051a39Sopenharmony_ci char *dgst, int dgst_len, 333e1051a39Sopenharmony_ci const unsigned char *sigbuf, 334e1051a39Sopenharmony_ci int sig_len, EC_KEY *eckey), 335e1051a39Sopenharmony_ci int (**pverify_sig)(const unsigned char *dgst, 336e1051a39Sopenharmony_ci int dgst_len, 337e1051a39Sopenharmony_ci const ECDSA_SIG *sig, 338e1051a39Sopenharmony_ci EC_KEY *eckey)) 339e1051a39Sopenharmony_ci{ 340e1051a39Sopenharmony_ci if (pverify != NULL) 341e1051a39Sopenharmony_ci *pverify = meth->verify; 342e1051a39Sopenharmony_ci if (pverify_sig != NULL) 343e1051a39Sopenharmony_ci *pverify_sig = meth->verify_sig; 344e1051a39Sopenharmony_ci} 345