~brian-sidebotham/openssl-cmake/1.0.1e

« back to all changes in this revision

Viewing changes to engines/ccgost/gost_sign.c

  • Committer: Brian Sidebotham
  • Date: 2013-10-19 21:50:27 UTC
  • Revision ID: brian.sidebotham@gmail.com-20131019215027-yzoyh4svqj87uepu
ImportĀ OpenSSLĀ 1.0.1e

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa)
 
52
        {
 
53
        BIGNUM *k=NULL,*tmp=NULL,*tmp2=NULL;
 
54
        DSA_SIG *newsig = DSA_SIG_new();
 
55
        BIGNUM *md = hashsum2bn(dgst);
 
56
        /* check if H(M) mod q is zero */
 
57
        BN_CTX *ctx=BN_CTX_new();
 
58
        BN_CTX_start(ctx);
 
59
        if (!newsig)
 
60
                {
 
61
                GOSTerr(GOST_F_GOST_DO_SIGN,GOST_R_NO_MEMORY);
 
62
                goto err;
 
63
                }       
 
64
        tmp=BN_CTX_get(ctx);
 
65
        k = BN_CTX_get(ctx);
 
66
        tmp2 = BN_CTX_get(ctx);
 
67
        BN_mod(tmp,md,dsa->q,ctx);
 
68
        if (BN_is_zero(tmp))
 
69
                {
 
70
                BN_one(md);
 
71
                }       
 
72
        do
 
73
                {
 
74
                do
 
75
                        {
 
76
                        /*Generate random number k less than q*/
 
77
                        BN_rand_range(k,dsa->q);
 
78
                        /* generate r = (a^x mod p) mod q */
 
79
                        BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx);
 
80
                        if (!(newsig->r)) newsig->r=BN_new();
 
81
                        BN_mod(newsig->r,tmp,dsa->q,ctx);
 
82
                        }
 
83
                while (BN_is_zero(newsig->r));
 
84
                /* generate s = (xr + k(Hm)) mod q */
 
85
                BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx);
 
86
                BN_mod_mul(tmp2,k,md,dsa->q,ctx);
 
87
                if (!newsig->s) newsig->s=BN_new();
 
88
                BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx);
 
89
                }
 
90
        while (BN_is_zero(newsig->s));          
 
91
        err:
 
92
        BN_free(md);
 
93
        BN_CTX_end(ctx);
 
94
        BN_CTX_free(ctx);
 
95
        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
int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
 
120
        {
 
121
        *siglen = 2*order;
 
122
        memset(sig,0,*siglen);
 
123
        store_bignum(s->s, sig, order);
 
124
        store_bignum(s->r, sig+order,order);
 
125
        dump_signature("serialized",sig,*siglen);
 
126
        DSA_SIG_free(s);
 
127
        return 1;
 
128
        }
 
129
 
 
130
/*
 
131
 * Verifies signature passed as DSA_SIG structure
 
132
 *
 
133
 */
 
134
 
 
135
int gost_do_verify(const unsigned char *dgst, int dgst_len,
 
136
        DSA_SIG *sig, DSA *dsa)
 
137
        {
 
138
        BIGNUM *md, *tmp=NULL;
 
139
        BIGNUM *q2=NULL;
 
140
        BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL;
 
141
        BIGNUM *tmp2=NULL,*tmp3=NULL;
 
142
        int ok;
 
143
        BN_CTX *ctx = BN_CTX_new();
 
144
 
 
145
        BN_CTX_start(ctx);
 
146
        if (BN_cmp(sig->s,dsa->q)>=1||
 
147
                BN_cmp(sig->r,dsa->q)>=1)
 
148
                {
 
149
                GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
 
150
                return 0;
 
151
                }
 
152
        md=hashsum2bn(dgst);
 
153
        
 
154
        tmp=BN_CTX_get(ctx);
 
155
        v=BN_CTX_get(ctx);
 
156
        q2=BN_CTX_get(ctx);
 
157
        z1=BN_CTX_get(ctx);
 
158
        z2=BN_CTX_get(ctx);
 
159
        tmp2=BN_CTX_get(ctx);
 
160
        tmp3=BN_CTX_get(ctx);
 
161
        u = BN_CTX_get(ctx);
 
162
        
 
163
        BN_mod(tmp,md,dsa->q,ctx);
 
164
        if (BN_is_zero(tmp))
 
165
                {
 
166
                BN_one(md);
 
167
                }
 
168
        BN_copy(q2,dsa->q);
 
169
        BN_sub_word(q2,2);
 
170
        BN_mod_exp(v,md,q2,dsa->q,ctx);
 
171
        BN_mod_mul(z1,sig->s,v,dsa->q,ctx);
 
172
        BN_sub(tmp,dsa->q,sig->r);
 
173
        BN_mod_mul(z2,tmp,v,dsa->p,ctx);
 
174
        BN_mod_exp(tmp,dsa->g,z1,dsa->p,ctx);
 
175
        BN_mod_exp(tmp2,dsa->pub_key,z2,dsa->p,ctx);
 
176
        BN_mod_mul(tmp3,tmp,tmp2,dsa->p,ctx);
 
177
        BN_mod(u,tmp3,dsa->q,ctx);
 
178
        ok= BN_cmp(u,sig->r);
 
179
        
 
180
        BN_free(md);
 
181
        BN_CTX_end(ctx);
 
182
        BN_CTX_free(ctx);
 
183
        if (ok!=0)
 
184
                {
 
185
                GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
 
186
                }       
 
187
        return (ok==0);
 
188
        }
 
189
 
 
190
/*
 
191
 * Computes public keys for GOST R 34.10-94 algorithm
 
192
 *
 
193
 */
 
194
int gost94_compute_public(DSA *dsa)
 
195
        {
 
196
        /* Now fill algorithm parameters with correct values */
 
197
        BN_CTX *ctx = BN_CTX_new();
 
198
        if (!dsa->g)
 
199
                {
 
200
                GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED);
 
201
                return 0;
 
202
                }       
 
203
        /* Compute public key  y = a^x mod p */
 
204
        dsa->pub_key=BN_new();
 
205
        BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx);
 
206
        BN_CTX_free(ctx);
 
207
        return 1;
 
208
        }
 
209
 
 
210
/*
 
211
 * Fill GOST 94 params, searching them in R3410_paramset array
 
212
 * by nid of paramset
 
213
 *
 
214
 */
 
215
int fill_GOST94_params(DSA *dsa,int nid)
 
216
        {
 
217
        R3410_params *params=R3410_paramset;
 
218
        while (params->nid!=NID_undef && params->nid !=nid) params++;
 
219
        if (params->nid == NID_undef)
 
220
                {
 
221
                GOSTerr(GOST_F_FILL_GOST94_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
 
222
                return 0;
 
223
                }       
 
224
#define dump_signature(a,b,c)
 
225
        if (dsa->p) { BN_free(dsa->p); }
 
226
        dsa->p=NULL;
 
227
        BN_dec2bn(&(dsa->p),params->p);
 
228
        if (dsa->q) { BN_free(dsa->q); }
 
229
        dsa->q=NULL;
 
230
        BN_dec2bn(&(dsa->q),params->q);
 
231
        if (dsa->g) { BN_free(dsa->g); }
 
232
        dsa->g=NULL;
 
233
        BN_dec2bn(&(dsa->g),params->a);
 
234
        return 1;
 
235
        }       
 
236
 
 
237
/*
 
238
 *  Generate GOST R 34.10-94 keypair
 
239
 *
 
240
 *
 
241
 */
 
242
int gost_sign_keygen(DSA *dsa)
 
243
        {
 
244
        dsa->priv_key = BN_new();
 
245
        BN_rand_range(dsa->priv_key,dsa->q);
 
246
        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
DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen)
 
267
        {
 
268
        DSA_SIG *s;
 
269
 
 
270
        s = DSA_SIG_new();
 
271
        if (s == NULL)
 
272
                {
 
273
                GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY);
 
274
                return NULL;
 
275
                }
 
276
        s->s = getbnfrombuf(sig , siglen/2);
 
277
        s->r = getbnfrombuf(sig + siglen/2, siglen/2);
 
278
        return s;
 
279
        }
 
280
 
 
281
/* Convert little-endian byte array into bignum */
 
282
BIGNUM *hashsum2bn(const unsigned char *dgst)
 
283
        {
 
284
        unsigned char buf[32];
 
285
        int i;
 
286
        for (i=0;i<32;i++)
 
287
                {
 
288
                buf[31-i]=dgst[i];
 
289
                }
 
290
        return getbnfrombuf(buf,32);
 
291
        }
 
292
 
 
293
/* Convert byte buffer to bignum, skipping leading zeros*/
 
294
BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len)
 
295
        {
 
296
        while (*buf==0&&len>0)
 
297
                {
 
298
                buf++; len--;
 
299
                }
 
300
        if (len)
 
301
                {
 
302
                return BN_bin2bn(buf,len,NULL);
 
303
                }
 
304
        else
 
305
                {
 
306
                BIGNUM *b=BN_new();
 
307
                BN_zero(b);
 
308
                return b;
 
309
                }
 
310
        }
 
311
 
 
312
/* Pack bignum into byte buffer of given size, filling all leading bytes
 
313
 * by zeros */
 
314
int store_bignum(BIGNUM *bn, unsigned char *buf,int len)
 
315
        {
 
316
        int bytes = BN_num_bytes(bn);
 
317
        if (bytes>len) return 0;
 
318
        memset(buf,0,len);
 
319
        BN_bn2bin(bn,buf+len-bytes);
 
320
        return 1;
 
321
        }