a4fae17667fd49332eea7f45f2abd22075ede410
[openssl.git] / 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 /*
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  */
64 #define xxxHASH    EVP_sha1()
65
66 #include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */
67
68 #include <stdio.h>
69 #include "internal/cryptlib.h"
70 #include <openssl/evp.h>
71 #include <openssl/bn.h>
72 #include <openssl/rand.h>
73 #include <openssl/sha.h>
74
75 #include "dsa_locl.h"
76
77 int DSA_generate_parameters_ex(DSA *ret, int bits,
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 }
102
103 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
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     if (seed_in != NULL) {
136         if (seed_len < (size_t)qsize)
137             return 0;
138         if (seed_len > (size_t)qsize) {
139             /* Don't overflow seed local variable. */
140             seed_len = qsize;
141         }
142         memcpy(seed, seed_in, seed_len);
143     }
144
145     if ((ctx = BN_CTX_new()) == NULL)
146         goto err;
147
148     if ((mont = BN_MONT_CTX_new()) == NULL)
149         goto err;
150
151     BN_CTX_start(ctx);
152     r0 = BN_CTX_get(ctx);
153     g = BN_CTX_get(ctx);
154     W = BN_CTX_get(ctx);
155     q = BN_CTX_get(ctx);
156     X = BN_CTX_get(ctx);
157     c = BN_CTX_get(ctx);
158     p = BN_CTX_get(ctx);
159     test = BN_CTX_get(ctx);
160
161     if (!BN_lshift(test, BN_value_one(), bits - 1))
162         goto err;
163
164     for (;;) {
165         for (;;) {              /* find q */
166             int seed_is_random = seed_in == NULL;
167
168             /* step 1 */
169             if (!BN_GENCB_call(cb, 0, m++))
170                 goto err;
171
172             if (seed_is_random) {
173                 if (RAND_bytes(seed, qsize) <= 0)
174                     goto err;
175             } else {
176                 /* If we come back through, use random seed next time. */
177                 seed_in = NULL;
178             }
179             memcpy(buf, seed, qsize);
180             memcpy(buf2, seed, qsize);
181             /* precompute "SEED + 1" for step 7: */
182             for (i = qsize - 1; i >= 0; i--) {
183                 buf[i]++;
184                 if (buf[i] != 0)
185                     break;
186             }
187
188             /* step 2 */
189             if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
190                 goto err;
191             if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
192                 goto err;
193             for (i = 0; i < qsize; i++)
194                 md[i] ^= buf2[i];
195
196             /* step 3 */
197             md[0] |= 0x80;
198             md[qsize - 1] |= 0x01;
199             if (!BN_bin2bn(md, qsize, q))
200                 goto err;
201
202             /* step 4 */
203             r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
204                                         seed_is_random, cb);
205             if (r > 0)
206                 break;
207             if (r != 0)
208                 goto err;
209
210             /* do a callback call */
211             /* step 5 */
212         }
213
214         if (!BN_GENCB_call(cb, 2, 0))
215             goto err;
216         if (!BN_GENCB_call(cb, 3, 0))
217             goto err;
218
219         /* step 6 */
220         counter = 0;
221         /* "offset = 2" */
222
223         n = (bits - 1) / 160;
224
225         for (;;) {
226             if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
227                 goto err;
228
229             /* step 7 */
230             BN_zero(W);
231             /* now 'buf' contains "SEED + offset - 1" */
232             for (k = 0; k <= n; k++) {
233                 /*
234                  * obtain "SEED + offset + k" by incrementing:
235                  */
236                 for (i = qsize - 1; i >= 0; i--) {
237                     buf[i]++;
238                     if (buf[i] != 0)
239                         break;
240                 }
241
242                 if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
243                     goto err;
244
245                 /* step 8 */
246                 if (!BN_bin2bn(md, qsize, r0))
247                     goto err;
248                 if (!BN_lshift(r0, r0, (qsize << 3) * k))
249                     goto err;
250                 if (!BN_add(W, W, r0))
251                     goto err;
252             }
253
254             /* more of step 8 */
255             if (!BN_mask_bits(W, bits - 1))
256                 goto err;
257             if (!BN_copy(X, W))
258                 goto err;
259             if (!BN_add(X, X, test))
260                 goto err;
261
262             /* step 9 */
263             if (!BN_lshift1(r0, q))
264                 goto err;
265             if (!BN_mod(c, X, r0, ctx))
266                 goto err;
267             if (!BN_sub(r0, c, BN_value_one()))
268                 goto err;
269             if (!BN_sub(p, X, r0))
270                 goto err;
271
272             /* step 10 */
273             if (BN_cmp(p, test) >= 0) {
274                 /* step 11 */
275                 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
276                 if (r > 0)
277                     goto end;   /* found it */
278                 if (r != 0)
279                     goto err;
280             }
281
282             /* step 13 */
283             counter++;
284             /* "offset = offset + n + 1" */
285
286             /* step 14 */
287             if (counter >= 4096)
288                 break;
289         }
290     }
291  end:
292     if (!BN_GENCB_call(cb, 2, 1))
293         goto err;
294
295     /* We now need to generate g */
296     /* Set r0=(p-1)/q */
297     if (!BN_sub(test, p, BN_value_one()))
298         goto err;
299     if (!BN_div(r0, NULL, test, q, ctx))
300         goto err;
301
302     if (!BN_set_word(test, h))
303         goto err;
304     if (!BN_MONT_CTX_set(mont, p, ctx))
305         goto err;
306
307     for (;;) {
308         /* g=test^r0%p */
309         if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
310             goto err;
311         if (!BN_is_one(g))
312             break;
313         if (!BN_add(test, test, BN_value_one()))
314             goto err;
315         h++;
316     }
317
318     if (!BN_GENCB_call(cb, 3, 1))
319         goto err;
320
321     ok = 1;
322  err:
323     if (ok) {
324         BN_free(ret->p);
325         BN_free(ret->q);
326         BN_free(ret->g);
327         ret->p = BN_dup(p);
328         ret->q = BN_dup(q);
329         ret->g = BN_dup(g);
330         if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
331             ok = 0;
332             goto err;
333         }
334         if (counter_ret != NULL)
335             *counter_ret = counter;
336         if (h_ret != NULL)
337             *h_ret = h;
338         if (seed_out)
339             memcpy(seed_out, seed, qsize);
340     }
341     if (ctx)
342         BN_CTX_end(ctx);
343     BN_CTX_free(ctx);
344     BN_MONT_CTX_free(mont);
345     return ok;
346 }
347
348 /*
349  * This is a parameter generation algorithm for the DSA2 algorithm as
350  * described in FIPS 186-3.
351  */
352
353 int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
354                           const EVP_MD *evpmd, const unsigned char *seed_in,
355                           size_t seed_len, int idx, unsigned char *seed_out,
356                           int *counter_ret, unsigned long *h_ret,
357                           BN_GENCB *cb)
358 {
359     int ok = -1;
360     unsigned char *seed = NULL, *seed_tmp = NULL;
361     unsigned char md[EVP_MAX_MD_SIZE];
362     int mdsize;
363     BIGNUM *r0, *W, *X, *c, *test;
364     BIGNUM *g = NULL, *q = NULL, *p = NULL;
365     BN_MONT_CTX *mont = NULL;
366     int i, k, n = 0, m = 0, qsize = N >> 3;
367     int counter = 0;
368     int r = 0;
369     BN_CTX *ctx = NULL;
370     EVP_MD_CTX mctx;
371     unsigned int h = 2;
372
373     EVP_MD_CTX_init(&mctx);
374
375     if (evpmd == NULL) {
376         if (N == 160)
377             evpmd = EVP_sha1();
378         else if (N == 224)
379             evpmd = EVP_sha224();
380         else
381             evpmd = EVP_sha256();
382     }
383
384     mdsize = M_EVP_MD_size(evpmd);
385     /* If unverificable g generation only don't need seed */
386     if (!ret->p || !ret->q || idx >= 0) {
387         if (seed_len == 0)
388             seed_len = mdsize;
389
390         seed = OPENSSL_malloc(seed_len);
391
392         if (seed_out)
393             seed_tmp = seed_out;
394         else
395             seed_tmp = OPENSSL_malloc(seed_len);
396
397         if (!seed || !seed_tmp)
398             goto err;
399
400         if (seed_in)
401             memcpy(seed, seed_in, seed_len);
402
403     }
404
405     if ((ctx = BN_CTX_new()) == NULL)
406         goto err;
407
408     if ((mont = BN_MONT_CTX_new()) == NULL)
409         goto err;
410
411     BN_CTX_start(ctx);
412     r0 = BN_CTX_get(ctx);
413     g = BN_CTX_get(ctx);
414     W = BN_CTX_get(ctx);
415     X = BN_CTX_get(ctx);
416     c = BN_CTX_get(ctx);
417     test = BN_CTX_get(ctx);
418
419     /* if p, q already supplied generate g only */
420     if (ret->p && ret->q) {
421         p = ret->p;
422         q = ret->q;
423         if (idx >= 0)
424             memcpy(seed_tmp, seed, seed_len);
425         goto g_only;
426     } else {
427         p = BN_CTX_get(ctx);
428         q = BN_CTX_get(ctx);
429     }
430
431     if (!BN_lshift(test, BN_value_one(), L - 1))
432         goto err;
433     for (;;) {
434         for (;;) {              /* find q */
435             unsigned char *pmd;
436             /* step 1 */
437             if (!BN_GENCB_call(cb, 0, m++))
438                 goto err;
439
440             if (!seed_in) {
441                 if (RAND_bytes(seed, seed_len) <= 0)
442                     goto err;
443             }
444             /* step 2 */
445             if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
446                 goto err;
447             /* Take least significant bits of md */
448             if (mdsize > qsize)
449                 pmd = md + mdsize - qsize;
450             else
451                 pmd = md;
452
453             if (mdsize < qsize)
454                 memset(md + mdsize, 0, qsize - mdsize);
455
456             /* step 3 */
457             pmd[0] |= 0x80;
458             pmd[qsize - 1] |= 0x01;
459             if (!BN_bin2bn(pmd, qsize, q))
460                 goto err;
461
462             /* step 4 */
463             r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
464                                         seed_in ? 1 : 0, cb);
465             if (r > 0)
466                 break;
467             if (r != 0)
468                 goto err;
469             /* Provided seed didn't produce a prime: error */
470             if (seed_in) {
471                 ok = 0;
472                 DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME);
473                 goto err;
474             }
475
476             /* do a callback call */
477             /* step 5 */
478         }
479         /* Copy seed to seed_out before we mess with it */
480         if (seed_out)
481             memcpy(seed_out, seed, seed_len);
482
483         if (!BN_GENCB_call(cb, 2, 0))
484             goto err;
485         if (!BN_GENCB_call(cb, 3, 0))
486             goto err;
487
488         /* step 6 */
489         counter = 0;
490         /* "offset = 1" */
491
492         n = (L - 1) / (mdsize << 3);
493
494         for (;;) {
495             if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
496                 goto err;
497
498             /* step 7 */
499             BN_zero(W);
500             /* now 'buf' contains "SEED + offset - 1" */
501             for (k = 0; k <= n; k++) {
502                 /*
503                  * obtain "SEED + offset + k" by incrementing:
504                  */
505                 for (i = seed_len - 1; i >= 0; i--) {
506                     seed[i]++;
507                     if (seed[i] != 0)
508                         break;
509                 }
510
511                 if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
512                     goto err;
513
514                 /* step 8 */
515                 if (!BN_bin2bn(md, mdsize, r0))
516                     goto err;
517                 if (!BN_lshift(r0, r0, (mdsize << 3) * k))
518                     goto err;
519                 if (!BN_add(W, W, r0))
520                     goto err;
521             }
522
523             /* more of step 8 */
524             if (!BN_mask_bits(W, L - 1))
525                 goto err;
526             if (!BN_copy(X, W))
527                 goto err;
528             if (!BN_add(X, X, test))
529                 goto err;
530
531             /* step 9 */
532             if (!BN_lshift1(r0, q))
533                 goto err;
534             if (!BN_mod(c, X, r0, ctx))
535                 goto err;
536             if (!BN_sub(r0, c, BN_value_one()))
537                 goto err;
538             if (!BN_sub(p, X, r0))
539                 goto err;
540
541             /* step 10 */
542             if (BN_cmp(p, test) >= 0) {
543                 /* step 11 */
544                 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
545                 if (r > 0)
546                     goto end;   /* found it */
547                 if (r != 0)
548                     goto err;
549             }
550
551             /* step 13 */
552             counter++;
553             /* "offset = offset + n + 1" */
554
555             /* step 14 */
556             if (counter >= (int)(4 * L))
557                 break;
558         }
559         if (seed_in) {
560             ok = 0;
561             DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
562             goto err;
563         }
564     }
565  end:
566     if (!BN_GENCB_call(cb, 2, 1))
567         goto err;
568
569  g_only:
570
571     /* We now need to generate g */
572     /* Set r0=(p-1)/q */
573     if (!BN_sub(test, p, BN_value_one()))
574         goto err;
575     if (!BN_div(r0, NULL, test, q, ctx))
576         goto err;
577
578     if (idx < 0) {
579         if (!BN_set_word(test, h))
580             goto err;
581     } else
582         h = 1;
583     if (!BN_MONT_CTX_set(mont, p, ctx))
584         goto err;
585
586     for (;;) {
587         static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e };
588         if (idx >= 0) {
589             md[0] = idx & 0xff;
590             md[1] = (h >> 8) & 0xff;
591             md[2] = h & 0xff;
592             if (!EVP_DigestInit_ex(&mctx, evpmd, NULL))
593                 goto err;
594             if (!EVP_DigestUpdate(&mctx, seed_tmp, seed_len))
595                 goto err;
596             if (!EVP_DigestUpdate(&mctx, ggen, sizeof(ggen)))
597                 goto err;
598             if (!EVP_DigestUpdate(&mctx, md, 3))
599                 goto err;
600             if (!EVP_DigestFinal_ex(&mctx, md, NULL))
601                 goto err;
602             if (!BN_bin2bn(md, mdsize, test))
603                 goto err;
604         }
605         /* g=test^r0%p */
606         if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
607             goto err;
608         if (!BN_is_one(g))
609             break;
610         if (idx < 0 && !BN_add(test, test, BN_value_one()))
611             goto err;
612         h++;
613         if (idx >= 0 && h > 0xffff)
614             goto err;
615     }
616
617     if (!BN_GENCB_call(cb, 3, 1))
618         goto err;
619
620     ok = 1;
621  err:
622     if (ok == 1) {
623         if (p != ret->p) {
624             BN_free(ret->p);
625             ret->p = BN_dup(p);
626         }
627         if (q != ret->q) {
628             BN_free(ret->q);
629             ret->q = BN_dup(q);
630         }
631         BN_free(ret->g);
632         ret->g = BN_dup(g);
633         if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
634             ok = -1;
635             goto err;
636         }
637         if (counter_ret != NULL)
638             *counter_ret = counter;
639         if (h_ret != NULL)
640             *h_ret = h;
641     }
642     OPENSSL_free(seed);
643     if (seed_out != seed_tmp)
644         OPENSSL_free(seed_tmp);
645     if (ctx)
646         BN_CTX_end(ctx);
647     BN_CTX_free(ctx);
648     BN_MONT_CTX_free(mont);
649     EVP_MD_CTX_cleanup(&mctx);
650     return ok;
651 }
652
653 int dsa_paramgen_check_g(DSA *dsa)
654 {
655     BN_CTX *ctx;
656     BIGNUM *tmp;
657     BN_MONT_CTX *mont = NULL;
658     int rv = -1;
659     ctx = BN_CTX_new();
660     if (!ctx)
661         return -1;
662     BN_CTX_start(ctx);
663     if (BN_cmp(dsa->g, BN_value_one()) <= 0)
664         return 0;
665     if (BN_cmp(dsa->g, dsa->p) >= 0)
666         return 0;
667     tmp = BN_CTX_get(ctx);
668     if (!tmp)
669         goto err;
670     if ((mont = BN_MONT_CTX_new()) == NULL)
671         goto err;
672     if (!BN_MONT_CTX_set(mont, dsa->p, ctx))
673         goto err;
674     /* Work out g^q mod p */
675     if (!BN_mod_exp_mont(tmp, dsa->g, dsa->q, dsa->p, ctx, mont))
676         goto err;
677     if (!BN_cmp(tmp, BN_value_one()))
678         rv = 1;
679     else
680         rv = 0;
681  err:
682     BN_CTX_end(ctx);
683     BN_MONT_CTX_free(mont);
684     BN_CTX_free(ctx);
685     return rv;
686
687 }