1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2  * project 2006.
3  */
4 /* ====================================================================
5  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    licensing@OpenSSL.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com). */
55 
56 #include <openssl/evp.h>
57 
58 #include <openssl/asn1t.h>
59 #include <openssl/bn.h>
60 #include <openssl/ec.h>
61 #include <openssl/err.h>
62 #include <openssl/mem.h>
63 #include <openssl/obj.h>
64 #include <openssl/x509.h>
65 
66 #include "internal.h"
67 
68 
eckey_param2type(int * pptype,void ** ppval,EC_KEY * ec_key)69 static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) {
70   const EC_GROUP *group;
71   int nid;
72 
73   if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
74     OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
75     return 0;
76   }
77 
78   nid = EC_GROUP_get_curve_name(group);
79   if (nid == NID_undef) {
80     OPENSSL_PUT_ERROR(EVP, EVP_R_NO_NID_FOR_CURVE);
81     return 0;
82   }
83 
84   *ppval = (void*) OBJ_nid2obj(nid);
85   *pptype = V_ASN1_OBJECT;
86   return 1;
87 }
88 
eckey_pub_encode(X509_PUBKEY * pk,const EVP_PKEY * pkey)89 static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
90   EC_KEY *ec_key = pkey->pkey.ec;
91   void *pval = NULL;
92   int ptype;
93   uint8_t *penc = NULL, *p;
94   int penclen;
95 
96   if (!eckey_param2type(&ptype, &pval, ec_key)) {
97     OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
98     return 0;
99   }
100   penclen = i2o_ECPublicKey(ec_key, NULL);
101   if (penclen <= 0) {
102     goto err;
103   }
104   penc = OPENSSL_malloc(penclen);
105   if (!penc) {
106     goto err;
107   }
108   p = penc;
109   penclen = i2o_ECPublicKey(ec_key, &p);
110   if (penclen <= 0) {
111     goto err;
112   }
113   if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), ptype, pval, penc,
114                              penclen)) {
115     return 1;
116   }
117 
118 err:
119   if (ptype == V_ASN1_OBJECT) {
120     ASN1_OBJECT_free(pval);
121   } else {
122     ASN1_STRING_free(pval);
123   }
124   if (penc) {
125     OPENSSL_free(penc);
126   }
127   return 0;
128 }
129 
eckey_type2param(int ptype,void * pval)130 static EC_KEY *eckey_type2param(int ptype, void *pval) {
131   EC_KEY *eckey = NULL;
132 
133   if (ptype == V_ASN1_SEQUENCE) {
134     ASN1_STRING *pstr = pval;
135     const uint8_t *pm = pstr->data;
136     int pmlen = pstr->length;
137 
138     eckey = d2i_ECParameters(NULL, &pm, pmlen);
139     if (eckey == NULL) {
140       OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
141       goto err;
142     }
143   } else if (ptype == V_ASN1_OBJECT) {
144     ASN1_OBJECT *poid = pval;
145 
146     /* type == V_ASN1_OBJECT => the parameters are given
147      * by an asn1 OID */
148     eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid(poid));
149     if (eckey == NULL) {
150       goto err;
151     }
152   } else {
153     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
154     goto err;
155   }
156 
157   return eckey;
158 
159 err:
160   if (eckey) {
161     EC_KEY_free(eckey);
162   }
163   return NULL;
164 }
165 
eckey_pub_decode(EVP_PKEY * pkey,X509_PUBKEY * pubkey)166 static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
167   const uint8_t *p = NULL;
168   void *pval;
169   int ptype, pklen;
170   EC_KEY *eckey = NULL;
171   X509_ALGOR *palg;
172 
173   if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) {
174     return 0;
175   }
176   X509_ALGOR_get0(NULL, &ptype, &pval, palg);
177 
178   eckey = eckey_type2param(ptype, pval);
179   if (!eckey) {
180     OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
181     return 0;
182   }
183 
184   /* We have parameters now set public key */
185   if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
186     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
187     goto err;
188   }
189 
190   EVP_PKEY_assign_EC_KEY(pkey, eckey);
191   return 1;
192 
193 err:
194   if (eckey) {
195     EC_KEY_free(eckey);
196   }
197   return 0;
198 }
199 
eckey_pub_cmp(const EVP_PKEY * a,const EVP_PKEY * b)200 static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
201   int r;
202   const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
203   const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
204                  *pb = EC_KEY_get0_public_key(b->pkey.ec);
205   r = EC_POINT_cmp(group, pa, pb, NULL);
206   if (r == 0) {
207     return 1;
208   } else if (r == 1) {
209     return 0;
210   } else {
211     return -2;
212   }
213 }
214 
eckey_priv_decode(EVP_PKEY * pkey,PKCS8_PRIV_KEY_INFO * p8)215 static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
216   const uint8_t *p = NULL;
217   void *pval;
218   int ptype, pklen;
219   EC_KEY *eckey = NULL;
220   X509_ALGOR *palg;
221 
222   if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) {
223     return 0;
224   }
225   X509_ALGOR_get0(NULL, &ptype, &pval, palg);
226 
227   eckey = eckey_type2param(ptype, pval);
228 
229   if (!eckey) {
230     goto ecliberr;
231   }
232 
233   /* We have parameters now set private key */
234   if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
235     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
236     goto ecerr;
237   }
238 
239   /* calculate public key (if necessary) */
240   if (EC_KEY_get0_public_key(eckey) == NULL) {
241     const BIGNUM *priv_key;
242     const EC_GROUP *group;
243     EC_POINT *pub_key;
244     /* the public key was not included in the SEC1 private
245      * key => calculate the public key */
246     group = EC_KEY_get0_group(eckey);
247     pub_key = EC_POINT_new(group);
248     if (pub_key == NULL) {
249       OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
250       goto ecliberr;
251     }
252     if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
253       EC_POINT_free(pub_key);
254       OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
255       goto ecliberr;
256     }
257     priv_key = EC_KEY_get0_private_key(eckey);
258     if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
259       EC_POINT_free(pub_key);
260       OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
261       goto ecliberr;
262     }
263     if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
264       EC_POINT_free(pub_key);
265       OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
266       goto ecliberr;
267     }
268     EC_POINT_free(pub_key);
269   }
270 
271   EVP_PKEY_assign_EC_KEY(pkey, eckey);
272   return 1;
273 
274 ecliberr:
275   OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
276 ecerr:
277   if (eckey) {
278     EC_KEY_free(eckey);
279   }
280   return 0;
281 }
282 
eckey_priv_encode(PKCS8_PRIV_KEY_INFO * p8,const EVP_PKEY * pkey)283 static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
284   EC_KEY *ec_key;
285   uint8_t *ep, *p;
286   int eplen, ptype;
287   void *pval;
288   unsigned int tmp_flags, old_flags;
289 
290   ec_key = pkey->pkey.ec;
291 
292   if (!eckey_param2type(&ptype, &pval, ec_key)) {
293     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
294     return 0;
295   }
296 
297   /* set the private key */
298 
299   /* do not include the parameters in the SEC1 private key
300    * see PKCS#11 12.11 */
301   old_flags = EC_KEY_get_enc_flags(ec_key);
302   tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
303   EC_KEY_set_enc_flags(ec_key, tmp_flags);
304   eplen = i2d_ECPrivateKey(ec_key, NULL);
305   if (!eplen) {
306     EC_KEY_set_enc_flags(ec_key, old_flags);
307     OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
308     return 0;
309   }
310   ep = (uint8_t *)OPENSSL_malloc(eplen);
311   if (!ep) {
312     EC_KEY_set_enc_flags(ec_key, old_flags);
313     OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
314     return 0;
315   }
316   p = ep;
317   if (!i2d_ECPrivateKey(ec_key, &p)) {
318     EC_KEY_set_enc_flags(ec_key, old_flags);
319     OPENSSL_free(ep);
320     OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
321     return 0;
322   }
323   /* restore old encoding flags */
324   EC_KEY_set_enc_flags(ec_key, old_flags);
325 
326   if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
327                        0, ptype, pval, ep, eplen)) {
328     OPENSSL_free(ep);
329     return 0;
330   }
331 
332   return 1;
333 }
334 
int_ec_size(const EVP_PKEY * pkey)335 static int int_ec_size(const EVP_PKEY *pkey) {
336   return ECDSA_size(pkey->pkey.ec);
337 }
338 
ec_bits(const EVP_PKEY * pkey)339 static int ec_bits(const EVP_PKEY *pkey) {
340   const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec);
341   if (group == NULL) {
342     ERR_clear_error();
343     return 0;
344   }
345   return BN_num_bits(EC_GROUP_get0_order(group));
346 }
347 
ec_missing_parameters(const EVP_PKEY * pkey)348 static int ec_missing_parameters(const EVP_PKEY *pkey) {
349   return EC_KEY_get0_group(pkey->pkey.ec) == NULL;
350 }
351 
ec_copy_parameters(EVP_PKEY * to,const EVP_PKEY * from)352 static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
353   EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
354   if (group == NULL ||
355       EC_KEY_set_group(to->pkey.ec, group) == 0) {
356     return 0;
357   }
358   EC_GROUP_free(group);
359   return 1;
360 }
361 
ec_cmp_parameters(const EVP_PKEY * a,const EVP_PKEY * b)362 static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
363   const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
364                  *group_b = EC_KEY_get0_group(b->pkey.ec);
365   if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) {
366     /* mismatch */
367     return 0;
368   }
369   return 1;
370 }
371 
int_ec_free(EVP_PKEY * pkey)372 static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); }
373 
do_EC_KEY_print(BIO * bp,const EC_KEY * x,int off,int ktype)374 static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
375   uint8_t *buffer = NULL;
376   const char *ecstr;
377   size_t buf_len = 0, i;
378   int ret = 0, reason = ERR_R_BIO_LIB;
379   BN_CTX *ctx = NULL;
380   const EC_GROUP *group;
381   const EC_POINT *public_key;
382   const BIGNUM *priv_key;
383   uint8_t *pub_key_bytes = NULL;
384   size_t pub_key_bytes_len = 0;
385 
386   if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
387     reason = ERR_R_PASSED_NULL_PARAMETER;
388     goto err;
389   }
390 
391   ctx = BN_CTX_new();
392   if (ctx == NULL) {
393     reason = ERR_R_MALLOC_FAILURE;
394     goto err;
395   }
396 
397   if (ktype > 0) {
398     public_key = EC_KEY_get0_public_key(x);
399     if (public_key != NULL) {
400       pub_key_bytes_len = EC_POINT_point2oct(
401           group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
402       if (pub_key_bytes_len == 0) {
403         reason = ERR_R_MALLOC_FAILURE;
404         goto err;
405       }
406       pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
407       if (pub_key_bytes == NULL) {
408         reason = ERR_R_MALLOC_FAILURE;
409         goto err;
410       }
411       pub_key_bytes_len =
412           EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
413                              pub_key_bytes, pub_key_bytes_len, ctx);
414       if (pub_key_bytes_len == 0) {
415         reason = ERR_R_MALLOC_FAILURE;
416         goto err;
417       }
418       buf_len = pub_key_bytes_len;
419     }
420   }
421 
422   if (ktype == 2) {
423     priv_key = EC_KEY_get0_private_key(x);
424     if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
425       buf_len = i;
426     }
427   } else {
428     priv_key = NULL;
429   }
430 
431   if (ktype > 0) {
432     buf_len += 10;
433     if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
434       reason = ERR_R_MALLOC_FAILURE;
435       goto err;
436     }
437   }
438   if (ktype == 2) {
439     ecstr = "Private-Key";
440   } else if (ktype == 1) {
441     ecstr = "Public-Key";
442   } else {
443     ecstr = "ECDSA-Parameters";
444   }
445 
446   if (!BIO_indent(bp, off, 128)) {
447     goto err;
448   }
449   const BIGNUM *order = EC_GROUP_get0_order(group);
450   if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
451     goto err;
452   }
453 
454   if ((priv_key != NULL) &&
455       !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) {
456     goto err;
457   }
458   if (pub_key_bytes != NULL) {
459     BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
460   }
461   /* TODO(fork): implement */
462   /*
463   if (!ECPKParameters_print(bp, group, off))
464     goto err; */
465   ret = 1;
466 
467 err:
468   if (!ret) {
469     OPENSSL_PUT_ERROR(EVP, reason);
470   }
471   OPENSSL_free(pub_key_bytes);
472   BN_CTX_free(ctx);
473   OPENSSL_free(buffer);
474   return ret;
475 }
476 
eckey_param_decode(EVP_PKEY * pkey,const uint8_t ** pder,int derlen)477 static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder,
478                               int derlen) {
479   EC_KEY *eckey;
480   if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
481     OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
482     return 0;
483   }
484   EVP_PKEY_assign_EC_KEY(pkey, eckey);
485   return 1;
486 }
487 
eckey_param_encode(const EVP_PKEY * pkey,uint8_t ** pder)488 static int eckey_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
489   return i2d_ECParameters(pkey->pkey.ec, pder);
490 }
491 
eckey_param_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)492 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
493                              ASN1_PCTX *ctx) {
494   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
495 }
496 
eckey_pub_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)497 static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
498                            ASN1_PCTX *ctx) {
499   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
500 }
501 
502 
eckey_priv_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)503 static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
504                             ASN1_PCTX *ctx) {
505   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
506 }
507 
eckey_opaque(const EVP_PKEY * pkey)508 static int eckey_opaque(const EVP_PKEY *pkey) {
509   return EC_KEY_is_opaque(pkey->pkey.ec);
510 }
511 
old_ec_priv_decode(EVP_PKEY * pkey,const uint8_t ** pder,int derlen)512 static int old_ec_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
513                               int derlen) {
514   EC_KEY *ec;
515   if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
516     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
517     return 0;
518   }
519   EVP_PKEY_assign_EC_KEY(pkey, ec);
520   return 1;
521 }
522 
old_ec_priv_encode(const EVP_PKEY * pkey,uint8_t ** pder)523 static int old_ec_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
524   return i2d_ECPrivateKey(pkey->pkey.ec, pder);
525 }
526 
527 const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
528   EVP_PKEY_EC,
529   EVP_PKEY_EC,
530   0,
531   "EC",
532 
533   eckey_pub_decode,
534   eckey_pub_encode,
535   eckey_pub_cmp,
536   eckey_pub_print,
537 
538   eckey_priv_decode,
539   eckey_priv_encode,
540   eckey_priv_print,
541 
542   eckey_opaque,
543   0 /* pkey_supports_digest */,
544 
545   int_ec_size,
546   ec_bits,
547 
548   eckey_param_decode,
549   eckey_param_encode,
550   ec_missing_parameters,
551   ec_copy_parameters,
552   ec_cmp_parameters,
553   eckey_param_print,
554   0,
555 
556   int_ec_free,
557   old_ec_priv_decode,
558   old_ec_priv_encode,
559 
560   NULL /* digest_verify_init_from_algorithm */,
561   NULL /* digest_sign_algorithm */,
562 };
563