Home | History | Annotate | Download | only in evp
      1 /* Written by Dr Stephen N Henson (steve (at) 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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
     54  * Hudson (tjh (at) 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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    335 static int int_ec_size(const EVP_PKEY *pkey) {
    336   return ECDSA_size(pkey->pkey.ec);
    337 }
    338 
    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 
    348 static int ec_missing_parameters(const EVP_PKEY *pkey) {
    349   return EC_KEY_get0_group(pkey->pkey.ec) == NULL;
    350 }
    351 
    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 
    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 
    372 static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); }
    373 
    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 
    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 
    488 static int eckey_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
    489   return i2d_ECParameters(pkey->pkey.ec, pder);
    490 }
    491 
    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 
    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 
    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 
    508 static int eckey_opaque(const EVP_PKEY *pkey) {
    509   return EC_KEY_is_opaque(pkey->pkey.ec);
    510 }
    511 
    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 
    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