LCOV - code coverage report
Current view: top level - ec - ec_pmeth.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 111 226 49.1 %
Date: 2014-08-02 Functions: 7 11 63.6 %
Branches: 59 164 36.0 %

           Branch data     Line data    Source code
       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                 :            :  */
      57                 :            : 
      58                 :            : #include <stdio.h>
      59                 :            : #include "cryptlib.h"
      60                 :            : #include <openssl/asn1t.h>
      61                 :            : #include <openssl/x509.h>
      62                 :            : #include <openssl/ec.h>
      63                 :            : #include "ec_lcl.h"
      64                 :            : #include <openssl/ecdsa.h>
      65                 :            : #include <openssl/evp.h>
      66                 :            : #include "evp_locl.h"
      67                 :            : 
      68                 :            : /* EC pkey context structure */
      69                 :            : 
      70                 :            : typedef struct
      71                 :            :         {
      72                 :            :         /* Key and paramgen group */
      73                 :            :         EC_GROUP *gen_group;
      74                 :            :         /* message digest */
      75                 :            :         const EVP_MD *md;
      76                 :            :         /* Duplicate key if custom cofactor needed */
      77                 :            :         EC_KEY *co_key;
      78                 :            :         /* Cofactor mode */
      79                 :            :         signed char cofactor_mode;
      80                 :            :         /* KDF (if any) to use for ECDH */
      81                 :            :         char kdf_type;
      82                 :            :         /* Message digest to use for key derivation */
      83                 :            :         const EVP_MD *kdf_md;
      84                 :            :         /* User key material */
      85                 :            :         unsigned char *kdf_ukm;
      86                 :            :         size_t kdf_ukmlen;
      87                 :            :         /* KDF output length */
      88                 :            :         size_t kdf_outlen;
      89                 :            : 
      90                 :            :         } EC_PKEY_CTX;
      91                 :            : 
      92                 :          9 : static int pkey_ec_init(EVP_PKEY_CTX *ctx)
      93                 :            :         {
      94                 :            :         EC_PKEY_CTX *dctx;
      95                 :          9 :         dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
      96         [ +  - ]:          9 :         if (!dctx)
      97                 :            :                 return 0;
      98                 :          9 :         dctx->gen_group = NULL;
      99                 :          9 :         dctx->md = NULL;
     100                 :            : 
     101                 :          9 :         dctx->cofactor_mode = -1;
     102                 :          9 :         dctx->co_key = NULL;
     103                 :          9 :         dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
     104                 :          9 :         dctx->kdf_md = NULL;
     105                 :          9 :         dctx->kdf_outlen = 0;
     106                 :          9 :         dctx->kdf_ukm = NULL;
     107                 :          9 :         dctx->kdf_ukmlen = 0;
     108                 :            : 
     109                 :          9 :         ctx->data = dctx;
     110                 :            : 
     111                 :          9 :         return 1;
     112                 :            :         }
     113                 :            : 
     114                 :          0 : static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
     115                 :            :         {
     116                 :            :         EC_PKEY_CTX *dctx, *sctx;
     117         [ #  # ]:          0 :         if (!pkey_ec_init(dst))
     118                 :            :                 return 0;
     119                 :          0 :         sctx = src->data;
     120                 :          0 :         dctx = dst->data;
     121         [ #  # ]:          0 :         if (sctx->gen_group)
     122                 :            :                 {
     123                 :          0 :                 dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
     124         [ #  # ]:          0 :                 if (!dctx->gen_group)
     125                 :            :                         return 0;
     126                 :            :                 }
     127                 :          0 :         dctx->md = sctx->md;
     128                 :            : 
     129         [ #  # ]:          0 :         if (sctx->co_key)
     130                 :            :                 {
     131                 :          0 :                 dctx->co_key = EC_KEY_dup(sctx->co_key);
     132         [ #  # ]:          0 :                 if (!dctx->co_key)
     133                 :            :                         return 0;
     134                 :            :                 }
     135                 :          0 :         dctx->kdf_type = sctx->kdf_type;
     136                 :          0 :         dctx->kdf_md = sctx->kdf_md;
     137                 :          0 :         dctx->kdf_outlen = sctx->kdf_outlen;
     138         [ #  # ]:          0 :         if (sctx->kdf_ukm)
     139                 :            :                 {
     140                 :          0 :                 dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
     141         [ #  # ]:          0 :                 if (!dctx->kdf_ukm)
     142                 :            :                         return 0;
     143                 :            :                 }
     144                 :            :         else
     145                 :          0 :                 dctx->kdf_ukm = NULL;
     146                 :          0 :         dctx->kdf_ukmlen = sctx->kdf_ukmlen;
     147                 :          0 :         return 1;
     148                 :            :         }
     149                 :            : 
     150                 :          9 : static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
     151                 :            :         {
     152                 :          9 :         EC_PKEY_CTX *dctx = ctx->data;
     153         [ +  - ]:          9 :         if (dctx)
     154                 :            :                 {
     155         [ -  + ]:          9 :                 if (dctx->gen_group)
     156                 :          0 :                         EC_GROUP_free(dctx->gen_group);
     157         [ +  + ]:          9 :                 if (dctx->co_key)
     158                 :          2 :                         EC_KEY_free(dctx->co_key);
     159         [ +  + ]:          9 :                 if (dctx->kdf_ukm)
     160                 :          6 :                         OPENSSL_free(dctx->kdf_ukm);
     161                 :          9 :                 OPENSSL_free(dctx);
     162                 :            :                 }
     163                 :          9 :         }
     164                 :            : 
     165                 :          0 : static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
     166                 :            :                                         const unsigned char *tbs, size_t tbslen)
     167                 :            :         {
     168                 :            :         int ret, type;
     169                 :            :         unsigned int sltmp;
     170                 :          0 :         EC_PKEY_CTX *dctx = ctx->data;
     171                 :          0 :         EC_KEY *ec = ctx->pkey->pkey.ec;
     172                 :            : 
     173         [ #  # ]:          0 :         if (!sig)
     174                 :            :                 {
     175                 :          0 :                 *siglen = ECDSA_size(ec);
     176                 :          0 :                 return 1;
     177                 :            :                 }
     178         [ #  # ]:          0 :         else if(*siglen < (size_t)ECDSA_size(ec))
     179                 :            :                 {
     180                 :          0 :                 ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
     181                 :          0 :                 return 0;
     182                 :            :                 }
     183                 :            : 
     184         [ #  # ]:          0 :         if (dctx->md)
     185                 :          0 :                 type = EVP_MD_type(dctx->md);
     186                 :            :         else
     187                 :            :                 type = NID_sha1;
     188                 :            : 
     189                 :            : 
     190                 :          0 :         ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
     191                 :            : 
     192         [ #  # ]:          0 :         if (ret <= 0)
     193                 :            :                 return ret;
     194                 :          0 :         *siglen = (size_t)sltmp;
     195                 :          0 :         return 1;
     196                 :            :         }
     197                 :            : 
     198                 :          0 : static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
     199                 :            :                                         const unsigned char *sig, size_t siglen,
     200                 :            :                                         const unsigned char *tbs, size_t tbslen)
     201                 :            :         {
     202                 :            :         int ret, type;
     203                 :          0 :         EC_PKEY_CTX *dctx = ctx->data;
     204                 :          0 :         EC_KEY *ec = ctx->pkey->pkey.ec;
     205                 :            : 
     206         [ #  # ]:          0 :         if (dctx->md)
     207                 :          0 :                 type = EVP_MD_type(dctx->md);
     208                 :            :         else
     209                 :            :                 type = NID_sha1;
     210                 :            : 
     211                 :          0 :         ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
     212                 :            : 
     213                 :          0 :         return ret;
     214                 :            :         }
     215                 :            : 
     216                 :         12 : static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
     217                 :            :         {
     218                 :            :         int ret;
     219                 :            :         size_t outlen;
     220                 :         12 :         const EC_POINT *pubkey = NULL;
     221                 :            :         EC_KEY *eckey;
     222                 :         12 :         EC_PKEY_CTX *dctx = ctx->data;
     223 [ +  - ][ -  + ]:         12 :         if (!ctx->pkey || !ctx->peerkey)
     224                 :            :                 {
     225                 :          0 :                 ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
     226                 :          0 :                 return 0;
     227                 :            :                 }
     228                 :            : 
     229         [ +  + ]:         12 :         eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
     230                 :            : 
     231         [ +  + ]:         12 :         if (!key)
     232                 :            :                 {
     233                 :            :                 const EC_GROUP *group;
     234                 :          6 :                 group = EC_KEY_get0_group(eckey);
     235                 :          6 :                 *keylen = (EC_GROUP_get_degree(group) + 7)/8;
     236                 :          6 :                 return 1;
     237                 :            :                 }
     238                 :          6 :         pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
     239                 :            : 
     240                 :            :         /* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
     241                 :            :          * not an error, the result is truncated.
     242                 :            :          */
     243                 :            : 
     244                 :          6 :         outlen = *keylen;
     245                 :            :                 
     246                 :          6 :         ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0);
     247         [ +  - ]:          6 :         if (ret < 0)
     248                 :            :                 return ret;
     249                 :          6 :         *keylen = ret;
     250                 :          6 :         return 1;
     251                 :            :         }
     252                 :            : 
     253                 :          6 : static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
     254                 :            :                                 unsigned char *key, size_t *keylen)
     255                 :            :         {
     256                 :          6 :         EC_PKEY_CTX *dctx = ctx->data;
     257                 :          6 :         unsigned char *ktmp = NULL;
     258                 :            :         size_t ktmplen;
     259                 :          6 :         int rv = 0;
     260         [ -  + ]:          6 :         if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE)
     261                 :          0 :                 return pkey_ec_derive(ctx, key, keylen);
     262         [ -  + ]:          6 :         if (!key)
     263                 :            :                 {
     264                 :          0 :                 *keylen = dctx->kdf_outlen;
     265                 :          0 :                 return 1;
     266                 :            :                 }
     267         [ +  - ]:          6 :         if (*keylen != dctx->kdf_outlen)
     268                 :            :                 return 0;
     269         [ +  - ]:          6 :         if (!pkey_ec_derive(ctx, NULL, &ktmplen))
     270                 :            :                 return 0;
     271                 :          6 :         ktmp = OPENSSL_malloc(ktmplen);
     272         [ +  - ]:          6 :         if (!ktmp)
     273                 :            :                 return 0;
     274         [ +  - ]:          6 :         if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
     275                 :            :                 goto err;
     276                 :            :         /* Do KDF stuff */
     277         [ +  - ]:          6 :         if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen, 
     278                 :          6 :                                 dctx->kdf_ukm, dctx->kdf_ukmlen,
     279                 :            :                                 dctx->kdf_md))
     280                 :            :                 goto err;
     281                 :          6 :         rv = 1;
     282                 :            : 
     283                 :            :         err:
     284         [ +  - ]:          6 :         if (ktmp)
     285                 :            :                 {
     286                 :          6 :                 OPENSSL_cleanse(ktmp, ktmplen);
     287                 :          6 :                 OPENSSL_free(ktmp);
     288                 :            :                 }
     289                 :          6 :         return rv;
     290                 :            :         }
     291                 :            : 
     292                 :         49 : static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
     293                 :            :         {
     294                 :         49 :         EC_PKEY_CTX *dctx = ctx->data;
     295                 :            :         EC_GROUP *group;
     296   [ -  -  +  +  :         49 :         switch (type)
          +  +  +  -  +  
             -  -  -  -  
                      + ]
     297                 :            :                 {
     298                 :            :                 case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
     299                 :          0 :                 group = EC_GROUP_new_by_curve_name(p1);
     300         [ #  # ]:          0 :                 if (group == NULL)
     301                 :            :                         {
     302                 :          0 :                         ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
     303                 :          0 :                         return 0;
     304                 :            :                         }
     305         [ #  # ]:          0 :                 if (dctx->gen_group)
     306                 :          0 :                         EC_GROUP_free(dctx->gen_group);
     307                 :          0 :                 dctx->gen_group = group;
     308                 :          0 :                 return 1;
     309                 :            : 
     310                 :            :                 case EVP_PKEY_CTRL_EC_PARAM_ENC:
     311         [ #  # ]:          0 :                 if (!dctx->gen_group)
     312                 :            :                         {
     313                 :          0 :                         ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
     314                 :          0 :                         return 0;
     315                 :            :                         }
     316                 :          0 :                 EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
     317                 :          0 :                 return 1;
     318                 :            : 
     319                 :            :                 case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
     320         [ +  + ]:          7 :                 if (p1 == -2)
     321                 :            :                         {
     322         [ +  + ]:          3 :                         if (dctx->cofactor_mode != -1)
     323                 :          1 :                                 return dctx->cofactor_mode;
     324                 :            :                         else
     325                 :            :                                 {
     326                 :          2 :                                 EC_KEY *ec_key = ctx->pkey->pkey.ec;
     327                 :          2 :                                 return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
     328                 :            :                                 }
     329                 :            :                         }
     330         [ +  - ]:          4 :                 else if (p1 < -1 || p1 > 1)
     331                 :            :                         return -2;
     332                 :          4 :                 dctx->cofactor_mode = p1;
     333         [ +  - ]:          4 :                 if (p1 != -1)
     334                 :            :                         {
     335                 :          4 :                         EC_KEY *ec_key = ctx->pkey->pkey.ec;
     336         [ +  - ]:          4 :                         if (!ec_key->group)
     337                 :            :                                 return -2;
     338                 :            :                         /* If cofactor is 1 cofactor mode does nothing */
     339 [ +  - ][ +  + ]:          4 :                         if (BN_is_one(&ec_key->group->cofactor))
                 [ -  + ]
     340                 :            :                                 return 1;
     341         [ +  - ]:          2 :                         if (!dctx->co_key)
     342                 :            :                                 {
     343                 :          2 :                                 dctx->co_key = EC_KEY_dup(ec_key);
     344         [ +  - ]:          2 :                                 if (!dctx->co_key)
     345                 :            :                                         return 0;
     346                 :            :                                 }
     347         [ +  - ]:          2 :                         if (p1)
     348                 :          2 :                                 EC_KEY_set_flags(dctx->co_key,
     349                 :            :                                                         EC_FLAG_COFACTOR_ECDH);
     350                 :            :                         else
     351                 :          0 :                                 EC_KEY_clear_flags(dctx->co_key,
     352                 :            :                                                         EC_FLAG_COFACTOR_ECDH);
     353                 :            :                         }
     354         [ #  # ]:          0 :                 else if (dctx->co_key)
     355                 :            :                         {
     356                 :          0 :                         EC_KEY_free(dctx->co_key);
     357                 :          0 :                         dctx->co_key = NULL;
     358                 :            :                         }
     359                 :            :                 return 1;
     360                 :            : 
     361                 :            :                 case EVP_PKEY_CTRL_EC_KDF_TYPE:
     362         [ +  + ]:          9 :                 if (p1 == -2)
     363                 :          3 :                         return dctx->kdf_type;
     364         [ +  - ]:          6 :                 if (p1 != EVP_PKEY_ECDH_KDF_NONE &&
     365                 :            :                     p1 != EVP_PKEY_ECDH_KDF_X9_62)
     366                 :            :                         return -2;
     367                 :          6 :                 dctx->kdf_type = p1;
     368                 :          6 :                 return 1;
     369                 :            : 
     370                 :            :                 case EVP_PKEY_CTRL_EC_KDF_MD:
     371                 :          6 :                 dctx->kdf_md = p2;
     372                 :          6 :                 return 1;
     373                 :            : 
     374                 :            :                 case EVP_PKEY_CTRL_GET_EC_KDF_MD:
     375                 :          3 :                 *(const EVP_MD **)p2 = dctx->kdf_md;
     376                 :          3 :                 return 1;
     377                 :            : 
     378                 :            :                 case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
     379         [ +  - ]:          6 :                 if (p1 <= 0)
     380                 :            :                         return -2;
     381                 :          6 :                 dctx->kdf_outlen = (size_t)p1;
     382                 :          6 :                 return 1;
     383                 :            : 
     384                 :            :                 case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
     385                 :          0 :                 *(int *)p2 = dctx->kdf_outlen;
     386                 :          0 :                 return 1;
     387                 :            : 
     388                 :            :                 case EVP_PKEY_CTRL_EC_KDF_UKM:
     389         [ -  + ]:          6 :                 if (dctx->kdf_ukm)
     390                 :          0 :                         OPENSSL_free(dctx->kdf_ukm);
     391                 :          6 :                 dctx->kdf_ukm = p2;
     392         [ +  - ]:          6 :                 if (p2)
     393                 :          6 :                         dctx->kdf_ukmlen = p1;
     394                 :            :                 else
     395                 :          0 :                         dctx->kdf_ukmlen = 0;
     396                 :            :                 return 1;
     397                 :            : 
     398                 :            :                 case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
     399                 :          0 :                 *(unsigned char **)p2 = dctx->kdf_ukm;
     400                 :          0 :                 return dctx->kdf_ukmlen;
     401                 :            : 
     402                 :            :                 case EVP_PKEY_CTRL_MD:
     403   [ #  #  #  # ]:          0 :                 if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
     404         [ #  # ]:          0 :                     EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
     405         [ #  # ]:          0 :                     EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
     406         [ #  # ]:          0 :                     EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
     407         [ #  # ]:          0 :                     EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
     408                 :          0 :                     EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
     409                 :            :                         {
     410                 :          0 :                         ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
     411                 :          0 :                         return 0;
     412                 :            :                         }
     413                 :          0 :                 dctx->md = p2;
     414                 :          0 :                 return 1;
     415                 :            : 
     416                 :            :                 case EVP_PKEY_CTRL_GET_MD:
     417                 :          0 :                 *(const EVP_MD **)p2 = dctx->md;
     418                 :          0 :                 return 1;
     419                 :            : 
     420                 :            :                 case EVP_PKEY_CTRL_PEER_KEY:
     421                 :            :                 /* Default behaviour is OK */
     422                 :            :                 case EVP_PKEY_CTRL_DIGESTINIT:
     423                 :            :                 case EVP_PKEY_CTRL_PKCS7_SIGN:
     424                 :            :                 case EVP_PKEY_CTRL_CMS_SIGN:
     425                 :            :                 return 1;
     426                 :            : 
     427                 :            :                 default:
     428                 :          0 :                 return -2;
     429                 :            : 
     430                 :            :                 }
     431                 :            :         }
     432                 :            :                         
     433                 :          3 : static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
     434                 :            :                         const char *type, const char *value)
     435                 :            :         {
     436         [ -  + ]:          3 :         if (!strcmp(type, "ec_paramgen_curve"))
     437                 :            :                 {
     438                 :            :                 int nid;
     439                 :          0 :                 nid = EC_curve_nist2nid(value);
     440         [ #  # ]:          0 :                 if (nid == NID_undef)
     441                 :          0 :                         nid = OBJ_sn2nid(value);
     442         [ #  # ]:          0 :                 if (nid == NID_undef)
     443                 :          0 :                         nid = OBJ_ln2nid(value);
     444         [ #  # ]:          0 :                 if (nid == NID_undef)
     445                 :            :                         {
     446                 :          0 :                         ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
     447                 :          0 :                         return 0;
     448                 :            :                         }
     449                 :          0 :                 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
     450                 :            :                 }
     451         [ -  + ]:          3 :         else if (!strcmp(type, "ec_param_enc"))
     452                 :            :                 {
     453                 :            :                 int param_enc;
     454         [ #  # ]:          0 :                 if (!strcmp(value, "explicit"))
     455                 :            :                         param_enc = 0;
     456         [ #  # ]:          0 :                 else if (!strcmp(value, "named_curve"))
     457                 :            :                         param_enc = OPENSSL_EC_NAMED_CURVE;
     458                 :            :                 else
     459                 :            :                         return -2;
     460                 :          0 :                 return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
     461                 :            :                 }
     462         [ +  + ]:          3 :         else if (!strcmp(type, "ecdh_kdf_md"))
     463                 :            :                 {
     464                 :            :                 const EVP_MD *md;
     465         [ -  + ]:          2 :                 if (!(md = EVP_get_digestbyname(value)))
     466                 :            :                         {
     467                 :          0 :                         ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST);
     468                 :          0 :                         return 0;
     469                 :            :                         }
     470                 :          2 :                 return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
     471                 :            :                 }
     472         [ +  - ]:          1 :         else if (!strcmp(type, "ecdh_cofactor_mode"))
     473                 :            :                 {
     474                 :            :                 int co_mode;
     475                 :          1 :                 co_mode = atoi(value);
     476                 :          1 :                 return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode);
     477                 :            :                 }
     478                 :            :                         
     479                 :            :         return -2;
     480                 :            :         }
     481                 :            : 
     482                 :          0 : static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     483                 :            :         {
     484                 :          0 :         EC_KEY *ec = NULL;
     485                 :          0 :         EC_PKEY_CTX *dctx = ctx->data;
     486                 :          0 :         int ret = 0;
     487         [ #  # ]:          0 :         if (dctx->gen_group == NULL)
     488                 :            :                 {
     489                 :          0 :                 ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
     490                 :          0 :                 return 0;
     491                 :            :                 }
     492                 :          0 :         ec = EC_KEY_new();
     493         [ #  # ]:          0 :         if (!ec)
     494                 :            :                 return 0;
     495                 :          0 :         ret = EC_KEY_set_group(ec, dctx->gen_group);
     496         [ #  # ]:          0 :         if (ret)
     497                 :          0 :                 EVP_PKEY_assign_EC_KEY(pkey, ec);
     498                 :            :         else
     499                 :          0 :                 EC_KEY_free(ec);
     500                 :          0 :         return ret;
     501                 :            :         }
     502                 :            : 
     503                 :          3 : static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     504                 :            :         {
     505                 :          3 :         EC_KEY *ec = NULL;
     506                 :          3 :         EC_PKEY_CTX *dctx = ctx->data;
     507 [ -  + ][ #  # ]:          3 :         if (ctx->pkey == NULL && dctx->gen_group == NULL)
     508                 :            :                 {
     509                 :          0 :                 ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
     510                 :          0 :                 return 0;
     511                 :            :                 }
     512                 :          3 :         ec = EC_KEY_new();
     513         [ +  - ]:          3 :         if (!ec)
     514                 :            :                 return 0;
     515                 :          3 :         EVP_PKEY_assign_EC_KEY(pkey, ec);
     516         [ +  - ]:          3 :         if (ctx->pkey)
     517                 :            :                 {
     518                 :            :                 /* Note: if error return, pkey is freed by parent routine */
     519         [ +  - ]:          3 :                 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
     520                 :            :                         return 0;
     521                 :            :                 }
     522                 :            :         else
     523                 :            :                 {
     524         [ #  # ]:          0 :                 if (!EC_KEY_set_group(ec, dctx->gen_group))
     525                 :            :                         return 0;
     526                 :            :                 }
     527                 :          3 :         return EC_KEY_generate_key(pkey->pkey.ec);
     528                 :            :         }
     529                 :            : 
     530                 :            : const EVP_PKEY_METHOD ec_pkey_meth = 
     531                 :            :         {
     532                 :            :         EVP_PKEY_EC,
     533                 :            :         0,
     534                 :            :         pkey_ec_init,
     535                 :            :         pkey_ec_copy,
     536                 :            :         pkey_ec_cleanup,
     537                 :            : 
     538                 :            :         0,
     539                 :            :         pkey_ec_paramgen,
     540                 :            : 
     541                 :            :         0,
     542                 :            :         pkey_ec_keygen,
     543                 :            : 
     544                 :            :         0,
     545                 :            :         pkey_ec_sign,
     546                 :            : 
     547                 :            :         0,
     548                 :            :         pkey_ec_verify,
     549                 :            : 
     550                 :            :         0,0,
     551                 :            : 
     552                 :            :         0,0,0,0,
     553                 :            : 
     554                 :            :         0,0,
     555                 :            : 
     556                 :            :         0,0,
     557                 :            : 
     558                 :            :         0,
     559                 :            :         pkey_ec_kdf_derive,
     560                 :            : 
     561                 :            :         pkey_ec_ctrl,
     562                 :            :         pkey_ec_ctrl_str
     563                 :            : 
     564                 :            :         };

Generated by: LCOV version 1.9