Deleted Added
full compact
gost_sign.c (256281) gost_sign.c (280304)
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 *

--- 4 unchanged lines hidden (view full) ---

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
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 *

--- 4 unchanged lines hidden (view full) ---

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
21void 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 }
21void dump_signature(const char *message, const unsigned char *buffer,
22 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 if (i % 16 == 0)
28 fputc('\n', stderr);
29 fprintf(stderr, " %02x", buffer[i]);
30 }
31 fprintf(stderr, "\nEnd of signature\n");
32}
32
33void dump_dsa_sig(const char *message, DSA_SIG *sig)
33
34void 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 }
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}
41
42#else
43
42
43#else
44
44#define dump_signature(a,b,c)
45#define dump_dsa_sig(a,b)
45# define dump_signature(a,b,c)
46# define dump_dsa_sig(a,b)
46#endif
47
48/*
49 * Computes signature and returns it as DSA_SIG structure
50 */
47#endif
48
49/*
50 * Computes signature and returns it as DSA_SIG structure
51 */
51DSA_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 }
52DSA_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 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 BN_one(md);
70 }
71 do {
72 do {
73 /*
74 * Generate random number k less than q
75 */
76 BN_rand_range(k, dsa->q);
77 /* generate r = (a^x mod p) mod q */
78 BN_mod_exp(tmp, dsa->g, k, dsa->p, ctx);
79 if (!(newsig->r))
80 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)
88 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}
97
98
98
99/*
100 * Packs signature according to Cryptocom rules
101 * and frees up DSA_SIG structure
102 */
99/*
100 * Packs signature according to Cryptocom rules
101 * and frees up DSA_SIG structure
102 */
103/*
103/*-
104int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
104int 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 }
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 */
114*/
115/*
116 * Packs signature according to Cryptopro rules
117 * and frees up DSA_SIG structure
118 */
119int 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 }
119int 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
135int gost_do_verify(const unsigned char *dgst, int dgst_len,
129
130/*
131 * Verifies signature passed as DSA_SIG structure
132 *
133 */
134
135int 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();
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
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 }
145 BN_CTX_start(ctx);
146 if (BN_cmp(sig->s, dsa->q) >= 1 || BN_cmp(sig->r, dsa->q) >= 1) {
147 GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
148 return 0;
149 }
150 md = hashsum2bn(dgst);
189
151
152 tmp = BN_CTX_get(ctx);
153 v = BN_CTX_get(ctx);
154 q2 = BN_CTX_get(ctx);
155 z1 = BN_CTX_get(ctx);
156 z2 = BN_CTX_get(ctx);
157 tmp2 = BN_CTX_get(ctx);
158 tmp3 = BN_CTX_get(ctx);
159 u = BN_CTX_get(ctx);
160
161 BN_mod(tmp, md, dsa->q, ctx);
162 if (BN_is_zero(tmp)) {
163 BN_one(md);
164 }
165 BN_copy(q2, dsa->q);
166 BN_sub_word(q2, 2);
167 BN_mod_exp(v, md, q2, dsa->q, ctx);
168 BN_mod_mul(z1, sig->s, v, dsa->q, ctx);
169 BN_sub(tmp, dsa->q, sig->r);
170 BN_mod_mul(z2, tmp, v, dsa->p, ctx);
171 BN_mod_exp(tmp, dsa->g, z1, dsa->p, ctx);
172 BN_mod_exp(tmp2, dsa->pub_key, z2, dsa->p, ctx);
173 BN_mod_mul(tmp3, tmp, tmp2, dsa->p, ctx);
174 BN_mod(u, tmp3, dsa->q, ctx);
175 ok = BN_cmp(u, sig->r);
176
177 BN_free(md);
178 BN_CTX_end(ctx);
179 BN_CTX_free(ctx);
180 if (ok != 0) {
181 GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH);
182 }
183 return (ok == 0);
184}
185
190/*
191 * Computes public keys for GOST R 34.10-94 algorithm
192 *
193 */
194int gost94_compute_public(DSA *dsa)
186/*
187 * Computes public keys for GOST R 34.10-94 algorithm
188 *
189 */
190int 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 }
191{
192 /* Now fill algorithm parameters with correct values */
193 BN_CTX *ctx = BN_CTX_new();
194 if (!dsa->g) {
195 GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, GOST_R_KEY_IS_NOT_INITALIZED);
196 return 0;
197 }
198 /* Compute public key y = a^x mod p */
199 dsa->pub_key = BN_new();
200 BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx);
201 BN_CTX_free(ctx);
202 return 1;
203}
209
210/*
211 * Fill GOST 94 params, searching them in R3410_paramset array
212 * by nid of paramset
213 *
214 */
204
205/*
206 * Fill GOST 94 params, searching them in R3410_paramset array
207 * by nid of paramset
208 *
209 */
215int 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 }
210int fill_GOST94_params(DSA *dsa, int nid)
211{
212 R3410_params *params = R3410_paramset;
213 while (params->nid != NID_undef && params->nid != nid)
214 params++;
215 if (params->nid == NID_undef) {
216 GOSTerr(GOST_F_FILL_GOST94_PARAMS, GOST_R_UNSUPPORTED_PARAMETER_SET);
217 return 0;
218 }
224#define dump_signature(a,b,c)
219#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 }
220 if (dsa->p) {
221 BN_free(dsa->p);
222 }
223 dsa->p = NULL;
224 BN_dec2bn(&(dsa->p), params->p);
225 if (dsa->q) {
226 BN_free(dsa->q);
227 }
228 dsa->q = NULL;
229 BN_dec2bn(&(dsa->q), params->q);
230 if (dsa->g) {
231 BN_free(dsa->g);
232 }
233 dsa->g = NULL;
234 BN_dec2bn(&(dsa->g), params->a);
235 return 1;
236}
236
237/*
238 * Generate GOST R 34.10-94 keypair
239 *
240 *
241 */
242int gost_sign_keygen(DSA *dsa)
237
238/*
239 * Generate GOST R 34.10-94 keypair
240 *
241 *
242 */
243int 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 }
244{
245 dsa->priv_key = BN_new();
246 BN_rand_range(dsa->priv_key, dsa->q);
247 return gost94_compute_public(dsa);
248}
248
249/* Unpack signature according to cryptocom rules */
249
250/* Unpack signature according to cryptocom rules */
250/*
251/*-
251DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen)
252DSA_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 }
253 {
254 DSA_SIG *s;
255 s = DSA_SIG_new();
256 if (s == NULL)
257 {
258 GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
259 return(NULL);
260 }
261 s->r = getbnfrombuf(sig, siglen/2);
262 s->s = getbnfrombuf(sig + siglen/2, siglen/2);
263 return s;
264 }
264*/
265/* Unpack signature according to cryptopro rules */
265*/
266/* Unpack signature according to cryptopro rules */
266DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen)
267 {
268 DSA_SIG *s;
267DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen)
268{
269 DSA_SIG *s;
269
270
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 }
271 s = DSA_SIG_new();
272 if (s == NULL) {
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 */
282BIGNUM *hashsum2bn(const unsigned char *dgst)
280
281/* Convert little-endian byte array into bignum */
282BIGNUM *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 }
283{
284 unsigned char buf[32];
285 int i;
286 for (i = 0; i < 32; i++) {
287 buf[31 - i] = dgst[i];
288 }
289 return getbnfrombuf(buf, 32);
290}
292
293/* Convert byte buffer to bignum, skipping leading zeros*/
291
292/* Convert byte buffer to bignum, skipping leading zeros*/
294BIGNUM *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 }
293BIGNUM *getbnfrombuf(const unsigned char *buf, size_t len)
294{
295 while (*buf == 0 && len > 0) {
296 buf++;
297 len--;
298 }
299 if (len) {
300 return BN_bin2bn(buf, len, NULL);
301 } else {
302 BIGNUM *b = BN_new();
303 BN_zero(b);
304 return b;
305 }
306}
311
307
312/* Pack bignum into byte buffer of given size, filling all leading bytes
313 * by zeros */
314int 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 }
308/*
309 * Pack bignum into byte buffer of given size, filling all leading bytes by
310 * zeros
311 */
312int store_bignum(BIGNUM *bn, unsigned char *buf, int len)
313{
314 int bytes = BN_num_bytes(bn);
315 if (bytes > len)
316 return 0;
317 memset(buf, 0, len);
318 BN_bn2bin(bn, buf + len - bytes);
319 return 1;
320}