]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssl/crypto/dsa/dsa_gen.c
Merge OpenSSL 1.0.2q.
[FreeBSD/FreeBSD.git] / crypto / openssl / crypto / dsa / dsa_gen.c
1 /* crypto/dsa/dsa_gen.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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.
8  *
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).
15  *
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.
22  *
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 :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
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.
52  *
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
59 #undef GENUINE_DSA
60
61 #ifdef GENUINE_DSA
62 /*
63  * Parameter generation follows the original release of FIPS PUB 186,
64  * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180)
65  */
66 # define HASH    EVP_sha()
67 #else
68 /*
69  * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
70  * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB
71  * 180-1)
72  */
73 # define HASH    EVP_sha1()
74 #endif
75
76 #include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */
77
78 #ifndef OPENSSL_NO_SHA
79
80 # include <stdio.h>
81 # include "cryptlib.h"
82 # include <openssl/evp.h>
83 # include <openssl/bn.h>
84 # include <openssl/rand.h>
85 # include <openssl/sha.h>
86 # include "dsa_locl.h"
87
88 # ifdef OPENSSL_FIPS
89 /* Workaround bug in prototype */
90 #  define fips_dsa_builtin_paramgen2 fips_dsa_paramgen_bad
91 #  include <openssl/fips.h>
92 # endif
93
94 int DSA_generate_parameters_ex(DSA *ret, int bits,
95                                const unsigned char *seed_in, int seed_len,
96                                int *counter_ret, unsigned long *h_ret,
97                                BN_GENCB *cb)
98 {
99 # ifdef OPENSSL_FIPS
100     if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD)
101         && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW)) {
102         DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD);
103         return 0;
104     }
105 # endif
106     if (ret->meth->dsa_paramgen)
107         return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
108                                        counter_ret, h_ret, cb);
109 # ifdef OPENSSL_FIPS
110     else if (FIPS_mode()) {
111         return FIPS_dsa_generate_parameters_ex(ret, bits,
112                                                seed_in, seed_len,
113                                                counter_ret, h_ret, cb);
114     }
115 # endif
116     else {
117         const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1();
118         size_t qbits = EVP_MD_size(evpmd) * 8;
119
120         return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
121                                     seed_in, seed_len, NULL, counter_ret,
122                                     h_ret, cb);
123     }
124 }
125
126 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
127                          const EVP_MD *evpmd, const unsigned char *seed_in,
128                          size_t seed_len, unsigned char *seed_out,
129                          int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
130 {
131     int ok = 0;
132     unsigned char seed[SHA256_DIGEST_LENGTH];
133     unsigned char md[SHA256_DIGEST_LENGTH];
134     unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
135     BIGNUM *r0, *W, *X, *c, *test;
136     BIGNUM *g = NULL, *q = NULL, *p = NULL;
137     BN_MONT_CTX *mont = NULL;
138     int i, k, n = 0, m = 0, qsize = qbits >> 3;
139     int counter = 0;
140     int r = 0;
141     BN_CTX *ctx = NULL;
142     unsigned int h = 2;
143
144     if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
145         qsize != SHA256_DIGEST_LENGTH)
146         /* invalid q size */
147         return 0;
148
149     if (evpmd == NULL) {
150         if (qsize == SHA_DIGEST_LENGTH)
151             evpmd = EVP_sha1();
152         else if (qsize == SHA224_DIGEST_LENGTH)
153             evpmd = EVP_sha224();
154         else
155             evpmd = EVP_sha256();
156     } else {
157         qsize = EVP_MD_size(evpmd);
158     }
159
160     if (bits < 512)
161         bits = 512;
162
163     bits = (bits + 63) / 64 * 64;
164
165     /*
166      * NB: seed_len == 0 is special case: copy generated seed to seed_in if
167      * it is not NULL.
168      */
169     if (seed_len && (seed_len < (size_t)qsize))
170         seed_in = NULL;         /* seed buffer too small -- ignore */
171     if (seed_len > (size_t)qsize)
172         seed_len = qsize;       /* App. 2.2 of FIPS PUB 186 allows larger
173                                  * SEED, but our internal buffers are
174                                  * restricted to 160 bits */
175     if (seed_in != NULL)
176         memcpy(seed, seed_in, seed_len);
177
178     if ((mont = BN_MONT_CTX_new()) == NULL)
179         goto err;
180
181     if ((ctx = BN_CTX_new()) == NULL)
182         goto err;
183
184     BN_CTX_start(ctx);
185
186     r0 = BN_CTX_get(ctx);
187     g = BN_CTX_get(ctx);
188     W = BN_CTX_get(ctx);
189     q = BN_CTX_get(ctx);
190     X = BN_CTX_get(ctx);
191     c = BN_CTX_get(ctx);
192     p = BN_CTX_get(ctx);
193     test = BN_CTX_get(ctx);
194
195     if (test == NULL)
196         goto err;
197
198     if (!BN_lshift(test, BN_value_one(), bits - 1))
199         goto err;
200
201     for (;;) {
202         for (;;) {              /* find q */
203             int seed_is_random;
204
205             /* step 1 */
206             if (!BN_GENCB_call(cb, 0, m++))
207                 goto err;
208
209             if (!seed_len || !seed_in) {
210                 if (RAND_bytes(seed, qsize) <= 0)
211                     goto err;
212                 seed_is_random = 1;
213             } else {
214                 seed_is_random = 0;
215                 seed_len = 0;   /* use random seed if 'seed_in' turns out to
216                                  * be bad */
217             }
218             memcpy(buf, seed, qsize);
219             memcpy(buf2, seed, qsize);
220             /* precompute "SEED + 1" for step 7: */
221             for (i = qsize - 1; i >= 0; i--) {
222                 buf[i]++;
223                 if (buf[i] != 0)
224                     break;
225             }
226
227             /* step 2 */
228             if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
229                 goto err;
230             if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
231                 goto err;
232             for (i = 0; i < qsize; i++)
233                 md[i] ^= buf2[i];
234
235             /* step 3 */
236             md[0] |= 0x80;
237             md[qsize - 1] |= 0x01;
238             if (!BN_bin2bn(md, qsize, q))
239                 goto err;
240
241             /* step 4 */
242             r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
243                                         seed_is_random, cb);
244             if (r > 0)
245                 break;
246             if (r != 0)
247                 goto err;
248
249             /* do a callback call */
250             /* step 5 */
251         }
252
253         if (!BN_GENCB_call(cb, 2, 0))
254             goto err;
255         if (!BN_GENCB_call(cb, 3, 0))
256             goto err;
257
258         /* step 6 */
259         counter = 0;
260         /* "offset = 2" */
261
262         n = (bits - 1) / 160;
263
264         for (;;) {
265             if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
266                 goto err;
267
268             /* step 7 */
269             BN_zero(W);
270             /* now 'buf' contains "SEED + offset - 1" */
271             for (k = 0; k <= n; k++) {
272                 /*
273                  * obtain "SEED + offset + k" by incrementing:
274                  */
275                 for (i = qsize - 1; i >= 0; i--) {
276                     buf[i]++;
277                     if (buf[i] != 0)
278                         break;
279                 }
280
281                 if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
282                     goto err;
283
284                 /* step 8 */
285                 if (!BN_bin2bn(md, qsize, r0))
286                     goto err;
287                 if (!BN_lshift(r0, r0, (qsize << 3) * k))
288                     goto err;
289                 if (!BN_add(W, W, r0))
290                     goto err;
291             }
292
293             /* more of step 8 */
294             if (!BN_mask_bits(W, bits - 1))
295                 goto err;
296             if (!BN_copy(X, W))
297                 goto err;
298             if (!BN_add(X, X, test))
299                 goto err;
300
301             /* step 9 */
302             if (!BN_lshift1(r0, q))
303                 goto err;
304             if (!BN_mod(c, X, r0, ctx))
305                 goto err;
306             if (!BN_sub(r0, c, BN_value_one()))
307                 goto err;
308             if (!BN_sub(p, X, r0))
309                 goto err;
310
311             /* step 10 */
312             if (BN_cmp(p, test) >= 0) {
313                 /* step 11 */
314                 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
315                 if (r > 0)
316                     goto end;   /* found it */
317                 if (r != 0)
318                     goto err;
319             }
320
321             /* step 13 */
322             counter++;
323             /* "offset = offset + n + 1" */
324
325             /* step 14 */
326             if (counter >= 4096)
327                 break;
328         }
329     }
330  end:
331     if (!BN_GENCB_call(cb, 2, 1))
332         goto err;
333
334     /* We now need to generate g */
335     /* Set r0=(p-1)/q */
336     if (!BN_sub(test, p, BN_value_one()))
337         goto err;
338     if (!BN_div(r0, NULL, test, q, ctx))
339         goto err;
340
341     if (!BN_set_word(test, h))
342         goto err;
343     if (!BN_MONT_CTX_set(mont, p, ctx))
344         goto err;
345
346     for (;;) {
347         /* g=test^r0%p */
348         if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
349             goto err;
350         if (!BN_is_one(g))
351             break;
352         if (!BN_add(test, test, BN_value_one()))
353             goto err;
354         h++;
355     }
356
357     if (!BN_GENCB_call(cb, 3, 1))
358         goto err;
359
360     ok = 1;
361  err:
362     if (ok) {
363         if (ret->p)
364             BN_free(ret->p);
365         if (ret->q)
366             BN_free(ret->q);
367         if (ret->g)
368             BN_free(ret->g);
369         ret->p = BN_dup(p);
370         ret->q = BN_dup(q);
371         ret->g = BN_dup(g);
372         if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
373             ok = 0;
374             goto err;
375         }
376         if (counter_ret != NULL)
377             *counter_ret = counter;
378         if (h_ret != NULL)
379             *h_ret = h;
380         if (seed_out)
381             memcpy(seed_out, seed, qsize);
382     }
383     if (ctx) {
384         BN_CTX_end(ctx);
385         BN_CTX_free(ctx);
386     }
387     if (mont != NULL)
388         BN_MONT_CTX_free(mont);
389     return ok;
390 }
391
392 # ifdef OPENSSL_FIPS
393 #  undef fips_dsa_builtin_paramgen2
394 extern int fips_dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
395                                       const EVP_MD *evpmd,
396                                       const unsigned char *seed_in,
397                                       size_t seed_len, int idx,
398                                       unsigned char *seed_out,
399                                       int *counter_ret, unsigned long *h_ret,
400                                       BN_GENCB *cb);
401 # endif
402
403 /*
404  * This is a parameter generation algorithm for the DSA2 algorithm as
405  * described in FIPS 186-3.
406  */
407
408 int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
409                           const EVP_MD *evpmd, const unsigned char *seed_in,
410                           size_t seed_len, int idx, unsigned char *seed_out,
411                           int *counter_ret, unsigned long *h_ret,
412                           BN_GENCB *cb)
413 {
414     int ok = -1;
415     unsigned char *seed = NULL, *seed_tmp = NULL;
416     unsigned char md[EVP_MAX_MD_SIZE];
417     int mdsize;
418     BIGNUM *r0, *W, *X, *c, *test;
419     BIGNUM *g = NULL, *q = NULL, *p = NULL;
420     BN_MONT_CTX *mont = NULL;
421     int i, k, n = 0, m = 0, qsize = N >> 3;
422     int counter = 0;
423     int r = 0;
424     BN_CTX *ctx = NULL;
425     EVP_MD_CTX mctx;
426     unsigned int h = 2;
427
428 # ifdef OPENSSL_FIPS
429
430     if (FIPS_mode())
431         return fips_dsa_builtin_paramgen2(ret, L, N, evpmd,
432                                           seed_in, seed_len, idx,
433                                           seed_out, counter_ret, h_ret, cb);
434 # endif
435
436     EVP_MD_CTX_init(&mctx);
437
438     /* make sure L > N, otherwise we'll get trapped in an infinite loop */
439     if (L <= N) {
440         DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
441         goto err;
442     }
443
444     if (evpmd == NULL) {
445         if (N == 160)
446             evpmd = EVP_sha1();
447         else if (N == 224)
448             evpmd = EVP_sha224();
449         else
450             evpmd = EVP_sha256();
451     }
452
453     mdsize = EVP_MD_size(evpmd);
454     /* If unverificable g generation only don't need seed */
455     if (!ret->p || !ret->q || idx >= 0) {
456         if (seed_len == 0)
457             seed_len = mdsize;
458
459         seed = OPENSSL_malloc(seed_len);
460
461         if (seed_out)
462             seed_tmp = seed_out;
463         else
464             seed_tmp = OPENSSL_malloc(seed_len);
465
466         if (!seed || !seed_tmp)
467             goto err;
468
469         if (seed_in)
470             memcpy(seed, seed_in, seed_len);
471
472     }
473
474     if ((ctx = BN_CTX_new()) == NULL)
475         goto err;
476
477     if ((mont = BN_MONT_CTX_new()) == NULL)
478         goto err;
479
480     BN_CTX_start(ctx);
481     r0 = BN_CTX_get(ctx);
482     g = BN_CTX_get(ctx);
483     W = BN_CTX_get(ctx);
484     X = BN_CTX_get(ctx);
485     c = BN_CTX_get(ctx);
486     test = BN_CTX_get(ctx);
487
488     /* if p, q already supplied generate g only */
489     if (ret->p && ret->q) {
490         p = ret->p;
491         q = ret->q;
492         if (idx >= 0)
493             memcpy(seed_tmp, seed, seed_len);
494         goto g_only;
495     } else {
496         p = BN_CTX_get(ctx);
497         q = BN_CTX_get(ctx);
498         if (q == NULL)
499             goto err;
500     }
501
502     if (!BN_lshift(test, BN_value_one(), L - 1))
503         goto err;
504     for (;;) {
505         for (;;) {              /* find q */
506             unsigned char *pmd;
507             /* step 1 */
508             if (!BN_GENCB_call(cb, 0, m++))
509                 goto err;
510
511             if (!seed_in) {
512                 if (RAND_bytes(seed, seed_len) <= 0)
513                     goto err;
514             }
515             /* step 2 */
516             if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
517                 goto err;
518             /* Take least significant bits of md */
519             if (mdsize > qsize)
520                 pmd = md + mdsize - qsize;
521             else
522                 pmd = md;
523
524             if (mdsize < qsize)
525                 memset(md + mdsize, 0, qsize - mdsize);
526
527             /* step 3 */
528             pmd[0] |= 0x80;
529             pmd[qsize - 1] |= 0x01;
530             if (!BN_bin2bn(pmd, qsize, q))
531                 goto err;
532
533             /* step 4 */
534             r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
535                                         seed_in ? 1 : 0, cb);
536             if (r > 0)
537                 break;
538             if (r != 0)
539                 goto err;
540             /* Provided seed didn't produce a prime: error */
541             if (seed_in) {
542                 ok = 0;
543                 DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME);
544                 goto err;
545             }
546
547             /* do a callback call */
548             /* step 5 */
549         }
550         /* Copy seed to seed_out before we mess with it */
551         if (seed_out)
552             memcpy(seed_out, seed, seed_len);
553
554         if (!BN_GENCB_call(cb, 2, 0))
555             goto err;
556         if (!BN_GENCB_call(cb, 3, 0))
557             goto err;
558
559         /* step 6 */
560         counter = 0;
561         /* "offset = 1" */
562
563         n = (L - 1) / (mdsize << 3);
564
565         for (;;) {
566             if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
567                 goto err;
568
569             /* step 7 */
570             BN_zero(W);
571             /* now 'buf' contains "SEED + offset - 1" */
572             for (k = 0; k <= n; k++) {
573                 /*
574                  * obtain "SEED + offset + k" by incrementing:
575                  */
576                 for (i = seed_len - 1; i >= 0; i--) {
577                     seed[i]++;
578                     if (seed[i] != 0)
579                         break;
580                 }
581
582                 if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
583                     goto err;
584
585                 /* step 8 */
586                 if (!BN_bin2bn(md, mdsize, r0))
587                     goto err;
588                 if (!BN_lshift(r0, r0, (mdsize << 3) * k))
589                     goto err;
590                 if (!BN_add(W, W, r0))
591                     goto err;
592             }
593
594             /* more of step 8 */
595             if (!BN_mask_bits(W, L - 1))
596                 goto err;
597             if (!BN_copy(X, W))
598                 goto err;
599             if (!BN_add(X, X, test))
600                 goto err;
601
602             /* step 9 */
603             if (!BN_lshift1(r0, q))
604                 goto err;
605             if (!BN_mod(c, X, r0, ctx))
606                 goto err;
607             if (!BN_sub(r0, c, BN_value_one()))
608                 goto err;
609             if (!BN_sub(p, X, r0))
610                 goto err;
611
612             /* step 10 */
613             if (BN_cmp(p, test) >= 0) {
614                 /* step 11 */
615                 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
616                 if (r > 0)
617                     goto end;   /* found it */
618                 if (r != 0)
619                     goto err;
620             }
621
622             /* step 13 */
623             counter++;
624             /* "offset = offset + n + 1" */
625
626             /* step 14 */
627             if (counter >= (int)(4 * L))
628                 break;
629         }
630         if (seed_in) {
631             ok = 0;
632             DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
633             goto err;
634         }
635     }
636  end:
637     if (!BN_GENCB_call(cb, 2, 1))
638         goto err;
639
640  g_only:
641
642     /* We now need to generate g */
643     /* Set r0=(p-1)/q */
644     if (!BN_sub(test, p, BN_value_one()))
645         goto err;
646     if (!BN_div(r0, NULL, test, q, ctx))
647         goto err;
648
649     if (idx < 0) {
650         if (!BN_set_word(test, h))
651             goto err;
652     } else
653         h = 1;
654     if (!BN_MONT_CTX_set(mont, p, ctx))
655         goto err;
656
657     for (;;) {
658         static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e };
659         if (idx >= 0) {
660             md[0] = idx & 0xff;
661             md[1] = (h >> 8) & 0xff;
662             md[2] = h & 0xff;
663             if (!EVP_DigestInit_ex(&mctx, evpmd, NULL))
664                 goto err;
665             if (!EVP_DigestUpdate(&mctx, seed_tmp, seed_len))
666                 goto err;
667             if (!EVP_DigestUpdate(&mctx, ggen, sizeof(ggen)))
668                 goto err;
669             if (!EVP_DigestUpdate(&mctx, md, 3))
670                 goto err;
671             if (!EVP_DigestFinal_ex(&mctx, md, NULL))
672                 goto err;
673             if (!BN_bin2bn(md, mdsize, test))
674                 goto err;
675         }
676         /* g=test^r0%p */
677         if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
678             goto err;
679         if (!BN_is_one(g))
680             break;
681         if (idx < 0 && !BN_add(test, test, BN_value_one()))
682             goto err;
683         h++;
684         if (idx >= 0 && h > 0xffff)
685             goto err;
686     }
687
688     if (!BN_GENCB_call(cb, 3, 1))
689         goto err;
690
691     ok = 1;
692  err:
693     if (ok == 1) {
694         if (p != ret->p) {
695             if (ret->p)
696                 BN_free(ret->p);
697             ret->p = BN_dup(p);
698         }
699         if (q != ret->q) {
700             if (ret->q)
701                 BN_free(ret->q);
702             ret->q = BN_dup(q);
703         }
704         if (ret->g)
705             BN_free(ret->g);
706         ret->g = BN_dup(g);
707         if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
708             ok = -1;
709             goto err;
710         }
711         if (counter_ret != NULL)
712             *counter_ret = counter;
713         if (h_ret != NULL)
714             *h_ret = h;
715     }
716     if (seed)
717         OPENSSL_free(seed);
718     if (seed_out != seed_tmp)
719         OPENSSL_free(seed_tmp);
720     if (ctx) {
721         BN_CTX_end(ctx);
722         BN_CTX_free(ctx);
723     }
724     if (mont != NULL)
725         BN_MONT_CTX_free(mont);
726     EVP_MD_CTX_cleanup(&mctx);
727     return ok;
728 }
729
730 int dsa_paramgen_check_g(DSA *dsa)
731 {
732     BN_CTX *ctx;
733     BIGNUM *tmp;
734     BN_MONT_CTX *mont = NULL;
735     int rv = -1;
736     ctx = BN_CTX_new();
737     if (!ctx)
738         return -1;
739     BN_CTX_start(ctx);
740     if (BN_cmp(dsa->g, BN_value_one()) <= 0)
741         return 0;
742     if (BN_cmp(dsa->g, dsa->p) >= 0)
743         return 0;
744     tmp = BN_CTX_get(ctx);
745     if (!tmp)
746         goto err;
747     if ((mont = BN_MONT_CTX_new()) == NULL)
748         goto err;
749     if (!BN_MONT_CTX_set(mont, dsa->p, ctx))
750         goto err;
751     /* Work out g^q mod p */
752     if (!BN_mod_exp_mont(tmp, dsa->g, dsa->q, dsa->p, ctx, mont))
753         goto err;
754     if (!BN_cmp(tmp, BN_value_one()))
755         rv = 1;
756     else
757         rv = 0;
758  err:
759     BN_CTX_end(ctx);
760     if (mont)
761         BN_MONT_CTX_free(mont);
762     BN_CTX_free(ctx);
763     return rv;
764
765 }
766 #endif