blob: faa19a166bf6d1d67e72dbb0761bd7a6426dc082 [file] [log] [blame]
millert@openbsd.org6f56fe42018-06-26 11:23:59 +00001/* $OpenBSD: dh.c,v 1.65 2018/06/26 11:23:59 millert 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) {
Damien Miller874d77b2000-10-14 16:23:11 +1100193 if (!parse_prime(linenum, line, &dhg))
194 continue;
Ben Lindstrom5ba23b32001-04-05 02:05:21 +0000195 if ((dhg.size > max || dhg.size < min) ||
196 dhg.size != best ||
197 linenum++ != which) {
Damien Miller9ef95dd2002-01-22 23:10:33 +1100198 BN_clear_free(dhg.g);
199 BN_clear_free(dhg.p);
Damien Miller874d77b2000-10-14 16:23:11 +1100200 continue;
201 }
202 break;
203 }
markus@openbsd.org7f906352018-06-06 18:29:18 +0000204 free(line);
205 line = NULL;
Damien Miller874d77b2000-10-14 16:23:11 +1100206 fclose(f);
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000207 if (linenum != which+1) {
208 logit("WARNING: line %d disappeared in %s, giving up",
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000209 which, _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000210 return (dh_new_group_fallback(max));
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000211 }
Damien Miller874d77b2000-10-14 16:23:11 +1100212
213 return (dh_new_group(dhg.g, dhg.p));
214}
Damien Miller9709f902001-03-30 10:50:10 +1000215
Damien Millerf675fc42004-06-15 10:30:09 +1000216/* diffie-hellman-groupN-sha1 */
Damien Miller9709f902001-03-30 10:50:10 +1000217
218int
219dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
220{
221 int i;
222 int n = BN_num_bits(dh_pub);
223 int bits_set = 0;
Darren Tucker31cde682006-05-06 17:43:33 +1000224 BIGNUM *tmp;
Damien Miller9709f902001-03-30 10:50:10 +1000225
226 if (dh_pub->neg) {
Damien Miller603077a2007-10-26 14:25:55 +1000227 logit("invalid public DH value: negative");
Damien Miller9709f902001-03-30 10:50:10 +1000228 return 0;
229 }
Darren Tucker31cde682006-05-06 17:43:33 +1000230 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
231 logit("invalid public DH value: <= 1");
232 return 0;
233 }
234
Damien Miller603077a2007-10-26 14:25:55 +1000235 if ((tmp = BN_new()) == NULL) {
236 error("%s: BN_new failed", __func__);
237 return 0;
238 }
Darren Tucker31cde682006-05-06 17:43:33 +1000239 if (!BN_sub(tmp, dh->p, BN_value_one()) ||
240 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
241 BN_clear_free(tmp);
242 logit("invalid public DH value: >= p-1");
243 return 0;
244 }
245 BN_clear_free(tmp);
246
Damien Miller9709f902001-03-30 10:50:10 +1000247 for (i = 0; i <= n; i++)
248 if (BN_is_bit_set(dh_pub, i))
249 bits_set++;
Ben Lindstrom1f530832002-12-23 02:03:02 +0000250 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
Damien Miller9709f902001-03-30 10:50:10 +1000251
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000252 /*
253 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
254 */
255 if (bits_set < 4) {
256 logit("invalid public DH value (%d/%d)",
257 bits_set, BN_num_bits(dh->p));
258 return 0;
259 }
260 return 1;
Damien Miller9709f902001-03-30 10:50:10 +1000261}
262
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000263int
Damien Miller9709f902001-03-30 10:50:10 +1000264dh_gen_key(DH *dh, int need)
265{
Damien Miller0fde8ac2013-11-21 14:12:23 +1100266 int pbits;
Damien Miller9709f902001-03-30 10:50:10 +1000267
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000268 if (need < 0 || dh->p == NULL ||
269 (pbits = BN_num_bits(dh->p)) <= 0 ||
djm@openbsd.orgb8afbe22015-03-26 06:59:28 +0000270 need > INT_MAX / 2 || 2 * need > pbits)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000271 return SSH_ERR_INVALID_ARGUMENT;
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000272 if (need < 256)
273 need = 256;
274 /*
275 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
276 * so double requested need here.
277 */
deraadt@openbsd.org9136ec12016-09-12 01:22:38 +0000278 dh->length = MINIMUM(need * 2, pbits - 1);
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000279 if (DH_generate_key(dh) == 0 ||
280 !dh_pub_is_valid(dh, dh->pub_key)) {
281 BN_clear_free(dh->priv_key);
282 return SSH_ERR_LIBCRYPTO_ERROR;
283 }
284 return 0;
Damien Miller9709f902001-03-30 10:50:10 +1000285}
286
287DH *
288dh_new_group_asc(const char *gen, const char *modulus)
289{
290 DH *dh;
Damien Miller9709f902001-03-30 10:50:10 +1000291
Damien Millerda755162002-01-22 23:09:22 +1100292 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000293 return NULL;
294 if (BN_hex2bn(&dh->p, modulus) == 0 ||
295 BN_hex2bn(&dh->g, gen) == 0) {
296 DH_free(dh);
297 return NULL;
298 }
Damien Miller9709f902001-03-30 10:50:10 +1000299 return (dh);
300}
301
302/*
303 * This just returns the group, we still need to generate the exchange
304 * value.
305 */
306
307DH *
308dh_new_group(BIGNUM *gen, BIGNUM *modulus)
309{
310 DH *dh;
311
Damien Millerda755162002-01-22 23:09:22 +1100312 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000313 return NULL;
Damien Miller9709f902001-03-30 10:50:10 +1000314 dh->p = modulus;
315 dh->g = gen;
316
317 return (dh);
318}
319
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000320/* rfc2409 "Second Oakley Group" (1024 bits) */
Damien Miller9709f902001-03-30 10:50:10 +1000321DH *
322dh_new_group1(void)
323{
324 static char *gen = "2", *group1 =
325 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
326 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
327 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
328 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
329 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
330 "FFFFFFFF" "FFFFFFFF";
331
332 return (dh_new_group_asc(gen, group1));
333}
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000334
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000335/* rfc3526 group 14 "2048-bit MODP Group" */
Damien Millerf675fc42004-06-15 10:30:09 +1000336DH *
337dh_new_group14(void)
338{
339 static char *gen = "2", *group14 =
340 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
341 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
342 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
343 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
344 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
345 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
346 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
347 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
348 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
349 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
350 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
351
352 return (dh_new_group_asc(gen, group14));
353}
354
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000355/* rfc3526 group 16 "4096-bit MODP Group" */
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000356DH *
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000357dh_new_group16(void)
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000358{
359 static char *gen = "2", *group16 =
360 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
361 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
362 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
363 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
364 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
365 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
366 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
367 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
368 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
369 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
370 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
371 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
372 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
373 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
374 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
375 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
376 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
377 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
378 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
379 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
380 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
381 "FFFFFFFF" "FFFFFFFF";
382
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000383 return (dh_new_group_asc(gen, group16));
384}
385
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000386/* rfc3526 group 18 "8192-bit MODP Group" */
387DH *
388dh_new_group18(void)
389{
390 static char *gen = "2", *group16 =
391 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
392 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
393 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
394 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
395 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
396 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
397 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
398 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
399 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
400 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
401 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
402 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
403 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
404 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
405 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
406 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
407 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
408 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
409 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
410 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
411 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
412 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
413 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
414 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
415 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
416 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
417 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
418 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
419 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
420 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
421 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
422 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
423 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
424 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
425 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
426 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
427 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
428 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
429 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
430 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
431 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
432 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
433 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
434
435 return (dh_new_group_asc(gen, group16));
436}
437
438/* Select fallback group used by DH-GEX if moduli file cannot be read. */
439DH *
440dh_new_group_fallback(int max)
441{
442 debug3("%s: requested max size %d", __func__, max);
443 if (max < 3072) {
444 debug3("using 2k bit group 14");
445 return dh_new_group14();
446 } else if (max < 6144) {
447 debug3("using 4k bit group 16");
448 return dh_new_group16();
449 }
450 debug3("using 8k bit group 18");
451 return dh_new_group18();
452}
453
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000454/*
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000455 * Estimates the group order for a Diffie-Hellman group that has an
Darren Tuckerdf62d712013-10-10 10:32:39 +1100456 * attack complexity approximately the same as O(2**bits).
457 * Values from NIST Special Publication 800-57: Recommendation for Key
458 * Management Part 1 (rev 3) limited by the recommended maximum value
459 * from RFC4419 section 3.
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000460 */
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000461u_int
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000462dh_estimate(int bits)
463{
Darren Tuckerdf62d712013-10-10 10:32:39 +1100464 if (bits <= 112)
465 return 2048;
Damien Miller8975ddf2003-12-17 16:33:53 +1100466 if (bits <= 128)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100467 return 3072;
Damien Miller8975ddf2003-12-17 16:33:53 +1100468 if (bits <= 192)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100469 return 7680;
470 return 8192;
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000471}
Marcus Folkesson6b373e42017-10-28 19:48:39 +0200472
473#endif /* WITH_OPENSSL */