OpenSSL
1.0.1c
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
engines
ccgost
gost_sign.c
Go to the documentation of this file.
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
}
Generated on Thu Jan 10 2013 09:53:41 for OpenSSL by
1.8.2