Modify DSA and DH keys to use a shared FFC_PARAMS struct
[openssl.git] / crypto / dsa / dsa_gen.c
1 /*
2  * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /*
11  * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
12  * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB
13  * 180-1)
14  */
15 #define xxxHASH    EVP_sha1()
16
17 #include <openssl/opensslconf.h>
18 #include <stdio.h>
19 #include "internal/cryptlib.h"
20 #include <openssl/evp.h>
21 #include <openssl/bn.h>
22 #include <openssl/rand.h>
23 #include <openssl/sha.h>
24 #include "dsa_local.h"
25
26 int DSA_generate_parameters_ex(DSA *ret, int bits,
27                                const unsigned char *seed_in, int seed_len,
28                                int *counter_ret, unsigned long *h_ret,
29                                BN_GENCB *cb)
30 {
31     if (ret->meth->dsa_paramgen)
32         return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
33                                        counter_ret, h_ret, cb);
34     else {
35         const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1();
36         size_t qbits = EVP_MD_size(evpmd) * 8;
37
38         return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
39                                     seed_in, seed_len, NULL, counter_ret,
40                                     h_ret, cb);
41     }
42 }
43
44 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
45                          const EVP_MD *evpmd, const unsigned char *seed_in,
46                          size_t seed_len, unsigned char *seed_out,
47                          int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
48 {
49     int ok = 0;
50     unsigned char seed[SHA256_DIGEST_LENGTH];
51     unsigned char md[SHA256_DIGEST_LENGTH];
52     unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
53     BIGNUM *r0, *W, *X, *c, *test;
54     BIGNUM *g = NULL, *q = NULL, *p = NULL;
55     BN_MONT_CTX *mont = NULL;
56     int i, k, n = 0, m = 0, qsize = qbits >> 3;
57     int counter = 0;
58     int r = 0;
59     BN_CTX *ctx = NULL;
60     unsigned int h = 2;
61
62     if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
63         qsize != SHA256_DIGEST_LENGTH)
64         /* invalid q size */
65         return 0;
66
67     if (evpmd == NULL) {
68         if (qsize == SHA_DIGEST_LENGTH)
69             evpmd = EVP_sha1();
70         else if (qsize == SHA224_DIGEST_LENGTH)
71             evpmd = EVP_sha224();
72         else
73             evpmd = EVP_sha256();
74     } else {
75         qsize = EVP_MD_size(evpmd);
76     }
77
78     if (bits < 512)
79         bits = 512;
80
81     bits = (bits + 63) / 64 * 64;
82
83     if (seed_in != NULL) {
84         if (seed_len < (size_t)qsize) {
85             DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_SEED_LEN_SMALL);
86             return 0;
87         }
88         if (seed_len > (size_t)qsize) {
89             /* Only consume as much seed as is expected. */
90             seed_len = qsize;
91         }
92         memcpy(seed, seed_in, seed_len);
93     }
94
95     if ((mont = BN_MONT_CTX_new()) == NULL)
96         goto err;
97
98     if ((ctx = BN_CTX_new()) == NULL)
99         goto err;
100
101     BN_CTX_start(ctx);
102
103     r0 = BN_CTX_get(ctx);
104     g = BN_CTX_get(ctx);
105     W = BN_CTX_get(ctx);
106     q = BN_CTX_get(ctx);
107     X = BN_CTX_get(ctx);
108     c = BN_CTX_get(ctx);
109     p = BN_CTX_get(ctx);
110     test = BN_CTX_get(ctx);
111
112     if (test == NULL)
113         goto err;
114
115     if (!BN_lshift(test, BN_value_one(), bits - 1))
116         goto err;
117
118     for (;;) {
119         for (;;) {              /* find q */
120             int use_random_seed = (seed_in == NULL);
121
122             /* step 1 */
123             if (!BN_GENCB_call(cb, 0, m++))
124                 goto err;
125
126             if (use_random_seed) {
127                 if (RAND_bytes(seed, qsize) <= 0)
128                     goto err;
129             } else {
130                 /* If we come back through, use random seed next time. */
131                 seed_in = NULL;
132             }
133             memcpy(buf, seed, qsize);
134             memcpy(buf2, seed, qsize);
135             /* precompute "SEED + 1" for step 7: */
136             for (i = qsize - 1; i >= 0; i--) {
137                 buf[i]++;
138                 if (buf[i] != 0)
139                     break;
140             }
141
142             /* step 2 */
143             if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
144                 goto err;
145             if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
146                 goto err;
147             for (i = 0; i < qsize; i++)
148                 md[i] ^= buf2[i];
149
150             /* step 3 */
151             md[0] |= 0x80;
152             md[qsize - 1] |= 0x01;
153             if (!BN_bin2bn(md, qsize, q))
154                 goto err;
155
156             /* step 4 */
157             r = BN_check_prime(q, ctx, cb);
158             if (r > 0)
159                 break;
160             if (r != 0)
161                 goto err;
162
163             /* do a callback call */
164             /* step 5 */
165         }
166
167         if (!BN_GENCB_call(cb, 2, 0))
168             goto err;
169         if (!BN_GENCB_call(cb, 3, 0))
170             goto err;
171
172         /* step 6 */
173         counter = 0;
174         /* "offset = 2" */
175
176         n = (bits - 1) / 160;
177
178         for (;;) {
179             if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
180                 goto err;
181
182             /* step 7 */
183             BN_zero(W);
184             /* now 'buf' contains "SEED + offset - 1" */
185             for (k = 0; k <= n; k++) {
186                 /*
187                  * obtain "SEED + offset + k" by incrementing:
188                  */
189                 for (i = qsize - 1; i >= 0; i--) {
190                     buf[i]++;
191                     if (buf[i] != 0)
192                         break;
193                 }
194
195                 if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
196                     goto err;
197
198                 /* step 8 */
199                 if (!BN_bin2bn(md, qsize, r0))
200                     goto err;
201                 if (!BN_lshift(r0, r0, (qsize << 3) * k))
202                     goto err;
203                 if (!BN_add(W, W, r0))
204                     goto err;
205             }
206
207             /* more of step 8 */
208             if (!BN_mask_bits(W, bits - 1))
209                 goto err;
210             if (!BN_copy(X, W))
211                 goto err;
212             if (!BN_add(X, X, test))
213                 goto err;
214
215             /* step 9 */
216             if (!BN_lshift1(r0, q))
217                 goto err;
218             if (!BN_mod(c, X, r0, ctx))
219                 goto err;
220             if (!BN_sub(r0, c, BN_value_one()))
221                 goto err;
222             if (!BN_sub(p, X, r0))
223                 goto err;
224
225             /* step 10 */
226             if (BN_cmp(p, test) >= 0) {
227                 /* step 11 */
228                 r = BN_check_prime(p, ctx, cb);
229                 if (r > 0)
230                     goto end;   /* found it */
231                 if (r != 0)
232                     goto err;
233             }
234
235             /* step 13 */
236             counter++;
237             /* "offset = offset + n + 1" */
238
239             /* step 14 */
240             if (counter >= 4096)
241                 break;
242         }
243     }
244  end:
245     if (!BN_GENCB_call(cb, 2, 1))
246         goto err;
247
248     /* We now need to generate g */
249     /* Set r0=(p-1)/q */
250     if (!BN_sub(test, p, BN_value_one()))
251         goto err;
252     if (!BN_div(r0, NULL, test, q, ctx))
253         goto err;
254
255     if (!BN_set_word(test, h))
256         goto err;
257     if (!BN_MONT_CTX_set(mont, p, ctx))
258         goto err;
259
260     for (;;) {
261         /* g=test^r0%p */
262         if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
263             goto err;
264         if (!BN_is_one(g))
265             break;
266         if (!BN_add(test, test, BN_value_one()))
267             goto err;
268         h++;
269     }
270
271     if (!BN_GENCB_call(cb, 3, 1))
272         goto err;
273
274     ok = 1;
275  err:
276     if (ok) {
277         BN_free(ret->params.p);
278         BN_free(ret->params.q);
279         BN_free(ret->params.g);
280         ret->params.p = BN_dup(p);
281         ret->params.q = BN_dup(q);
282         ret->params.g = BN_dup(g);
283         ret->dirty_cnt++;
284         if (ret->params.p == NULL
285             || ret->params.q == NULL
286             || ret->params.g == NULL) {
287             ok = 0;
288             goto err;
289         }
290         if (counter_ret != NULL)
291             *counter_ret = counter;
292         if (h_ret != NULL)
293             *h_ret = h;
294         if (seed_out)
295             memcpy(seed_out, seed, qsize);
296     }
297     BN_CTX_end(ctx);
298     BN_CTX_free(ctx);
299     BN_MONT_CTX_free(mont);
300     return ok;
301 }
302
303 /*
304  * This is a parameter generation algorithm for the DSA2 algorithm as
305  * described in FIPS 186-3.
306  */
307
308 int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
309                           const EVP_MD *evpmd, const unsigned char *seed_in,
310                           size_t seed_len, int idx, unsigned char *seed_out,
311                           int *counter_ret, unsigned long *h_ret,
312                           BN_GENCB *cb)
313 {
314     int ok = -1;
315     unsigned char *seed = NULL, *seed_tmp = NULL;
316     unsigned char md[EVP_MAX_MD_SIZE];
317     int mdsize;
318     BIGNUM *r0, *W, *X, *c, *test;
319     BIGNUM *g = NULL, *q = NULL, *p = NULL;
320     BN_MONT_CTX *mont = NULL;
321     int i, k, n = 0, m = 0, qsize = N >> 3;
322     int counter = 0;
323     int r = 0;
324     BN_CTX *ctx = NULL;
325     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
326     unsigned int h = 2;
327
328     if (mctx == NULL)
329         goto err;
330
331     /* make sure L > N, otherwise we'll get trapped in an infinite loop */
332     if (L <= N) {
333         DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
334         goto err;
335     }
336
337     if (evpmd == NULL) {
338         if (N == 160)
339             evpmd = EVP_sha1();
340         else if (N == 224)
341             evpmd = EVP_sha224();
342         else
343             evpmd = EVP_sha256();
344     }
345
346     mdsize = EVP_MD_size(evpmd);
347     /* If unverifiable g generation only don't need seed */
348     if (!ret->params.p || !ret->params.q || idx >= 0) {
349         if (seed_len == 0)
350             seed_len = mdsize;
351
352         seed = OPENSSL_malloc(seed_len);
353
354         if (seed_out)
355             seed_tmp = seed_out;
356         else
357             seed_tmp = OPENSSL_malloc(seed_len);
358
359         if (seed == NULL || seed_tmp == NULL)
360             goto err;
361
362         if (seed_in)
363             memcpy(seed, seed_in, seed_len);
364
365     }
366
367     if ((ctx = BN_CTX_new()) == NULL)
368         goto err;
369
370     if ((mont = BN_MONT_CTX_new()) == NULL)
371         goto err;
372
373     BN_CTX_start(ctx);
374     r0 = BN_CTX_get(ctx);
375     g = BN_CTX_get(ctx);
376     W = BN_CTX_get(ctx);
377     X = BN_CTX_get(ctx);
378     c = BN_CTX_get(ctx);
379     test = BN_CTX_get(ctx);
380     if (test == NULL)
381         goto err;
382
383     /* if p, q already supplied generate g only */
384     if (ret->params.p && ret->params.q) {
385         p = ret->params.p;
386         q = ret->params.q;
387         if (idx >= 0)
388             memcpy(seed_tmp, seed, seed_len);
389         goto g_only;
390     } else {
391         p = BN_CTX_get(ctx);
392         q = BN_CTX_get(ctx);
393         if (q == NULL)
394             goto err;
395     }
396
397     if (!BN_lshift(test, BN_value_one(), L - 1))
398         goto err;
399     for (;;) {
400         for (;;) {              /* find q */
401             unsigned char *pmd;
402             /* step 1 */
403             if (!BN_GENCB_call(cb, 0, m++))
404                 goto err;
405
406             if (!seed_in) {
407                 if (RAND_bytes(seed, seed_len) <= 0)
408                     goto err;
409             }
410             /* step 2 */
411             if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
412                 goto err;
413             /* Take least significant bits of md */
414             if (mdsize > qsize)
415                 pmd = md + mdsize - qsize;
416             else
417                 pmd = md;
418
419             if (mdsize < qsize)
420                 memset(md + mdsize, 0, qsize - mdsize);
421
422             /* step 3 */
423             pmd[0] |= 0x80;
424             pmd[qsize - 1] |= 0x01;
425             if (!BN_bin2bn(pmd, qsize, q))
426                 goto err;
427
428             /* step 4 */
429             r = BN_check_prime(q, ctx, cb);
430             if (r > 0)
431                 break;
432             if (r != 0)
433                 goto err;
434             /* Provided seed didn't produce a prime: error */
435             if (seed_in) {
436                 ok = 0;
437                 DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME);
438                 goto err;
439             }
440
441             /* do a callback call */
442             /* step 5 */
443         }
444         /* Copy seed to seed_out before we mess with it */
445         if (seed_out)
446             memcpy(seed_out, seed, seed_len);
447
448         if (!BN_GENCB_call(cb, 2, 0))
449             goto err;
450         if (!BN_GENCB_call(cb, 3, 0))
451             goto err;
452
453         /* step 6 */
454         counter = 0;
455         /* "offset = 1" */
456
457         n = (L - 1) / (mdsize << 3);
458
459         for (;;) {
460             if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
461                 goto err;
462
463             /* step 7 */
464             BN_zero(W);
465             /* now 'buf' contains "SEED + offset - 1" */
466             for (k = 0; k <= n; k++) {
467                 /*
468                  * obtain "SEED + offset + k" by incrementing:
469                  */
470                 for (i = seed_len - 1; i >= 0; i--) {
471                     seed[i]++;
472                     if (seed[i] != 0)
473                         break;
474                 }
475
476                 if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
477                     goto err;
478
479                 /* step 8 */
480                 if (!BN_bin2bn(md, mdsize, r0))
481                     goto err;
482                 if (!BN_lshift(r0, r0, (mdsize << 3) * k))
483                     goto err;
484                 if (!BN_add(W, W, r0))
485                     goto err;
486             }
487
488             /* more of step 8 */
489             if (!BN_mask_bits(W, L - 1))
490                 goto err;
491             if (!BN_copy(X, W))
492                 goto err;
493             if (!BN_add(X, X, test))
494                 goto err;
495
496             /* step 9 */
497             if (!BN_lshift1(r0, q))
498                 goto err;
499             if (!BN_mod(c, X, r0, ctx))
500                 goto err;
501             if (!BN_sub(r0, c, BN_value_one()))
502                 goto err;
503             if (!BN_sub(p, X, r0))
504                 goto err;
505
506             /* step 10 */
507             if (BN_cmp(p, test) >= 0) {
508                 /* step 11 */
509                 r = BN_check_prime(p, ctx, cb);
510                 if (r > 0)
511                     goto end;   /* found it */
512                 if (r != 0)
513                     goto err;
514             }
515
516             /* step 13 */
517             counter++;
518             /* "offset = offset + n + 1" */
519
520             /* step 14 */
521             if (counter >= (int)(4 * L))
522                 break;
523         }
524         if (seed_in) {
525             ok = 0;
526             DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
527             goto err;
528         }
529     }
530  end:
531     if (!BN_GENCB_call(cb, 2, 1))
532         goto err;
533
534  g_only:
535
536     /* We now need to generate g */
537     /* Set r0=(p-1)/q */
538     if (!BN_sub(test, p, BN_value_one()))
539         goto err;
540     if (!BN_div(r0, NULL, test, q, ctx))
541         goto err;
542
543     if (idx < 0) {
544         if (!BN_set_word(test, h))
545             goto err;
546     } else
547         h = 1;
548     if (!BN_MONT_CTX_set(mont, p, ctx))
549         goto err;
550
551     for (;;) {
552         static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e };
553         if (idx >= 0) {
554             md[0] = idx & 0xff;
555             md[1] = (h >> 8) & 0xff;
556             md[2] = h & 0xff;
557             if (!EVP_DigestInit_ex(mctx, evpmd, NULL))
558                 goto err;
559             if (!EVP_DigestUpdate(mctx, seed_tmp, seed_len))
560                 goto err;
561             if (!EVP_DigestUpdate(mctx, ggen, sizeof(ggen)))
562                 goto err;
563             if (!EVP_DigestUpdate(mctx, md, 3))
564                 goto err;
565             if (!EVP_DigestFinal_ex(mctx, md, NULL))
566                 goto err;
567             if (!BN_bin2bn(md, mdsize, test))
568                 goto err;
569         }
570         /* g=test^r0%p */
571         if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
572             goto err;
573         if (!BN_is_one(g))
574             break;
575         if (idx < 0 && !BN_add(test, test, BN_value_one()))
576             goto err;
577         h++;
578         if (idx >= 0 && h > 0xffff)
579             goto err;
580     }
581
582     if (!BN_GENCB_call(cb, 3, 1))
583         goto err;
584
585     ok = 1;
586  err:
587     if (ok == 1) {
588         if (p != ret->params.p) {
589             BN_free(ret->params.p);
590             ret->params.p = BN_dup(p);
591         }
592         if (q != ret->params.q) {
593             BN_free(ret->params.q);
594             ret->params.q = BN_dup(q);
595         }
596         BN_free(ret->params.g);
597         ret->params.g = BN_dup(g);
598         if (ret->params.p == NULL
599             || ret->params.q == NULL
600             || ret->params.g == NULL) {
601             ok = -1;
602             goto err;
603         }
604         ret->dirty_cnt++;
605         if (counter_ret != NULL)
606             *counter_ret = counter;
607         if (h_ret != NULL)
608             *h_ret = h;
609     }
610     OPENSSL_free(seed);
611     if (seed_out != seed_tmp)
612         OPENSSL_free(seed_tmp);
613     BN_CTX_end(ctx);
614     BN_CTX_free(ctx);
615     BN_MONT_CTX_free(mont);
616     EVP_MD_CTX_free(mctx);
617     return ok;
618 }