blob: f3ed388290db9f626b7441f09b7de8dc5827be9f [file] [log] [blame]
djm@openbsd.org967226a2018-08-04 00:55:06 +00001/* $OpenBSD: dh.c,v 1.66 2018/08/04 00:55:06 djm 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
Damien Miller48f54b92018-09-13 12:13:50 +100046#include "openbsd-compat/openssl-compat.h"
47
Ben Lindstrombba81212001-06-25 05:01:22 +000048static int
Damien Miller874d77b2000-10-14 16:23:11 +110049parse_prime(int linenum, char *line, struct dhgroup *dhg)
50{
51 char *cp, *arg;
52 char *strsize, *gen, *prime;
Damien Miller5a73c1a2006-03-31 23:09:41 +110053 const char *errstr = NULL;
Damien Miller2e9cf492008-06-29 22:47:04 +100054 long long n;
Damien Miller874d77b2000-10-14 16:23:11 +110055
Damien Miller0d02c3e2013-07-18 16:12:06 +100056 dhg->p = dhg->g = NULL;
Damien Miller874d77b2000-10-14 16:23:11 +110057 cp = line;
Damien Miller928b2362006-03-26 13:53:32 +110058 if ((arg = strdelim(&cp)) == NULL)
59 return 0;
Damien Miller874d77b2000-10-14 16:23:11 +110060 /* Ignore leading whitespace */
61 if (*arg == '\0')
62 arg = strdelim(&cp);
Ben Lindstrom04f9af72002-07-04 00:03:56 +000063 if (!arg || !*arg || *arg == '#')
Damien Miller874d77b2000-10-14 16:23:11 +110064 return 0;
65
66 /* time */
67 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100068 goto truncated;
Damien Miller874d77b2000-10-14 16:23:11 +110069 arg = strsep(&cp, " "); /* type */
70 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100071 goto truncated;
Damien Miller2e9cf492008-06-29 22:47:04 +100072 /* Ensure this is a safe prime */
73 n = strtonum(arg, 0, 5, &errstr);
Damien Millerbbeb1da2013-07-18 16:10:49 +100074 if (errstr != NULL || n != MODULI_TYPE_SAFE) {
75 error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
Damien Miller2e9cf492008-06-29 22:47:04 +100076 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100077 }
Damien Miller874d77b2000-10-14 16:23:11 +110078 arg = strsep(&cp, " "); /* tests */
79 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100080 goto truncated;
Damien Miller2e9cf492008-06-29 22:47:04 +100081 /* Ensure prime has been tested and is not composite */
82 n = strtonum(arg, 0, 0x1f, &errstr);
83 if (errstr != NULL ||
Damien Millerbbeb1da2013-07-18 16:10:49 +100084 (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
85 error("moduli:%d: invalid moduli tests flag", linenum);
Damien Miller2e9cf492008-06-29 22:47:04 +100086 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100087 }
Damien Miller874d77b2000-10-14 16:23:11 +110088 arg = strsep(&cp, " "); /* tries */
89 if (cp == NULL || *arg == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +100090 goto truncated;
Damien Miller2e9cf492008-06-29 22:47:04 +100091 n = strtonum(arg, 0, 1<<30, &errstr);
Damien Millerbbeb1da2013-07-18 16:10:49 +100092 if (errstr != NULL || n == 0) {
93 error("moduli:%d: invalid primality trial count", linenum);
Damien Miller2e9cf492008-06-29 22:47:04 +100094 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +100095 }
Damien Miller874d77b2000-10-14 16:23:11 +110096 strsize = strsep(&cp, " "); /* size */
97 if (cp == NULL || *strsize == '\0' ||
Darren Tucker759cb2a2009-10-07 09:01:50 +110098 (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
Damien Millerbbeb1da2013-07-18 16:10:49 +100099 errstr) {
100 error("moduli:%d: invalid prime length", linenum);
Damien Miller874d77b2000-10-14 16:23:11 +1100101 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +1000102 }
Ben Lindstromdf221392001-03-29 00:36:16 +0000103 /* The whole group is one bit larger */
104 dhg->size++;
Damien Miller874d77b2000-10-14 16:23:11 +1100105 gen = strsep(&cp, " "); /* gen */
106 if (cp == NULL || *gen == '\0')
Damien Millerbbeb1da2013-07-18 16:10:49 +1000107 goto truncated;
Damien Miller874d77b2000-10-14 16:23:11 +1100108 prime = strsep(&cp, " "); /* prime */
Damien Millerbbeb1da2013-07-18 16:10:49 +1000109 if (cp != NULL || *prime == '\0') {
110 truncated:
111 error("moduli:%d: truncated", linenum);
Damien Miller874d77b2000-10-14 16:23:11 +1100112 goto fail;
Damien Millerbbeb1da2013-07-18 16:10:49 +1000113 }
Damien Miller874d77b2000-10-14 16:23:11 +1100114
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000115 if ((dhg->g = BN_new()) == NULL ||
116 (dhg->p = BN_new()) == NULL) {
117 error("parse_prime: BN_new failed");
118 goto fail;
119 }
Damien Millerbbeb1da2013-07-18 16:10:49 +1000120 if (BN_hex2bn(&dhg->g, gen) == 0) {
121 error("moduli:%d: could not parse generator value", linenum);
122 goto fail;
123 }
124 if (BN_hex2bn(&dhg->p, prime) == 0) {
125 error("moduli:%d: could not parse prime value", linenum);
126 goto fail;
127 }
128 if (BN_num_bits(dhg->p) != dhg->size) {
129 error("moduli:%d: prime has wrong size: actual %d listed %d",
130 linenum, BN_num_bits(dhg->p), dhg->size - 1);
131 goto fail;
132 }
133 if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
134 error("moduli:%d: generator is invalid", linenum);
135 goto fail;
136 }
Damien Millerbbeb1da2013-07-18 16:10:49 +1000137 return 1;
Damien Miller23e526e2001-03-30 10:47:43 +1000138
Damien Miller874d77b2000-10-14 16:23:11 +1100139 fail:
jsing@openbsd.org7cd31632018-02-07 02:06:50 +0000140 BN_clear_free(dhg->g);
141 BN_clear_free(dhg->p);
Damien Millerbbeb1da2013-07-18 16:10:49 +1000142 dhg->g = dhg->p = NULL;
Damien Millerbbeb1da2013-07-18 16:10:49 +1000143 return 0;
Damien Miller874d77b2000-10-14 16:23:11 +1100144}
145
146DH *
Ben Lindstromdf221392001-03-29 00:36:16 +0000147choose_dh(int min, int wantbits, int max)
Damien Miller874d77b2000-10-14 16:23:11 +1100148{
149 FILE *f;
markus@openbsd.org7f906352018-06-06 18:29:18 +0000150 char *line = NULL;
151 size_t linesize = 0;
152 int best, bestcount, which, linenum;
Damien Miller874d77b2000-10-14 16:23:11 +1100153 struct dhgroup dhg;
154
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000155 if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
dtucker@openbsd.orgdcc7d742016-12-15 21:20:41 +0000156 logit("WARNING: could not open %s (%s), using fixed modulus",
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000157 _PATH_DH_MODULI, strerror(errno));
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000158 return (dh_new_group_fallback(max));
Damien Miller874d77b2000-10-14 16:23:11 +1100159 }
160
161 linenum = 0;
162 best = bestcount = 0;
markus@openbsd.org7f906352018-06-06 18:29:18 +0000163 while (getline(&line, &linesize, f) != -1) {
Damien Miller874d77b2000-10-14 16:23:11 +1100164 linenum++;
165 if (!parse_prime(linenum, line, &dhg))
166 continue;
Damien Miller9ef95dd2002-01-22 23:10:33 +1100167 BN_clear_free(dhg.g);
168 BN_clear_free(dhg.p);
Damien Miller874d77b2000-10-14 16:23:11 +1100169
Ben Lindstromdf221392001-03-29 00:36:16 +0000170 if (dhg.size > max || dhg.size < min)
171 continue;
172
173 if ((dhg.size > wantbits && dhg.size < best) ||
174 (dhg.size > best && best < wantbits)) {
Damien Miller874d77b2000-10-14 16:23:11 +1100175 best = dhg.size;
176 bestcount = 0;
177 }
178 if (dhg.size == best)
179 bestcount++;
180 }
markus@openbsd.org7f906352018-06-06 18:29:18 +0000181 free(line);
182 line = NULL;
183 linesize = 0;
Ben Lindstromaf738802001-06-25 04:18:59 +0000184 rewind(f);
Damien Miller874d77b2000-10-14 16:23:11 +1100185
186 if (bestcount == 0) {
Ben Lindstromaf738802001-06-25 04:18:59 +0000187 fclose(f);
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000188 logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000189 return (dh_new_group_fallback(max));
Damien Miller874d77b2000-10-14 16:23:11 +1100190 }
191
Damien Miller874d77b2000-10-14 16:23:11 +1100192 linenum = 0;
Damien Miller354c48c2008-05-19 14:50:00 +1000193 which = arc4random_uniform(bestcount);
markus@openbsd.org7f906352018-06-06 18:29:18 +0000194 while (getline(&line, &linesize, f) != -1) {
Damien Miller874d77b2000-10-14 16:23:11 +1100195 if (!parse_prime(linenum, line, &dhg))
196 continue;
Ben Lindstrom5ba23b32001-04-05 02:05:21 +0000197 if ((dhg.size > max || dhg.size < min) ||
198 dhg.size != best ||
199 linenum++ != which) {
Damien Miller9ef95dd2002-01-22 23:10:33 +1100200 BN_clear_free(dhg.g);
201 BN_clear_free(dhg.p);
Damien Miller874d77b2000-10-14 16:23:11 +1100202 continue;
203 }
204 break;
205 }
markus@openbsd.org7f906352018-06-06 18:29:18 +0000206 free(line);
207 line = NULL;
Damien Miller874d77b2000-10-14 16:23:11 +1100208 fclose(f);
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000209 if (linenum != which+1) {
210 logit("WARNING: line %d disappeared in %s, giving up",
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000211 which, _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000212 return (dh_new_group_fallback(max));
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000213 }
Damien Miller874d77b2000-10-14 16:23:11 +1100214
215 return (dh_new_group(dhg.g, dhg.p));
216}
Damien Miller9709f902001-03-30 10:50:10 +1000217
Damien Millerf675fc42004-06-15 10:30:09 +1000218/* diffie-hellman-groupN-sha1 */
Damien Miller9709f902001-03-30 10:50:10 +1000219
220int
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000221dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
Damien Miller9709f902001-03-30 10:50:10 +1000222{
223 int i;
224 int n = BN_num_bits(dh_pub);
225 int bits_set = 0;
Darren Tucker31cde682006-05-06 17:43:33 +1000226 BIGNUM *tmp;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000227 const BIGNUM *dh_p;
Damien Miller9709f902001-03-30 10:50:10 +1000228
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000229 DH_get0_pqg(dh, &dh_p, NULL, NULL);
230
231 if (BN_is_negative(dh_pub)) {
Damien Miller603077a2007-10-26 14:25:55 +1000232 logit("invalid public DH value: negative");
Damien Miller9709f902001-03-30 10:50:10 +1000233 return 0;
234 }
Darren Tucker31cde682006-05-06 17:43:33 +1000235 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
236 logit("invalid public DH value: <= 1");
237 return 0;
238 }
239
Damien Miller603077a2007-10-26 14:25:55 +1000240 if ((tmp = BN_new()) == NULL) {
241 error("%s: BN_new failed", __func__);
242 return 0;
243 }
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000244 if (!BN_sub(tmp, dh_p, BN_value_one()) ||
Darren Tucker31cde682006-05-06 17:43:33 +1000245 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
246 BN_clear_free(tmp);
247 logit("invalid public DH value: >= p-1");
248 return 0;
249 }
250 BN_clear_free(tmp);
251
Damien Miller9709f902001-03-30 10:50:10 +1000252 for (i = 0; i <= n; i++)
253 if (BN_is_bit_set(dh_pub, i))
254 bits_set++;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000255 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p));
Damien Miller9709f902001-03-30 10:50:10 +1000256
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000257 /*
258 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
259 */
260 if (bits_set < 4) {
261 logit("invalid public DH value (%d/%d)",
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000262 bits_set, BN_num_bits(dh_p));
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000263 return 0;
264 }
265 return 1;
Damien Miller9709f902001-03-30 10:50:10 +1000266}
267
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000268int
Damien Miller9709f902001-03-30 10:50:10 +1000269dh_gen_key(DH *dh, int need)
270{
Damien Miller0fde8ac2013-11-21 14:12:23 +1100271 int pbits;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000272 const BIGNUM *dh_p, *pub_key;
Damien Miller9709f902001-03-30 10:50:10 +1000273
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000274 DH_get0_pqg(dh, &dh_p, NULL, NULL);
275
276 if (need < 0 || dh_p == NULL ||
277 (pbits = BN_num_bits(dh_p)) <= 0 ||
djm@openbsd.orgb8afbe22015-03-26 06:59:28 +0000278 need > INT_MAX / 2 || 2 * need > pbits)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000279 return SSH_ERR_INVALID_ARGUMENT;
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000280 if (need < 256)
281 need = 256;
282 /*
283 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
284 * so double requested need here.
285 */
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000286 if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000287 return SSH_ERR_LIBCRYPTO_ERROR;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000288
289 if (DH_generate_key(dh) == 0)
290 return SSH_ERR_LIBCRYPTO_ERROR;
291 DH_get0_key(dh, &pub_key, NULL);
292 if (!dh_pub_is_valid(dh, pub_key))
293 return SSH_ERR_INVALID_FORMAT;
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000294 return 0;
Damien Miller9709f902001-03-30 10:50:10 +1000295}
296
297DH *
298dh_new_group_asc(const char *gen, const char *modulus)
299{
300 DH *dh;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000301 BIGNUM *dh_p = NULL, *dh_g = NULL;
Damien Miller9709f902001-03-30 10:50:10 +1000302
Damien Millerda755162002-01-22 23:09:22 +1100303 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000304 return NULL;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000305 if (BN_hex2bn(&dh_p, modulus) == 0 ||
306 BN_hex2bn(&dh_g, gen) == 0)
307 goto fail;
308 if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
309 goto fail;
310 return dh;
311 fail:
312 DH_free(dh);
313 BN_clear_free(dh_p);
314 BN_clear_free(dh_g);
315 return NULL;
Damien Miller9709f902001-03-30 10:50:10 +1000316}
317
318/*
319 * This just returns the group, we still need to generate the exchange
320 * value.
321 */
Damien Miller9709f902001-03-30 10:50:10 +1000322DH *
323dh_new_group(BIGNUM *gen, BIGNUM *modulus)
324{
325 DH *dh;
326
Damien Millerda755162002-01-22 23:09:22 +1100327 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000328 return NULL;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000329 if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
330 DH_free(dh);
331 return NULL;
332 }
Damien Miller9709f902001-03-30 10:50:10 +1000333
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000334 return dh;
Damien Miller9709f902001-03-30 10:50:10 +1000335}
336
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000337/* rfc2409 "Second Oakley Group" (1024 bits) */
Damien Miller9709f902001-03-30 10:50:10 +1000338DH *
339dh_new_group1(void)
340{
341 static char *gen = "2", *group1 =
342 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
343 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
344 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
345 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
346 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
347 "FFFFFFFF" "FFFFFFFF";
348
349 return (dh_new_group_asc(gen, group1));
350}
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000351
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000352/* rfc3526 group 14 "2048-bit MODP Group" */
Damien Millerf675fc42004-06-15 10:30:09 +1000353DH *
354dh_new_group14(void)
355{
356 static char *gen = "2", *group14 =
357 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
358 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
359 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
360 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
361 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
362 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
363 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
364 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
365 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
366 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
367 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
368
369 return (dh_new_group_asc(gen, group14));
370}
371
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000372/* rfc3526 group 16 "4096-bit MODP Group" */
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000373DH *
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000374dh_new_group16(void)
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000375{
376 static char *gen = "2", *group16 =
377 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
378 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
379 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
380 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
381 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
382 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
383 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
384 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
385 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
386 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
387 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
388 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
389 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
390 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
391 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
392 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
393 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
394 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
395 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
396 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
397 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
398 "FFFFFFFF" "FFFFFFFF";
399
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000400 return (dh_new_group_asc(gen, group16));
401}
402
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000403/* rfc3526 group 18 "8192-bit MODP Group" */
404DH *
405dh_new_group18(void)
406{
407 static char *gen = "2", *group16 =
408 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
409 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
410 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
411 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
412 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
413 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
414 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
415 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
416 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
417 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
418 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
419 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
420 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
421 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
422 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
423 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
424 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
425 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
426 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
427 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
428 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
429 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
430 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
431 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
432 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
433 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
434 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
435 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
436 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
437 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
438 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
439 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
440 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
441 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
442 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
443 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
444 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
445 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
446 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
447 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
448 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
449 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
450 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
451
452 return (dh_new_group_asc(gen, group16));
453}
454
455/* Select fallback group used by DH-GEX if moduli file cannot be read. */
456DH *
457dh_new_group_fallback(int max)
458{
459 debug3("%s: requested max size %d", __func__, max);
460 if (max < 3072) {
461 debug3("using 2k bit group 14");
462 return dh_new_group14();
463 } else if (max < 6144) {
464 debug3("using 4k bit group 16");
465 return dh_new_group16();
466 }
467 debug3("using 8k bit group 18");
468 return dh_new_group18();
469}
470
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000471/*
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000472 * Estimates the group order for a Diffie-Hellman group that has an
Darren Tuckerdf62d712013-10-10 10:32:39 +1100473 * attack complexity approximately the same as O(2**bits).
474 * Values from NIST Special Publication 800-57: Recommendation for Key
475 * Management Part 1 (rev 3) limited by the recommended maximum value
476 * from RFC4419 section 3.
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000477 */
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000478u_int
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000479dh_estimate(int bits)
480{
Darren Tuckerdf62d712013-10-10 10:32:39 +1100481 if (bits <= 112)
482 return 2048;
Damien Miller8975ddf2003-12-17 16:33:53 +1100483 if (bits <= 128)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100484 return 3072;
Damien Miller8975ddf2003-12-17 16:33:53 +1100485 if (bits <= 192)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100486 return 7680;
487 return 8192;
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000488}
Marcus Folkesson6b373e42017-10-28 19:48:39 +0200489
490#endif /* WITH_OPENSSL */