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