blob: 167d3714ed3122e158c382aa77d519f817a692d3 [file] [log] [blame]
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +00001/* $OpenBSD: dh.c,v 1.60 2016/05/02 10:26:04 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
deraadt@openbsd.org087266e2015-01-20 23:14:00 +000028#include <sys/param.h> /* MIN */
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:
Damien Millerbbeb1da2013-07-18 16:10:49 +1000138 if (dhg->g != NULL)
139 BN_clear_free(dhg->g);
140 if (dhg->p != NULL)
141 BN_clear_free(dhg->p);
142 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;
Darren Tuckerc56c7ef2004-02-29 20:13:34 +1100150 char line[4096];
Damien Miller874d77b2000-10-14 16:23:11 +1100151 int best, bestcount, which;
152 int linenum;
153 struct dhgroup dhg;
154
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000155 if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
156 logit("WARNING: could open open %s (%s), using fixed modulus",
157 _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;
163 while (fgets(line, sizeof(line), f)) {
164 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 }
Ben Lindstromaf738802001-06-25 04:18:59 +0000181 rewind(f);
Damien Miller874d77b2000-10-14 16:23:11 +1100182
183 if (bestcount == 0) {
Ben Lindstromaf738802001-06-25 04:18:59 +0000184 fclose(f);
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000185 logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000186 return (dh_new_group_fallback(max));
Damien Miller874d77b2000-10-14 16:23:11 +1100187 }
188
Damien Miller874d77b2000-10-14 16:23:11 +1100189 linenum = 0;
Damien Miller354c48c2008-05-19 14:50:00 +1000190 which = arc4random_uniform(bestcount);
Damien Miller874d77b2000-10-14 16:23:11 +1100191 while (fgets(line, sizeof(line), f)) {
192 if (!parse_prime(linenum, line, &dhg))
193 continue;
Ben Lindstrom5ba23b32001-04-05 02:05:21 +0000194 if ((dhg.size > max || dhg.size < min) ||
195 dhg.size != best ||
196 linenum++ != which) {
Damien Miller9ef95dd2002-01-22 23:10:33 +1100197 BN_clear_free(dhg.g);
198 BN_clear_free(dhg.p);
Damien Miller874d77b2000-10-14 16:23:11 +1100199 continue;
200 }
201 break;
202 }
203 fclose(f);
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000204 if (linenum != which+1) {
205 logit("WARNING: line %d disappeared in %s, giving up",
dtucker@openbsd.orgfdfbf452016-03-31 05:24:06 +0000206 which, _PATH_DH_MODULI);
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000207 return (dh_new_group_fallback(max));
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000208 }
Damien Miller874d77b2000-10-14 16:23:11 +1100209
210 return (dh_new_group(dhg.g, dhg.p));
211}
Damien Miller9709f902001-03-30 10:50:10 +1000212
Damien Millerf675fc42004-06-15 10:30:09 +1000213/* diffie-hellman-groupN-sha1 */
Damien Miller9709f902001-03-30 10:50:10 +1000214
215int
216dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
217{
218 int i;
219 int n = BN_num_bits(dh_pub);
220 int bits_set = 0;
Darren Tucker31cde682006-05-06 17:43:33 +1000221 BIGNUM *tmp;
Damien Miller9709f902001-03-30 10:50:10 +1000222
223 if (dh_pub->neg) {
Damien Miller603077a2007-10-26 14:25:55 +1000224 logit("invalid public DH value: negative");
Damien Miller9709f902001-03-30 10:50:10 +1000225 return 0;
226 }
Darren Tucker31cde682006-05-06 17:43:33 +1000227 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
228 logit("invalid public DH value: <= 1");
229 return 0;
230 }
231
Damien Miller603077a2007-10-26 14:25:55 +1000232 if ((tmp = BN_new()) == NULL) {
233 error("%s: BN_new failed", __func__);
234 return 0;
235 }
Darren Tucker31cde682006-05-06 17:43:33 +1000236 if (!BN_sub(tmp, dh->p, BN_value_one()) ||
237 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
238 BN_clear_free(tmp);
239 logit("invalid public DH value: >= p-1");
240 return 0;
241 }
242 BN_clear_free(tmp);
243
Damien Miller9709f902001-03-30 10:50:10 +1000244 for (i = 0; i <= n; i++)
245 if (BN_is_bit_set(dh_pub, i))
246 bits_set++;
Ben Lindstrom1f530832002-12-23 02:03:02 +0000247 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
Damien Miller9709f902001-03-30 10:50:10 +1000248
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000249 /*
250 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
251 */
252 if (bits_set < 4) {
253 logit("invalid public DH value (%d/%d)",
254 bits_set, BN_num_bits(dh->p));
255 return 0;
256 }
257 return 1;
Damien Miller9709f902001-03-30 10:50:10 +1000258}
259
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000260int
Damien Miller9709f902001-03-30 10:50:10 +1000261dh_gen_key(DH *dh, int need)
262{
Damien Miller0fde8ac2013-11-21 14:12:23 +1100263 int pbits;
Damien Miller9709f902001-03-30 10:50:10 +1000264
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000265 if (need < 0 || dh->p == NULL ||
266 (pbits = BN_num_bits(dh->p)) <= 0 ||
djm@openbsd.orgb8afbe22015-03-26 06:59:28 +0000267 need > INT_MAX / 2 || 2 * need > pbits)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000268 return SSH_ERR_INVALID_ARGUMENT;
djm@openbsd.org6e7f68c2016-02-28 22:27:00 +0000269 if (need < 256)
270 need = 256;
271 /*
272 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
273 * so double requested need here.
274 */
Damien Miller0fde8ac2013-11-21 14:12:23 +1100275 dh->length = MIN(need * 2, pbits - 1);
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000276 if (DH_generate_key(dh) == 0 ||
277 !dh_pub_is_valid(dh, dh->pub_key)) {
278 BN_clear_free(dh->priv_key);
279 return SSH_ERR_LIBCRYPTO_ERROR;
280 }
281 return 0;
Damien Miller9709f902001-03-30 10:50:10 +1000282}
283
284DH *
285dh_new_group_asc(const char *gen, const char *modulus)
286{
287 DH *dh;
Damien Miller9709f902001-03-30 10:50:10 +1000288
Damien Millerda755162002-01-22 23:09:22 +1100289 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000290 return NULL;
291 if (BN_hex2bn(&dh->p, modulus) == 0 ||
292 BN_hex2bn(&dh->g, gen) == 0) {
293 DH_free(dh);
294 return NULL;
295 }
Damien Miller9709f902001-03-30 10:50:10 +1000296 return (dh);
297}
298
299/*
300 * This just returns the group, we still need to generate the exchange
301 * value.
302 */
303
304DH *
305dh_new_group(BIGNUM *gen, BIGNUM *modulus)
306{
307 DH *dh;
308
Damien Millerda755162002-01-22 23:09:22 +1100309 if ((dh = DH_new()) == NULL)
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000310 return NULL;
Damien Miller9709f902001-03-30 10:50:10 +1000311 dh->p = modulus;
312 dh->g = gen;
313
314 return (dh);
315}
316
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000317/* rfc2409 "Second Oakley Group" (1024 bits) */
Damien Miller9709f902001-03-30 10:50:10 +1000318DH *
319dh_new_group1(void)
320{
321 static char *gen = "2", *group1 =
322 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
323 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
324 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
325 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
326 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
327 "FFFFFFFF" "FFFFFFFF";
328
329 return (dh_new_group_asc(gen, group1));
330}
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000331
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000332/* rfc3526 group 14 "2048-bit MODP Group" */
Damien Millerf675fc42004-06-15 10:30:09 +1000333DH *
334dh_new_group14(void)
335{
336 static char *gen = "2", *group14 =
337 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
338 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
339 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
340 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
341 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
342 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
343 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
344 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
345 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
346 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
347 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
348
349 return (dh_new_group_asc(gen, group14));
350}
351
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000352/* rfc3526 group 16 "4096-bit MODP Group" */
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000353DH *
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000354dh_new_group16(void)
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000355{
356 static char *gen = "2", *group16 =
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" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
368 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
369 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
370 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
371 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
372 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
373 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
374 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
375 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
376 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
377 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
378 "FFFFFFFF" "FFFFFFFF";
379
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000380 return (dh_new_group_asc(gen, group16));
381}
382
djm@openbsd.org0e8eeec2016-05-02 10:26:04 +0000383/* rfc3526 group 18 "8192-bit MODP Group" */
384DH *
385dh_new_group18(void)
386{
387 static char *gen = "2", *group16 =
388 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
389 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
390 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
391 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
392 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
393 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
394 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
395 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
396 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
397 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
398 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
399 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
400 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
401 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
402 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
403 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
404 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
405 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
406 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
407 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
408 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
409 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
410 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
411 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
412 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
413 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
414 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
415 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
416 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
417 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
418 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
419 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
420 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
421 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
422 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
423 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
424 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
425 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
426 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
427 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
428 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
429 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
430 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
431
432 return (dh_new_group_asc(gen, group16));
433}
434
435/* Select fallback group used by DH-GEX if moduli file cannot be read. */
436DH *
437dh_new_group_fallback(int max)
438{
439 debug3("%s: requested max size %d", __func__, max);
440 if (max < 3072) {
441 debug3("using 2k bit group 14");
442 return dh_new_group14();
443 } else if (max < 6144) {
444 debug3("using 4k bit group 16");
445 return dh_new_group16();
446 }
447 debug3("using 8k bit group 18");
448 return dh_new_group18();
449}
450
dtucker@openbsd.org40f64292015-05-27 23:39:18 +0000451/*
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000452 * Estimates the group order for a Diffie-Hellman group that has an
Darren Tuckerdf62d712013-10-10 10:32:39 +1100453 * attack complexity approximately the same as O(2**bits).
454 * Values from NIST Special Publication 800-57: Recommendation for Key
455 * Management Part 1 (rev 3) limited by the recommended maximum value
456 * from RFC4419 section 3.
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000457 */
markus@openbsd.org57d10cb2015-01-19 20:16:15 +0000458u_int
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000459dh_estimate(int bits)
460{
Darren Tuckerdf62d712013-10-10 10:32:39 +1100461 if (bits <= 112)
462 return 2048;
Damien Miller8975ddf2003-12-17 16:33:53 +1100463 if (bits <= 128)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100464 return 3072;
Damien Miller8975ddf2003-12-17 16:33:53 +1100465 if (bits <= 192)
Darren Tuckerdf62d712013-10-10 10:32:39 +1100466 return 7680;
467 return 8192;
Ben Lindstrom20d7c7b2001-04-04 01:56:17 +0000468}