diff options
Diffstat (limited to 'src/lib/libcrypto/gost/gostr341001.c')
-rw-r--r-- | src/lib/libcrypto/gost/gostr341001.c | 256 |
1 files changed, 167 insertions, 89 deletions
diff --git a/src/lib/libcrypto/gost/gostr341001.c b/src/lib/libcrypto/gost/gostr341001.c index 3c314765f7..171cf1b80a 100644 --- a/src/lib/libcrypto/gost/gostr341001.c +++ b/src/lib/libcrypto/gost/gostr341001.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gostr341001.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */ | 1 | /* $OpenBSD: gostr341001.c,v 1.2 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -59,10 +59,12 @@ | |||
59 | #include "gost_locl.h" | 59 | #include "gost_locl.h" |
60 | 60 | ||
61 | /* Convert little-endian byte array into bignum */ | 61 | /* Convert little-endian byte array into bignum */ |
62 | BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) | 62 | BIGNUM * |
63 | GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn) | ||
63 | { | 64 | { |
64 | unsigned char temp[64]; | 65 | unsigned char temp[64]; |
65 | int i; | 66 | int i; |
67 | |||
66 | if (len > 64) | 68 | if (len > 64) |
67 | return NULL; | 69 | return NULL; |
68 | 70 | ||
@@ -73,7 +75,8 @@ BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) | |||
73 | return BN_bin2bn(temp, len, bn); | 75 | return BN_bin2bn(temp, len, bn); |
74 | } | 76 | } |
75 | 77 | ||
76 | int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) | 78 | int |
79 | GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len) | ||
77 | { | 80 | { |
78 | unsigned char temp[64]; | 81 | unsigned char temp[64]; |
79 | int i, bytes; | 82 | int i, bytes; |
@@ -93,8 +96,8 @@ int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) | |||
93 | return 1; | 96 | return 1; |
94 | } | 97 | } |
95 | 98 | ||
96 | 99 | int | |
97 | int gost2001_compute_public(GOST_KEY * ec) | 100 | gost2001_compute_public(GOST_KEY *ec) |
98 | { | 101 | { |
99 | const EC_GROUP *group = GOST_KEY_get0_group(ec); | 102 | const EC_GROUP *group = GOST_KEY_get0_group(ec); |
100 | EC_POINT *pub_key = NULL; | 103 | EC_POINT *pub_key = NULL; |
@@ -102,36 +105,44 @@ int gost2001_compute_public(GOST_KEY * ec) | |||
102 | BN_CTX *ctx = NULL; | 105 | BN_CTX *ctx = NULL; |
103 | int ok = 0; | 106 | int ok = 0; |
104 | 107 | ||
105 | if (!group) { | 108 | if (group == NULL) { |
106 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, | 109 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, |
107 | GOST_R_KEY_IS_NOT_INITIALIZED); | 110 | GOST_R_KEY_IS_NOT_INITIALIZED); |
108 | return 0; | 111 | return 0; |
109 | } | 112 | } |
110 | ctx = BN_CTX_new(); | 113 | ctx = BN_CTX_new(); |
114 | if (ctx == NULL) { | ||
115 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, | ||
116 | ERR_R_MALLOC_FAILURE); | ||
117 | return 0; | ||
118 | } | ||
111 | BN_CTX_start(ctx); | 119 | BN_CTX_start(ctx); |
112 | if (!(priv_key = GOST_KEY_get0_private_key(ec))) { | 120 | if ((priv_key = GOST_KEY_get0_private_key(ec)) == NULL) |
113 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); | ||
114 | goto err; | 121 | goto err; |
115 | } | ||
116 | 122 | ||
117 | pub_key = EC_POINT_new(group); | 123 | pub_key = EC_POINT_new(group); |
118 | if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { | 124 | if (pub_key == NULL) |
119 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); | ||
120 | goto err; | 125 | goto err; |
121 | } | 126 | if (EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx) == 0) |
122 | if (!GOST_KEY_set_public_key(ec, pub_key)) { | ||
123 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); | ||
124 | goto err; | 127 | goto err; |
125 | } | 128 | if (GOST_KEY_set_public_key(ec, pub_key) == 0) |
126 | ok = 256; | 129 | goto err; |
130 | ok = 1; | ||
131 | |||
132 | if (ok == 0) { | ||
127 | err: | 133 | err: |
128 | BN_CTX_end(ctx); | 134 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); |
135 | } | ||
129 | EC_POINT_free(pub_key); | 136 | EC_POINT_free(pub_key); |
130 | BN_CTX_free(ctx); | 137 | if (ctx != NULL) { |
138 | BN_CTX_end(ctx); | ||
139 | BN_CTX_free(ctx); | ||
140 | } | ||
131 | return ok; | 141 | return ok; |
132 | } | 142 | } |
133 | 143 | ||
134 | ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) | 144 | ECDSA_SIG * |
145 | gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey) | ||
135 | { | 146 | { |
136 | ECDSA_SIG *newsig = NULL; | 147 | ECDSA_SIG *newsig = NULL; |
137 | BIGNUM *order = NULL; | 148 | BIGNUM *order = NULL; |
@@ -141,9 +152,15 @@ ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) | |||
141 | NULL, *e = NULL; | 152 | NULL, *e = NULL; |
142 | EC_POINT *C = NULL; | 153 | EC_POINT *C = NULL; |
143 | BN_CTX *ctx = BN_CTX_new(); | 154 | BN_CTX *ctx = BN_CTX_new(); |
155 | int ok = 0; | ||
156 | |||
157 | if (ctx == NULL) { | ||
158 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
159 | return NULL; | ||
160 | } | ||
144 | BN_CTX_start(ctx); | 161 | BN_CTX_start(ctx); |
145 | newsig = ECDSA_SIG_new(); | 162 | newsig = ECDSA_SIG_new(); |
146 | if (!newsig) { | 163 | if (newsig == NULL) { |
147 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); | 164 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); |
148 | goto err; | 165 | goto err; |
149 | } | 166 | } |
@@ -151,70 +168,88 @@ ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) | |||
151 | r = newsig->r; | 168 | r = newsig->r; |
152 | group = GOST_KEY_get0_group(eckey); | 169 | group = GOST_KEY_get0_group(eckey); |
153 | order = BN_CTX_get(ctx); | 170 | order = BN_CTX_get(ctx); |
154 | EC_GROUP_get_order(group, order, ctx); | 171 | if (order == NULL) |
172 | goto err; | ||
173 | if (EC_GROUP_get_order(group, order, ctx) == 0) | ||
174 | goto err; | ||
155 | priv_key = GOST_KEY_get0_private_key(eckey); | 175 | priv_key = GOST_KEY_get0_private_key(eckey); |
156 | e = BN_CTX_get(ctx); | 176 | e = BN_CTX_get(ctx); |
157 | BN_mod(e, md, order, ctx); | 177 | if (e == NULL) |
158 | if (BN_is_zero(e)) { | 178 | goto err; |
179 | if (BN_mod(e, md, order, ctx) == 0) | ||
180 | goto err; | ||
181 | if (BN_is_zero(e)) | ||
159 | BN_one(e); | 182 | BN_one(e); |
160 | } | ||
161 | k = BN_CTX_get(ctx); | 183 | k = BN_CTX_get(ctx); |
162 | X = BN_CTX_get(ctx); | 184 | X = BN_CTX_get(ctx); |
163 | C = EC_POINT_new(group); | 185 | C = EC_POINT_new(group); |
186 | if (C == NULL) | ||
187 | goto err; | ||
164 | do { | 188 | do { |
165 | do { | 189 | do { |
166 | if (!BN_rand_range(k, order)) { | 190 | if (!BN_rand_range(k, order)) { |
167 | GOSTerr(GOST_F_GOST2001_DO_SIGN, | 191 | GOSTerr(GOST_F_GOST2001_DO_SIGN, |
168 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); | 192 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); |
169 | ECDSA_SIG_free(newsig); | ||
170 | newsig = NULL; | ||
171 | goto err; | 193 | goto err; |
172 | } | 194 | } |
173 | /* We do not want timing information to leak the length of k, | 195 | /* |
174 | * so we compute G*k using an equivalent scalar of fixed | 196 | * We do not want timing information to leak the length |
175 | * bit-length. */ | 197 | * of k, so we compute G*k using an equivalent scalar |
176 | if (!BN_add(k, k, order)) | 198 | * of fixed bit-length. |
199 | */ | ||
200 | if (BN_add(k, k, order) == 0) | ||
177 | goto err; | 201 | goto err; |
178 | if (BN_num_bits(k) <= BN_num_bits(order)) | 202 | if (BN_num_bits(k) <= BN_num_bits(order)) |
179 | if (!BN_add(k, k, order)) | 203 | if (BN_add(k, k, order) == 0) |
180 | goto err; | 204 | goto err; |
181 | 205 | ||
182 | if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) { | 206 | if (EC_POINT_mul(group, C, k, NULL, NULL, ctx) == 0) { |
183 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); | 207 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); |
184 | ECDSA_SIG_free(newsig); | ||
185 | newsig = NULL; | ||
186 | goto err; | 208 | goto err; |
187 | } | 209 | } |
188 | if (!EC_POINT_get_affine_coordinates_GFp | 210 | if (EC_POINT_get_affine_coordinates_GFp(group, C, X, |
189 | (group, C, X, NULL, ctx)) { | 211 | NULL, ctx) == 0) { |
190 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); | 212 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); |
191 | ECDSA_SIG_free(newsig); | ||
192 | newsig = NULL; | ||
193 | goto err; | 213 | goto err; |
194 | } | 214 | } |
195 | BN_nnmod(r, X, order, ctx); | 215 | if (BN_nnmod(r, X, order, ctx) == 0) |
196 | } | 216 | goto err; |
197 | while (BN_is_zero(r)); | 217 | } while (BN_is_zero(r)); |
198 | /* s = (r*priv_key+k*e) mod order */ | 218 | /* s = (r*priv_key+k*e) mod order */ |
199 | if (!tmp) | 219 | if (tmp == NULL) { |
200 | tmp = BN_CTX_get(ctx); | 220 | tmp = BN_CTX_get(ctx); |
201 | BN_mod_mul(tmp, priv_key, r, order, ctx); | 221 | if (tmp == NULL) |
202 | if (!tmp2) | 222 | goto err; |
223 | } | ||
224 | if (BN_mod_mul(tmp, priv_key, r, order, ctx) == 0) | ||
225 | goto err; | ||
226 | if (tmp2 == NULL) { | ||
203 | tmp2 = BN_CTX_get(ctx); | 227 | tmp2 = BN_CTX_get(ctx); |
204 | BN_mod_mul(tmp2, k, e, order, ctx); | 228 | if (tmp2 == NULL) |
205 | BN_mod_add(s, tmp, tmp2, order, ctx); | 229 | goto err; |
206 | } | 230 | } |
207 | while (BN_is_zero(s)); | 231 | if (BN_mod_mul(tmp2, k, e, order, ctx) == 0) |
232 | goto err; | ||
233 | if (BN_mod_add(s, tmp, tmp2, order, ctx) == 0) | ||
234 | goto err; | ||
235 | } while (BN_is_zero(s)); | ||
236 | ok = 1; | ||
208 | 237 | ||
209 | err: | 238 | err: |
210 | BN_CTX_end(ctx); | ||
211 | BN_CTX_free(ctx); | ||
212 | EC_POINT_free(C); | 239 | EC_POINT_free(C); |
213 | BN_free(md); | 240 | if (ctx != NULL) { |
241 | BN_CTX_end(ctx); | ||
242 | BN_CTX_free(ctx); | ||
243 | } | ||
244 | if (ok == 0) { | ||
245 | ECDSA_SIG_free(newsig); | ||
246 | newsig = NULL; | ||
247 | } | ||
214 | return newsig; | 248 | return newsig; |
215 | } | 249 | } |
216 | 250 | ||
217 | int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) | 251 | int |
252 | gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec) | ||
218 | { | 253 | { |
219 | BN_CTX *ctx = BN_CTX_new(); | 254 | BN_CTX *ctx = BN_CTX_new(); |
220 | const EC_GROUP *group = GOST_KEY_get0_group(ec); | 255 | const EC_GROUP *group = GOST_KEY_get0_group(ec); |
@@ -225,6 +260,8 @@ int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) | |||
225 | const EC_POINT *pub_key = NULL; | 260 | const EC_POINT *pub_key = NULL; |
226 | int ok = 0; | 261 | int ok = 0; |
227 | 262 | ||
263 | if (ctx == NULL) | ||
264 | goto err; | ||
228 | BN_CTX_start(ctx); | 265 | BN_CTX_start(ctx); |
229 | order = BN_CTX_get(ctx); | 266 | order = BN_CTX_get(ctx); |
230 | e = BN_CTX_get(ctx); | 267 | e = BN_CTX_get(ctx); |
@@ -234,88 +271,129 @@ int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) | |||
234 | X = BN_CTX_get(ctx); | 271 | X = BN_CTX_get(ctx); |
235 | R = BN_CTX_get(ctx); | 272 | R = BN_CTX_get(ctx); |
236 | v = BN_CTX_get(ctx); | 273 | v = BN_CTX_get(ctx); |
274 | if (v == NULL) | ||
275 | goto err; | ||
237 | 276 | ||
238 | EC_GROUP_get_order(group, order, ctx); | 277 | if (EC_GROUP_get_order(group, order, ctx) == 0) |
278 | goto err; | ||
239 | pub_key = GOST_KEY_get0_public_key(ec); | 279 | pub_key = GOST_KEY_get0_public_key(ec); |
240 | if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || | 280 | if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || |
241 | (BN_cmp(sig->s, order) >= 1) || (BN_cmp(sig->r, order) >= 1)) { | 281 | BN_cmp(sig->s, order) >= 1 || BN_cmp(sig->r, order) >= 1) { |
242 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); | 282 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, |
283 | GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); | ||
243 | goto err; | 284 | goto err; |
244 | |||
245 | } | 285 | } |
246 | 286 | ||
247 | BN_mod(e, md, order, ctx); | 287 | if (BN_mod(e, md, order, ctx) == 0) |
288 | goto err; | ||
248 | if (BN_is_zero(e)) | 289 | if (BN_is_zero(e)) |
249 | BN_one(e); | 290 | BN_one(e); |
250 | v = BN_mod_inverse(v, e, order, ctx); | 291 | v = BN_mod_inverse(v, e, order, ctx); |
251 | BN_mod_mul(z1, sig->s, v, order, ctx); | 292 | if (v == NULL) |
252 | BN_sub(tmp, order, sig->r); | 293 | goto err; |
253 | BN_mod_mul(z2, tmp, v, order, ctx); | 294 | if (BN_mod_mul(z1, sig->s, v, order, ctx) == 0) |
295 | goto err; | ||
296 | if (BN_sub(tmp, order, sig->r) == 0) | ||
297 | goto err; | ||
298 | if (BN_mod_mul(z2, tmp, v, order, ctx) == 0) | ||
299 | goto err; | ||
254 | C = EC_POINT_new(group); | 300 | C = EC_POINT_new(group); |
255 | if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) { | 301 | if (C == NULL) |
302 | goto err; | ||
303 | if (EC_POINT_mul(group, C, z1, pub_key, z2, ctx) == 0) { | ||
256 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); | 304 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); |
257 | goto err; | 305 | goto err; |
258 | } | 306 | } |
259 | if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { | 307 | if (EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx) == 0) { |
260 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); | 308 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); |
261 | goto err; | 309 | goto err; |
262 | } | 310 | } |
263 | BN_mod(R, X, order, ctx); | 311 | if (BN_mod(R, X, order, ctx) == 0) |
312 | goto err; | ||
264 | if (BN_cmp(R, sig->r) != 0) { | 313 | if (BN_cmp(R, sig->r) != 0) { |
265 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); | 314 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); |
266 | } else { | 315 | } else { |
267 | ok = 1; | 316 | ok = 1; |
268 | } | 317 | } |
269 | err: | 318 | err: |
270 | EC_POINT_free(C); | 319 | EC_POINT_free(C); |
271 | BN_CTX_end(ctx); | 320 | if (ctx != NULL) { |
272 | BN_CTX_free(ctx); | 321 | BN_CTX_end(ctx); |
322 | BN_CTX_free(ctx); | ||
323 | } | ||
273 | return ok; | 324 | return ok; |
274 | } | 325 | } |
275 | 326 | ||
276 | |||
277 | /* Implementation of CryptoPro VKO 34.10-2001 algorithm */ | 327 | /* Implementation of CryptoPro VKO 34.10-2001 algorithm */ |
278 | void VKO_compute_key(BIGNUM * X, BIGNUM * Y, | 328 | int |
279 | const GOST_KEY * pkey, GOST_KEY * priv_key, | 329 | VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, GOST_KEY *priv_key, |
280 | const BIGNUM * ukm) | 330 | const BIGNUM *ukm) |
281 | { | 331 | { |
282 | BIGNUM *p = NULL, *order = NULL; | 332 | BIGNUM *p = NULL, *order = NULL; |
283 | const BIGNUM *key = GOST_KEY_get0_private_key(priv_key); | 333 | const BIGNUM *key = GOST_KEY_get0_private_key(priv_key); |
334 | const EC_GROUP *group = GOST_KEY_get0_group(priv_key); | ||
284 | const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey); | 335 | const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey); |
285 | EC_POINT *pnt = EC_POINT_new(GOST_KEY_get0_group(priv_key)); | 336 | EC_POINT *pnt; |
286 | BN_CTX *ctx = BN_CTX_new(); | 337 | BN_CTX *ctx = NULL; |
338 | int ok = 0; | ||
287 | 339 | ||
340 | pnt = EC_POINT_new(group); | ||
341 | if (pnt == NULL) | ||
342 | goto err; | ||
343 | ctx = BN_CTX_new(); | ||
344 | if (ctx == NULL) | ||
345 | goto err; | ||
288 | BN_CTX_start(ctx); | 346 | BN_CTX_start(ctx); |
289 | p = BN_CTX_get(ctx); | 347 | p = BN_CTX_get(ctx); |
290 | order = BN_CTX_get(ctx); | 348 | order = BN_CTX_get(ctx); |
291 | EC_GROUP_get_order(GOST_KEY_get0_group(priv_key), order, ctx); | 349 | if (order == NULL) |
292 | BN_mod_mul(p, key, ukm, order, ctx); | 350 | goto err; |
293 | EC_POINT_mul(GOST_KEY_get0_group(priv_key), pnt, NULL, pub_key, p, ctx); | 351 | if (EC_GROUP_get_order(group, order, ctx) == 0) |
294 | EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(priv_key), | 352 | goto err; |
295 | pnt, X, Y, ctx); | 353 | if (BN_mod_mul(p, key, ukm, order, ctx) == 0) |
296 | BN_CTX_end(ctx); | 354 | goto err; |
297 | BN_CTX_free(ctx); | 355 | if (EC_POINT_mul(group, pnt, NULL, pub_key, p, ctx) == 0) |
356 | goto err; | ||
357 | if (EC_POINT_get_affine_coordinates_GFp(group, pnt, X, Y, ctx) == 0) | ||
358 | goto err; | ||
359 | ok = 1; | ||
360 | |||
361 | err: | ||
362 | if (ctx != NULL) { | ||
363 | BN_CTX_end(ctx); | ||
364 | BN_CTX_free(ctx); | ||
365 | } | ||
298 | EC_POINT_free(pnt); | 366 | EC_POINT_free(pnt); |
367 | return ok; | ||
299 | } | 368 | } |
300 | 369 | ||
301 | int gost2001_keygen(GOST_KEY * ec) | 370 | int |
371 | gost2001_keygen(GOST_KEY *ec) | ||
302 | { | 372 | { |
303 | BIGNUM *order = BN_new(), *d = BN_new(); | 373 | BIGNUM *order = BN_new(), *d = BN_new(); |
304 | const EC_GROUP *group = GOST_KEY_get0_group(ec); | 374 | const EC_GROUP *group = GOST_KEY_get0_group(ec); |
305 | EC_GROUP_get_order(group, order, NULL); | 375 | int rc = 0; |
376 | |||
377 | if (order == NULL || d == NULL) | ||
378 | goto err; | ||
379 | if (EC_GROUP_get_order(group, order, NULL) == 0) | ||
380 | goto err; | ||
306 | 381 | ||
307 | do { | 382 | do { |
308 | if (!BN_rand_range(d, order)) { | 383 | if (BN_rand_range(d, order) == 0) { |
309 | GOSTerr(GOST_F_GOST2001_KEYGEN, | 384 | GOSTerr(GOST_F_GOST2001_KEYGEN, |
310 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); | 385 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); |
311 | BN_free(d); | 386 | goto err; |
312 | BN_free(order); | ||
313 | return 0; | ||
314 | } | 387 | } |
315 | } while (BN_is_zero(d)); | 388 | } while (BN_is_zero(d)); |
316 | GOST_KEY_set_private_key(ec, d); | 389 | |
390 | if (GOST_KEY_set_private_key(ec, d) == 0) | ||
391 | goto err; | ||
392 | rc = gost2001_compute_public(ec); | ||
393 | |||
394 | err: | ||
317 | BN_free(d); | 395 | BN_free(d); |
318 | BN_free(order); | 396 | BN_free(order); |
319 | return gost2001_compute_public(ec); | 397 | return rc; |
320 | } | 398 | } |
321 | #endif | 399 | #endif |