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