LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/ec - ec_ameth.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 399 0.0 %
Date: 2015-10-10 Functions: 0 27 0.0 %

          Line data    Source code
       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 <openssl/asn1t.h>
      68             : #include "asn1_locl.h"
      69             : 
      70             : static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
      71             : static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
      72             : 
      73           0 : static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
      74             : {
      75             :     const EC_GROUP *group;
      76             :     int nid;
      77           0 :     if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
      78           0 :         ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
      79           0 :         return 0;
      80             :     }
      81           0 :     if (EC_GROUP_get_asn1_flag(group)
      82           0 :         && (nid = EC_GROUP_get_curve_name(group)))
      83             :         /* we have a 'named curve' => just set the OID */
      84             :     {
      85           0 :         *ppval = OBJ_nid2obj(nid);
      86           0 :         *pptype = V_ASN1_OBJECT;
      87             :     } else {                    /* explicit parameters */
      88             : 
      89             :         ASN1_STRING *pstr = NULL;
      90           0 :         pstr = ASN1_STRING_new();
      91           0 :         if (!pstr)
      92             :             return 0;
      93           0 :         pstr->length = i2d_ECParameters(ec_key, &pstr->data);
      94           0 :         if (pstr->length <= 0) {
      95           0 :             ASN1_STRING_free(pstr);
      96           0 :             ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
      97           0 :             return 0;
      98             :         }
      99           0 :         *ppval = pstr;
     100           0 :         *pptype = V_ASN1_SEQUENCE;
     101             :     }
     102             :     return 1;
     103             : }
     104             : 
     105           0 : static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
     106             : {
     107           0 :     EC_KEY *ec_key = pkey->pkey.ec;
     108           0 :     void *pval = NULL;
     109             :     int ptype;
     110             :     unsigned char *penc = NULL, *p;
     111             :     int penclen;
     112             : 
     113           0 :     if (!eckey_param2type(&ptype, &pval, ec_key)) {
     114           0 :         ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
     115           0 :         return 0;
     116             :     }
     117           0 :     penclen = i2o_ECPublicKey(ec_key, NULL);
     118           0 :     if (penclen <= 0)
     119             :         goto err;
     120           0 :     penc = OPENSSL_malloc(penclen);
     121           0 :     if (!penc)
     122             :         goto err;
     123           0 :     p = penc;
     124           0 :     penclen = i2o_ECPublicKey(ec_key, &p);
     125           0 :     if (penclen <= 0)
     126             :         goto err;
     127           0 :     if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
     128             :                                ptype, pval, penc, penclen))
     129             :         return 1;
     130             :  err:
     131           0 :     if (ptype == V_ASN1_OBJECT)
     132           0 :         ASN1_OBJECT_free(pval);
     133             :     else
     134           0 :         ASN1_STRING_free(pval);
     135           0 :     if (penc)
     136           0 :         OPENSSL_free(penc);
     137             :     return 0;
     138             : }
     139             : 
     140           0 : static EC_KEY *eckey_type2param(int ptype, void *pval)
     141             : {
     142             :     EC_KEY *eckey = NULL;
     143           0 :     if (ptype == V_ASN1_SEQUENCE) {
     144             :         ASN1_STRING *pstr = pval;
     145           0 :         const unsigned char *pm = NULL;
     146             :         int pmlen;
     147           0 :         pm = pstr->data;
     148           0 :         pmlen = pstr->length;
     149           0 :         if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
     150           0 :             ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
     151           0 :             goto ecerr;
     152             :         }
     153           0 :     } else if (ptype == V_ASN1_OBJECT) {
     154             :         ASN1_OBJECT *poid = pval;
     155             :         EC_GROUP *group;
     156             : 
     157             :         /*
     158             :          * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
     159             :          */
     160           0 :         if ((eckey = EC_KEY_new()) == NULL) {
     161           0 :             ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
     162           0 :             goto ecerr;
     163             :         }
     164           0 :         group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
     165           0 :         if (group == NULL)
     166             :             goto ecerr;
     167           0 :         EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
     168           0 :         if (EC_KEY_set_group(eckey, group) == 0)
     169             :             goto ecerr;
     170           0 :         EC_GROUP_free(group);
     171             :     } else {
     172           0 :         ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
     173           0 :         goto ecerr;
     174             :     }
     175             : 
     176           0 :     return eckey;
     177             : 
     178             :  ecerr:
     179           0 :     if (eckey)
     180           0 :         EC_KEY_free(eckey);
     181             :     return NULL;
     182             : }
     183             : 
     184           0 : static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
     185             : {
     186           0 :     const unsigned char *p = NULL;
     187             :     void *pval;
     188             :     int ptype, pklen;
     189           0 :     EC_KEY *eckey = NULL;
     190             :     X509_ALGOR *palg;
     191             : 
     192           0 :     if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
     193             :         return 0;
     194           0 :     X509_ALGOR_get0(NULL, &ptype, &pval, palg);
     195             : 
     196           0 :     eckey = eckey_type2param(ptype, pval);
     197             : 
     198           0 :     if (!eckey) {
     199           0 :         ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
     200           0 :         return 0;
     201             :     }
     202             : 
     203             :     /* We have parameters now set public key */
     204           0 :     if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
     205           0 :         ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
     206             :         goto ecerr;
     207             :     }
     208             : 
     209           0 :     EVP_PKEY_assign_EC_KEY(pkey, eckey);
     210           0 :     return 1;
     211             : 
     212             :  ecerr:
     213           0 :     if (eckey)
     214           0 :         EC_KEY_free(eckey);
     215             :     return 0;
     216             : }
     217             : 
     218           0 : static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
     219             : {
     220             :     int r;
     221           0 :     const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
     222           0 :     const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
     223           0 :         *pb = EC_KEY_get0_public_key(b->pkey.ec);
     224           0 :     r = EC_POINT_cmp(group, pa, pb, NULL);
     225           0 :     if (r == 0)
     226             :         return 1;
     227           0 :     if (r == 1)
     228             :         return 0;
     229           0 :     return -2;
     230             : }
     231             : 
     232           0 : static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
     233             : {
     234           0 :     const unsigned char *p = NULL;
     235             :     void *pval;
     236             :     int ptype, pklen;
     237           0 :     EC_KEY *eckey = NULL;
     238             :     X509_ALGOR *palg;
     239             : 
     240           0 :     if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
     241             :         return 0;
     242           0 :     X509_ALGOR_get0(NULL, &ptype, &pval, palg);
     243             : 
     244           0 :     eckey = eckey_type2param(ptype, pval);
     245             : 
     246           0 :     if (!eckey)
     247             :         goto ecliberr;
     248             : 
     249             :     /* We have parameters now set private key */
     250           0 :     if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
     251           0 :         ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
     252           0 :         goto ecerr;
     253             :     }
     254             : 
     255             :     /* calculate public key (if necessary) */
     256           0 :     if (EC_KEY_get0_public_key(eckey) == NULL) {
     257             :         const BIGNUM *priv_key;
     258             :         const EC_GROUP *group;
     259             :         EC_POINT *pub_key;
     260             :         /*
     261             :          * the public key was not included in the SEC1 private key =>
     262             :          * calculate the public key
     263             :          */
     264           0 :         group = EC_KEY_get0_group(eckey);
     265           0 :         pub_key = EC_POINT_new(group);
     266           0 :         if (pub_key == NULL) {
     267           0 :             ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
     268           0 :             goto ecliberr;
     269             :         }
     270           0 :         if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
     271           0 :             EC_POINT_free(pub_key);
     272           0 :             ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
     273           0 :             goto ecliberr;
     274             :         }
     275           0 :         priv_key = EC_KEY_get0_private_key(eckey);
     276           0 :         if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
     277           0 :             EC_POINT_free(pub_key);
     278           0 :             ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
     279           0 :             goto ecliberr;
     280             :         }
     281           0 :         if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
     282           0 :             EC_POINT_free(pub_key);
     283           0 :             ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
     284           0 :             goto ecliberr;
     285             :         }
     286           0 :         EC_POINT_free(pub_key);
     287             :     }
     288             : 
     289           0 :     EVP_PKEY_assign_EC_KEY(pkey, eckey);
     290           0 :     return 1;
     291             : 
     292             :  ecliberr:
     293           0 :     ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
     294             :  ecerr:
     295           0 :     if (eckey)
     296           0 :         EC_KEY_free(eckey);
     297             :     return 0;
     298             : }
     299             : 
     300           0 : static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
     301             : {
     302             :     EC_KEY *ec_key;
     303             :     unsigned char *ep, *p;
     304             :     int eplen, ptype;
     305             :     void *pval;
     306             :     unsigned int tmp_flags, old_flags;
     307             : 
     308           0 :     ec_key = pkey->pkey.ec;
     309             : 
     310           0 :     if (!eckey_param2type(&ptype, &pval, ec_key)) {
     311           0 :         ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
     312           0 :         return 0;
     313             :     }
     314             : 
     315             :     /* set the private key */
     316             : 
     317             :     /*
     318             :      * do not include the parameters in the SEC1 private key see PKCS#11
     319             :      * 12.11
     320             :      */
     321           0 :     old_flags = EC_KEY_get_enc_flags(ec_key);
     322           0 :     tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
     323           0 :     EC_KEY_set_enc_flags(ec_key, tmp_flags);
     324           0 :     eplen = i2d_ECPrivateKey(ec_key, NULL);
     325           0 :     if (!eplen) {
     326           0 :         EC_KEY_set_enc_flags(ec_key, old_flags);
     327           0 :         ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
     328           0 :         return 0;
     329             :     }
     330           0 :     ep = (unsigned char *)OPENSSL_malloc(eplen);
     331           0 :     if (!ep) {
     332           0 :         EC_KEY_set_enc_flags(ec_key, old_flags);
     333           0 :         ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
     334           0 :         return 0;
     335             :     }
     336           0 :     p = ep;
     337           0 :     if (!i2d_ECPrivateKey(ec_key, &p)) {
     338           0 :         EC_KEY_set_enc_flags(ec_key, old_flags);
     339           0 :         OPENSSL_free(ep);
     340           0 :         ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
     341           0 :         return 0;
     342             :     }
     343             :     /* restore old encoding flags */
     344           0 :     EC_KEY_set_enc_flags(ec_key, old_flags);
     345             : 
     346           0 :     if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
     347             :                          ptype, pval, ep, eplen))
     348             :         return 0;
     349             : 
     350           0 :     return 1;
     351             : }
     352             : 
     353           0 : static int int_ec_size(const EVP_PKEY *pkey)
     354             : {
     355           0 :     return ECDSA_size(pkey->pkey.ec);
     356             : }
     357             : 
     358           0 : static int ec_bits(const EVP_PKEY *pkey)
     359             : {
     360           0 :     BIGNUM *order = BN_new();
     361             :     const EC_GROUP *group;
     362             :     int ret;
     363             : 
     364           0 :     if (!order) {
     365           0 :         ERR_clear_error();
     366           0 :         return 0;
     367             :     }
     368           0 :     group = EC_KEY_get0_group(pkey->pkey.ec);
     369           0 :     if (!EC_GROUP_get_order(group, order, NULL)) {
     370           0 :         ERR_clear_error();
     371           0 :         return 0;
     372             :     }
     373             : 
     374           0 :     ret = BN_num_bits(order);
     375           0 :     BN_free(order);
     376           0 :     return ret;
     377             : }
     378             : 
     379           0 : static int ec_missing_parameters(const EVP_PKEY *pkey)
     380             : {
     381           0 :     if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
     382             :         return 1;
     383           0 :     return 0;
     384             : }
     385             : 
     386           0 : static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
     387             : {
     388           0 :     EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
     389           0 :     if (group == NULL)
     390             :         return 0;
     391           0 :     if (EC_KEY_set_group(to->pkey.ec, group) == 0)
     392             :         return 0;
     393           0 :     EC_GROUP_free(group);
     394           0 :     return 1;
     395             : }
     396             : 
     397           0 : static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
     398             : {
     399           0 :     const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
     400           0 :         *group_b = EC_KEY_get0_group(b->pkey.ec);
     401           0 :     if (EC_GROUP_cmp(group_a, group_b, NULL))
     402             :         return 0;
     403             :     else
     404           0 :         return 1;
     405             : }
     406             : 
     407           0 : static void int_ec_free(EVP_PKEY *pkey)
     408             : {
     409           0 :     EC_KEY_free(pkey->pkey.ec);
     410           0 : }
     411             : 
     412           0 : static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
     413             : {
     414             :     unsigned char *buffer = NULL;
     415             :     const char *ecstr;
     416             :     size_t buf_len = 0, i;
     417             :     int ret = 0, reason = ERR_R_BIO_LIB;
     418             :     BIGNUM *pub_key = NULL, *order = NULL;
     419             :     BN_CTX *ctx = NULL;
     420             :     const EC_GROUP *group;
     421             :     const EC_POINT *public_key;
     422             :     const BIGNUM *priv_key;
     423             : 
     424           0 :     if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
     425             :         reason = ERR_R_PASSED_NULL_PARAMETER;
     426             :         goto err;
     427             :     }
     428             : 
     429           0 :     ctx = BN_CTX_new();
     430           0 :     if (ctx == NULL) {
     431             :         reason = ERR_R_MALLOC_FAILURE;
     432             :         goto err;
     433             :     }
     434             : 
     435           0 :     if (ktype > 0) {
     436           0 :         public_key = EC_KEY_get0_public_key(x);
     437           0 :         if (public_key != NULL) {
     438           0 :             if ((pub_key = EC_POINT_point2bn(group, public_key,
     439             :                                              EC_KEY_get_conv_form(x), NULL,
     440             :                                              ctx)) == NULL) {
     441             :                 reason = ERR_R_EC_LIB;
     442             :                 goto err;
     443             :             }
     444           0 :             buf_len = (size_t)BN_num_bytes(pub_key);
     445             :         }
     446             :     }
     447             : 
     448           0 :     if (ktype == 2) {
     449           0 :         priv_key = EC_KEY_get0_private_key(x);
     450           0 :         if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
     451             :             buf_len = i;
     452             :     } else
     453             :         priv_key = NULL;
     454             : 
     455           0 :     if (ktype > 0) {
     456           0 :         buf_len += 10;
     457           0 :         if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
     458             :             reason = ERR_R_MALLOC_FAILURE;
     459             :             goto err;
     460             :         }
     461             :     }
     462           0 :     if (ktype == 2)
     463             :         ecstr = "Private-Key";
     464           0 :     else if (ktype == 1)
     465             :         ecstr = "Public-Key";
     466             :     else
     467             :         ecstr = "ECDSA-Parameters";
     468             : 
     469           0 :     if (!BIO_indent(bp, off, 128))
     470             :         goto err;
     471           0 :     if ((order = BN_new()) == NULL)
     472             :         goto err;
     473           0 :     if (!EC_GROUP_get_order(group, order, NULL))
     474             :         goto err;
     475           0 :     if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0)
     476             :         goto err;
     477             : 
     478           0 :     if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
     479             :                                              buffer, off))
     480             :         goto err;
     481           0 :     if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
     482             :                                             buffer, off))
     483             :         goto err;
     484           0 :     if (!ECPKParameters_print(bp, group, off))
     485             :         goto err;
     486             :     ret = 1;
     487             :  err:
     488           0 :     if (!ret)
     489           0 :         ECerr(EC_F_DO_EC_KEY_PRINT, reason);
     490           0 :     if (pub_key)
     491           0 :         BN_free(pub_key);
     492           0 :     if (order)
     493           0 :         BN_free(order);
     494           0 :     if (ctx)
     495           0 :         BN_CTX_free(ctx);
     496           0 :     if (buffer != NULL)
     497           0 :         OPENSSL_free(buffer);
     498           0 :     return (ret);
     499             : }
     500             : 
     501           0 : static int eckey_param_decode(EVP_PKEY *pkey,
     502             :                               const unsigned char **pder, int derlen)
     503             : {
     504             :     EC_KEY *eckey;
     505           0 :     if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
     506           0 :         ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
     507           0 :         return 0;
     508             :     }
     509           0 :     EVP_PKEY_assign_EC_KEY(pkey, eckey);
     510           0 :     return 1;
     511             : }
     512             : 
     513           0 : static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
     514             : {
     515           0 :     return i2d_ECParameters(pkey->pkey.ec, pder);
     516             : }
     517             : 
     518           0 : static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
     519             :                              ASN1_PCTX *ctx)
     520             : {
     521           0 :     return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
     522             : }
     523             : 
     524           0 : static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
     525             :                            ASN1_PCTX *ctx)
     526             : {
     527           0 :     return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
     528             : }
     529             : 
     530           0 : static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
     531             :                             ASN1_PCTX *ctx)
     532             : {
     533           0 :     return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
     534             : }
     535             : 
     536           0 : static int old_ec_priv_decode(EVP_PKEY *pkey,
     537             :                               const unsigned char **pder, int derlen)
     538             : {
     539             :     EC_KEY *ec;
     540           0 :     if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
     541           0 :         ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
     542           0 :         return 0;
     543             :     }
     544           0 :     EVP_PKEY_assign_EC_KEY(pkey, ec);
     545           0 :     return 1;
     546             : }
     547             : 
     548           0 : static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
     549             : {
     550           0 :     return i2d_ECPrivateKey(pkey->pkey.ec, pder);
     551             : }
     552             : 
     553           0 : static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
     554             : {
     555           0 :     switch (op) {
     556             :     case ASN1_PKEY_CTRL_PKCS7_SIGN:
     557           0 :         if (arg1 == 0) {
     558             :             int snid, hnid;
     559             :             X509_ALGOR *alg1, *alg2;
     560           0 :             PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
     561           0 :             if (alg1 == NULL || alg1->algorithm == NULL)
     562           0 :                 return -1;
     563           0 :             hnid = OBJ_obj2nid(alg1->algorithm);
     564           0 :             if (hnid == NID_undef)
     565             :                 return -1;
     566           0 :             if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
     567             :                 return -1;
     568           0 :             X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
     569             :         }
     570             :         return 1;
     571             : #ifndef OPENSSL_NO_CMS
     572             :     case ASN1_PKEY_CTRL_CMS_SIGN:
     573           0 :         if (arg1 == 0) {
     574             :             int snid, hnid;
     575             :             X509_ALGOR *alg1, *alg2;
     576           0 :             CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
     577           0 :             if (alg1 == NULL || alg1->algorithm == NULL)
     578           0 :                 return -1;
     579           0 :             hnid = OBJ_obj2nid(alg1->algorithm);
     580           0 :             if (hnid == NID_undef)
     581             :                 return -1;
     582           0 :             if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
     583             :                 return -1;
     584           0 :             X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
     585             :         }
     586             :         return 1;
     587             : 
     588             :     case ASN1_PKEY_CTRL_CMS_ENVELOPE:
     589           0 :         if (arg1 == 1)
     590           0 :             return ecdh_cms_decrypt(arg2);
     591           0 :         else if (arg1 == 0)
     592           0 :             return ecdh_cms_encrypt(arg2);
     593             :         return -2;
     594             : 
     595             :     case ASN1_PKEY_CTRL_CMS_RI_TYPE:
     596           0 :         *(int *)arg2 = CMS_RECIPINFO_AGREE;
     597           0 :         return 1;
     598             : #endif
     599             : 
     600             :     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
     601           0 :         *(int *)arg2 = NID_sha256;
     602           0 :         return 2;
     603             : 
     604             :     default:
     605             :         return -2;
     606             : 
     607             :     }
     608             : 
     609             : }
     610             : 
     611             : const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
     612             :     EVP_PKEY_EC,
     613             :     EVP_PKEY_EC,
     614             :     0,
     615             :     "EC",
     616             :     "OpenSSL EC algorithm",
     617             : 
     618             :     eckey_pub_decode,
     619             :     eckey_pub_encode,
     620             :     eckey_pub_cmp,
     621             :     eckey_pub_print,
     622             : 
     623             :     eckey_priv_decode,
     624             :     eckey_priv_encode,
     625             :     eckey_priv_print,
     626             : 
     627             :     int_ec_size,
     628             :     ec_bits,
     629             : 
     630             :     eckey_param_decode,
     631             :     eckey_param_encode,
     632             :     ec_missing_parameters,
     633             :     ec_copy_parameters,
     634             :     ec_cmp_parameters,
     635             :     eckey_param_print,
     636             :     0,
     637             : 
     638             :     int_ec_free,
     639             :     ec_pkey_ctrl,
     640             :     old_ec_priv_decode,
     641             :     old_ec_priv_encode
     642             : };
     643             : 
     644             : #ifndef OPENSSL_NO_CMS
     645             : 
     646           0 : static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
     647             :                                 X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
     648             : {
     649             :     ASN1_OBJECT *aoid;
     650             :     int atype;
     651             :     void *aval;
     652             :     int rv = 0;
     653             :     EVP_PKEY *pkpeer = NULL;
     654           0 :     EC_KEY *ecpeer = NULL;
     655             :     const unsigned char *p;
     656             :     int plen;
     657           0 :     X509_ALGOR_get0(&aoid, &atype, &aval, alg);
     658           0 :     if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
     659             :         goto err;
     660             :     /* If absent parameters get group from main key */
     661           0 :     if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
     662             :         const EC_GROUP *grp;
     663             :         EVP_PKEY *pk;
     664           0 :         pk = EVP_PKEY_CTX_get0_pkey(pctx);
     665           0 :         if (!pk)
     666             :             goto err;
     667           0 :         grp = EC_KEY_get0_group(pk->pkey.ec);
     668           0 :         ecpeer = EC_KEY_new();
     669           0 :         if (!ecpeer)
     670             :             goto err;
     671           0 :         if (!EC_KEY_set_group(ecpeer, grp))
     672             :             goto err;
     673             :     } else {
     674           0 :         ecpeer = eckey_type2param(atype, aval);
     675           0 :         if (!ecpeer)
     676             :             goto err;
     677             :     }
     678             :     /* We have parameters now set public key */
     679           0 :     plen = ASN1_STRING_length(pubkey);
     680           0 :     p = ASN1_STRING_data(pubkey);
     681           0 :     if (!p || !plen)
     682             :         goto err;
     683           0 :     if (!o2i_ECPublicKey(&ecpeer, &p, plen))
     684             :         goto err;
     685           0 :     pkpeer = EVP_PKEY_new();
     686           0 :     if (!pkpeer)
     687             :         goto err;
     688           0 :     EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
     689           0 :     if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
     690             :         rv = 1;
     691             :  err:
     692           0 :     if (ecpeer)
     693           0 :         EC_KEY_free(ecpeer);
     694           0 :     if (pkpeer)
     695           0 :         EVP_PKEY_free(pkpeer);
     696           0 :     return rv;
     697             : }
     698             : 
     699             : /* Set KDF parameters based on KDF NID */
     700           0 : static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
     701             : {
     702             :     int kdf_nid, kdfmd_nid, cofactor;
     703             :     const EVP_MD *kdf_md;
     704           0 :     if (eckdf_nid == NID_undef)
     705             :         return 0;
     706             : 
     707             :     /* Lookup KDF type, cofactor mode and digest */
     708           0 :     if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
     709             :         return 0;
     710             : 
     711           0 :     if (kdf_nid == NID_dh_std_kdf)
     712             :         cofactor = 0;
     713           0 :     else if (kdf_nid == NID_dh_cofactor_kdf)
     714             :         cofactor = 1;
     715             :     else
     716             :         return 0;
     717             : 
     718           0 :     if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
     719             :         return 0;
     720             : 
     721           0 :     if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0)
     722             :         return 0;
     723             : 
     724           0 :     kdf_md = EVP_get_digestbynid(kdfmd_nid);
     725           0 :     if (!kdf_md)
     726             :         return 0;
     727             : 
     728           0 :     if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
     729             :         return 0;
     730           0 :     return 1;
     731             : }
     732             : 
     733           0 : static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
     734             : {
     735             :     int rv = 0;
     736             : 
     737             :     X509_ALGOR *alg, *kekalg = NULL;
     738             :     ASN1_OCTET_STRING *ukm;
     739             :     const unsigned char *p;
     740           0 :     unsigned char *der = NULL;
     741             :     int plen, keylen;
     742             :     const EVP_CIPHER *kekcipher;
     743             :     EVP_CIPHER_CTX *kekctx;
     744             : 
     745           0 :     if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
     746             :         return 0;
     747             : 
     748           0 :     if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
     749           0 :         ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
     750           0 :         return 0;
     751             :     }
     752             : 
     753           0 :     if (alg->parameter->type != V_ASN1_SEQUENCE)
     754             :         return 0;
     755             : 
     756           0 :     p = alg->parameter->value.sequence->data;
     757           0 :     plen = alg->parameter->value.sequence->length;
     758           0 :     kekalg = d2i_X509_ALGOR(NULL, &p, plen);
     759           0 :     if (!kekalg)
     760             :         goto err;
     761           0 :     kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
     762           0 :     if (!kekctx)
     763             :         goto err;
     764           0 :     kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
     765           0 :     if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
     766             :         goto err;
     767           0 :     if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
     768             :         goto err;
     769           0 :     if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
     770             :         goto err;
     771             : 
     772           0 :     keylen = EVP_CIPHER_CTX_key_length(kekctx);
     773           0 :     if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
     774             :         goto err;
     775             : 
     776           0 :     plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
     777             : 
     778           0 :     if (!plen)
     779             :         goto err;
     780             : 
     781           0 :     if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
     782             :         goto err;
     783           0 :     der = NULL;
     784             : 
     785             :     rv = 1;
     786             :  err:
     787           0 :     if (kekalg)
     788           0 :         X509_ALGOR_free(kekalg);
     789           0 :     if (der)
     790           0 :         OPENSSL_free(der);
     791           0 :     return rv;
     792             : }
     793             : 
     794           0 : static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
     795             : {
     796             :     EVP_PKEY_CTX *pctx;
     797           0 :     pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
     798           0 :     if (!pctx)
     799             :         return 0;
     800             :     /* See if we need to set peer key */
     801           0 :     if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
     802             :         X509_ALGOR *alg;
     803             :         ASN1_BIT_STRING *pubkey;
     804           0 :         if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
     805             :                                                  NULL, NULL, NULL))
     806           0 :             return 0;
     807           0 :         if (!alg || !pubkey)
     808             :             return 0;
     809           0 :         if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
     810           0 :             ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR);
     811           0 :             return 0;
     812             :         }
     813             :     }
     814             :     /* Set ECDH derivation parameters and initialise unwrap context */
     815           0 :     if (!ecdh_cms_set_shared_info(pctx, ri)) {
     816           0 :         ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR);
     817           0 :         return 0;
     818             :     }
     819             :     return 1;
     820             : }
     821             : 
     822           0 : static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
     823             : {
     824             :     EVP_PKEY_CTX *pctx;
     825             :     EVP_PKEY *pkey;
     826             :     EVP_CIPHER_CTX *ctx;
     827             :     int keylen;
     828             :     X509_ALGOR *talg, *wrap_alg = NULL;
     829             :     ASN1_OBJECT *aoid;
     830             :     ASN1_BIT_STRING *pubkey;
     831             :     ASN1_STRING *wrap_str;
     832             :     ASN1_OCTET_STRING *ukm;
     833           0 :     unsigned char *penc = NULL;
     834             :     int penclen;
     835             :     int rv = 0;
     836             :     int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
     837             :     const EVP_MD *kdf_md;
     838           0 :     pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
     839           0 :     if (!pctx)
     840             :         return 0;
     841             :     /* Get ephemeral key */
     842           0 :     pkey = EVP_PKEY_CTX_get0_pkey(pctx);
     843           0 :     if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
     844             :                                              NULL, NULL, NULL))
     845             :         goto err;
     846           0 :     X509_ALGOR_get0(&aoid, NULL, NULL, talg);
     847             :     /* Is everything uninitialised? */
     848           0 :     if (aoid == OBJ_nid2obj(NID_undef)) {
     849             : 
     850           0 :         EC_KEY *eckey = pkey->pkey.ec;
     851             :         /* Set the key */
     852             :         unsigned char *p;
     853             : 
     854           0 :         penclen = i2o_ECPublicKey(eckey, NULL);
     855           0 :         if (penclen <= 0)
     856             :             goto err;
     857           0 :         penc = OPENSSL_malloc(penclen);
     858           0 :         if (!penc)
     859             :             goto err;
     860           0 :         p = penc;
     861           0 :         penclen = i2o_ECPublicKey(eckey, &p);
     862           0 :         if (penclen <= 0)
     863             :             goto err;
     864           0 :         ASN1_STRING_set0(pubkey, penc, penclen);
     865           0 :         pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
     866           0 :         pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
     867             : 
     868           0 :         penc = NULL;
     869           0 :         X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
     870             :                         V_ASN1_UNDEF, NULL);
     871             :     }
     872             : 
     873             :     /* See if custom paraneters set */
     874           0 :     kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
     875           0 :     if (kdf_type <= 0)
     876             :         goto err;
     877           0 :     if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
     878             :         goto err;
     879           0 :     ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
     880           0 :     if (ecdh_nid < 0)
     881             :         goto err;
     882           0 :     else if (ecdh_nid == 0)
     883             :         ecdh_nid = NID_dh_std_kdf;
     884           0 :     else if (ecdh_nid == 1)
     885             :         ecdh_nid = NID_dh_cofactor_kdf;
     886             : 
     887           0 :     if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
     888             :         kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
     889           0 :         if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
     890             :             goto err;
     891             :     } else
     892             :         /* Uknown KDF */
     893             :         goto err;
     894           0 :     if (kdf_md == NULL) {
     895             :         /* Fixme later for better MD */
     896           0 :         kdf_md = EVP_sha1();
     897           0 :         if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
     898             :             goto err;
     899             :     }
     900             : 
     901           0 :     if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
     902             :         goto err;
     903             : 
     904             :     /* Lookup NID for KDF+cofactor+digest */
     905             : 
     906           0 :     if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
     907             :         goto err;
     908             :     /* Get wrap NID */
     909           0 :     ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
     910           0 :     wrap_nid = EVP_CIPHER_CTX_type(ctx);
     911           0 :     keylen = EVP_CIPHER_CTX_key_length(ctx);
     912             : 
     913             :     /* Package wrap algorithm in an AlgorithmIdentifier */
     914             : 
     915           0 :     wrap_alg = X509_ALGOR_new();
     916           0 :     if (!wrap_alg)
     917             :         goto err;
     918           0 :     wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
     919           0 :     wrap_alg->parameter = ASN1_TYPE_new();
     920           0 :     if (!wrap_alg->parameter)
     921             :         goto err;
     922           0 :     if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
     923             :         goto err;
     924           0 :     if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
     925           0 :         ASN1_TYPE_free(wrap_alg->parameter);
     926           0 :         wrap_alg->parameter = NULL;
     927             :     }
     928             : 
     929           0 :     if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
     930             :         goto err;
     931             : 
     932           0 :     penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
     933             : 
     934           0 :     if (!penclen)
     935             :         goto err;
     936             : 
     937           0 :     if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
     938             :         goto err;
     939           0 :     penc = NULL;
     940             : 
     941             :     /*
     942             :      * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
     943             :      * of another AlgorithmIdentifier.
     944             :      */
     945           0 :     penclen = i2d_X509_ALGOR(wrap_alg, &penc);
     946           0 :     if (!penc || !penclen)
     947             :         goto err;
     948           0 :     wrap_str = ASN1_STRING_new();
     949           0 :     if (!wrap_str)
     950             :         goto err;
     951           0 :     ASN1_STRING_set0(wrap_str, penc, penclen);
     952           0 :     penc = NULL;
     953           0 :     X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
     954             : 
     955             :     rv = 1;
     956             : 
     957             :  err:
     958           0 :     if (penc)
     959           0 :         OPENSSL_free(penc);
     960           0 :     if (wrap_alg)
     961           0 :         X509_ALGOR_free(wrap_alg);
     962           0 :     return rv;
     963             : }
     964             : 
     965             : #endif

Generated by: LCOV version 1.10