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