LCOV - code coverage report
Current view: top level - home/mbr/git/openssl.git/engines/ccgost - gost_sign.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 0 131 0.0 %
Date: 2014-08-02 Functions: 0 10 0.0 %
Branches: 0 46 0.0 %

           Branch data     Line data    Source code
       1                 :            : /**********************************************************************
       2                 :            :  *                          gost_sign.c                               *
       3                 :            :  *             Copyright (c) 2005-2006 Cryptocom LTD                  *
       4                 :            :  *         This file is distributed under the same license as OpenSSL *
       5                 :            :  *                                                                    *
       6                 :            :  *       Implementation of GOST R 34.10-94 signature algorithm        *
       7                 :            :  *       for OpenSSL                                                  *
       8                 :            :  *          Requires OpenSSL 0.9.9 for compilation                    *
       9                 :            :  **********************************************************************/
      10                 :            : #include <string.h>
      11                 :            : #include <openssl/rand.h>
      12                 :            : #include <openssl/bn.h>
      13                 :            : #include <openssl/dsa.h>
      14                 :            : #include <openssl/evp.h>
      15                 :            : 
      16                 :            : #include "gost_params.h"
      17                 :            : #include "gost_lcl.h"
      18                 :            : #include "e_gost_err.h"
      19                 :            : 
      20                 :            : #ifdef DEBUG_SIGN
      21                 :            : void dump_signature(const char *message,const unsigned char *buffer,size_t len)
      22                 :            :         {
      23                 :            :         size_t i;
      24                 :            :         fprintf(stderr,"signature %s Length=%d",message,len);
      25                 :            :         for (i=0; i<len; i++)
      26                 :            :                 {
      27                 :            :                 if (i% 16 ==0) fputc('\n',stderr);
      28                 :            :                 fprintf (stderr," %02x",buffer[i]);
      29                 :            :                 }
      30                 :            :         fprintf(stderr,"\nEnd of signature\n");
      31                 :            :         }
      32                 :            : 
      33                 :            : void dump_dsa_sig(const char *message, DSA_SIG *sig)
      34                 :            :         {
      35                 :            :         fprintf(stderr,"%s\nR=",message);
      36                 :            :         BN_print_fp(stderr,sig->r);
      37                 :            :         fprintf(stderr,"\nS=");
      38                 :            :         BN_print_fp(stderr,sig->s);
      39                 :            :         fprintf(stderr,"\n");
      40                 :            :         }
      41                 :            : 
      42                 :            : #else
      43                 :            : 
      44                 :            : #define dump_signature(a,b,c)
      45                 :            : #define dump_dsa_sig(a,b)
      46                 :            : #endif
      47                 :            : 
      48                 :            : /*
      49                 :            :  * Computes signature and returns it as DSA_SIG structure
      50                 :            :  */
      51                 :          0 : DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa)
      52                 :            :         {
      53                 :          0 :         BIGNUM *k=NULL,*tmp=NULL,*tmp2=NULL;
      54                 :          0 :         DSA_SIG *newsig = DSA_SIG_new();
      55                 :          0 :         BIGNUM *md = hashsum2bn(dgst);
      56                 :            :         /* check if H(M) mod q is zero */
      57                 :          0 :         BN_CTX *ctx=BN_CTX_new();
      58                 :          0 :         BN_CTX_start(ctx);
      59         [ #  # ]:          0 :         if (!newsig)
      60                 :            :                 {
      61                 :          0 :                 GOSTerr(GOST_F_GOST_DO_SIGN,GOST_R_NO_MEMORY);
      62                 :          0 :                 goto err;
      63                 :            :                 }       
      64                 :          0 :         tmp=BN_CTX_get(ctx);
      65                 :          0 :         k = BN_CTX_get(ctx);
      66                 :          0 :         tmp2 = BN_CTX_get(ctx);
      67                 :          0 :         BN_mod(tmp,md,dsa->q,ctx);
      68         [ #  # ]:          0 :         if (BN_is_zero(tmp))
      69                 :            :                 {
      70                 :          0 :                 BN_one(md);
      71                 :            :                 }       
      72                 :            :         do
      73                 :            :                 {
      74                 :            :                 do
      75                 :            :                         {
      76                 :            :                         /*Generate random number k less than q*/
      77                 :          0 :                         BN_rand_range(k,dsa->q);
      78                 :            :                         /* generate r = (a^x mod p) mod q */
      79                 :          0 :                         BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx);
      80         [ #  # ]:          0 :                         if (!(newsig->r)) newsig->r=BN_new();
      81                 :          0 :                         BN_mod(newsig->r,tmp,dsa->q,ctx);
      82                 :            :                         }
      83         [ #  # ]:          0 :                 while (BN_is_zero(newsig->r));
      84                 :            :                 /* generate s = (xr + k(Hm)) mod q */
      85                 :          0 :                 BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx);
      86                 :          0 :                 BN_mod_mul(tmp2,k,md,dsa->q,ctx);
      87         [ #  # ]:          0 :                 if (!newsig->s) newsig->s=BN_new();
      88                 :          0 :                 BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx);
      89                 :            :                 }
      90         [ #  # ]:          0 :         while (BN_is_zero(newsig->s));               
      91                 :            :         err:
      92                 :          0 :         BN_free(md);
      93                 :          0 :         BN_CTX_end(ctx);
      94                 :          0 :         BN_CTX_free(ctx);
      95                 :          0 :         return newsig;
      96                 :            :         }       
      97                 :            : 
      98                 :            : 
      99                 :            : /*
     100                 :            :  * Packs signature according to Cryptocom rules
     101                 :            :  * and frees up DSA_SIG structure
     102                 :            :  */
     103                 :            : /*
     104                 :            : int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
     105                 :            :         {
     106                 :            :         *siglen = 2*order;
     107                 :            :         memset(sig,0,*siglen);
     108                 :            :         store_bignum(s->r, sig,order);
     109                 :            :         store_bignum(s->s, sig + order,order);
     110                 :            :         dump_signature("serialized",sig,*siglen);
     111                 :            :         DSA_SIG_free(s);
     112                 :            :         return 1;
     113                 :            :         }
     114                 :            : */
     115                 :            : /*
     116                 :            :  * Packs signature according to Cryptopro rules
     117                 :            :  * and frees up DSA_SIG structure
     118                 :            :  */
     119                 :          0 : int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
     120                 :            :         {
     121                 :          0 :         *siglen = 2*order;
     122                 :          0 :         memset(sig,0,*siglen);
     123                 :          0 :         store_bignum(s->s, sig, order);
     124                 :          0 :         store_bignum(s->r, sig+order,order);
     125                 :            :         dump_signature("serialized",sig,*siglen);
     126                 :          0 :         DSA_SIG_free(s);
     127                 :          0 :         return 1;
     128                 :            :         }
     129                 :            : 
     130                 :            : /*
     131                 :            :  * Verifies signature passed as DSA_SIG structure
     132                 :            :  *
     133                 :            :  */
     134                 :            : 
     135                 :          0 : int gost_do_verify(const unsigned char *dgst, int dgst_len,
     136                 :            :         DSA_SIG *sig, DSA *dsa)
     137                 :            :         {
     138                 :          0 :         BIGNUM *md, *tmp=NULL;
     139                 :          0 :         BIGNUM *q2=NULL;
     140                 :          0 :         BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL;
     141                 :          0 :         BIGNUM *tmp2=NULL,*tmp3=NULL;
     142                 :            :         int ok;
     143                 :          0 :         BN_CTX *ctx = BN_CTX_new();
     144                 :            : 
     145                 :          0 :         BN_CTX_start(ctx);
     146   [ #  #  #  # ]:          0 :         if (BN_cmp(sig->s,dsa->q)>=1||
     147                 :          0 :                 BN_cmp(sig->r,dsa->q)>=1)
     148                 :            :                 {
     149                 :          0 :                 GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
     150                 :          0 :                 return 0;
     151                 :            :                 }
     152                 :          0 :         md=hashsum2bn(dgst);
     153                 :            :         
     154                 :          0 :         tmp=BN_CTX_get(ctx);
     155                 :          0 :         v=BN_CTX_get(ctx);
     156                 :          0 :         q2=BN_CTX_get(ctx);
     157                 :          0 :         z1=BN_CTX_get(ctx);
     158                 :          0 :         z2=BN_CTX_get(ctx);
     159                 :          0 :         tmp2=BN_CTX_get(ctx);
     160                 :          0 :         tmp3=BN_CTX_get(ctx);
     161                 :          0 :         u = BN_CTX_get(ctx);
     162                 :            :         
     163                 :          0 :         BN_mod(tmp,md,dsa->q,ctx);
     164         [ #  # ]:          0 :         if (BN_is_zero(tmp))
     165                 :            :                 {
     166                 :          0 :                 BN_one(md);
     167                 :            :                 }
     168                 :          0 :         BN_copy(q2,dsa->q);
     169                 :          0 :         BN_sub_word(q2,2);
     170                 :          0 :         BN_mod_exp(v,md,q2,dsa->q,ctx);
     171                 :          0 :         BN_mod_mul(z1,sig->s,v,dsa->q,ctx);
     172                 :          0 :         BN_sub(tmp,dsa->q,sig->r);
     173                 :          0 :         BN_mod_mul(z2,tmp,v,dsa->p,ctx);
     174                 :          0 :         BN_mod_exp(tmp,dsa->g,z1,dsa->p,ctx);
     175                 :          0 :         BN_mod_exp(tmp2,dsa->pub_key,z2,dsa->p,ctx);
     176                 :          0 :         BN_mod_mul(tmp3,tmp,tmp2,dsa->p,ctx);
     177                 :          0 :         BN_mod(u,tmp3,dsa->q,ctx);
     178                 :          0 :         ok= BN_cmp(u,sig->r);
     179                 :            :         
     180                 :          0 :         BN_free(md);
     181                 :          0 :         BN_CTX_end(ctx);
     182                 :          0 :         BN_CTX_free(ctx);
     183         [ #  # ]:          0 :         if (ok!=0)
     184                 :            :                 {
     185                 :          0 :                 GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
     186                 :            :                 }       
     187                 :          0 :         return (ok==0);
     188                 :            :         }
     189                 :            : 
     190                 :            : /*
     191                 :            :  * Computes public keys for GOST R 34.10-94 algorithm
     192                 :            :  *
     193                 :            :  */
     194                 :          0 : int gost94_compute_public(DSA *dsa)
     195                 :            :         {
     196                 :            :         /* Now fill algorithm parameters with correct values */
     197                 :          0 :         BN_CTX *ctx = BN_CTX_new();
     198         [ #  # ]:          0 :         if (!dsa->g)
     199                 :            :                 {
     200                 :          0 :                 GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED);
     201                 :          0 :                 return 0;
     202                 :            :                 }       
     203                 :            :         /* Compute public key  y = a^x mod p */
     204                 :          0 :         dsa->pub_key=BN_new();
     205                 :          0 :         BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx);
     206                 :          0 :         BN_CTX_free(ctx);
     207                 :          0 :         return 1;
     208                 :            :         }
     209                 :            : 
     210                 :            : /*
     211                 :            :  * Fill GOST 94 params, searching them in R3410_paramset array
     212                 :            :  * by nid of paramset
     213                 :            :  *
     214                 :            :  */
     215                 :          0 : int fill_GOST94_params(DSA *dsa,int nid)
     216                 :            :         {
     217                 :          0 :         R3410_params *params=R3410_paramset;
     218 [ #  # ][ #  # ]:          0 :         while (params->nid!=NID_undef && params->nid !=nid) params++;
     219         [ #  # ]:          0 :         if (params->nid == NID_undef)
     220                 :            :                 {
     221                 :          0 :                 GOSTerr(GOST_F_FILL_GOST94_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
     222                 :          0 :                 return 0;
     223                 :            :                 }       
     224                 :            : #define dump_signature(a,b,c)
     225         [ #  # ]:          0 :         if (dsa->p) { BN_free(dsa->p); }
     226                 :          0 :         dsa->p=NULL;
     227                 :          0 :         BN_dec2bn(&(dsa->p),params->p);
     228         [ #  # ]:          0 :         if (dsa->q) { BN_free(dsa->q); }
     229                 :          0 :         dsa->q=NULL;
     230                 :          0 :         BN_dec2bn(&(dsa->q),params->q);
     231         [ #  # ]:          0 :         if (dsa->g) { BN_free(dsa->g); }
     232                 :          0 :         dsa->g=NULL;
     233                 :          0 :         BN_dec2bn(&(dsa->g),params->a);
     234                 :          0 :         return 1;
     235                 :            :         }       
     236                 :            : 
     237                 :            : /*
     238                 :            :  *  Generate GOST R 34.10-94 keypair
     239                 :            :  *
     240                 :            :  *
     241                 :            :  */
     242                 :          0 : int gost_sign_keygen(DSA *dsa)
     243                 :            :         {
     244                 :          0 :         dsa->priv_key = BN_new();
     245                 :          0 :         BN_rand_range(dsa->priv_key,dsa->q);
     246                 :          0 :         return gost94_compute_public( dsa);
     247                 :            :         }
     248                 :            : 
     249                 :            : /* Unpack signature according to cryptocom rules  */
     250                 :            : /*
     251                 :            : DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen)
     252                 :            :         {
     253                 :            :         DSA_SIG *s;
     254                 :            :         s = DSA_SIG_new();
     255                 :            :         if (s == NULL)
     256                 :            :                 {
     257                 :            :                 GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
     258                 :            :                 return(NULL);
     259                 :            :                 }
     260                 :            :         s->r = getbnfrombuf(sig, siglen/2);
     261                 :            :         s->s = getbnfrombuf(sig + siglen/2, siglen/2);
     262                 :            :         return s;
     263                 :            :         }
     264                 :            : */
     265                 :            : /* Unpack signature according to cryptopro rules  */
     266                 :          0 : DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen)
     267                 :            :         {
     268                 :            :         DSA_SIG *s;
     269                 :            : 
     270                 :          0 :         s = DSA_SIG_new();
     271         [ #  # ]:          0 :         if (s == NULL)
     272                 :            :                 {
     273                 :          0 :                 GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY);
     274                 :          0 :                 return NULL;
     275                 :            :                 }
     276                 :          0 :         s->s = getbnfrombuf(sig , siglen/2);
     277                 :          0 :         s->r = getbnfrombuf(sig + siglen/2, siglen/2);
     278                 :          0 :         return s;
     279                 :            :         }
     280                 :            : 
     281                 :            : /* Convert little-endian byte array into bignum */
     282                 :          0 : BIGNUM *hashsum2bn(const unsigned char *dgst)
     283                 :            :         {
     284                 :            :         unsigned char buf[32];
     285                 :            :         int i;
     286         [ #  # ]:          0 :         for (i=0;i<32;i++)
     287                 :            :                 {
     288                 :          0 :                 buf[31-i]=dgst[i];
     289                 :            :                 }
     290                 :          0 :         return getbnfrombuf(buf,32);
     291                 :            :         }
     292                 :            : 
     293                 :            : /* Convert byte buffer to bignum, skipping leading zeros*/
     294                 :          0 : BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len)
     295                 :            :         {
     296 [ #  # ][ #  # ]:          0 :         while (*buf==0&&len>0)
     297                 :            :                 {
     298                 :          0 :                 buf++; len--;
     299                 :            :                 }
     300         [ #  # ]:          0 :         if (len)
     301                 :            :                 {
     302                 :          0 :                 return BN_bin2bn(buf,len,NULL);
     303                 :            :                 }
     304                 :            :         else
     305                 :            :                 {
     306                 :          0 :                 BIGNUM *b=BN_new();
     307                 :          0 :                 BN_zero(b);
     308                 :          0 :                 return b;
     309                 :            :                 }
     310                 :            :         }
     311                 :            : 
     312                 :            : /* Pack bignum into byte buffer of given size, filling all leading bytes
     313                 :            :  * by zeros */
     314                 :          0 : int store_bignum(BIGNUM *bn, unsigned char *buf,int len)
     315                 :            :         {
     316                 :          0 :         int bytes = BN_num_bytes(bn);
     317         [ #  # ]:          0 :         if (bytes>len) return 0;
     318                 :          0 :         memset(buf,0,len);
     319                 :          0 :         BN_bn2bin(bn,buf+len-bytes);
     320                 :          0 :         return 1;
     321                 :            :         }       

Generated by: LCOV version 1.9