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, eckey_param2type, 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, eckey_param2type, 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, eckey_pub_encode, 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, eckey_type2param, 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, eckey_type2param, 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, eckey_pub_decode, 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, eckey_pub_decode, 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, eckey_priv_decode, 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, eckey_priv_decode, 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, eckey_priv_decode, 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, eckey_priv_decode, 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, eckey_priv_decode, 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, eckey_priv_decode, 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, eckey_priv_encode, 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, eckey_priv_encode, 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, eckey_priv_encode, 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, eckey_priv_encode, 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     return 0;
329   }
330 
331   return 1;
332 }
333 
int_ec_size(const EVP_PKEY * pkey)334 static int int_ec_size(const EVP_PKEY *pkey) {
335   return ECDSA_size(pkey->pkey.ec);
336 }
337 
ec_bits(const EVP_PKEY * pkey)338 static int ec_bits(const EVP_PKEY *pkey) {
339   BIGNUM *order = BN_new();
340   const EC_GROUP *group;
341   int ret;
342 
343   if (!order) {
344     ERR_clear_error();
345     return 0;
346   }
347   group = EC_KEY_get0_group(pkey->pkey.ec);
348   if (!EC_GROUP_get_order(group, order, NULL)) {
349     ERR_clear_error();
350     return 0;
351   }
352 
353   ret = BN_num_bits(order);
354   BN_free(order);
355   return ret;
356 }
357 
ec_missing_parameters(const EVP_PKEY * pkey)358 static int ec_missing_parameters(const EVP_PKEY *pkey) {
359   return EC_KEY_get0_group(pkey->pkey.ec) == NULL;
360 }
361 
ec_copy_parameters(EVP_PKEY * to,const EVP_PKEY * from)362 static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
363   EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
364   if (group == NULL ||
365       EC_KEY_set_group(to->pkey.ec, group) == 0) {
366     return 0;
367   }
368   EC_GROUP_free(group);
369   return 1;
370 }
371 
ec_cmp_parameters(const EVP_PKEY * a,const EVP_PKEY * b)372 static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
373   const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
374                  *group_b = EC_KEY_get0_group(b->pkey.ec);
375   if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) {
376     /* mismatch */
377     return 0;
378   }
379   return 1;
380 }
381 
int_ec_free(EVP_PKEY * pkey)382 static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); }
383 
do_EC_KEY_print(BIO * bp,const EC_KEY * x,int off,int ktype)384 static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
385   uint8_t *buffer = NULL;
386   const char *ecstr;
387   size_t buf_len = 0, i;
388   int ret = 0, reason = ERR_R_BIO_LIB;
389   BIGNUM *order = NULL;
390   BN_CTX *ctx = NULL;
391   const EC_GROUP *group;
392   const EC_POINT *public_key;
393   const BIGNUM *priv_key;
394   uint8_t *pub_key_bytes = NULL;
395   size_t pub_key_bytes_len = 0;
396 
397   if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
398     reason = ERR_R_PASSED_NULL_PARAMETER;
399     goto err;
400   }
401 
402   ctx = BN_CTX_new();
403   if (ctx == NULL) {
404     reason = ERR_R_MALLOC_FAILURE;
405     goto err;
406   }
407 
408   if (ktype > 0) {
409     public_key = EC_KEY_get0_public_key(x);
410     if (public_key != NULL) {
411       pub_key_bytes_len = EC_POINT_point2oct(
412           group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
413       if (pub_key_bytes_len == 0) {
414         reason = ERR_R_MALLOC_FAILURE;
415         goto err;
416       }
417       pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
418       if (pub_key_bytes == NULL) {
419         reason = ERR_R_MALLOC_FAILURE;
420         goto err;
421       }
422       pub_key_bytes_len =
423           EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
424                              pub_key_bytes, pub_key_bytes_len, ctx);
425       if (pub_key_bytes_len == 0) {
426         reason = ERR_R_MALLOC_FAILURE;
427         goto err;
428       }
429       buf_len = pub_key_bytes_len;
430     }
431   }
432 
433   if (ktype == 2) {
434     priv_key = EC_KEY_get0_private_key(x);
435     if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
436       buf_len = i;
437     }
438   } else {
439     priv_key = NULL;
440   }
441 
442   if (ktype > 0) {
443     buf_len += 10;
444     if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
445       reason = ERR_R_MALLOC_FAILURE;
446       goto err;
447     }
448   }
449   if (ktype == 2) {
450     ecstr = "Private-Key";
451   } else if (ktype == 1) {
452     ecstr = "Public-Key";
453   } else {
454     ecstr = "ECDSA-Parameters";
455   }
456 
457   if (!BIO_indent(bp, off, 128)) {
458     goto err;
459   }
460   order = BN_new();
461   if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
462       BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
463     goto err;
464   }
465 
466   if ((priv_key != NULL) &&
467       !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) {
468     goto err;
469   }
470   if (pub_key_bytes != NULL) {
471     BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
472   }
473   /* TODO(fork): implement */
474   /*
475   if (!ECPKParameters_print(bp, group, off))
476     goto err; */
477   ret = 1;
478 
479 err:
480   if (!ret) {
481     OPENSSL_PUT_ERROR(EVP, do_EC_KEY_print, reason);
482   }
483   OPENSSL_free(pub_key_bytes);
484   BN_free(order);
485   BN_CTX_free(ctx);
486   OPENSSL_free(buffer);
487   return ret;
488 }
489 
eckey_param_decode(EVP_PKEY * pkey,const uint8_t ** pder,int derlen)490 static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder,
491                               int derlen) {
492   EC_KEY *eckey;
493   if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
494     OPENSSL_PUT_ERROR(EVP, eckey_param_decode, ERR_R_EC_LIB);
495     return 0;
496   }
497   EVP_PKEY_assign_EC_KEY(pkey, eckey);
498   return 1;
499 }
500 
eckey_param_encode(const EVP_PKEY * pkey,uint8_t ** pder)501 static int eckey_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
502   return i2d_ECParameters(pkey->pkey.ec, pder);
503 }
504 
eckey_param_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)505 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
506                              ASN1_PCTX *ctx) {
507   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
508 }
509 
eckey_pub_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)510 static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
511                            ASN1_PCTX *ctx) {
512   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
513 }
514 
515 
eckey_priv_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)516 static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
517                             ASN1_PCTX *ctx) {
518   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
519 }
520 
eckey_opaque(const EVP_PKEY * pkey)521 static int eckey_opaque(const EVP_PKEY *pkey) {
522   return EC_KEY_is_opaque(pkey->pkey.ec);
523 }
524 
old_ec_priv_decode(EVP_PKEY * pkey,const uint8_t ** pder,int derlen)525 static int old_ec_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
526                               int derlen) {
527   EC_KEY *ec;
528   if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
529     OPENSSL_PUT_ERROR(EVP, old_ec_priv_decode, EVP_R_DECODE_ERROR);
530     return 0;
531   }
532   EVP_PKEY_assign_EC_KEY(pkey, ec);
533   return 1;
534 }
535 
old_ec_priv_encode(const EVP_PKEY * pkey,uint8_t ** pder)536 static int old_ec_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
537   return i2d_ECPrivateKey(pkey->pkey.ec, pder);
538 }
539 
540 const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
541   EVP_PKEY_EC,
542   EVP_PKEY_EC,
543   0,
544   "EC",
545   "OpenSSL EC algorithm",
546 
547   eckey_pub_decode,
548   eckey_pub_encode,
549   eckey_pub_cmp,
550   eckey_pub_print,
551 
552   eckey_priv_decode,
553   eckey_priv_encode,
554   eckey_priv_print,
555 
556   eckey_opaque,
557   0 /* pkey_supports_digest */,
558 
559   int_ec_size,
560   ec_bits,
561 
562   eckey_param_decode,
563   eckey_param_encode,
564   ec_missing_parameters,
565   ec_copy_parameters,
566   ec_cmp_parameters,
567   eckey_param_print,
568   0,
569 
570   int_ec_free,
571   old_ec_priv_decode,
572   old_ec_priv_encode
573 };
574