blob: a98d39ed5ff42a34d1928b98dae6061cf1b844f5 [file] [log] [blame]
djm@openbsd.org81f16202018-11-09 02:56:22 +00001/* $OpenBSD: dh.c,v 1.69 2018/11/09 02:56:22 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 }
millert@openbsd.org5e532322018-09-17 15:40:14 +0000191 which = arc4random_uniform(bestcount);
Damien Miller874d77b2000-10-14 16:23:11 +1100192
Damien Miller874d77b2000-10-14 16:23:11 +1100193 linenum = 0;
millert@openbsd.org5e532322018-09-17 15:40:14 +0000194 bestcount = 0;
markus@openbsd.org7f906352018-06-06 18:29:18 +0000195 while (getline(&line, &linesize, f) != -1) {
millert@openbsd.org5e532322018-09-17 15:40:14 +0000196 linenum++;
Damien Miller874d77b2000-10-14 16:23:11 +1100197 if (!parse_prime(linenum, line, &dhg))
198 continue;
Ben Lindstrom5ba23b32001-04-05 02:05:21 +0000199 if ((dhg.size > max || dhg.size < min) ||
200 dhg.size != best ||
millert@openbsd.org5e532322018-09-17 15:40:14 +0000201 bestcount++ != which) {
Damien Miller9ef95dd2002-01-22 23:10:33 +1100202 BN_clear_free(dhg.g);
203 BN_clear_free(dhg.p);
Damien Miller874d77b2000-10-14 16:23:11 +1100204 continue;
205 }
206 break;
207 }
markus@openbsd.org7f906352018-06-06 18:29:18 +0000208 free(line);
209 line = NULL;
Damien Miller874d77b2000-10-14 16:23:11 +1100210 fclose(f);
millert@openbsd.org5e532322018-09-17 15:40:14 +0000211 if (bestcount != which + 1) {
212 logit("WARNING: selected prime disappeared in %s, giving up",
213 _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000214 return (dh_new_group_fallback(max));
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000215 }
Damien Miller874d77b2000-10-14 16:23:11 +1100216
217 return (dh_new_group(dhg.g, dhg.p));
218}
Damien Miller9709f902001-03-30 10:50:10 +1000219
Damien Millerf675fc42004-06-15 10:30:09 +1000220/* diffie-hellman-groupN-sha1 */
Damien Miller9709f902001-03-30 10:50:10 +1000221
222int
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000223dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
Damien Miller9709f902001-03-30 10:50:10 +1000224{
225 int i;
226 int n = BN_num_bits(dh_pub);
227 int bits_set = 0;
Darren Tucker31cde682006-05-06 17:43:33 +1000228 BIGNUM *tmp;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000229 const BIGNUM *dh_p;
Damien Miller9709f902001-03-30 10:50:10 +1000230
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000231 DH_get0_pqg(dh, &dh_p, NULL, NULL);
232
233 if (BN_is_negative(dh_pub)) {
Damien Miller603077a2007-10-26 14:25:55 +1000234 logit("invalid public DH value: negative");
Damien Miller9709f902001-03-30 10:50:10 +1000235 return 0;
236 }
Darren Tucker31cde682006-05-06 17:43:33 +1000237 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
238 logit("invalid public DH value: <= 1");
239 return 0;
240 }
241
Damien Miller603077a2007-10-26 14:25:55 +1000242 if ((tmp = BN_new()) == NULL) {
243 error("%s: BN_new failed", __func__);
244 return 0;
245 }
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000246 if (!BN_sub(tmp, dh_p, BN_value_one()) ||
Darren Tucker31cde682006-05-06 17:43:33 +1000247 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
248 BN_clear_free(tmp);
249 logit("invalid public DH value: >= p-1");
250 return 0;
251 }
252 BN_clear_free(tmp);
253
Damien Miller9709f902001-03-30 10:50:10 +1000254 for (i = 0; i <= n; i++)
255 if (BN_is_bit_set(dh_pub, i))
256 bits_set++;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000257 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p));
Damien Miller9709f902001-03-30 10:50:10 +1000258
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000259 /*
260 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
261 */
262 if (bits_set < 4) {
263 logit("invalid public DH value (%d/%d)",
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000264 bits_set, BN_num_bits(dh_p));
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000265 return 0;
266 }
267 return 1;
Damien Miller9709f902001-03-30 10:50:10 +1000268}
269
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000270int
Damien Miller9709f902001-03-30 10:50:10 +1000271dh_gen_key(DH *dh, int need)
272{
Damien Miller0fde8ac2013-11-21 14:12:23 +1100273 int pbits;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000274 const BIGNUM *dh_p, *pub_key;
Damien Miller9709f902001-03-30 10:50:10 +1000275
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000276 DH_get0_pqg(dh, &dh_p, NULL, NULL);
277
278 if (need < 0 || dh_p == NULL ||
279 (pbits = BN_num_bits(dh_p)) <= 0 ||
djm@openbsd.orgb8afbe22015-03-26 06:59:28 +0000280 need > INT_MAX / 2 || 2 * need > pbits)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000281 return SSH_ERR_INVALID_ARGUMENT;
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000282 if (need < 256)
283 need = 256;
284 /*
285 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
286 * so double requested need here.
287 */
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000288 if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000289 return SSH_ERR_LIBCRYPTO_ERROR;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000290
291 if (DH_generate_key(dh) == 0)
292 return SSH_ERR_LIBCRYPTO_ERROR;
293 DH_get0_key(dh, &pub_key, NULL);
294 if (!dh_pub_is_valid(dh, pub_key))
295 return SSH_ERR_INVALID_FORMAT;
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000296 return 0;
Damien Miller9709f902001-03-30 10:50:10 +1000297}
298
299DH *
300dh_new_group_asc(const char *gen, const char *modulus)
301{
302 DH *dh;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000303 BIGNUM *dh_p = NULL, *dh_g = NULL;
Damien Miller9709f902001-03-30 10:50:10 +1000304
Damien Millerda755162002-01-22 23:09:22 +1100305 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000306 return NULL;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000307 if (BN_hex2bn(&dh_p, modulus) == 0 ||
308 BN_hex2bn(&dh_g, gen) == 0)
309 goto fail;
310 if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
311 goto fail;
312 return dh;
313 fail:
314 DH_free(dh);
315 BN_clear_free(dh_p);
316 BN_clear_free(dh_g);
317 return NULL;
Damien Miller9709f902001-03-30 10:50:10 +1000318}
319
320/*
321 * This just returns the group, we still need to generate the exchange
322 * value.
323 */
Damien Miller9709f902001-03-30 10:50:10 +1000324DH *
325dh_new_group(BIGNUM *gen, BIGNUM *modulus)
326{
327 DH *dh;
328
Damien Millerda755162002-01-22 23:09:22 +1100329 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000330 return NULL;
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000331 if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
332 DH_free(dh);
333 return NULL;
334 }
Damien Miller9709f902001-03-30 10:50:10 +1000335
djm@openbsd.org482d23b2018-09-13 02:08:33 +0000336 return dh;
Damien Miller9709f902001-03-30 10:50:10 +1000337}
338
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000339/* rfc2409 "Second Oakley Group" (1024 bits) */
Damien Miller9709f902001-03-30 10:50:10 +1000340DH *
341dh_new_group1(void)
342{
343 static char *gen = "2", *group1 =
344 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
345 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
346 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
347 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
348 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
349 "FFFFFFFF" "FFFFFFFF";
350
351 return (dh_new_group_asc(gen, group1));
352}
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000353
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000354/* rfc3526 group 14 "2048-bit MODP Group" */
Damien Millerf675fc42004-06-15 10:30:09 +1000355DH *
356dh_new_group14(void)
357{
358 static char *gen = "2", *group14 =
359 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
360 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
361 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
362 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
363 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
364 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
365 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
366 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
367 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
368 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
369 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
370
371 return (dh_new_group_asc(gen, group14));
372}
373
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000374/* rfc3526 group 16 "4096-bit MODP Group" */
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000375DH *
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000376dh_new_group16(void)
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000377{
378 static char *gen = "2", *group16 =
379 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
380 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
381 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
382 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
383 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
384 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
385 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
386 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
387 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
388 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
389 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
390 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
391 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
392 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
393 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
394 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
395 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
396 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
397 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
398 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
399 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
400 "FFFFFFFF" "FFFFFFFF";
401
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000402 return (dh_new_group_asc(gen, group16));
403}
404
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000405/* rfc3526 group 18 "8192-bit MODP Group" */
406DH *
407dh_new_group18(void)
408{
djm@openbsd.org81f16202018-11-09 02:56:22 +0000409 static char *gen = "2", *group18 =
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000410 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
411 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
412 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
413 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
414 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
415 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
416 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
417 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
418 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
419 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
420 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
421 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
422 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
423 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
424 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
425 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
426 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
427 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
428 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
429 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
430 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
431 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
432 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
433 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
434 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
435 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
436 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
437 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
438 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
439 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
440 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
441 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
442 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
443 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
444 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
445 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
446 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
447 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
448 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
449 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
450 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
451 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
452 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
453
djm@openbsd.org81f16202018-11-09 02:56:22 +0000454 return (dh_new_group_asc(gen, group18));
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000455}
456
457/* Select fallback group used by DH-GEX if moduli file cannot be read. */
458DH *
459dh_new_group_fallback(int max)
460{
461 debug3("%s: requested max size %d", __func__, max);
462 if (max < 3072) {
463 debug3("using 2k bit group 14");
464 return dh_new_group14();
465 } else if (max < 6144) {
466 debug3("using 4k bit group 16");
467 return dh_new_group16();
468 }
469 debug3("using 8k bit group 18");
470 return dh_new_group18();
471}
472
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000473/*
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000474 * Estimates the group order for a Diffie-Hellman group that has an
Darren Tuckerdf62d712013-10-10 10:32:39 +1100475 * attack complexity approximately the same as O(2**bits).
476 * Values from NIST Special Publication 800-57: Recommendation for Key
477 * Management Part 1 (rev 3) limited by the recommended maximum value
478 * from RFC4419 section 3.
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000479 */
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000480u_int
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000481dh_estimate(int bits)
482{
Darren Tuckerdf62d712013-10-10 10:32:39 +1100483 if (bits <= 112)
484 return 2048;
Damien Miller8975ddf2003-12-17 16:33:53 +1100485 if (bits <= 128)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100486 return 3072;
Damien Miller8975ddf2003-12-17 16:33:53 +1100487 if (bits <= 192)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100488 return 7680;
489 return 8192;
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000490}
Marcus Folkesson6b373e42017-10-28 19:48:39 +0200491
492#endif /* WITH_OPENSSL */