blob: 16eb132766f8bb884ab5ab841cc1c5468a568061 [file] [log] [blame]
markus@openbsd.org7f906352018-06-06 18:29:18 +00001/* $OpenBSD: dh.c,v 1.64 2018/06/06 18:29:18 markus 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
Marcus Folkesson6b373e42017-10-28 19:48:39 +020028#ifdef WITH_OPENSSL
Damien Miller8dbffe72006-08-05 11:02:17 +100029
Damien Miller874d77b2000-10-14 16:23:11 +110030#include <openssl/bn.h>
31#include <openssl/dh.h>
Damien Miller874d77b2000-10-14 16:23:11 +110032
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +000033#include <errno.h>
Damien Millerded319c2006-09-01 15:38:36 +100034#include <stdarg.h>
Damien Millera7a73ee2006-08-05 11:37:59 +100035#include <stdio.h>
Damien Millere7a1e5c2006-08-05 11:34:19 +100036#include <stdlib.h>
Damien Millere3476ed2006-07-24 14:13:33 +100037#include <string.h>
deraadt@openbsd.org087266e2015-01-20 23:14:00 +000038#include <limits.h>
Damien Millere3476ed2006-07-24 14:13:33 +100039
Damien Miller874d77b2000-10-14 16:23:11 +110040#include "dh.h"
Ben Lindstrom226cfa02001-01-22 05:34:40 +000041#include "pathnames.h"
42#include "log.h"
43#include "misc.h"
markus@openbsd.org57d10cb2015-01-19 20:16:15 +000044#include "ssherr.h"
Damien Miller874d77b2000-10-14 16:23:11 +110045
Ben Lindstrombba81212001-06-25 05:01:22 +000046static int
Damien Miller874d77b2000-10-14 16:23:11 +110047parse_prime(int linenum, char *line, struct dhgroup *dhg)
48{
49 char *cp, *arg;
50 char *strsize, *gen, *prime;
Damien Miller5a73c1a2006-03-31 23:09:41 +110051 const char *errstr = NULL;
Damien Miller2e9cf492008-06-29 22:47:04 +100052 long long n;
Damien Miller874d77b2000-10-14 16:23:11 +110053
Damien Miller0d02c3e2013-07-18 16:12:06 +100054 dhg->p = dhg->g = NULL;
Damien Miller874d77b2000-10-14 16:23:11 +110055 cp = line;
Damien Miller928b2362006-03-26 13:53:32 +110056 if ((arg = strdelim(&cp)) == NULL)
57 return 0;
Damien Miller874d77b2000-10-14 16:23:11 +110058 /* Ignore leading whitespace */
59 if (*arg == '\0')
60 arg = strdelim(&cp);
Ben Lindstrom04f9af72002-07-04 00:03:56 +000061 if (!arg || !*arg || *arg == '#')
Damien Miller874d77b2000-10-14 16:23:11 +110062 return 0;
63
64 /* time */
65 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100066 goto truncated;
Damien Miller874d77b2000-10-14 16:23:11 +110067 arg = strsep(&cp, " "); /* type */
68 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100069 goto truncated;
Damien Miller2e9cf492008-06-29 22:47:04 +100070 /* Ensure this is a safe prime */
71 n = strtonum(arg, 0, 5, &errstr);
Damien Millerbbeb1da2013-07-18 16:10:49 +100072 if (errstr != NULL || n != MODULI_TYPE_SAFE) {
73 error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
Damien Miller2e9cf492008-06-29 22:47:04 +100074 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100075 }
Damien Miller874d77b2000-10-14 16:23:11 +110076 arg = strsep(&cp, " "); /* tests */
77 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100078 goto truncated;
Damien Miller2e9cf492008-06-29 22:47:04 +100079 /* Ensure prime has been tested and is not composite */
80 n = strtonum(arg, 0, 0x1f, &errstr);
81 if (errstr != NULL ||
Damien Millerbbeb1da2013-07-18 16:10:49 +100082 (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
83 error("moduli:%d: invalid moduli tests flag", linenum);
Damien Miller2e9cf492008-06-29 22:47:04 +100084 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100085 }
Damien Miller874d77b2000-10-14 16:23:11 +110086 arg = strsep(&cp, " "); /* tries */
87 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100088 goto truncated;
Damien Miller2e9cf492008-06-29 22:47:04 +100089 n = strtonum(arg, 0, 1<<30, &errstr);
Damien Millerbbeb1da2013-07-18 16:10:49 +100090 if (errstr != NULL || n == 0) {
91 error("moduli:%d: invalid primality trial count", linenum);
Damien Miller2e9cf492008-06-29 22:47:04 +100092 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100093 }
Damien Miller874d77b2000-10-14 16:23:11 +110094 strsize = strsep(&cp, " "); /* size */
95 if (cp == NULL || *strsize == '\0' ||
Darren Tucker759cb2a2009-10-07 09:01:50 +110096 (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
Damien Millerbbeb1da2013-07-18 16:10:49 +100097 errstr) {
98 error("moduli:%d: invalid prime length", linenum);
Damien Miller874d77b2000-10-14 16:23:11 +110099 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +1000100 }
Ben Lindstromdf221392001-03-29 00:36:16 +0000101 /* The whole group is one bit larger */
102 dhg->size++;
Damien Miller874d77b2000-10-14 16:23:11 +1100103 gen = strsep(&cp, " "); /* gen */
104 if (cp == NULL || *gen == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +1000105 goto truncated;
Damien Miller874d77b2000-10-14 16:23:11 +1100106 prime = strsep(&cp, " "); /* prime */
Damien Millerbbeb1da2013-07-18 16:10:49 +1000107 if (cp != NULL || *prime == '\0') {
108 truncated:
109 error("moduli:%d: truncated", linenum);
Damien Miller874d77b2000-10-14 16:23:11 +1100110 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +1000111 }
Damien Miller874d77b2000-10-14 16:23:11 +1100112
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000113 if ((dhg->g = BN_new()) == NULL ||
114 (dhg->p = BN_new()) == NULL) {
115 error("parse_prime: BN_new failed");
116 goto fail;
117 }
Damien Millerbbeb1da2013-07-18 16:10:49 +1000118 if (BN_hex2bn(&dhg->g, gen) == 0) {
119 error("moduli:%d: could not parse generator value", linenum);
120 goto fail;
121 }
122 if (BN_hex2bn(&dhg->p, prime) == 0) {
123 error("moduli:%d: could not parse prime value", linenum);
124 goto fail;
125 }
126 if (BN_num_bits(dhg->p) != dhg->size) {
127 error("moduli:%d: prime has wrong size: actual %d listed %d",
128 linenum, BN_num_bits(dhg->p), dhg->size - 1);
129 goto fail;
130 }
131 if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
132 error("moduli:%d: generator is invalid", linenum);
133 goto fail;
134 }
Damien Millerbbeb1da2013-07-18 16:10:49 +1000135 return 1;
Damien Miller23e526e2001-03-30 10:47:43 +1000136
Damien Miller874d77b2000-10-14 16:23:11 +1100137 fail:
jsing@openbsd.org7cd31632018-02-07 02:06:50 +0000138 BN_clear_free(dhg->g);
139 BN_clear_free(dhg->p);
Damien Millerbbeb1da2013-07-18 16:10:49 +1000140 dhg->g = dhg->p = NULL;
Damien Millerbbeb1da2013-07-18 16:10:49 +1000141 return 0;
Damien Miller874d77b2000-10-14 16:23:11 +1100142}
143
144DH *
Ben Lindstromdf221392001-03-29 00:36:16 +0000145choose_dh(int min, int wantbits, int max)
Damien Miller874d77b2000-10-14 16:23:11 +1100146{
147 FILE *f;
markus@openbsd.org7f906352018-06-06 18:29:18 +0000148 char *line = NULL;
149 size_t linesize = 0;
150 int best, bestcount, which, linenum;
Damien Miller874d77b2000-10-14 16:23:11 +1100151 struct dhgroup dhg;
152
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000153 if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
dtucker@openbsd.orgdcc7d742016-12-15 21:20:41 +0000154 logit("WARNING: could not open %s (%s), using fixed modulus",
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000155 _PATH_DH_MODULI, strerror(errno));
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000156 return (dh_new_group_fallback(max));
Damien Miller874d77b2000-10-14 16:23:11 +1100157 }
158
159 linenum = 0;
160 best = bestcount = 0;
markus@openbsd.org7f906352018-06-06 18:29:18 +0000161 while (getline(&line, &linesize, f) != -1) {
Damien Miller874d77b2000-10-14 16:23:11 +1100162 linenum++;
163 if (!parse_prime(linenum, line, &dhg))
164 continue;
Damien Miller9ef95dd2002-01-22 23:10:33 +1100165 BN_clear_free(dhg.g);
166 BN_clear_free(dhg.p);
Damien Miller874d77b2000-10-14 16:23:11 +1100167
Ben Lindstromdf221392001-03-29 00:36:16 +0000168 if (dhg.size > max || dhg.size < min)
169 continue;
170
171 if ((dhg.size > wantbits && dhg.size < best) ||
172 (dhg.size > best && best < wantbits)) {
Damien Miller874d77b2000-10-14 16:23:11 +1100173 best = dhg.size;
174 bestcount = 0;
175 }
176 if (dhg.size == best)
177 bestcount++;
178 }
markus@openbsd.org7f906352018-06-06 18:29:18 +0000179 free(line);
180 line = NULL;
181 linesize = 0;
Ben Lindstromaf738802001-06-25 04:18:59 +0000182 rewind(f);
Damien Miller874d77b2000-10-14 16:23:11 +1100183
184 if (bestcount == 0) {
Ben Lindstromaf738802001-06-25 04:18:59 +0000185 fclose(f);
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000186 logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000187 return (dh_new_group_fallback(max));
Damien Miller874d77b2000-10-14 16:23:11 +1100188 }
189
Damien Miller874d77b2000-10-14 16:23:11 +1100190 linenum = 0;
Damien Miller354c48c2008-05-19 14:50:00 +1000191 which = arc4random_uniform(bestcount);
markus@openbsd.org7f906352018-06-06 18:29:18 +0000192 while (getline(&line, &linesize, f) != -1) {
193 linenum++;
Damien Miller874d77b2000-10-14 16:23:11 +1100194 if (!parse_prime(linenum, line, &dhg))
195 continue;
Ben Lindstrom5ba23b32001-04-05 02:05:21 +0000196 if ((dhg.size > max || dhg.size < min) ||
197 dhg.size != best ||
198 linenum++ != which) {
Damien Miller9ef95dd2002-01-22 23:10:33 +1100199 BN_clear_free(dhg.g);
200 BN_clear_free(dhg.p);
Damien Miller874d77b2000-10-14 16:23:11 +1100201 continue;
202 }
203 break;
204 }
markus@openbsd.org7f906352018-06-06 18:29:18 +0000205 free(line);
206 line = NULL;
Damien Miller874d77b2000-10-14 16:23:11 +1100207 fclose(f);
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000208 if (linenum != which+1) {
209 logit("WARNING: line %d disappeared in %s, giving up",
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000210 which, _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000211 return (dh_new_group_fallback(max));
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000212 }
Damien Miller874d77b2000-10-14 16:23:11 +1100213
214 return (dh_new_group(dhg.g, dhg.p));
215}
Damien Miller9709f902001-03-30 10:50:10 +1000216
Damien Millerf675fc42004-06-15 10:30:09 +1000217/* diffie-hellman-groupN-sha1 */
Damien Miller9709f902001-03-30 10:50:10 +1000218
219int
220dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
221{
222 int i;
223 int n = BN_num_bits(dh_pub);
224 int bits_set = 0;
Darren Tucker31cde682006-05-06 17:43:33 +1000225 BIGNUM *tmp;
Damien Miller9709f902001-03-30 10:50:10 +1000226
227 if (dh_pub->neg) {
Damien Miller603077a2007-10-26 14:25:55 +1000228 logit("invalid public DH value: negative");
Damien Miller9709f902001-03-30 10:50:10 +1000229 return 0;
230 }
Darren Tucker31cde682006-05-06 17:43:33 +1000231 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
232 logit("invalid public DH value: <= 1");
233 return 0;
234 }
235
Damien Miller603077a2007-10-26 14:25:55 +1000236 if ((tmp = BN_new()) == NULL) {
237 error("%s: BN_new failed", __func__);
238 return 0;
239 }
Darren Tucker31cde682006-05-06 17:43:33 +1000240 if (!BN_sub(tmp, dh->p, BN_value_one()) ||
241 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
242 BN_clear_free(tmp);
243 logit("invalid public DH value: >= p-1");
244 return 0;
245 }
246 BN_clear_free(tmp);
247
Damien Miller9709f902001-03-30 10:50:10 +1000248 for (i = 0; i <= n; i++)
249 if (BN_is_bit_set(dh_pub, i))
250 bits_set++;
Ben Lindstrom1f530832002-12-23 02:03:02 +0000251 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
Damien Miller9709f902001-03-30 10:50:10 +1000252
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000253 /*
254 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
255 */
256 if (bits_set < 4) {
257 logit("invalid public DH value (%d/%d)",
258 bits_set, BN_num_bits(dh->p));
259 return 0;
260 }
261 return 1;
Damien Miller9709f902001-03-30 10:50:10 +1000262}
263
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000264int
Damien Miller9709f902001-03-30 10:50:10 +1000265dh_gen_key(DH *dh, int need)
266{
Damien Miller0fde8ac2013-11-21 14:12:23 +1100267 int pbits;
Damien Miller9709f902001-03-30 10:50:10 +1000268
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000269 if (need < 0 || dh->p == NULL ||
270 (pbits = BN_num_bits(dh->p)) <= 0 ||
djm@openbsd.orgb8afbe22015-03-26 06:59:28 +0000271 need > INT_MAX / 2 || 2 * need > pbits)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000272 return SSH_ERR_INVALID_ARGUMENT;
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000273 if (need < 256)
274 need = 256;
275 /*
276 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
277 * so double requested need here.
278 */
deraadt@openbsd.org9136ec12016-09-12 01:22:38 +0000279 dh->length = MINIMUM(need * 2, pbits - 1);
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000280 if (DH_generate_key(dh) == 0 ||
281 !dh_pub_is_valid(dh, dh->pub_key)) {
282 BN_clear_free(dh->priv_key);
283 return SSH_ERR_LIBCRYPTO_ERROR;
284 }
285 return 0;
Damien Miller9709f902001-03-30 10:50:10 +1000286}
287
288DH *
289dh_new_group_asc(const char *gen, const char *modulus)
290{
291 DH *dh;
Damien Miller9709f902001-03-30 10:50:10 +1000292
Damien Millerda755162002-01-22 23:09:22 +1100293 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000294 return NULL;
295 if (BN_hex2bn(&dh->p, modulus) == 0 ||
296 BN_hex2bn(&dh->g, gen) == 0) {
297 DH_free(dh);
298 return NULL;
299 }
Damien Miller9709f902001-03-30 10:50:10 +1000300 return (dh);
301}
302
303/*
304 * This just returns the group, we still need to generate the exchange
305 * value.
306 */
307
308DH *
309dh_new_group(BIGNUM *gen, BIGNUM *modulus)
310{
311 DH *dh;
312
Damien Millerda755162002-01-22 23:09:22 +1100313 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000314 return NULL;
Damien Miller9709f902001-03-30 10:50:10 +1000315 dh->p = modulus;
316 dh->g = gen;
317
318 return (dh);
319}
320
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000321/* rfc2409 "Second Oakley Group" (1024 bits) */
Damien Miller9709f902001-03-30 10:50:10 +1000322DH *
323dh_new_group1(void)
324{
325 static char *gen = "2", *group1 =
326 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
327 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
328 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
329 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
330 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
331 "FFFFFFFF" "FFFFFFFF";
332
333 return (dh_new_group_asc(gen, group1));
334}
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000335
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000336/* rfc3526 group 14 "2048-bit MODP Group" */
Damien Millerf675fc42004-06-15 10:30:09 +1000337DH *
338dh_new_group14(void)
339{
340 static char *gen = "2", *group14 =
341 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
342 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
343 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
344 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
345 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
346 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
347 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
348 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
349 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
350 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
351 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
352
353 return (dh_new_group_asc(gen, group14));
354}
355
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000356/* rfc3526 group 16 "4096-bit MODP Group" */
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000357DH *
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000358dh_new_group16(void)
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000359{
360 static char *gen = "2", *group16 =
361 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
362 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
363 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
364 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
365 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
366 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
367 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
368 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
369 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
370 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
371 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
372 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
373 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
374 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
375 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
376 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
377 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
378 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
379 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
380 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
381 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
382 "FFFFFFFF" "FFFFFFFF";
383
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000384 return (dh_new_group_asc(gen, group16));
385}
386
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000387/* rfc3526 group 18 "8192-bit MODP Group" */
388DH *
389dh_new_group18(void)
390{
391 static char *gen = "2", *group16 =
392 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
393 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
394 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
395 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
396 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
397 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
398 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
399 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
400 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
401 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
402 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
403 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
404 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
405 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
406 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
407 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
408 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
409 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
410 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
411 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
412 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
413 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
414 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
415 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
416 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
417 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
418 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
419 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
420 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
421 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
422 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
423 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
424 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
425 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
426 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
427 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
428 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
429 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
430 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
431 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
432 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
433 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
434 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
435
436 return (dh_new_group_asc(gen, group16));
437}
438
439/* Select fallback group used by DH-GEX if moduli file cannot be read. */
440DH *
441dh_new_group_fallback(int max)
442{
443 debug3("%s: requested max size %d", __func__, max);
444 if (max < 3072) {
445 debug3("using 2k bit group 14");
446 return dh_new_group14();
447 } else if (max < 6144) {
448 debug3("using 4k bit group 16");
449 return dh_new_group16();
450 }
451 debug3("using 8k bit group 18");
452 return dh_new_group18();
453}
454
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000455/*
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000456 * Estimates the group order for a Diffie-Hellman group that has an
Darren Tuckerdf62d712013-10-10 10:32:39 +1100457 * attack complexity approximately the same as O(2**bits).
458 * Values from NIST Special Publication 800-57: Recommendation for Key
459 * Management Part 1 (rev 3) limited by the recommended maximum value
460 * from RFC4419 section 3.
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000461 */
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000462u_int
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000463dh_estimate(int bits)
464{
Darren Tuckerdf62d712013-10-10 10:32:39 +1100465 if (bits <= 112)
466 return 2048;
Damien Miller8975ddf2003-12-17 16:33:53 +1100467 if (bits <= 128)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100468 return 3072;
Damien Miller8975ddf2003-12-17 16:33:53 +1100469 if (bits <= 192)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100470 return 7680;
471 return 8192;
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000472}
Marcus Folkesson6b373e42017-10-28 19:48:39 +0200473
474#endif /* WITH_OPENSSL */