LCOV - code coverage report
Current view: top level - home/mbr/git/openssl.git/engines/ccgost - gost_pmeth.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 80 284 28.2 %
Date: 2014-08-02 Functions: 8 26 30.8 %
Branches: 16 153 10.5 %

           Branch data     Line data    Source code
       1                 :            : /**********************************************************************
       2                 :            :  *                          gost_pmeth.c                              *
       3                 :            :  *             Copyright (c) 2005-2006 Cryptocom LTD                  *
       4                 :            :  *         This file is distributed under the same license as OpenSSL *
       5                 :            :  *                                                                    *
       6                 :            :  *   Implementation of RFC 4357 (GOST R 34.10) Publick key method     *
       7                 :            :  *       for OpenSSL                                                  *
       8                 :            :  *          Requires OpenSSL 0.9.9 for compilation                    *
       9                 :            :  **********************************************************************/
      10                 :            : #include <openssl/evp.h>
      11                 :            : #include <openssl/objects.h>
      12                 :            : #include <openssl/ec.h>
      13                 :            : #include <openssl/x509v3.h> /*For string_to_hex */
      14                 :            : #include <stdlib.h>
      15                 :            : #include <string.h>
      16                 :            : #include <ctype.h>
      17                 :            : #include "gost_params.h"
      18                 :            : #include "gost_lcl.h"
      19                 :            : #include "e_gost_err.h"
      20                 :            : /*-------init, cleanup, copy - uniform for all algs  ---------------*/
      21                 :            : /* Allocates new gost_pmeth_data structure and assigns it as data */
      22                 :          0 : static int pkey_gost_init(EVP_PKEY_CTX *ctx)
      23                 :            :         {
      24                 :            :         struct gost_pmeth_data *data;
      25                 :          0 :         EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
      26                 :          0 :         data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
      27         [ #  # ]:          0 :         if (!data) return 0;
      28                 :            :         memset(data,0,sizeof(struct gost_pmeth_data));
      29 [ #  # ][ #  # ]:          0 :         if (pkey && EVP_PKEY_get0(pkey)) 
      30                 :            :                 {
      31      [ #  #  # ]:          0 :                 switch (EVP_PKEY_base_id(pkey)) {
      32                 :            :                 case NID_id_GostR3410_94:
      33                 :          0 :                   data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey));
      34                 :          0 :                   break;
      35                 :            :                 case NID_id_GostR3410_2001:
      36                 :          0 :                    data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
      37                 :          0 :                 break;
      38                 :            :                 default:
      39                 :            :                         return 0;
      40                 :            :                 }         
      41                 :            :                 }
      42                 :          0 :         EVP_PKEY_CTX_set_data(ctx,data);
      43                 :          0 :         return 1;
      44                 :            :         }
      45                 :            : 
      46                 :            : /* Copies contents of gost_pmeth_data structure */
      47                 :          0 : static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
      48                 :            :         {
      49                 :            :         struct gost_pmeth_data *dst_data,*src_data;
      50         [ #  # ]:          0 :         if (!pkey_gost_init(dst))
      51                 :            :                 {
      52                 :            :                 return 0;
      53                 :            :                 }
      54                 :          0 :         src_data = EVP_PKEY_CTX_get_data(src);
      55                 :          0 :         dst_data = EVP_PKEY_CTX_get_data(dst);
      56                 :          0 :         *dst_data = *src_data;
      57         [ #  # ]:          0 :         if (src_data -> shared_ukm) {
      58                 :          0 :                 dst_data->shared_ukm=NULL;
      59                 :            :         }       
      60                 :            :         return 1;
      61                 :            :         }
      62                 :            : 
      63                 :            : /* Frees up gost_pmeth_data structure */
      64                 :          0 : static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx)
      65                 :            :         {
      66                 :          0 :         struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
      67         [ #  # ]:          0 :         if (data->shared_ukm) OPENSSL_free(data->shared_ukm);
      68                 :          0 :         OPENSSL_free(data);
      69                 :          0 :         }       
      70                 :            : 
      71                 :            : /* --------------------- control functions  ------------------------------*/
      72                 :          0 : static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
      73                 :            :         {
      74                 :          0 :         struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
      75   [ #  #  #  #  :          0 :         switch (type)
                #  #  # ]
      76                 :            :                 {
      77                 :            :                 case EVP_PKEY_CTRL_MD:
      78                 :            :                 {
      79         [ #  # ]:          0 :                 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94)
      80                 :            :                         {
      81                 :          0 :                         GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
      82                 :          0 :                         return 0;
      83                 :            :                         }
      84                 :          0 :                 pctx->md = (EVP_MD *)p2;
      85                 :          0 :                 return 1;
      86                 :            :                 }
      87                 :            :                 break;
      88                 :            : 
      89                 :            :                 case EVP_PKEY_CTRL_GET_MD:
      90                 :          0 :                 *(const EVP_MD **)p2 = pctx->md;
      91                 :          0 :                 return 1;
      92                 :            : 
      93                 :            :                 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
      94                 :            :                 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
      95                 :            :                 case EVP_PKEY_CTRL_PKCS7_SIGN:
      96                 :            :                 case EVP_PKEY_CTRL_DIGESTINIT:
      97                 :            : #ifndef OPENSSL_NO_CMS          
      98                 :            :                 case EVP_PKEY_CTRL_CMS_ENCRYPT:
      99                 :            :                 case EVP_PKEY_CTRL_CMS_DECRYPT:
     100                 :            :                 case EVP_PKEY_CTRL_CMS_SIGN:
     101                 :            : #endif          
     102                 :            :                         return 1;
     103                 :            : 
     104                 :            :                 case EVP_PKEY_CTRL_GOST_PARAMSET:
     105                 :          0 :                         pctx->sign_param_nid = (int)p1;
     106                 :          0 :                         return 1;
     107                 :            :                 case EVP_PKEY_CTRL_SET_IV:
     108                 :          0 :                         pctx->shared_ukm=OPENSSL_malloc((int)p1);
     109                 :          0 :                         memcpy(pctx->shared_ukm,p2,(int) p1);
     110                 :          0 :                         return 1;
     111                 :            :                 case EVP_PKEY_CTRL_PEER_KEY:
     112         [ #  # ]:          0 :                         if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
     113                 :            :                                 return 1;
     114         [ #  # ]:          0 :                         if (p1 == 2)            /* TLS: peer key used? */
     115                 :          0 :                                 return pctx->peer_key_used;
     116         [ #  # ]:          0 :                         if (p1 == 3)            /* TLS: peer key used! */
     117                 :          0 :                                 return (pctx->peer_key_used = 1);
     118                 :            :                         return -2;
     119                 :            :                 }
     120                 :          0 :         return -2;
     121                 :            :         }
     122                 :            : 
     123                 :            : 
     124                 :          0 : static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
     125                 :            :         const char *type, const char *value)
     126                 :            :         {
     127                 :          0 :         int param_nid=0;
     128         [ #  # ]:          0 :         if(!strcmp(type, param_ctrl_string))
     129                 :            :                 {
     130         [ #  # ]:          0 :                 if (!value)
     131                 :            :                         {
     132                 :            :                         return 0;
     133                 :            :                         }
     134         [ #  # ]:          0 :                 if (strlen(value) == 1)
     135                 :            :                         {
     136   [ #  #  #  #  :          0 :                         switch(toupper((unsigned char)value[0]))
                      # ]
     137                 :            :                                 {
     138                 :            :                                 case 'A':
     139                 :            :                                         param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
     140                 :            :                                         break;
     141                 :            :                                 case 'B':
     142                 :          0 :                                         param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet;
     143                 :          0 :                                         break;
     144                 :            :                                 case 'C':
     145                 :          0 :                                         param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet;
     146                 :          0 :                                         break;
     147                 :            :                                 case 'D':
     148                 :          0 :                                         param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet;
     149                 :          0 :                                         break;
     150                 :            :                                 default:
     151                 :            :                                         return 0;
     152                 :            :                                         break;
     153                 :            :                                 }
     154                 :            :                         }
     155 [ #  # ][ #  # ]:          0 :                 else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
     156                 :            :                         {
     157   [ #  #  #  # ]:          0 :                         switch (toupper((unsigned char)value[1]))
     158                 :            :                                 {
     159                 :            :                                 case 'A':
     160                 :            :                                         param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
     161                 :            :                                         break;
     162                 :            :                                 case 'B':
     163                 :          0 :                                         param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet;
     164                 :          0 :                                         break;
     165                 :            :                                 case 'C':
     166                 :          0 :                                         param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet;
     167                 :          0 :                                         break;
     168                 :            :                                 default:
     169                 :            :                                         return 0;
     170                 :            :                                         break;
     171                 :            :                                 }
     172                 :            :                         }
     173                 :            :                 else
     174                 :            :                         {
     175                 :          0 :                         R3410_params *p = R3410_paramset;
     176                 :          0 :                         param_nid = OBJ_txt2nid(value);
     177         [ #  # ]:          0 :                         if (param_nid == NID_undef)
     178                 :            :                                 {
     179                 :            :                                 return 0;
     180                 :            :                                 }
     181         [ #  # ]:          0 :                         for (;p->nid != NID_undef;p++)
     182                 :            :                                 {
     183         [ #  # ]:          0 :                                 if (p->nid == param_nid) break;
     184                 :            :                                 }
     185         [ #  # ]:          0 :                         if (p->nid == NID_undef)
     186                 :            :                                 {
     187                 :          0 :                                 GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR,
     188                 :            :                                         GOST_R_INVALID_PARAMSET);
     189                 :          0 :                                 return 0;
     190                 :            :                                 }
     191                 :            :                         }
     192                 :            : 
     193                 :          0 :                 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
     194                 :            :                         param_nid, NULL);
     195                 :            :                 }
     196                 :            :         return -2;
     197                 :            :         }
     198                 :            : 
     199                 :          0 : static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
     200                 :            :         const char *type, const char *value)
     201                 :            :         {
     202                 :          0 :         int param_nid=0;
     203         [ #  # ]:          0 :         if(!strcmp(type, param_ctrl_string))
     204                 :            :                 {
     205         [ #  # ]:          0 :                 if (!value)
     206                 :            :                         {
     207                 :            :                         return 0;
     208                 :            :                         }
     209         [ #  # ]:          0 :                 if (strlen(value) == 1)
     210                 :            :                         {
     211   [ #  #  #  #  :          0 :                         switch(toupper((unsigned char)value[0]))
                      # ]
     212                 :            :                                 {
     213                 :            :                                 case 'A':
     214                 :            :                                         param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
     215                 :            :                                         break;  
     216                 :            :                                 case 'B':
     217                 :          0 :                                         param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
     218                 :          0 :                                         break;
     219                 :            :                                 case 'C':
     220                 :          0 :                                         param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
     221                 :          0 :                                         break;
     222                 :            :                                 case '0':
     223                 :          0 :                                         param_nid = NID_id_GostR3410_2001_TestParamSet;
     224                 :          0 :                                         break;
     225                 :            :                                 default:
     226                 :            :                                         return 0;
     227                 :            :                                         break;
     228                 :            :                                 }
     229                 :            :                         }
     230 [ #  # ][ #  # ]:          0 :                 else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
     231                 :            :                         {
     232      [ #  #  # ]:          0 :                         switch (toupper((unsigned char)value[1]))
     233                 :            :                                 {
     234                 :            :                                 case 'A':
     235                 :            :                                         param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
     236                 :            :                                         break;
     237                 :            :                                 case 'B':
     238                 :          0 :                                         param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
     239                 :          0 :                                         break;
     240                 :            :                                 default:
     241                 :            :                                         return 0;
     242                 :            :                                         break;
     243                 :            :                                 }
     244                 :            :                         }
     245                 :            :                 else
     246                 :            :                         {
     247                 :          0 :                         R3410_2001_params *p = R3410_2001_paramset;
     248                 :          0 :                         param_nid = OBJ_txt2nid(value);
     249         [ #  # ]:          0 :                         if (param_nid == NID_undef)
     250                 :            :                                 {
     251                 :            :                                 return 0;
     252                 :            :                                 }
     253         [ #  # ]:          0 :                         for (;p->nid != NID_undef;p++)
     254                 :            :                                 {
     255         [ #  # ]:          0 :                                 if (p->nid == param_nid) break;
     256                 :            :                                 }
     257         [ #  # ]:          0 :                         if (p->nid == NID_undef)
     258                 :            :                                 {
     259                 :          0 :                                 GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR,
     260                 :            :                                         GOST_R_INVALID_PARAMSET);
     261                 :          0 :                                 return 0;
     262                 :            :                                 }
     263                 :            :                         }
     264                 :            : 
     265                 :          0 :                 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
     266                 :            :                         param_nid, NULL);
     267                 :            :                 }
     268                 :            :         return -2;
     269                 :            :         }
     270                 :            : 
     271                 :            : /* --------------------- key generation  --------------------------------*/
     272                 :            : 
     273                 :          0 : static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) {
     274                 :          0 :         return 1;
     275                 :            : }       
     276                 :          0 : static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 
     277                 :            :         {
     278                 :          0 :         struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
     279                 :          0 :         DSA *dsa=NULL;
     280         [ #  # ]:          0 :         if (data->sign_param_nid == NID_undef)
     281                 :            :                 {
     282                 :          0 :                         GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN,
     283                 :            :                                 GOST_R_NO_PARAMETERS_SET);
     284                 :          0 :                         return 0;
     285                 :            :                 }
     286                 :          0 :         dsa = DSA_new();
     287         [ #  # ]:          0 :         if (!fill_GOST94_params(dsa,data->sign_param_nid))
     288                 :            :                 {
     289                 :          0 :                 DSA_free(dsa);
     290                 :          0 :                 return 0;
     291                 :            :                 }
     292                 :          0 :         EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa);
     293                 :          0 :         return 1;
     294                 :            :         }
     295                 :          0 : static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     296                 :            :         {
     297                 :          0 :         struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
     298                 :          0 :         EC_KEY *ec=NULL;
     299                 :            : 
     300         [ #  # ]:          0 :         if (data->sign_param_nid == NID_undef)
     301                 :            :                 {
     302                 :          0 :                         GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN,
     303                 :            :                                 GOST_R_NO_PARAMETERS_SET);
     304                 :          0 :                         return 0;
     305                 :            :                 }
     306                 :            :         if (!ec)        
     307                 :          0 :                 ec = EC_KEY_new();
     308         [ #  # ]:          0 :         if (!fill_GOST2001_params(ec,data->sign_param_nid))
     309                 :            :                 {
     310                 :          0 :                 EC_KEY_free(ec);
     311                 :          0 :                 return 0;
     312                 :            :                 }
     313                 :          0 :         EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec);
     314                 :          0 :         return 1;
     315                 :            :         }
     316                 :            : 
     317                 :            : /* Generates Gost_R3410_94_cp key */
     318                 :          0 : static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     319                 :            :         {
     320                 :            :         DSA *dsa;
     321         [ #  # ]:          0 :         if (!pkey_gost94_paramgen(ctx,pkey)) return 0;
     322                 :          0 :         dsa = EVP_PKEY_get0(pkey);
     323                 :          0 :         gost_sign_keygen(dsa);
     324                 :          0 :         return 1;
     325                 :            :         }
     326                 :            : 
     327                 :            : /* Generates GOST_R3410 2001 key and assigns it using specified type */
     328                 :          0 : static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     329                 :            :         {
     330                 :            :         EC_KEY *ec;
     331         [ #  # ]:          0 :     if (!pkey_gost01_paramgen(ctx,pkey)) return 0;
     332                 :          0 :         ec = EVP_PKEY_get0(pkey);
     333                 :          0 :         gost2001_keygen(ec);
     334                 :          0 :         return 1;
     335                 :            :         }
     336                 :            : 
     337                 :            : 
     338                 :            : 
     339                 :            : /* ----------- sign callbacks --------------------------------------*/
     340                 :            : 
     341                 :          0 : static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
     342                 :            :         const unsigned char *tbs, size_t tbs_len)
     343                 :            :         {
     344                 :          0 :         DSA_SIG *unpacked_sig=NULL;
     345                 :          0 :         EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
     346         [ #  # ]:          0 :         if (!siglen) return 0;
     347         [ #  # ]:          0 :         if (!sig)
     348                 :            :                 {
     349                 :          0 :                 *siglen= 64; /* better to check size of pkey->pkey.dsa-q */
     350                 :          0 :                 return 1;
     351                 :            :                 }       
     352                 :          0 :         unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
     353         [ #  # ]:          0 :         if (!unpacked_sig)
     354                 :            :                 {
     355                 :            :                 return 0;
     356                 :            :                 }
     357                 :          0 :         return pack_sign_cp(unpacked_sig,32,sig,siglen);
     358                 :            :         }
     359                 :            : 
     360                 :          0 : static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
     361                 :            :         const unsigned char *tbs, size_t tbs_len)
     362                 :            :         {
     363                 :          0 :         DSA_SIG *unpacked_sig=NULL;
     364                 :          0 :         EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
     365         [ #  # ]:          0 :         if (!siglen) return 0;
     366         [ #  # ]:          0 :         if (!sig)
     367                 :            :                 {
     368                 :          0 :                 *siglen= 64; /* better to check size of curve order*/
     369                 :          0 :                 return 1;
     370                 :            :                 }       
     371                 :          0 :         unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
     372         [ #  # ]:          0 :         if (!unpacked_sig)
     373                 :            :                 {
     374                 :            :                 return 0;
     375                 :            :                 }
     376                 :          0 :         return pack_sign_cp(unpacked_sig,32,sig,siglen);
     377                 :            :         }
     378                 :            : 
     379                 :            : /* ------------------- verify callbacks ---------------------------*/
     380                 :            : 
     381                 :          0 : static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
     382                 :            :         size_t siglen, const unsigned char *tbs, size_t tbs_len)
     383                 :            :         {
     384                 :          0 :         int ok = 0;
     385                 :          0 :         EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
     386                 :          0 :         DSA_SIG *s=unpack_cp_signature(sig,siglen);
     387         [ #  # ]:          0 :         if (!s) return 0;
     388         [ #  # ]:          0 :         if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
     389                 :          0 :         DSA_SIG_free(s);
     390                 :          0 :         return ok;
     391                 :            :         }
     392                 :            : 
     393                 :            : 
     394                 :          0 : static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
     395                 :            :         size_t siglen, const unsigned char *tbs, size_t tbs_len)
     396                 :            :         {
     397                 :          0 :         int ok = 0;
     398                 :          0 :         EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
     399                 :          0 :         DSA_SIG *s=unpack_cp_signature(sig,siglen);
     400         [ #  # ]:          0 :         if (!s) return 0;
     401                 :            : #ifdef DEBUG_SIGN       
     402                 :            :         fprintf(stderr,"R=");
     403                 :            :         BN_print_fp(stderr,s->r);
     404                 :            :         fprintf(stderr,"\nS=");
     405                 :            :         BN_print_fp(stderr,s->s);
     406                 :            :         fprintf(stderr,"\n");
     407                 :            : #endif  
     408         [ #  # ]:          0 :         if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
     409                 :          0 :         DSA_SIG_free(s);
     410                 :          0 :         return ok;
     411                 :            :         }
     412                 :            : 
     413                 :            : /* ------------- encrypt init -------------------------------------*/
     414                 :            : /* Generates ephermeral key */
     415                 :          0 : static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
     416                 :            :         {
     417                 :          0 :         return 1;
     418                 :            :         }
     419                 :            : /* --------------- Derive init ------------------------------------*/
     420                 :          0 : static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
     421                 :            : {
     422                 :          0 :         return 1;
     423                 :            : }
     424                 :            : /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
     425                 :         21 : static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
     426                 :            :         {
     427                 :            :         struct gost_mac_pmeth_data *data;
     428                 :         21 :         data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data));
     429         [ +  - ]:         21 :         if (!data) return 0;
     430                 :            :         memset(data,0,sizeof(struct gost_mac_pmeth_data));
     431                 :         21 :         EVP_PKEY_CTX_set_data(ctx,data);
     432                 :         21 :         return 1;
     433                 :            :         }       
     434                 :         21 : static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx)
     435                 :            :         {
     436                 :         21 :         struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
     437                 :         21 :         OPENSSL_free(data);
     438                 :         21 :         }       
     439                 :          7 : static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
     440                 :            :         {
     441                 :            :         struct gost_mac_pmeth_data *dst_data,*src_data;
     442         [ +  - ]:          7 :         if (!pkey_gost_mac_init(dst))
     443                 :            :                 {
     444                 :            :                 return 0;
     445                 :            :                 }
     446                 :          7 :         src_data = EVP_PKEY_CTX_get_data(src);
     447                 :          7 :         dst_data = EVP_PKEY_CTX_get_data(dst);
     448                 :          7 :         *dst_data = *src_data;
     449                 :          7 :         return 1;
     450                 :            :         }
     451                 :            :         
     452                 :         21 : static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
     453                 :            :         {
     454                 :         21 :         struct gost_mac_pmeth_data *data =
     455                 :            : (struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
     456                 :            : 
     457   [ +  -  +  +  :         21 :         switch (type)
                   -  - ]
     458                 :            :                 {
     459                 :            :                 case EVP_PKEY_CTRL_MD:
     460                 :            :                 {
     461         [ -  + ]:          7 :                 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC)
     462                 :            :                         {
     463                 :          0 :                         GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE);
     464                 :          0 :                         return 0;
     465                 :            :                         }
     466                 :          7 :                 data->md = (EVP_MD *)p2;
     467                 :          7 :                 return 1;
     468                 :            :                 }
     469                 :            :                 break;
     470                 :            : 
     471                 :            :                 case EVP_PKEY_CTRL_GET_MD:
     472                 :          0 :                 *(const EVP_MD **)p2 = data->md;
     473                 :          0 :                 return 1;
     474                 :            : 
     475                 :            :                 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
     476                 :            :                 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
     477                 :            :                 case EVP_PKEY_CTRL_PKCS7_SIGN:
     478                 :            :                         return 1;
     479                 :            :                 case EVP_PKEY_CTRL_SET_MAC_KEY:
     480         [ -  + ]:          7 :                         if (p1 != 32) 
     481                 :            :                                 {
     482                 :          0 :                                 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
     483                 :            :                                         GOST_R_INVALID_MAC_KEY_LENGTH);
     484                 :          0 :                                 return 0;
     485                 :            :                                 }
     486                 :            : 
     487                 :          7 :                         memcpy(data->key,p2,32);
     488                 :          7 :                         data->key_set = 1;
     489                 :          7 :                         return 1;
     490                 :            :                 case EVP_PKEY_CTRL_DIGESTINIT:
     491                 :            :                         { 
     492                 :          7 :                         EVP_MD_CTX *mctx = p2;
     493                 :            :                         void *key;
     494         [ +  - ]:          7 :                         if (!data->key_set)
     495                 :            :                                 { 
     496                 :          7 :                                 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
     497         [ -  + ]:          7 :                                 if (!pkey) 
     498                 :            :                                         {
     499                 :          0 :                                         GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
     500                 :          0 :                                         return 0;
     501                 :            :                                         }
     502                 :          7 :                                 key = EVP_PKEY_get0(pkey);
     503         [ -  + ]:          7 :                                 if (!key) 
     504                 :            :                                         {
     505                 :          0 :                                         GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
     506                 :          0 :                                         return 0;
     507                 :            :                                         }
     508                 :            :                                 } else {
     509                 :          0 :                                 key = &(data->key);
     510                 :            :                                 }
     511                 :          7 :                         return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key);
     512                 :            :                         }  
     513                 :            :                 }       
     514                 :          0 :         return -2;
     515                 :            :         }
     516                 :          0 : static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
     517                 :            :         const char *type, const char *value)
     518                 :            :         {
     519         [ #  # ]:          0 :         if (!strcmp(type, key_ctrl_string)) 
     520                 :            :                 {
     521         [ #  # ]:          0 :                 if (strlen(value)!=32) 
     522                 :            :                         {
     523                 :          0 :                         GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
     524                 :            :                                 GOST_R_INVALID_MAC_KEY_LENGTH);
     525                 :          0 :                         return 0;       
     526                 :            :                         }
     527                 :          0 :                 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
     528                 :            :                         32,(char *)value);
     529                 :            :                 }
     530         [ #  # ]:          0 :         if (!strcmp(type, hexkey_ctrl_string)) 
     531                 :            :                 {
     532                 :            :                         long keylen; int ret;
     533                 :          0 :                         unsigned char *keybuf=string_to_hex(value,&keylen);
     534         [ #  # ]:          0 :                         if (keylen != 32) 
     535                 :            :                                 {
     536                 :          0 :                                 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
     537                 :            :                                         GOST_R_INVALID_MAC_KEY_LENGTH);
     538                 :          0 :                                 OPENSSL_free(keybuf);
     539                 :          0 :                                 return 0;       
     540                 :            :                                 }
     541                 :          0 :                         ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
     542                 :            :                                 32,keybuf);
     543                 :          0 :                         OPENSSL_free(keybuf);
     544                 :          0 :                         return ret;
     545                 :            :         
     546                 :            :                 }
     547                 :            :         return -2;
     548                 :            :         }       
     549                 :            : 
     550                 :          7 : static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     551                 :            :         {
     552                 :          7 :                 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
     553                 :            :                 unsigned char *keydata;
     554         [ -  + ]:          7 :                 if (!data->key_set) 
     555                 :            :                 {
     556                 :          0 :                         GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_SET);
     557                 :          0 :                         return 0;
     558                 :            :                 }
     559                 :          7 :                 keydata = OPENSSL_malloc(32);
     560                 :          7 :                 memcpy(keydata,data->key,32);
     561                 :          7 :                 EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
     562                 :          7 :                 return 1;
     563                 :            :         }
     564                 :            : 
     565                 :          7 : static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
     566                 :            :         {
     567                 :          7 :         return 1;
     568                 :            : }
     569                 :            : 
     570                 :          7 : static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx)
     571                 :            :         {
     572                 :          7 :                 unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(int)!=sizeof(size_t)*/
     573                 :            :                 int ret;
     574         [ -  + ]:          7 :                 if (!sig) 
     575                 :            :                         {
     576                 :          0 :                         *siglen = 4;
     577                 :          0 :                         return 1;
     578                 :            :                         }
     579                 :          7 :                 ret=EVP_DigestFinal_ex(mctx,sig,&tmpsiglen);
     580                 :          7 :                 *siglen = tmpsiglen;
     581                 :          7 :                 return ret;
     582                 :            :         }
     583                 :            : /* ----------------------------------------------------------------*/
     584                 :       2184 : int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags)
     585                 :            :         {
     586                 :       2184 :         *pmeth = EVP_PKEY_meth_new(id, flags);
     587         [ +  - ]:       2184 :         if (!*pmeth) return 0;
     588                 :            : 
     589   [ +  +  +  - ]:       2184 :         switch (id)
     590                 :            :                 {
     591                 :            :                 case NID_id_GostR3410_94:
     592                 :        728 :                         EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_str);
     593                 :        728 :                         EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keygen);
     594                 :        728 :                         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign);
     595                 :        728 :                         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify);
     596                 :        728 :                         EVP_PKEY_meth_set_encrypt(*pmeth,
     597                 :            :                                 pkey_gost_encrypt_init, pkey_GOST94cp_encrypt);
     598                 :        728 :                         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt);
     599                 :        728 :                         EVP_PKEY_meth_set_derive(*pmeth,
     600                 :            :                                 pkey_gost_derive_init, pkey_gost94_derive);
     601                 :        728 :                         EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost94_paramgen);       
     602                 :        728 :                         break;
     603                 :            :                 case NID_id_GostR3410_2001:
     604                 :        728 :                         EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01_str);
     605                 :        728 :                         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign);
     606                 :        728 :                         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify);
     607                 :            : 
     608                 :        728 :                         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen);
     609                 :            : 
     610                 :        728 :                         EVP_PKEY_meth_set_encrypt(*pmeth,
     611                 :            :                                 pkey_gost_encrypt_init, pkey_GOST01cp_encrypt);
     612                 :        728 :                         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt);
     613                 :        728 :                         EVP_PKEY_meth_set_derive(*pmeth,
     614                 :            :                                 pkey_gost_derive_init, pkey_gost2001_derive);
     615                 :        728 :                         EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost01_paramgen);       
     616                 :        728 :                         break;
     617                 :            :                 case NID_id_Gost28147_89_MAC:
     618                 :        728 :                         EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str);
     619                 :        728 :                         EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_init, pkey_gost_mac_signctx);
     620                 :        728 :                         EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keygen);
     621                 :        728 :                         EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init);
     622                 :        728 :                         EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup);
     623                 :        728 :                         EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy);
     624                 :        728 :                         return 1;
     625                 :            :                 default: /*Unsupported method*/
     626                 :            :                         return 0;
     627                 :            :                 }
     628                 :       1456 :         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
     629                 :       1456 :         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
     630                 :            : 
     631                 :       1456 :         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
     632                 :            :         /*FIXME derive etc...*/
     633                 :            :         
     634                 :       1456 :         return 1;
     635                 :            :         }
     636                 :            : 

Generated by: LCOV version 1.9