blob: 475312427805893d238424fd7044c30398748745 [file] [log] [blame]
dtucker@openbsd.orgdcc7d742016-12-15 21:20:41 +00001/* $OpenBSD: dh.c,v 1.62 2016/12/15 21:20:41 dtucker Exp $ */
Damien Miller874d77b2000-10-14 16:23:11 +11002/*
3 * Copyright (c) 2000 Niels Provos. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "includes.h"
Damien Miller874d77b2000-10-14 16:23:11 +110027
Damien Miller8dbffe72006-08-05 11:02:17 +100028
Damien Miller874d77b2000-10-14 16:23:11 +110029#include <openssl/bn.h>
30#include <openssl/dh.h>
Damien Miller874d77b2000-10-14 16:23:11 +110031
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +000032#include <errno.h>
Damien Millerded319c2006-09-01 15:38:36 +100033#include <stdarg.h>
Damien Millera7a73ee2006-08-05 11:37:59 +100034#include <stdio.h>
Damien Millere7a1e5c2006-08-05 11:34:19 +100035#include <stdlib.h>
Damien Millere3476ed2006-07-24 14:13:33 +100036#include <string.h>
deraadt@openbsd.org087266e2015-01-20 23:14:00 +000037#include <limits.h>
Damien Millere3476ed2006-07-24 14:13:33 +100038
Damien Miller874d77b2000-10-14 16:23:11 +110039#include "dh.h"
Ben Lindstrom226cfa02001-01-22 05:34:40 +000040#include "pathnames.h"
41#include "log.h"
42#include "misc.h"
markus@openbsd.org57d10cb2015-01-19 20:16:15 +000043#include "ssherr.h"
Damien Miller874d77b2000-10-14 16:23:11 +110044
Ben Lindstrombba81212001-06-25 05:01:22 +000045static int
Damien Miller874d77b2000-10-14 16:23:11 +110046parse_prime(int linenum, char *line, struct dhgroup *dhg)
47{
48 char *cp, *arg;
49 char *strsize, *gen, *prime;
Damien Miller5a73c1a2006-03-31 23:09:41 +110050 const char *errstr = NULL;
Damien Miller2e9cf492008-06-29 22:47:04 +100051 long long n;
Damien Miller874d77b2000-10-14 16:23:11 +110052
Damien Miller0d02c3e2013-07-18 16:12:06 +100053 dhg->p = dhg->g = NULL;
Damien Miller874d77b2000-10-14 16:23:11 +110054 cp = line;
Damien Miller928b2362006-03-26 13:53:32 +110055 if ((arg = strdelim(&cp)) == NULL)
56 return 0;
Damien Miller874d77b2000-10-14 16:23:11 +110057 /* Ignore leading whitespace */
58 if (*arg == '\0')
59 arg = strdelim(&cp);
Ben Lindstrom04f9af72002-07-04 00:03:56 +000060 if (!arg || !*arg || *arg == '#')
Damien Miller874d77b2000-10-14 16:23:11 +110061 return 0;
62
63 /* time */
64 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100065 goto truncated;
Damien Miller874d77b2000-10-14 16:23:11 +110066 arg = strsep(&cp, " "); /* type */
67 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100068 goto truncated;
Damien Miller2e9cf492008-06-29 22:47:04 +100069 /* Ensure this is a safe prime */
70 n = strtonum(arg, 0, 5, &errstr);
Damien Millerbbeb1da2013-07-18 16:10:49 +100071 if (errstr != NULL || n != MODULI_TYPE_SAFE) {
72 error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
Damien Miller2e9cf492008-06-29 22:47:04 +100073 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100074 }
Damien Miller874d77b2000-10-14 16:23:11 +110075 arg = strsep(&cp, " "); /* tests */
76 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100077 goto truncated;
Damien Miller2e9cf492008-06-29 22:47:04 +100078 /* Ensure prime has been tested and is not composite */
79 n = strtonum(arg, 0, 0x1f, &errstr);
80 if (errstr != NULL ||
Damien Millerbbeb1da2013-07-18 16:10:49 +100081 (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
82 error("moduli:%d: invalid moduli tests flag", linenum);
Damien Miller2e9cf492008-06-29 22:47:04 +100083 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100084 }
Damien Miller874d77b2000-10-14 16:23:11 +110085 arg = strsep(&cp, " "); /* tries */
86 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100087 goto truncated;
Damien Miller2e9cf492008-06-29 22:47:04 +100088 n = strtonum(arg, 0, 1<<30, &errstr);
Damien Millerbbeb1da2013-07-18 16:10:49 +100089 if (errstr != NULL || n == 0) {
90 error("moduli:%d: invalid primality trial count", linenum);
Damien Miller2e9cf492008-06-29 22:47:04 +100091 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100092 }
Damien Miller874d77b2000-10-14 16:23:11 +110093 strsize = strsep(&cp, " "); /* size */
94 if (cp == NULL || *strsize == '\0' ||
Darren Tucker759cb2a2009-10-07 09:01:50 +110095 (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
Damien Millerbbeb1da2013-07-18 16:10:49 +100096 errstr) {
97 error("moduli:%d: invalid prime length", linenum);
Damien Miller874d77b2000-10-14 16:23:11 +110098 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100099 }
Ben Lindstromdf221392001-03-29 00:36:16 +0000100 /* The whole group is one bit larger */
101 dhg->size++;
Damien Miller874d77b2000-10-14 16:23:11 +1100102 gen = strsep(&cp, " "); /* gen */
103 if (cp == NULL || *gen == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +1000104 goto truncated;
Damien Miller874d77b2000-10-14 16:23:11 +1100105 prime = strsep(&cp, " "); /* prime */
Damien Millerbbeb1da2013-07-18 16:10:49 +1000106 if (cp != NULL || *prime == '\0') {
107 truncated:
108 error("moduli:%d: truncated", linenum);
Damien Miller874d77b2000-10-14 16:23:11 +1100109 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +1000110 }
Damien Miller874d77b2000-10-14 16:23:11 +1100111
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000112 if ((dhg->g = BN_new()) == NULL ||
113 (dhg->p = BN_new()) == NULL) {
114 error("parse_prime: BN_new failed");
115 goto fail;
116 }
Damien Millerbbeb1da2013-07-18 16:10:49 +1000117 if (BN_hex2bn(&dhg->g, gen) == 0) {
118 error("moduli:%d: could not parse generator value", linenum);
119 goto fail;
120 }
121 if (BN_hex2bn(&dhg->p, prime) == 0) {
122 error("moduli:%d: could not parse prime value", linenum);
123 goto fail;
124 }
125 if (BN_num_bits(dhg->p) != dhg->size) {
126 error("moduli:%d: prime has wrong size: actual %d listed %d",
127 linenum, BN_num_bits(dhg->p), dhg->size - 1);
128 goto fail;
129 }
130 if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
131 error("moduli:%d: generator is invalid", linenum);
132 goto fail;
133 }
Damien Millerbbeb1da2013-07-18 16:10:49 +1000134 return 1;
Damien Miller23e526e2001-03-30 10:47:43 +1000135
Damien Miller874d77b2000-10-14 16:23:11 +1100136 fail:
Damien Millerbbeb1da2013-07-18 16:10:49 +1000137 if (dhg->g != NULL)
138 BN_clear_free(dhg->g);
139 if (dhg->p != NULL)
140 BN_clear_free(dhg->p);
141 dhg->g = dhg->p = NULL;
Damien Millerbbeb1da2013-07-18 16:10:49 +1000142 return 0;
Damien Miller874d77b2000-10-14 16:23:11 +1100143}
144
145DH *
Ben Lindstromdf221392001-03-29 00:36:16 +0000146choose_dh(int min, int wantbits, int max)
Damien Miller874d77b2000-10-14 16:23:11 +1100147{
148 FILE *f;
Darren Tuckerc56c7ef2004-02-29 20:13:34 +1100149 char line[4096];
Damien Miller874d77b2000-10-14 16:23:11 +1100150 int best, bestcount, which;
151 int linenum;
152 struct dhgroup dhg;
153
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000154 if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
dtucker@openbsd.orgdcc7d742016-12-15 21:20:41 +0000155 logit("WARNING: could not open %s (%s), using fixed modulus",
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000156 _PATH_DH_MODULI, strerror(errno));
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000157 return (dh_new_group_fallback(max));
Damien Miller874d77b2000-10-14 16:23:11 +1100158 }
159
160 linenum = 0;
161 best = bestcount = 0;
162 while (fgets(line, sizeof(line), f)) {
163 linenum++;
164 if (!parse_prime(linenum, line, &dhg))
165 continue;
Damien Miller9ef95dd2002-01-22 23:10:33 +1100166 BN_clear_free(dhg.g);
167 BN_clear_free(dhg.p);
Damien Miller874d77b2000-10-14 16:23:11 +1100168
Ben Lindstromdf221392001-03-29 00:36:16 +0000169 if (dhg.size > max || dhg.size < min)
170 continue;
171
172 if ((dhg.size > wantbits && dhg.size < best) ||
173 (dhg.size > best && best < wantbits)) {
Damien Miller874d77b2000-10-14 16:23:11 +1100174 best = dhg.size;
175 bestcount = 0;
176 }
177 if (dhg.size == best)
178 bestcount++;
179 }
Ben Lindstromaf738802001-06-25 04:18:59 +0000180 rewind(f);
Damien Miller874d77b2000-10-14 16:23:11 +1100181
182 if (bestcount == 0) {
Ben Lindstromaf738802001-06-25 04:18:59 +0000183 fclose(f);
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000184 logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000185 return (dh_new_group_fallback(max));
Damien Miller874d77b2000-10-14 16:23:11 +1100186 }
187
Damien Miller874d77b2000-10-14 16:23:11 +1100188 linenum = 0;
Damien Miller354c48c2008-05-19 14:50:00 +1000189 which = arc4random_uniform(bestcount);
Damien Miller874d77b2000-10-14 16:23:11 +1100190 while (fgets(line, sizeof(line), f)) {
191 if (!parse_prime(linenum, line, &dhg))
192 continue;
Ben Lindstrom5ba23b32001-04-05 02:05:21 +0000193 if ((dhg.size > max || dhg.size < min) ||
194 dhg.size != best ||
195 linenum++ != which) {
Damien Miller9ef95dd2002-01-22 23:10:33 +1100196 BN_clear_free(dhg.g);
197 BN_clear_free(dhg.p);
Damien Miller874d77b2000-10-14 16:23:11 +1100198 continue;
199 }
200 break;
201 }
202 fclose(f);
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000203 if (linenum != which+1) {
204 logit("WARNING: line %d disappeared in %s, giving up",
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000205 which, _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000206 return (dh_new_group_fallback(max));
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000207 }
Damien Miller874d77b2000-10-14 16:23:11 +1100208
209 return (dh_new_group(dhg.g, dhg.p));
210}
Damien Miller9709f902001-03-30 10:50:10 +1000211
Damien Millerf675fc42004-06-15 10:30:09 +1000212/* diffie-hellman-groupN-sha1 */
Damien Miller9709f902001-03-30 10:50:10 +1000213
214int
215dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
216{
217 int i;
218 int n = BN_num_bits(dh_pub);
219 int bits_set = 0;
Darren Tucker31cde682006-05-06 17:43:33 +1000220 BIGNUM *tmp;
Damien Miller9709f902001-03-30 10:50:10 +1000221
222 if (dh_pub->neg) {
Damien Miller603077a2007-10-26 14:25:55 +1000223 logit("invalid public DH value: negative");
Damien Miller9709f902001-03-30 10:50:10 +1000224 return 0;
225 }
Darren Tucker31cde682006-05-06 17:43:33 +1000226 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
227 logit("invalid public DH value: <= 1");
228 return 0;
229 }
230
Damien Miller603077a2007-10-26 14:25:55 +1000231 if ((tmp = BN_new()) == NULL) {
232 error("%s: BN_new failed", __func__);
233 return 0;
234 }
Darren Tucker31cde682006-05-06 17:43:33 +1000235 if (!BN_sub(tmp, dh->p, BN_value_one()) ||
236 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
237 BN_clear_free(tmp);
238 logit("invalid public DH value: >= p-1");
239 return 0;
240 }
241 BN_clear_free(tmp);
242
Damien Miller9709f902001-03-30 10:50:10 +1000243 for (i = 0; i <= n; i++)
244 if (BN_is_bit_set(dh_pub, i))
245 bits_set++;
Ben Lindstrom1f530832002-12-23 02:03:02 +0000246 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
Damien Miller9709f902001-03-30 10:50:10 +1000247
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000248 /*
249 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
250 */
251 if (bits_set < 4) {
252 logit("invalid public DH value (%d/%d)",
253 bits_set, BN_num_bits(dh->p));
254 return 0;
255 }
256 return 1;
Damien Miller9709f902001-03-30 10:50:10 +1000257}
258
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000259int
Damien Miller9709f902001-03-30 10:50:10 +1000260dh_gen_key(DH *dh, int need)
261{
Damien Miller0fde8ac2013-11-21 14:12:23 +1100262 int pbits;
Damien Miller9709f902001-03-30 10:50:10 +1000263
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000264 if (need < 0 || dh->p == NULL ||
265 (pbits = BN_num_bits(dh->p)) <= 0 ||
djm@openbsd.orgb8afbe22015-03-26 06:59:28 +0000266 need > INT_MAX / 2 || 2 * need > pbits)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000267 return SSH_ERR_INVALID_ARGUMENT;
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000268 if (need < 256)
269 need = 256;
270 /*
271 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
272 * so double requested need here.
273 */
deraadt@openbsd.org9136ec12016-09-12 01:22:38 +0000274 dh->length = MINIMUM(need * 2, pbits - 1);
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000275 if (DH_generate_key(dh) == 0 ||
276 !dh_pub_is_valid(dh, dh->pub_key)) {
277 BN_clear_free(dh->priv_key);
278 return SSH_ERR_LIBCRYPTO_ERROR;
279 }
280 return 0;
Damien Miller9709f902001-03-30 10:50:10 +1000281}
282
283DH *
284dh_new_group_asc(const char *gen, const char *modulus)
285{
286 DH *dh;
Damien Miller9709f902001-03-30 10:50:10 +1000287
Damien Millerda755162002-01-22 23:09:22 +1100288 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000289 return NULL;
290 if (BN_hex2bn(&dh->p, modulus) == 0 ||
291 BN_hex2bn(&dh->g, gen) == 0) {
292 DH_free(dh);
293 return NULL;
294 }
Damien Miller9709f902001-03-30 10:50:10 +1000295 return (dh);
296}
297
298/*
299 * This just returns the group, we still need to generate the exchange
300 * value.
301 */
302
303DH *
304dh_new_group(BIGNUM *gen, BIGNUM *modulus)
305{
306 DH *dh;
307
Damien Millerda755162002-01-22 23:09:22 +1100308 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000309 return NULL;
Damien Miller9709f902001-03-30 10:50:10 +1000310 dh->p = modulus;
311 dh->g = gen;
312
313 return (dh);
314}
315
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000316/* rfc2409 "Second Oakley Group" (1024 bits) */
Damien Miller9709f902001-03-30 10:50:10 +1000317DH *
318dh_new_group1(void)
319{
320 static char *gen = "2", *group1 =
321 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
322 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
323 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
324 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
325 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
326 "FFFFFFFF" "FFFFFFFF";
327
328 return (dh_new_group_asc(gen, group1));
329}
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000330
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000331/* rfc3526 group 14 "2048-bit MODP Group" */
Damien Millerf675fc42004-06-15 10:30:09 +1000332DH *
333dh_new_group14(void)
334{
335 static char *gen = "2", *group14 =
336 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
337 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
338 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
339 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
340 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
341 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
342 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
343 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
344 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
345 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
346 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
347
348 return (dh_new_group_asc(gen, group14));
349}
350
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000351/* rfc3526 group 16 "4096-bit MODP Group" */
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000352DH *
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000353dh_new_group16(void)
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000354{
355 static char *gen = "2", *group16 =
356 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
357 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
358 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
359 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
360 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
361 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
362 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
363 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
364 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
365 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
366 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
367 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
368 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
369 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
370 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
371 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
372 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
373 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
374 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
375 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
376 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
377 "FFFFFFFF" "FFFFFFFF";
378
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000379 return (dh_new_group_asc(gen, group16));
380}
381
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000382/* rfc3526 group 18 "8192-bit MODP Group" */
383DH *
384dh_new_group18(void)
385{
386 static char *gen = "2", *group16 =
387 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
388 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
389 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
390 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
391 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
392 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
393 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
394 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
395 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
396 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
397 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
398 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
399 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
400 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
401 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
402 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
403 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
404 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
405 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
406 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
407 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
408 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
409 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
410 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
411 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
412 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
413 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
414 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
415 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
416 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
417 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
418 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
419 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
420 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
421 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
422 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
423 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
424 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
425 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
426 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
427 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
428 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
429 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
430
431 return (dh_new_group_asc(gen, group16));
432}
433
434/* Select fallback group used by DH-GEX if moduli file cannot be read. */
435DH *
436dh_new_group_fallback(int max)
437{
438 debug3("%s: requested max size %d", __func__, max);
439 if (max < 3072) {
440 debug3("using 2k bit group 14");
441 return dh_new_group14();
442 } else if (max < 6144) {
443 debug3("using 4k bit group 16");
444 return dh_new_group16();
445 }
446 debug3("using 8k bit group 18");
447 return dh_new_group18();
448}
449
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000450/*
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000451 * Estimates the group order for a Diffie-Hellman group that has an
Darren Tuckerdf62d712013-10-10 10:32:39 +1100452 * attack complexity approximately the same as O(2**bits).
453 * Values from NIST Special Publication 800-57: Recommendation for Key
454 * Management Part 1 (rev 3) limited by the recommended maximum value
455 * from RFC4419 section 3.
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000456 */
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000457u_int
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000458dh_estimate(int bits)
459{
Darren Tuckerdf62d712013-10-10 10:32:39 +1100460 if (bits <= 112)
461 return 2048;
Damien Miller8975ddf2003-12-17 16:33:53 +1100462 if (bits <= 128)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100463 return 3072;
Damien Miller8975ddf2003-12-17 16:33:53 +1100464 if (bits <= 192)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100465 return 7680;
466 return 8192;
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000467}