]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dsa/dsa_gen.c
RAND_bytes updates
[thirdparty/openssl.git] / crypto / dsa / dsa_gen.c
CommitLineData
d02b48c6 1/* crypto/dsa/dsa_gen.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
0f113f3e 8 *
d02b48c6
RE
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
0f113f3e 15 *
d02b48c6
RE
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
0f113f3e 22 *
d02b48c6
RE
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
0f113f3e 37 * 4. If you include any Windows specific code (or a derivative thereof) from
d02b48c6
RE
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
0f113f3e 40 *
d02b48c6
RE
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
0f113f3e 52 *
d02b48c6
RE
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
0f113f3e
MC
59/*
60 * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
61 * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB
62 * 180-1)
63 */
474e469b 64#define xxxHASH EVP_sha1()
d02b48c6 65
751ff1d3
RL
66#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */
67
474e469b
RS
68#include <stdio.h>
69#include "cryptlib.h"
70#include <openssl/evp.h>
71#include <openssl/bn.h>
72#include <openssl/rand.h>
73#include <openssl/sha.h>
a87030a1 74
474e469b 75#include "dsa_locl.h"
0e4aa0d2 76
e9224c71 77int DSA_generate_parameters_ex(DSA *ret, int bits,
0f113f3e
MC
78 const unsigned char *seed_in, int seed_len,
79 int *counter_ret, unsigned long *h_ret,
80 BN_GENCB *cb)
81{
82 if (ret->meth->dsa_paramgen)
83 return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
84 counter_ret, h_ret, cb);
85 else {
86 const EVP_MD *evpmd;
87 size_t qbits = bits >= 2048 ? 256 : 160;
88
89 if (bits >= 2048) {
90 qbits = 256;
91 evpmd = EVP_sha256();
92 } else {
93 qbits = 160;
94 evpmd = EVP_sha1();
95 }
96
97 return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
98 seed_in, seed_len, NULL, counter_ret,
99 h_ret, cb);
100 }
101}
0e4aa0d2 102
357d5de5 103int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
0f113f3e
MC
104 const EVP_MD *evpmd, const unsigned char *seed_in,
105 size_t seed_len, unsigned char *seed_out,
106 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
107{
108 int ok = 0;
109 unsigned char seed[SHA256_DIGEST_LENGTH];
110 unsigned char md[SHA256_DIGEST_LENGTH];
111 unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
112 BIGNUM *r0, *W, *X, *c, *test;
113 BIGNUM *g = NULL, *q = NULL, *p = NULL;
114 BN_MONT_CTX *mont = NULL;
115 int i, k, n = 0, m = 0, qsize = qbits >> 3;
116 int counter = 0;
117 int r = 0;
118 BN_CTX *ctx = NULL;
119 unsigned int h = 2;
120
121 if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
122 qsize != SHA256_DIGEST_LENGTH)
123 /* invalid q size */
124 return 0;
125
126 if (evpmd == NULL)
127 /* use SHA1 as default */
128 evpmd = EVP_sha1();
129
130 if (bits < 512)
131 bits = 512;
132
133 bits = (bits + 63) / 64 * 64;
134
135 /*
136 * NB: seed_len == 0 is special case: copy generated seed to seed_in if
137 * it is not NULL.
138 */
139 if (seed_len && (seed_len < (size_t)qsize))
140 seed_in = NULL; /* seed buffer too small -- ignore */
141 if (seed_len > (size_t)qsize)
142 seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger
143 * SEED, but our internal buffers are
144 * restricted to 160 bits */
145 if (seed_in != NULL)
146 memcpy(seed, seed_in, seed_len);
147
148 if ((ctx = BN_CTX_new()) == NULL)
149 goto err;
150
151 if ((mont = BN_MONT_CTX_new()) == NULL)
152 goto err;
153
154 BN_CTX_start(ctx);
155 r0 = BN_CTX_get(ctx);
156 g = BN_CTX_get(ctx);
157 W = BN_CTX_get(ctx);
158 q = BN_CTX_get(ctx);
159 X = BN_CTX_get(ctx);
160 c = BN_CTX_get(ctx);
161 p = BN_CTX_get(ctx);
162 test = BN_CTX_get(ctx);
163
164 if (!BN_lshift(test, BN_value_one(), bits - 1))
165 goto err;
166
167 for (;;) {
168 for (;;) { /* find q */
169 int seed_is_random;
170
171 /* step 1 */
172 if (!BN_GENCB_call(cb, 0, m++))
173 goto err;
174
175 if (!seed_len) {
266483d2 176 if (RAND_bytes(seed, qsize) <= 0)
0f113f3e
MC
177 goto err;
178 seed_is_random = 1;
179 } else {
180 seed_is_random = 0;
181 seed_len = 0; /* use random seed if 'seed_in' turns out to
182 * be bad */
183 }
184 memcpy(buf, seed, qsize);
185 memcpy(buf2, seed, qsize);
186 /* precompute "SEED + 1" for step 7: */
187 for (i = qsize - 1; i >= 0; i--) {
188 buf[i]++;
189 if (buf[i] != 0)
190 break;
191 }
192
193 /* step 2 */
194 if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
195 goto err;
196 if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
197 goto err;
198 for (i = 0; i < qsize; i++)
199 md[i] ^= buf2[i];
200
201 /* step 3 */
202 md[0] |= 0x80;
203 md[qsize - 1] |= 0x01;
204 if (!BN_bin2bn(md, qsize, q))
205 goto err;
206
207 /* step 4 */
208 r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
209 seed_is_random, cb);
210 if (r > 0)
211 break;
212 if (r != 0)
213 goto err;
214
215 /* do a callback call */
216 /* step 5 */
217 }
218
219 if (!BN_GENCB_call(cb, 2, 0))
220 goto err;
221 if (!BN_GENCB_call(cb, 3, 0))
222 goto err;
223
224 /* step 6 */
225 counter = 0;
226 /* "offset = 2" */
227
228 n = (bits - 1) / 160;
229
230 for (;;) {
231 if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
232 goto err;
233
234 /* step 7 */
235 BN_zero(W);
236 /* now 'buf' contains "SEED + offset - 1" */
237 for (k = 0; k <= n; k++) {
238 /*
239 * obtain "SEED + offset + k" by incrementing:
240 */
241 for (i = qsize - 1; i >= 0; i--) {
242 buf[i]++;
243 if (buf[i] != 0)
244 break;
245 }
246
247 if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
248 goto err;
249
250 /* step 8 */
251 if (!BN_bin2bn(md, qsize, r0))
252 goto err;
253 if (!BN_lshift(r0, r0, (qsize << 3) * k))
254 goto err;
255 if (!BN_add(W, W, r0))
256 goto err;
257 }
258
259 /* more of step 8 */
260 if (!BN_mask_bits(W, bits - 1))
261 goto err;
262 if (!BN_copy(X, W))
263 goto err;
264 if (!BN_add(X, X, test))
265 goto err;
266
267 /* step 9 */
268 if (!BN_lshift1(r0, q))
269 goto err;
270 if (!BN_mod(c, X, r0, ctx))
271 goto err;
272 if (!BN_sub(r0, c, BN_value_one()))
273 goto err;
274 if (!BN_sub(p, X, r0))
275 goto err;
276
277 /* step 10 */
278 if (BN_cmp(p, test) >= 0) {
279 /* step 11 */
280 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
281 if (r > 0)
282 goto end; /* found it */
283 if (r != 0)
284 goto err;
285 }
286
287 /* step 13 */
288 counter++;
289 /* "offset = offset + n + 1" */
290
291 /* step 14 */
292 if (counter >= 4096)
293 break;
294 }
295 }
296 end:
297 if (!BN_GENCB_call(cb, 2, 1))
298 goto err;
299
300 /* We now need to generate g */
301 /* Set r0=(p-1)/q */
302 if (!BN_sub(test, p, BN_value_one()))
303 goto err;
304 if (!BN_div(r0, NULL, test, q, ctx))
305 goto err;
306
307 if (!BN_set_word(test, h))
308 goto err;
309 if (!BN_MONT_CTX_set(mont, p, ctx))
310 goto err;
311
312 for (;;) {
313 /* g=test^r0%p */
314 if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
315 goto err;
316 if (!BN_is_one(g))
317 break;
318 if (!BN_add(test, test, BN_value_one()))
319 goto err;
320 h++;
321 }
322
323 if (!BN_GENCB_call(cb, 3, 1))
324 goto err;
325
326 ok = 1;
327 err:
328 if (ok) {
329 if (ret->p)
330 BN_free(ret->p);
331 if (ret->q)
332 BN_free(ret->q);
333 if (ret->g)
334 BN_free(ret->g);
335 ret->p = BN_dup(p);
336 ret->q = BN_dup(q);
337 ret->g = BN_dup(g);
338 if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
339 ok = 0;
340 goto err;
341 }
342 if (counter_ret != NULL)
343 *counter_ret = counter;
344 if (h_ret != NULL)
345 *h_ret = h;
346 if (seed_out)
347 memcpy(seed_out, seed, qsize);
348 }
349 if (ctx) {
350 BN_CTX_end(ctx);
351 BN_CTX_free(ctx);
352 }
353 if (mont != NULL)
354 BN_MONT_CTX_free(mont);
355 return ok;
356}
357
358/*
359 * This is a parameter generation algorithm for the DSA2 algorithm as
3dd9b31d
DSH
360 * described in FIPS 186-3.
361 */
362
363int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
0f113f3e
MC
364 const EVP_MD *evpmd, const unsigned char *seed_in,
365 size_t seed_len, int idx, unsigned char *seed_out,
366 int *counter_ret, unsigned long *h_ret,
367 BN_GENCB *cb)
368{
369 int ok = -1;
370 unsigned char *seed = NULL, *seed_tmp = NULL;
371 unsigned char md[EVP_MAX_MD_SIZE];
372 int mdsize;
373 BIGNUM *r0, *W, *X, *c, *test;
374 BIGNUM *g = NULL, *q = NULL, *p = NULL;
375 BN_MONT_CTX *mont = NULL;
376 int i, k, n = 0, m = 0, qsize = N >> 3;
377 int counter = 0;
378 int r = 0;
379 BN_CTX *ctx = NULL;
380 EVP_MD_CTX mctx;
381 unsigned int h = 2;
382
383 EVP_MD_CTX_init(&mctx);
384
385 if (evpmd == NULL) {
386 if (N == 160)
387 evpmd = EVP_sha1();
388 else if (N == 224)
389 evpmd = EVP_sha224();
390 else
391 evpmd = EVP_sha256();
392 }
393
394 mdsize = M_EVP_MD_size(evpmd);
395 /* If unverificable g generation only don't need seed */
396 if (!ret->p || !ret->q || idx >= 0) {
397 if (seed_len == 0)
398 seed_len = mdsize;
399
400 seed = OPENSSL_malloc(seed_len);
401
402 if (seed_out)
403 seed_tmp = seed_out;
404 else
405 seed_tmp = OPENSSL_malloc(seed_len);
406
407 if (!seed || !seed_tmp)
408 goto err;
409
410 if (seed_in)
411 memcpy(seed, seed_in, seed_len);
412
413 }
414
415 if ((ctx = BN_CTX_new()) == NULL)
416 goto err;
417
418 if ((mont = BN_MONT_CTX_new()) == NULL)
419 goto err;
420
421 BN_CTX_start(ctx);
422 r0 = BN_CTX_get(ctx);
423 g = BN_CTX_get(ctx);
424 W = BN_CTX_get(ctx);
425 X = BN_CTX_get(ctx);
426 c = BN_CTX_get(ctx);
427 test = BN_CTX_get(ctx);
428
429 /* if p, q already supplied generate g only */
430 if (ret->p && ret->q) {
431 p = ret->p;
432 q = ret->q;
433 if (idx >= 0)
434 memcpy(seed_tmp, seed, seed_len);
435 goto g_only;
436 } else {
437 p = BN_CTX_get(ctx);
438 q = BN_CTX_get(ctx);
439 }
440
441 if (!BN_lshift(test, BN_value_one(), L - 1))
442 goto err;
443 for (;;) {
444 for (;;) { /* find q */
445 unsigned char *pmd;
446 /* step 1 */
447 if (!BN_GENCB_call(cb, 0, m++))
448 goto err;
449
450 if (!seed_in) {
266483d2 451 if (RAND_bytes(seed, seed_len) <= 0)
0f113f3e
MC
452 goto err;
453 }
454 /* step 2 */
455 if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
456 goto err;
457 /* Take least significant bits of md */
458 if (mdsize > qsize)
459 pmd = md + mdsize - qsize;
460 else
461 pmd = md;
462
463 if (mdsize < qsize)
464 memset(md + mdsize, 0, qsize - mdsize);
465
466 /* step 3 */
467 pmd[0] |= 0x80;
468 pmd[qsize - 1] |= 0x01;
469 if (!BN_bin2bn(pmd, qsize, q))
470 goto err;
471
472 /* step 4 */
473 r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
474 seed_in ? 1 : 0, cb);
475 if (r > 0)
476 break;
477 if (r != 0)
478 goto err;
479 /* Provided seed didn't produce a prime: error */
480 if (seed_in) {
481 ok = 0;
482 DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME);
483 goto err;
484 }
485
486 /* do a callback call */
487 /* step 5 */
488 }
489 /* Copy seed to seed_out before we mess with it */
490 if (seed_out)
491 memcpy(seed_out, seed, seed_len);
492
493 if (!BN_GENCB_call(cb, 2, 0))
494 goto err;
495 if (!BN_GENCB_call(cb, 3, 0))
496 goto err;
497
498 /* step 6 */
499 counter = 0;
500 /* "offset = 1" */
501
502 n = (L - 1) / (mdsize << 3);
503
504 for (;;) {
505 if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
506 goto err;
507
508 /* step 7 */
509 BN_zero(W);
510 /* now 'buf' contains "SEED + offset - 1" */
511 for (k = 0; k <= n; k++) {
512 /*
513 * obtain "SEED + offset + k" by incrementing:
514 */
515 for (i = seed_len - 1; i >= 0; i--) {
516 seed[i]++;
517 if (seed[i] != 0)
518 break;
519 }
520
521 if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
522 goto err;
523
524 /* step 8 */
525 if (!BN_bin2bn(md, mdsize, r0))
526 goto err;
527 if (!BN_lshift(r0, r0, (mdsize << 3) * k))
528 goto err;
529 if (!BN_add(W, W, r0))
530 goto err;
531 }
532
533 /* more of step 8 */
534 if (!BN_mask_bits(W, L - 1))
535 goto err;
536 if (!BN_copy(X, W))
537 goto err;
538 if (!BN_add(X, X, test))
539 goto err;
540
541 /* step 9 */
542 if (!BN_lshift1(r0, q))
543 goto err;
544 if (!BN_mod(c, X, r0, ctx))
545 goto err;
546 if (!BN_sub(r0, c, BN_value_one()))
547 goto err;
548 if (!BN_sub(p, X, r0))
549 goto err;
550
551 /* step 10 */
552 if (BN_cmp(p, test) >= 0) {
553 /* step 11 */
554 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
555 if (r > 0)
556 goto end; /* found it */
557 if (r != 0)
558 goto err;
559 }
560
561 /* step 13 */
562 counter++;
563 /* "offset = offset + n + 1" */
564
565 /* step 14 */
566 if (counter >= (int)(4 * L))
567 break;
568 }
569 if (seed_in) {
570 ok = 0;
571 DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
572 goto err;
573 }
574 }
575 end:
576 if (!BN_GENCB_call(cb, 2, 1))
577 goto err;
578
579 g_only:
580
581 /* We now need to generate g */
582 /* Set r0=(p-1)/q */
583 if (!BN_sub(test, p, BN_value_one()))
584 goto err;
585 if (!BN_div(r0, NULL, test, q, ctx))
586 goto err;
587
588 if (idx < 0) {
589 if (!BN_set_word(test, h))
590 goto err;
591 } else
592 h = 1;
593 if (!BN_MONT_CTX_set(mont, p, ctx))
594 goto err;
595
596 for (;;) {
597 static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e };
598 if (idx >= 0) {
599 md[0] = idx & 0xff;
600 md[1] = (h >> 8) & 0xff;
601 md[2] = h & 0xff;
602 if (!EVP_DigestInit_ex(&mctx, evpmd, NULL))
603 goto err;
604 if (!EVP_DigestUpdate(&mctx, seed_tmp, seed_len))
605 goto err;
606 if (!EVP_DigestUpdate(&mctx, ggen, sizeof(ggen)))
607 goto err;
608 if (!EVP_DigestUpdate(&mctx, md, 3))
609 goto err;
610 if (!EVP_DigestFinal_ex(&mctx, md, NULL))
611 goto err;
612 if (!BN_bin2bn(md, mdsize, test))
613 goto err;
614 }
615 /* g=test^r0%p */
616 if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
617 goto err;
618 if (!BN_is_one(g))
619 break;
620 if (idx < 0 && !BN_add(test, test, BN_value_one()))
621 goto err;
622 h++;
623 if (idx >= 0 && h > 0xffff)
624 goto err;
625 }
626
627 if (!BN_GENCB_call(cb, 3, 1))
628 goto err;
629
630 ok = 1;
631 err:
632 if (ok == 1) {
633 if (p != ret->p) {
634 if (ret->p)
635 BN_free(ret->p);
636 ret->p = BN_dup(p);
637 }
638 if (q != ret->q) {
639 if (ret->q)
640 BN_free(ret->q);
641 ret->q = BN_dup(q);
642 }
643 if (ret->g)
644 BN_free(ret->g);
645 ret->g = BN_dup(g);
646 if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
647 ok = -1;
648 goto err;
649 }
650 if (counter_ret != NULL)
651 *counter_ret = counter;
652 if (h_ret != NULL)
653 *h_ret = h;
654 }
655 if (seed)
656 OPENSSL_free(seed);
657 if (seed_out != seed_tmp)
658 OPENSSL_free(seed_tmp);
659 if (ctx) {
660 BN_CTX_end(ctx);
661 BN_CTX_free(ctx);
662 }
663 if (mont != NULL)
664 BN_MONT_CTX_free(mont);
665 EVP_MD_CTX_cleanup(&mctx);
666 return ok;
667}
f55f5f77
DSH
668
669int dsa_paramgen_check_g(DSA *dsa)
0f113f3e
MC
670{
671 BN_CTX *ctx;
672 BIGNUM *tmp;
673 BN_MONT_CTX *mont = NULL;
674 int rv = -1;
675 ctx = BN_CTX_new();
676 if (!ctx)
677 return -1;
678 BN_CTX_start(ctx);
679 if (BN_cmp(dsa->g, BN_value_one()) <= 0)
680 return 0;
681 if (BN_cmp(dsa->g, dsa->p) >= 0)
682 return 0;
683 tmp = BN_CTX_get(ctx);
684 if (!tmp)
685 goto err;
686 if ((mont = BN_MONT_CTX_new()) == NULL)
687 goto err;
688 if (!BN_MONT_CTX_set(mont, dsa->p, ctx))
689 goto err;
690 /* Work out g^q mod p */
691 if (!BN_mod_exp_mont(tmp, dsa->g, dsa->q, dsa->p, ctx, mont))
692 goto err;
693 if (!BN_cmp(tmp, BN_value_one()))
694 rv = 1;
695 else
696 rv = 0;
697 err:
698 BN_CTX_end(ctx);
699 if (mont)
700 BN_MONT_CTX_free(mont);
701 BN_CTX_free(ctx);
702 return rv;
703
704}