Add more complete support for libctx/propq in the EC code
[openssl.git] / crypto / ec / ec_kmeth.c
1 /*
2  * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /*
11  * ECDH and ECDSA low level APIs are deprecated for public use, but still ok
12  * for internal use.
13  */
14 #include "internal/deprecated.h"
15
16 #include <string.h>
17 #include <openssl/ec.h>
18 #include <openssl/engine.h>
19 #include <openssl/err.h>
20 #include "ec_local.h"
21
22
23 static const EC_KEY_METHOD openssl_ec_key_method = {
24     "OpenSSL EC_KEY method",
25     0,
26     0,0,0,0,0,0,
27     ossl_ec_key_gen,
28     ossl_ecdh_compute_key,
29     ossl_ecdsa_sign,
30     ossl_ecdsa_sign_setup,
31     ossl_ecdsa_sign_sig,
32     ossl_ecdsa_verify,
33     ossl_ecdsa_verify_sig
34 };
35
36 static const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method;
37
38 const EC_KEY_METHOD *EC_KEY_OpenSSL(void)
39 {
40     return &openssl_ec_key_method;
41 }
42
43 const EC_KEY_METHOD *EC_KEY_get_default_method(void)
44 {
45     return default_ec_key_meth;
46 }
47
48 void EC_KEY_set_default_method(const EC_KEY_METHOD *meth)
49 {
50     if (meth == NULL)
51         default_ec_key_meth = &openssl_ec_key_method;
52     else
53         default_ec_key_meth = meth;
54 }
55
56 const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key)
57 {
58     return key->meth;
59 }
60
61 int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
62 {
63     void (*finish)(EC_KEY *key) = key->meth->finish;
64
65     if (finish != NULL)
66         finish(key);
67
68 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
69     ENGINE_finish(key->engine);
70     key->engine = NULL;
71 #endif
72
73     key->meth = meth;
74     if (meth->init != NULL)
75         return meth->init(key);
76     return 1;
77 }
78
79 EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, const char *propq,
80                               ENGINE *engine)
81 {
82     EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
83
84     if (ret == NULL) {
85         ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE);
86         return NULL;
87     }
88
89     ret->libctx = libctx;
90     if (propq != NULL) {
91         ret->propq = OPENSSL_strdup(propq);
92         if (ret->propq == NULL) {
93             ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE);
94             goto err;
95         }
96     }
97
98     ret->references = 1;
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);
102         goto err;
103     }
104
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);
110             goto err;
111         }
112         ret->engine = engine;
113     } else
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);
119             goto err;
120         }
121     }
122 #endif
123
124     ret->version = 1;
125     ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
126
127 /* No ex_data inside the FIPS provider */
128 #ifndef FIPS_MODULE
129     if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) {
130         goto err;
131     }
132 #endif
133
134     if (ret->meth->init != NULL && ret->meth->init(ret) == 0) {
135         ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_INIT_FAIL);
136         goto err;
137     }
138     return ret;
139
140  err:
141     EC_KEY_free(ret);
142     return NULL;
143 }
144
145 #ifndef FIPS_MODULE
146 EC_KEY *EC_KEY_new_method(ENGINE *engine)
147 {
148     return ec_key_new_method_int(NULL, NULL, engine);
149 }
150 #endif
151
152 int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
153                      const EC_KEY *eckey,
154                      void *(*KDF) (const void *in, size_t inlen, void *out,
155                                    size_t *outlen))
156 {
157     unsigned char *sec = NULL;
158     size_t seclen;
159     if (eckey->meth->compute_key == NULL) {
160         ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
161         return 0;
162     }
163     if (outlen > INT_MAX) {
164         ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_INVALID_OUTPUT_LENGTH);
165         return 0;
166     }
167     if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey))
168         return 0;
169     if (KDF != NULL) {
170         KDF(sec, seclen, out, &outlen);
171     } else {
172         if (outlen > seclen)
173             outlen = seclen;
174         memcpy(out, sec, outlen);
175     }
176     OPENSSL_clear_free(sec, seclen);
177     return outlen;
178 }
179
180 EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth)
181 {
182     EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth));
183
184     if (ret == NULL)
185         return NULL;
186     if (meth != NULL)
187         *ret = *meth;
188     ret->flags |= EC_KEY_METHOD_DYNAMIC;
189     return ret;
190 }
191
192 void EC_KEY_METHOD_free(EC_KEY_METHOD *meth)
193 {
194     if (meth->flags & EC_KEY_METHOD_DYNAMIC)
195         OPENSSL_free(meth);
196 }
197
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))
207 {
208     meth->init = init;
209     meth->finish = finish;
210     meth->copy = copy;
211     meth->set_group = set_group;
212     meth->set_private = set_private;
213     meth->set_public = set_public;
214 }
215
216 void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
217                               int (*keygen)(EC_KEY *key))
218 {
219     meth->keygen = keygen;
220 }
221
222 void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
223                                    int (*ckey)(unsigned char **psec,
224                                                size_t *pseclen,
225                                                const EC_POINT *pub_key,
226                                                const EC_KEY *ecdh))
227 {
228     meth->compute_key = ckey;
229 }
230
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,
236                                         EC_KEY *eckey),
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,
240                                                    int dgst_len,
241                                                    const BIGNUM *in_kinv,
242                                                    const BIGNUM *in_r,
243                                                    EC_KEY *eckey))
244 {
245     meth->sign = sign;
246     meth->sign_setup = sign_setup;
247     meth->sign_sig = sign_sig;
248 }
249
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,
256                                                 int dgst_len,
257                                                 const ECDSA_SIG *sig,
258                                                 EC_KEY *eckey))
259 {
260     meth->verify = verify;
261     meth->verify_sig = verify_sig;
262 }
263
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))
274 {
275     if (pinit != NULL)
276         *pinit = meth->init;
277     if (pfinish != NULL)
278         *pfinish = meth->finish;
279     if (pcopy != NULL)
280         *pcopy = meth->copy;
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;
287 }
288
289 void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth,
290                               int (**pkeygen)(EC_KEY *key))
291 {
292     if (pkeygen != NULL)
293         *pkeygen = meth->keygen;
294 }
295
296 void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth,
297                                    int (**pck)(unsigned char **pout,
298                                                size_t *poutlen,
299                                                const EC_POINT *pub_key,
300                                                const EC_KEY *ecdh))
301 {
302     if (pck != NULL)
303         *pck = meth->compute_key;
304 }
305
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,
311                                           EC_KEY *eckey),
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,
315                                                      int dgst_len,
316                                                      const BIGNUM *in_kinv,
317                                                      const BIGNUM *in_r,
318                                                      EC_KEY *eckey))
319 {
320     if (psign != NULL)
321         *psign = meth->sign;
322     if (psign_setup != NULL)
323         *psign_setup = meth->sign_setup;
324     if (psign_sig != NULL)
325         *psign_sig = meth->sign_sig;
326 }
327
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,
334                                                   int dgst_len,
335                                                   const ECDSA_SIG *sig,
336                                                   EC_KEY *eckey))
337 {
338     if (pverify != NULL)
339         *pverify = meth->verify;
340     if (pverify_sig != NULL)
341         *pverify_sig = meth->verify_sig;
342 }