LCOV - code coverage report
Current view: top level - home/mbr/git/openssl.git/engines/ccgost - gost_crypt.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 162 253 64.0 %
Date: 2014-08-02 Functions: 17 20 85.0 %
Branches: 70 136 51.5 %

           Branch data     Line data    Source code
       1                 :            : /**********************************************************************
       2                 :            :  *                          gost_crypt.c                              *
       3                 :            :  *             Copyright (c) 2005-2006 Cryptocom LTD                  *
       4                 :            :  *         This file is distributed under the same license as OpenSSL *
       5                 :            :  *                                                                    *
       6                 :            :  *       OpenSSL interface to GOST 28147-89 cipher functions          *
       7                 :            :  *          Requires OpenSSL 0.9.9 for compilation                    *
       8                 :            :  **********************************************************************/
       9                 :            : #include <string.h>
      10                 :            : #include "gost89.h"
      11                 :            : #include <openssl/rand.h>
      12                 :            : #include "e_gost_err.h"
      13                 :            : #include "gost_lcl.h"
      14                 :            : 
      15                 :            : #if !defined(CCGOST_DEBUG) && !defined(DEBUG)
      16                 :            : # ifndef NDEBUG
      17                 :            : #  define NDEBUG
      18                 :            : # endif
      19                 :            : #endif
      20                 :            : #include <assert.h>
      21                 :            : 
      22                 :            : static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 
      23                 :            :         const unsigned char *iv, int enc);
      24                 :            : static int      gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
      25                 :            :         const unsigned char *iv, int enc);
      26                 :            : /* Handles block of data in CFB mode */                 
      27                 :            : static int      gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
      28                 :            :         const unsigned char *in, size_t inl);
      29                 :            : /* Handles block of data in CNT mode */                 
      30                 :            : static int      gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
      31                 :            :         const unsigned char *in, size_t inl);
      32                 :            : /* Cleanup function */                  
      33                 :            : static int gost_cipher_cleanup(EVP_CIPHER_CTX *);
      34                 :            : /* set/get cipher parameters */
      35                 :            : static int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
      36                 :            : static int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
      37                 :            : /* Control function */
      38                 :            : static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr);
      39                 :            : 
      40                 :            : EVP_CIPHER cipher_gost = 
      41                 :            :         {
      42                 :            :         NID_id_Gost28147_89,
      43                 :            :         1,/*block_size*/
      44                 :            :         32,/*key_size*/
      45                 :            :         8,/*iv_len */
      46                 :            :         EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING |
      47                 :            :         EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
      48                 :            :         gost_cipher_init,
      49                 :            :         gost_cipher_do_cfb,
      50                 :            :         gost_cipher_cleanup,
      51                 :            :         sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */
      52                 :            :         gost89_set_asn1_parameters,
      53                 :            :         gost89_get_asn1_parameters,
      54                 :            :         gost_cipher_ctl,
      55                 :            :         NULL,
      56                 :            :         };
      57                 :            : 
      58                 :            : EVP_CIPHER cipher_gost_cpacnt = 
      59                 :            :         {
      60                 :            :         NID_gost89_cnt,
      61                 :            :         1,/*block_size*/
      62                 :            :         32,/*key_size*/
      63                 :            :         8,/*iv_len */
      64                 :            :         EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING |
      65                 :            :         EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
      66                 :            :         gost_cipher_init_cpa,
      67                 :            :         gost_cipher_do_cnt,
      68                 :            :         gost_cipher_cleanup,
      69                 :            :         sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
      70                 :            :         gost89_set_asn1_parameters,
      71                 :            :         gost89_get_asn1_parameters,
      72                 :            :         gost_cipher_ctl,
      73                 :            :         NULL,
      74                 :            :         };
      75                 :            : 
      76                 :            : /* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */
      77                 :            : /* Init functions which set specific parameters */
      78                 :            : static int gost_imit_init_cpa(EVP_MD_CTX *ctx);
      79                 :            : /* process block of data */
      80                 :            : static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count);
      81                 :            : /* Return computed value */
      82                 :            : static int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md);
      83                 :            : /* Copies context */
      84                 :            : static int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
      85                 :            : static int gost_imit_cleanup(EVP_MD_CTX *ctx);
      86                 :            : /* Control function, knows how to set MAC key.*/
      87                 :            : static int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr);
      88                 :            : 
      89                 :            : EVP_MD imit_gost_cpa =
      90                 :            :         {
      91                 :            :         NID_id_Gost28147_89_MAC,
      92                 :            :         NID_undef,
      93                 :            :         4,
      94                 :            :         0,
      95                 :            :         gost_imit_init_cpa,
      96                 :            :         gost_imit_update,
      97                 :            :         gost_imit_final,
      98                 :            :         gost_imit_copy,
      99                 :            :         gost_imit_cleanup,
     100                 :            :         NULL,
     101                 :            :         NULL,
     102                 :            :         {0,0,0,0,0},
     103                 :            :         8,
     104                 :            :         sizeof(struct ossl_gost_imit_ctx), 
     105                 :            :         gost_imit_ctrl
     106                 :            :         };
     107                 :            : 
     108                 :            : /* 
     109                 :            :  * Correspondence between gost parameter OIDs and substitution blocks
     110                 :            :  * NID field is filed by register_gost_NID function in engine.c
     111                 :            :  * upon engine initialization
     112                 :            :  */
     113                 :            : 
     114                 :            : struct gost_cipher_info gost_cipher_list[]=
     115                 :            :         {
     116                 :            : /* NID */  /* Subst block */          /* Key meshing*/
     117                 :            : /*{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},*/
     118                 :            :         {NID_id_Gost28147_89_cc,&GostR3411_94_CryptoProParamSet,0},
     119                 :            :         {NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1},
     120                 :            :         {NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1},
     121                 :            :         {NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1},
     122                 :            :         {NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
     123                 :            :         {NID_id_Gost28147_89_TestParamSet,&Gost28147_TestParamSet,1},
     124                 :            :         {NID_undef,NULL,0}
     125                 :            :         };      
     126                 :            : 
     127                 :            : /*  get encryption parameters from crypto network settings
     128                 :            :         FIXME For now we use environment var CRYPT_PARAMS as place to 
     129                 :            :         store these settings. Actually, it is better to use engine control   command, read from configuration file to set them */
     130                 :          5 : const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj)
     131                 :            :         {
     132                 :            :         int nid;
     133                 :            :         struct gost_cipher_info *param;
     134         [ +  - ]:          5 :         if (!obj)
     135                 :            :                 {
     136                 :          5 :                 const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS);
     137 [ +  - ][ +  - ]:          5 :                 if (!params || !strlen(params)) 
     138                 :            :                         return &gost_cipher_list[1];
     139                 :            : 
     140                 :          5 :                 nid = OBJ_txt2nid(params);
     141         [ -  + ]:          5 :                 if (nid == NID_undef)
     142                 :            :                         {
     143                 :          0 :                         GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,
     144                 :            :                                 GOST_R_INVALID_CIPHER_PARAM_OID);
     145                 :          0 :                         return NULL;
     146                 :            :                         }       
     147                 :            :                 }
     148                 :            :         else
     149                 :            :                 {
     150                 :          0 :                 nid= OBJ_obj2nid(obj);
     151                 :            :                 }
     152 [ +  - ][ +  + ]:         16 :         for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid; 
     153                 :         11 :                  param++);
     154         [ -  + ]:          5 :         if (!param->sblock)
     155                 :            :                 {
     156                 :          0 :                 GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS);
     157                 :          0 :                 return NULL;
     158                 :            :                 }       
     159                 :            :         return param;
     160                 :            :         }
     161                 :            : 
     162                 :            : /* Sets cipher param from paramset NID. */
     163                 :          5 : static int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid)
     164                 :            :         {
     165                 :            :         const struct gost_cipher_info *param;
     166         [ -  + ]:          5 :         param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid)));
     167         [ +  - ]:          5 :         if (!param) return 0;
     168                 :            :         
     169                 :          5 :         c->paramNID = param->nid;
     170                 :          5 :         c->key_meshing=param->key_meshing;
     171                 :          5 :         c->count=0;
     172                 :          5 :         gost_init(&(c->cctx), param->sblock);
     173                 :          5 :         return 1;
     174                 :            :         }
     175                 :            : 
     176                 :            : /* Initializes EVP_CIPHER_CTX by paramset NID */
     177                 :          5 : static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     178                 :            :         const unsigned char *iv, int enc, int paramNID,int mode)
     179                 :            :         {
     180                 :          5 :         struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
     181         [ +  - ]:          5 :         if (ctx->app_data == NULL)
     182                 :            :                 {
     183         [ +  - ]:          5 :                 if (!gost_cipher_set_param(c,paramNID)) return 0;
     184                 :          5 :                 ctx->app_data = ctx->cipher_data;
     185                 :            :                 }
     186         [ +  - ]:          5 :         if (key) gost_key(&(c->cctx),key);
     187         [ +  - ]:          5 :         if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
     188                 :          5 :         memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
     189                 :            :         return 1;
     190                 :            :         }       
     191                 :            : 
     192                 :          3 : static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     193                 :            :         const unsigned char *iv, int enc)
     194                 :            :         {
     195                 :          3 :         struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
     196                 :          3 :         gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
     197                 :          3 :         c->key_meshing=1;
     198                 :          3 :         c->count=0;
     199         [ +  - ]:          3 :         if(key) gost_key(&(c->cctx),key);
     200         [ +  - ]:          3 :         if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
     201                 :          3 :         memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
     202                 :          3 :         return 1;
     203                 :            :         }
     204                 :            : 
     205                 :            : /* Initializes EVP_CIPHER_CTX with default values */
     206                 :          5 : int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     207                 :            :         const unsigned char *iv, int enc)
     208                 :            :         {
     209                 :          5 :         return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE);
     210                 :            :         }       
     211                 :            : /* Wrapper around gostcrypt function from gost89.c which perform
     212                 :            :  * key meshing when nesseccary 
     213                 :            :  */
     214                 :     655496 : static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf)
     215                 :            :         {
     216                 :     655496 :         struct ossl_gost_cipher_ctx *c = ctx;
     217                 :            :         assert(c->count%8 == 0 && c->count <= 1024);
     218 [ +  - ][ +  + ]:     655496 :         if (c->key_meshing && c->count==1024)
     219                 :            :                 {
     220                 :       5121 :                 cryptopro_key_meshing(&(c->cctx),iv);
     221                 :            :                 }       
     222                 :     655496 :         gostcrypt(&(c->cctx),iv,buf);
     223                 :     655496 :         c->count = c->count%1024 + 8;
     224                 :     655496 :         }
     225                 :            : 
     226                 :     655493 : static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
     227                 :            :         {
     228                 :     655493 :         struct ossl_gost_cipher_ctx *c = ctx;
     229                 :            :         word32 g,go;
     230                 :            :         unsigned char buf1[8];
     231                 :            :         assert(c->count%8 == 0 && c->count <= 1024);
     232 [ +  - ][ +  + ]:     655493 :         if (c->key_meshing && c->count==1024)
     233                 :            :                 {
     234                 :       5121 :                 cryptopro_key_meshing(&(c->cctx),iv);
     235                 :            :                 }
     236         [ +  + ]:     655493 :         if (c->count==0)
     237                 :            :                 {
     238                 :          3 :                 gostcrypt(&(c->cctx),iv,buf1);
     239                 :            :                 }
     240                 :            :         else
     241                 :            :                 {
     242                 :            :                 memcpy(buf1,iv,8);
     243                 :            :                 }       
     244                 :     655493 :         g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|((word32)buf1[3]<<24);
     245                 :     655493 :         g += 0x01010101;
     246                 :     655493 :         buf1[0]=(unsigned char)(g&0xff);
     247                 :     655493 :         buf1[1]=(unsigned char)((g>>8)&0xff);
     248                 :     655493 :         buf1[2]=(unsigned char)((g>>16)&0xff);
     249                 :     655493 :         buf1[3]=(unsigned char)((g>>24)&0xff);
     250                 :     655493 :         g = buf1[4]|(buf1[5]<<8)|(buf1[6]<<16)|((word32)buf1[7]<<24);
     251                 :     655493 :         go = g;
     252                 :     655493 :         g += 0x01010104;
     253         [ +  + ]:     655493 :         if (go > g)      /*  overflow*/
     254                 :       2558 :                 g++;
     255                 :     655493 :         buf1[4]=(unsigned char)(g&0xff);
     256                 :     655493 :         buf1[5]=(unsigned char)((g>>8)&0xff);
     257                 :     655493 :         buf1[6]=(unsigned char)((g>>16)&0xff);
     258                 :     655493 :         buf1[7]=(unsigned char)((g>>24)&0xff);
     259                 :            :         memcpy(iv,buf1,8);
     260                 :     655493 :         gostcrypt(&(c->cctx),buf1,buf);
     261                 :     655493 :         c->count = c->count%1024 + 8;
     262                 :     655493 :         }
     263                 :            : 
     264                 :            : /* GOST encryption in CFB mode */
     265                 :          5 : int     gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
     266                 :            :         const unsigned char *in, size_t inl)
     267                 :            :         {
     268                 :          5 :         const unsigned char *in_ptr=in;
     269                 :          5 :         unsigned char *out_ptr=out;
     270                 :          5 :         size_t i=0;
     271                 :          5 :         size_t j=0;
     272                 :            : /* process partial block if any */
     273         [ -  + ]:          5 :         if (ctx->num) 
     274                 :            :                 {
     275         [ #  # ]:          0 :                 for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) 
     276                 :            :                         {
     277         [ #  # ]:          0 :                         if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr;
     278                 :          0 :                         *out_ptr=ctx->buf[j]^(*in_ptr);
     279         [ #  # ]:          0 :                         if (ctx->encrypt) ctx->buf[j+8]=*out_ptr;
     280                 :            :                         }       
     281         [ #  # ]:          0 :                 if (j==8)
     282                 :            :                         {
     283                 :          0 :                         memcpy(ctx->iv,ctx->buf+8,8);
     284                 :          5 :                         ctx->num=0;
     285                 :            :                         }
     286                 :            :                 else
     287                 :            :                         {
     288                 :          0 :                         ctx->num=j;
     289                 :          0 :                         return 1;
     290                 :            :                         }       
     291                 :            :                 }       
     292                 :            : 
     293         [ +  + ]:     655496 :         for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
     294                 :            :                 {
     295                 :            :                 /*block cipher current iv */
     296                 :     655491 :                 gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
     297                 :            :                 /*xor next block of input text with it and output it*/
     298                 :            :                 /*output this block */
     299         [ -  + ]:     655491 :                 if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8);
     300         [ +  + ]:    5899419 :                 for (j=0;j<8;j++)
     301                 :            :                         {
     302                 :    5243928 :                         out_ptr[j]=ctx->buf[j]^in_ptr[j];
     303                 :            :                         }       
     304                 :            :                 /* Encrypt */
     305                 :            :                 /* Next iv is next block of cipher text*/
     306         [ +  - ]:     655491 :                 if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8);
     307                 :            :                 }
     308                 :            : /* Process rest of buffer */
     309         [ +  - ]:          5 :         if (i<inl)
     310                 :            :                 {
     311                 :          5 :                 gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
     312         [ -  + ]:          5 :                 if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,inl-i);
     313         [ +  + ]:         33 :                 for (j=0;i<inl;j++,i++)
     314                 :            :                         {
     315                 :         28 :                         out_ptr[j]=ctx->buf[j]^in_ptr[j];
     316                 :            :                         }                       
     317                 :          5 :                 ctx->num = j;
     318         [ +  - ]:          5 :                 if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j);
     319                 :            :                 }
     320                 :            :         else
     321                 :            :                 {
     322                 :          0 :                 ctx->num = 0;
     323                 :            :                 }       
     324                 :            :         return 1;
     325                 :            :         }
     326                 :            : 
     327                 :          3 : static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
     328                 :            :         const unsigned char *in, size_t inl)
     329                 :            :         {
     330                 :          3 :         const unsigned char *in_ptr=in;
     331                 :          3 :         unsigned char *out_ptr=out;
     332                 :          3 :         size_t i=0;
     333                 :            :         size_t j;
     334                 :            : /* process partial block if any */
     335         [ -  + ]:          3 :         if (ctx->num) 
     336                 :            :                 {
     337         [ #  # ]:          0 :                 for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) 
     338                 :            :                         {
     339                 :          0 :                         *out_ptr=ctx->buf[j]^(*in_ptr);
     340                 :            :                         }       
     341         [ #  # ]:          0 :                 if (j==8)
     342                 :            :                         {
     343                 :          3 :                         ctx->num=0;
     344                 :            :                         }
     345                 :            :                 else
     346                 :            :                         {
     347                 :          0 :                         ctx->num=j;
     348                 :          0 :                         return 1;
     349                 :            :                         }       
     350                 :            :                 }       
     351                 :            : 
     352         [ +  + ]:     655493 :         for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
     353                 :            :                 {
     354                 :            :                 /*block cipher current iv */
     355                 :            :                 /* Encrypt */
     356                 :     655490 :                 gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
     357                 :            :                 /*xor next block of input text with it and output it*/
     358                 :            :                 /*output this block */
     359         [ +  + ]:    5899410 :                 for (j=0;j<8;j++)
     360                 :            :                         {
     361                 :    5243920 :                         out_ptr[j]=ctx->buf[j]^in_ptr[j];
     362                 :            :                         }       
     363                 :            :                 }
     364                 :            : /* Process rest of buffer */
     365         [ +  - ]:          3 :         if (i<inl)
     366                 :            :                 {
     367                 :          3 :                 gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
     368         [ +  + ]:         24 :                 for (j=0;i<inl;j++,i++)
     369                 :            :                         {
     370                 :         21 :                         out_ptr[j]=ctx->buf[j]^in_ptr[j];
     371                 :            :                         }                       
     372                 :          3 :                 ctx->num = j;
     373                 :            :                 }
     374                 :            :         else
     375                 :            :                 {
     376                 :          0 :                 ctx->num = 0;
     377                 :            :                 }       
     378                 :            :         return 1;
     379                 :            :         }
     380                 :            : 
     381                 :            : /* Cleaning up of EVP_CIPHER_CTX */
     382                 :          8 : int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx) 
     383                 :            :         {
     384                 :          8 :         gost_destroy(&((struct ossl_gost_cipher_ctx *)ctx->cipher_data)->cctx);
     385                 :          8 :         ctx->app_data = NULL;
     386                 :          8 :         return 1;
     387                 :            :         }       
     388                 :            : 
     389                 :            : /* Control function for gost cipher */
     390                 :          0 : int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr)
     391                 :            :         {
     392      [ #  #  # ]:          0 :         switch (type)
     393                 :            :                 {
     394                 :            :                 case EVP_CTRL_RAND_KEY:
     395                 :            :                 {
     396         [ #  # ]:          0 :                 if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0)
     397                 :            :                         {
     398                 :          0 :                         GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR);
     399                 :          0 :                         return -1;
     400                 :            :                         }
     401                 :            :                 break;
     402                 :            :                 }
     403                 :            :                 case EVP_CTRL_PBE_PRF_NID:
     404         [ #  # ]:          0 :                         if (ptr) {
     405                 :          0 :                                 *((int *)ptr)=  NID_id_HMACGostR3411_94;
     406                 :          0 :                                 return 1;
     407                 :            :                         } else {
     408                 :            :                                 return 0;
     409                 :            :                         }       
     410                 :            :                                 
     411                 :            :                 default:
     412                 :          0 :                         GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
     413                 :          0 :                         return -1;
     414                 :            :                 }
     415                 :            :         return 1;
     416                 :            :         }
     417                 :            : 
     418                 :            : /* Set cipher parameters from ASN1 structure */
     419                 :          0 : int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
     420                 :            :         {
     421                 :          0 :         int len=0;
     422                 :          0 :         unsigned char *buf=NULL;
     423                 :          0 :         unsigned char *p=NULL;
     424                 :          0 :         struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
     425                 :          0 :         GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
     426                 :          0 :         ASN1_OCTET_STRING *os = NULL;
     427         [ #  # ]:          0 :         if (!gcp)
     428                 :            :                 {
     429                 :          0 :                 GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
     430                 :          0 :                 return 0;
     431                 :            :                 }
     432         [ #  # ]:          0 :         if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len))
     433                 :            :                 {
     434                 :          0 :                 GOST_CIPHER_PARAMS_free(gcp);
     435                 :          0 :                 GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
     436                 :          0 :                 return 0;
     437                 :            :                 }
     438                 :          0 :         ASN1_OBJECT_free(gcp->enc_param_set);
     439                 :          0 :         gcp->enc_param_set = OBJ_nid2obj(c->paramNID);
     440                 :            : 
     441                 :          0 :         len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
     442                 :          0 :         p = buf = (unsigned char*)OPENSSL_malloc(len);
     443         [ #  # ]:          0 :         if (!buf)
     444                 :            :                 {
     445                 :          0 :                 GOST_CIPHER_PARAMS_free(gcp);
     446                 :          0 :                 GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
     447                 :          0 :                 return 0;
     448                 :            :                 }
     449                 :          0 :         i2d_GOST_CIPHER_PARAMS(gcp, &p);
     450                 :          0 :         GOST_CIPHER_PARAMS_free(gcp);
     451                 :            : 
     452                 :          0 :         os = ASN1_OCTET_STRING_new();
     453                 :            : 
     454 [ #  # ][ #  # ]:          0 :         if(!os || !ASN1_OCTET_STRING_set(os, buf, len))
     455                 :            :                 {
     456                 :          0 :                 OPENSSL_free(buf);
     457                 :          0 :                 GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
     458                 :          0 :                 return 0;
     459                 :            :                 }
     460                 :          0 :         OPENSSL_free(buf);
     461                 :            : 
     462                 :          0 :         ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
     463                 :          0 :         return 1;
     464                 :            :         }
     465                 :            : 
     466                 :            : /* Store parameters into ASN1 structure */
     467                 :          0 : int  gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
     468                 :            :         {
     469                 :          0 :         int ret = -1;
     470                 :            :         int len; 
     471                 :          0 :         GOST_CIPHER_PARAMS *gcp = NULL;
     472                 :            :         unsigned char *p;
     473                 :          0 :         struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
     474         [ #  # ]:          0 :         if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
     475                 :            :                 {
     476                 :            :                 return ret;
     477                 :            :                 }
     478                 :            : 
     479                 :          0 :         p = params->value.sequence->data;
     480                 :            : 
     481                 :          0 :         gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
     482                 :          0 :                 params->value.sequence->length);
     483                 :            : 
     484                 :          0 :         len = gcp->iv->length;
     485         [ #  # ]:          0 :         if (len != ctx->cipher->iv_len)
     486                 :            :                 {
     487                 :          0 :                 GOST_CIPHER_PARAMS_free(gcp);
     488                 :          0 :                 GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
     489                 :            :                         GOST_R_INVALID_IV_LENGTH);
     490                 :          0 :                 return -1;
     491                 :            :                 }
     492         [ #  # ]:          0 :         if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set)))
     493                 :            :                 {
     494                 :          0 :                 GOST_CIPHER_PARAMS_free(gcp);
     495                 :          0 :                 return -1;
     496                 :            :                 }
     497                 :          0 :         memcpy(ctx->oiv, gcp->iv->data, len);
     498                 :            : 
     499                 :          0 :         GOST_CIPHER_PARAMS_free(gcp);
     500                 :            : 
     501                 :          0 :         return 1;
     502                 :            :         }
     503                 :            : 
     504                 :            : 
     505                 :          7 : int gost_imit_init_cpa(EVP_MD_CTX *ctx)
     506                 :            :         {
     507                 :          7 :         struct ossl_gost_imit_ctx *c = ctx->md_data;
     508                 :          7 :         memset(c->buffer,0,sizeof(c->buffer));
     509                 :          7 :         memset(c->partial_block,0,sizeof(c->partial_block));
     510                 :          7 :         c->count = 0;
     511                 :          7 :         c->bytes_left=0;
     512                 :          7 :         c->key_meshing=1;
     513                 :          7 :         gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
     514                 :          7 :         return 1;
     515                 :            :         }
     516                 :            : 
     517                 :     655498 : static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *data)
     518                 :            :         {
     519                 :            :         unsigned char buffer[8];
     520                 :            :         /* We are using local buffer for iv because CryptoPro doesn't 
     521                 :            :          * interpret internal state of MAC algorithm as iv during keymeshing
     522                 :            :          * (but does initialize internal state from iv in key transport
     523                 :            :          */
     524                 :            :         assert(c->count%8 == 0 && c->count <= 1024);
     525 [ +  - ][ +  + ]:     655498 :         if (c->key_meshing && c->count==1024)
     526                 :            :                 {
     527                 :       5120 :                 cryptopro_key_meshing(&(c->cctx),buffer);
     528                 :            :                 }
     529                 :     655498 :         mac_block(&(c->cctx),c->buffer,data);
     530                 :     655498 :         c->count = c->count%1024 + 8;
     531                 :     655498 :         }
     532                 :            : 
     533                 :          9 : int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
     534                 :            :         {
     535                 :          9 :         struct ossl_gost_imit_ctx *c = ctx->md_data;
     536                 :          9 :         const unsigned char *p = data;
     537                 :          9 :         size_t bytes = count,i;
     538         [ -  + ]:          9 :         if (!(c->key_set)) {
     539                 :          0 :                 GOSTerr(GOST_F_GOST_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET);
     540                 :          0 :                 return 0;
     541                 :            :         }
     542         [ +  + ]:          9 :         if (c->bytes_left)
     543                 :            :                 {
     544         [ +  + ]:          4 :                 for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++)
     545                 :            :                         {
     546                 :          2 :                         c->partial_block[i]=*p;
     547                 :            :                         }
     548         [ +  - ]:          2 :                 if (i==8)
     549                 :            :                         {
     550                 :          9 :                         mac_block_mesh(c,c->partial_block);
     551                 :            :                         }
     552                 :            :                 else
     553                 :            :                         {
     554                 :          0 :                         c->bytes_left = i;
     555                 :          0 :                         return 1;
     556                 :            :                         }               
     557                 :            :                 }       
     558         [ +  + ]:     655499 :         while (bytes>8)
     559                 :            :                 {
     560                 :     655490 :                 mac_block_mesh(c,p);
     561                 :     655490 :                 p+=8;
     562                 :     655490 :                 bytes-=8;
     563                 :            :                 }
     564         [ +  + ]:          9 :         if (bytes>0)
     565                 :            :                 {
     566                 :          8 :                 memcpy(c->partial_block,p,bytes);
     567                 :            :                 }       
     568                 :          9 :         c->bytes_left=bytes;
     569                 :          9 :         return 1;
     570                 :            :         }
     571                 :            : 
     572                 :          7 : int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md)
     573                 :            :         {
     574                 :          7 :         struct ossl_gost_imit_ctx *c = ctx->md_data;
     575         [ -  + ]:          7 :         if (!c->key_set) {
     576                 :          0 :                 GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
     577                 :          0 :                 return 0;
     578                 :            :         }
     579 [ +  + ][ +  + ]:          7 :         if (c->count==0 && c->bytes_left)
     580                 :            :                 {
     581                 :            :                 unsigned char buffer[8];
     582                 :            :                 memset(buffer, 0, 8);
     583                 :          2 :                 gost_imit_update(ctx, buffer, 8);
     584                 :            :                 }
     585         [ +  + ]:          7 :         if (c->bytes_left)
     586                 :            :                 {
     587                 :            :                 int i;
     588         [ +  + ]:         19 :                 for (i=c->bytes_left;i<8;i++)
     589                 :            :                         {
     590                 :         13 :                         c->partial_block[i]=0;
     591                 :            :                         }
     592                 :          6 :                 mac_block_mesh(c,c->partial_block);
     593                 :            :                 }
     594                 :          7 :         get_mac(c->buffer,32,md);
     595                 :          7 :         return 1;
     596                 :            :         }
     597                 :            : 
     598                 :          7 : int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr)
     599                 :            :         {
     600      [ -  +  - ]:          7 :         switch (type)
     601                 :            :                 {
     602                 :            :                 case EVP_MD_CTRL_KEY_LEN:
     603                 :          0 :                         *((unsigned int*)(ptr)) = 32;
     604                 :          0 :                         return 1;
     605                 :            :                 case EVP_MD_CTRL_SET_KEY:
     606                 :            :                 {
     607         [ -  + ]:          7 :                 if (arg!=32) {
     608                 :          0 :                         GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
     609                 :          0 :                         return 0;
     610                 :            :                 }
     611                 :            : 
     612                 :          7 :                 gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr)   ;
     613                 :          7 :                 ((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1;
     614                 :          7 :                 return 1;
     615                 :            : 
     616                 :            :                 }
     617                 :            :                 default:
     618                 :            :                         return 0;
     619                 :            :                 }               
     620                 :            :         }
     621                 :            : 
     622                 :          7 : int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
     623                 :            :         {
     624                 :          7 :         memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_imit_ctx));
     625                 :          7 :         return 1;
     626                 :            :         }
     627                 :            : 
     628                 :            : /* Clean up imit ctx */
     629                 :         14 : int gost_imit_cleanup(EVP_MD_CTX *ctx)
     630                 :            :         {
     631                 :         14 :         memset(ctx->md_data,0,sizeof(struct ossl_gost_imit_ctx));
     632                 :         14 :         return 1;
     633                 :            :         }
     634                 :            : 

Generated by: LCOV version 1.9