2 * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * ECDH and ECDSA low level APIs are deprecated for public use, but still ok
14 #include "internal/deprecated.h"
17 #include <openssl/ec.h>
18 #include <openssl/engine.h>
19 #include <openssl/err.h>
23 static const EC_KEY_METHOD openssl_ec_key_method = {
24 "OpenSSL EC_KEY method",
28 ossl_ecdh_compute_key,
30 ossl_ecdsa_sign_setup,
36 static const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method;
38 const EC_KEY_METHOD *EC_KEY_OpenSSL(void)
40 return &openssl_ec_key_method;
43 const EC_KEY_METHOD *EC_KEY_get_default_method(void)
45 return default_ec_key_meth;
48 void EC_KEY_set_default_method(const EC_KEY_METHOD *meth)
51 default_ec_key_meth = &openssl_ec_key_method;
53 default_ec_key_meth = meth;
56 const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key)
61 int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
63 void (*finish)(EC_KEY *key) = key->meth->finish;
68 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
69 ENGINE_finish(key->engine);
74 if (meth->init != NULL)
75 return meth->init(key);
79 EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, const char *propq,
82 EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
85 ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE);
91 ret->propq = OPENSSL_strdup(propq);
92 if (ret->propq == NULL) {
93 ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE);
99 ret->lock = CRYPTO_THREAD_lock_new();
100 if (ret->lock == NULL) {
101 ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE);
105 ret->meth = EC_KEY_get_default_method();
106 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
107 if (engine != NULL) {
108 if (!ENGINE_init(engine)) {
109 ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_ENGINE_LIB);
112 ret->engine = engine;
114 ret->engine = ENGINE_get_default_EC();
115 if (ret->engine != NULL) {
116 ret->meth = ENGINE_get_EC(ret->engine);
117 if (ret->meth == NULL) {
118 ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_ENGINE_LIB);
125 ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
127 /* No ex_data inside the FIPS provider */
129 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) {
134 if (ret->meth->init != NULL && ret->meth->init(ret) == 0) {
135 ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_INIT_FAIL);
146 EC_KEY *EC_KEY_new_method(ENGINE *engine)
148 return ec_key_new_method_int(NULL, NULL, engine);
152 int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
154 void *(*KDF) (const void *in, size_t inlen, void *out,
157 unsigned char *sec = NULL;
159 if (eckey->meth->compute_key == NULL) {
160 ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
163 if (outlen > INT_MAX) {
164 ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_INVALID_OUTPUT_LENGTH);
167 if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey))
170 KDF(sec, seclen, out, &outlen);
174 memcpy(out, sec, outlen);
176 OPENSSL_clear_free(sec, seclen);
180 EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth)
182 EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth));
188 ret->flags |= EC_KEY_METHOD_DYNAMIC;
192 void EC_KEY_METHOD_free(EC_KEY_METHOD *meth)
194 if (meth->flags & EC_KEY_METHOD_DYNAMIC)
198 void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
199 int (*init)(EC_KEY *key),
200 void (*finish)(EC_KEY *key),
201 int (*copy)(EC_KEY *dest, const EC_KEY *src),
202 int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
203 int (*set_private)(EC_KEY *key,
204 const BIGNUM *priv_key),
205 int (*set_public)(EC_KEY *key,
206 const EC_POINT *pub_key))
209 meth->finish = finish;
211 meth->set_group = set_group;
212 meth->set_private = set_private;
213 meth->set_public = set_public;
216 void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
217 int (*keygen)(EC_KEY *key))
219 meth->keygen = keygen;
222 void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
223 int (*ckey)(unsigned char **psec,
225 const EC_POINT *pub_key,
228 meth->compute_key = ckey;
231 void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
232 int (*sign)(int type, const unsigned char *dgst,
233 int dlen, unsigned char *sig,
234 unsigned int *siglen,
235 const BIGNUM *kinv, const BIGNUM *r,
237 int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
238 BIGNUM **kinvp, BIGNUM **rp),
239 ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
241 const BIGNUM *in_kinv,
246 meth->sign_setup = sign_setup;
247 meth->sign_sig = sign_sig;
250 void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth,
251 int (*verify)(int type, const unsigned
252 char *dgst, int dgst_len,
253 const unsigned char *sigbuf,
254 int sig_len, EC_KEY *eckey),
255 int (*verify_sig)(const unsigned char *dgst,
257 const ECDSA_SIG *sig,
260 meth->verify = verify;
261 meth->verify_sig = verify_sig;
264 void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth,
265 int (**pinit)(EC_KEY *key),
266 void (**pfinish)(EC_KEY *key),
267 int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
268 int (**pset_group)(EC_KEY *key,
269 const EC_GROUP *grp),
270 int (**pset_private)(EC_KEY *key,
271 const BIGNUM *priv_key),
272 int (**pset_public)(EC_KEY *key,
273 const EC_POINT *pub_key))
278 *pfinish = meth->finish;
281 if (pset_group != NULL)
282 *pset_group = meth->set_group;
283 if (pset_private != NULL)
284 *pset_private = meth->set_private;
285 if (pset_public != NULL)
286 *pset_public = meth->set_public;
289 void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth,
290 int (**pkeygen)(EC_KEY *key))
293 *pkeygen = meth->keygen;
296 void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth,
297 int (**pck)(unsigned char **pout,
299 const EC_POINT *pub_key,
303 *pck = meth->compute_key;
306 void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth,
307 int (**psign)(int type, const unsigned char *dgst,
308 int dlen, unsigned char *sig,
309 unsigned int *siglen,
310 const BIGNUM *kinv, const BIGNUM *r,
312 int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
313 BIGNUM **kinvp, BIGNUM **rp),
314 ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
316 const BIGNUM *in_kinv,
322 if (psign_setup != NULL)
323 *psign_setup = meth->sign_setup;
324 if (psign_sig != NULL)
325 *psign_sig = meth->sign_sig;
328 void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
329 int (**pverify)(int type, const unsigned
330 char *dgst, int dgst_len,
331 const unsigned char *sigbuf,
332 int sig_len, EC_KEY *eckey),
333 int (**pverify_sig)(const unsigned char *dgst,
335 const ECDSA_SIG *sig,
339 *pverify = meth->verify;
340 if (pverify_sig != NULL)
341 *pverify_sig = meth->verify_sig;