1323134Sdes/* $OpenBSD: dh.c,v 1.62 2016/12/15 21:20:41 dtucker Exp $ */
269587Sgreen/*
369587Sgreen * Copyright (c) 2000 Niels Provos.  All rights reserved.
469587Sgreen *
569587Sgreen * Redistribution and use in source and binary forms, with or without
669587Sgreen * modification, are permitted provided that the following conditions
769587Sgreen * are met:
869587Sgreen * 1. Redistributions of source code must retain the above copyright
969587Sgreen *    notice, this list of conditions and the following disclaimer.
1069587Sgreen * 2. Redistributions in binary form must reproduce the above copyright
1169587Sgreen *    notice, this list of conditions and the following disclaimer in the
1269587Sgreen *    documentation and/or other materials provided with the distribution.
1369587Sgreen *
1469587Sgreen * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1569587Sgreen * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1669587Sgreen * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1769587Sgreen * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1869587Sgreen * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1969587Sgreen * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2069587Sgreen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2169587Sgreen * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2269587Sgreen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2369587Sgreen * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2469587Sgreen */
2569587Sgreen
2669587Sgreen#include "includes.h"
2769587Sgreen
2869587Sgreen
2969587Sgreen#include <openssl/bn.h>
3069587Sgreen#include <openssl/dh.h>
3169587Sgreen
32323129Sdes#include <errno.h>
33162852Sdes#include <stdarg.h>
34162852Sdes#include <stdio.h>
35162852Sdes#include <stdlib.h>
36162852Sdes#include <string.h>
37294332Sdes#include <limits.h>
38162852Sdes
3969587Sgreen#include "dh.h"
4076259Sgreen#include "pathnames.h"
4176259Sgreen#include "log.h"
4276259Sgreen#include "misc.h"
43294332Sdes#include "ssherr.h"
4469587Sgreen
4592555Sdesstatic int
4669587Sgreenparse_prime(int linenum, char *line, struct dhgroup *dhg)
4769587Sgreen{
4869587Sgreen	char *cp, *arg;
4969587Sgreen	char *strsize, *gen, *prime;
50162852Sdes	const char *errstr = NULL;
51181111Sdes	long long n;
5269587Sgreen
53255767Sdes	dhg->p = dhg->g = NULL;
5469587Sgreen	cp = line;
55162852Sdes	if ((arg = strdelim(&cp)) == NULL)
56162852Sdes		return 0;
5769587Sgreen	/* Ignore leading whitespace */
5869587Sgreen	if (*arg == '\0')
5969587Sgreen		arg = strdelim(&cp);
60106121Sdes	if (!arg || !*arg || *arg == '#')
6169587Sgreen		return 0;
6269587Sgreen
6369587Sgreen	/* time */
6469587Sgreen	if (cp == NULL || *arg == '\0')
65255767Sdes		goto truncated;
6669587Sgreen	arg = strsep(&cp, " "); /* type */
6769587Sgreen	if (cp == NULL || *arg == '\0')
68255767Sdes		goto truncated;
69181111Sdes	/* Ensure this is a safe prime */
70181111Sdes	n = strtonum(arg, 0, 5, &errstr);
71255767Sdes	if (errstr != NULL || n != MODULI_TYPE_SAFE) {
72255767Sdes		error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
73181111Sdes		goto fail;
74255767Sdes	}
7569587Sgreen	arg = strsep(&cp, " "); /* tests */
7669587Sgreen	if (cp == NULL || *arg == '\0')
77255767Sdes		goto truncated;
78181111Sdes	/* Ensure prime has been tested and is not composite */
79181111Sdes	n = strtonum(arg, 0, 0x1f, &errstr);
80181111Sdes	if (errstr != NULL ||
81255767Sdes	    (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
82255767Sdes		error("moduli:%d: invalid moduli tests flag", linenum);
83181111Sdes		goto fail;
84255767Sdes	}
8569587Sgreen	arg = strsep(&cp, " "); /* tries */
8669587Sgreen	if (cp == NULL || *arg == '\0')
87255767Sdes		goto truncated;
88181111Sdes	n = strtonum(arg, 0, 1<<30, &errstr);
89255767Sdes	if (errstr != NULL || n == 0) {
90255767Sdes		error("moduli:%d: invalid primality trial count", linenum);
91181111Sdes		goto fail;
92255767Sdes	}
9369587Sgreen	strsize = strsep(&cp, " "); /* size */
9469587Sgreen	if (cp == NULL || *strsize == '\0' ||
95204917Sdes	    (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
96255767Sdes	    errstr) {
97255767Sdes		error("moduli:%d: invalid prime length", linenum);
9869587Sgreen		goto fail;
99255767Sdes	}
10076259Sgreen	/* The whole group is one bit larger */
10176259Sgreen	dhg->size++;
10269587Sgreen	gen = strsep(&cp, " "); /* gen */
10369587Sgreen	if (cp == NULL || *gen == '\0')
104255767Sdes		goto truncated;
10569587Sgreen	prime = strsep(&cp, " "); /* prime */
106255767Sdes	if (cp != NULL || *prime == '\0') {
107255767Sdes truncated:
108255767Sdes		error("moduli:%d: truncated", linenum);
10969587Sgreen		goto fail;
110255767Sdes	}
11169587Sgreen
112294332Sdes	if ((dhg->g = BN_new()) == NULL ||
113294332Sdes	    (dhg->p = BN_new()) == NULL) {
114294332Sdes		error("parse_prime: BN_new failed");
115294332Sdes		goto fail;
116294332Sdes	}
117255767Sdes	if (BN_hex2bn(&dhg->g, gen) == 0) {
118255767Sdes		error("moduli:%d: could not parse generator value", linenum);
119255767Sdes		goto fail;
120255767Sdes	}
121255767Sdes	if (BN_hex2bn(&dhg->p, prime) == 0) {
122255767Sdes		error("moduli:%d: could not parse prime value", linenum);
123255767Sdes		goto fail;
124255767Sdes	}
125255767Sdes	if (BN_num_bits(dhg->p) != dhg->size) {
126255767Sdes		error("moduli:%d: prime has wrong size: actual %d listed %d",
127255767Sdes		    linenum, BN_num_bits(dhg->p), dhg->size - 1);
128255767Sdes		goto fail;
129255767Sdes	}
130255767Sdes	if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
131255767Sdes		error("moduli:%d: generator is invalid", linenum);
132255767Sdes		goto fail;
133255767Sdes	}
134255767Sdes	return 1;
13576259Sgreen
13669587Sgreen fail:
137255767Sdes	if (dhg->g != NULL)
138255767Sdes		BN_clear_free(dhg->g);
139255767Sdes	if (dhg->p != NULL)
140255767Sdes		BN_clear_free(dhg->p);
141255767Sdes	dhg->g = dhg->p = NULL;
142255767Sdes	return 0;
14369587Sgreen}
14469587Sgreen
14569587SgreenDH *
14676259Sgreenchoose_dh(int min, int wantbits, int max)
14769587Sgreen{
14869587Sgreen	FILE *f;
149128456Sdes	char line[4096];
15069587Sgreen	int best, bestcount, which;
15169587Sgreen	int linenum;
15269587Sgreen	struct dhgroup dhg;
15369587Sgreen
154323129Sdes	if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
155323134Sdes		logit("WARNING: could not open %s (%s), using fixed modulus",
156323129Sdes		    _PATH_DH_MODULI, strerror(errno));
157294336Sdes		return (dh_new_group_fallback(max));
15869587Sgreen	}
15969587Sgreen
16069587Sgreen	linenum = 0;
16169587Sgreen	best = bestcount = 0;
16269587Sgreen	while (fgets(line, sizeof(line), f)) {
16369587Sgreen		linenum++;
16469587Sgreen		if (!parse_prime(linenum, line, &dhg))
16569587Sgreen			continue;
16692555Sdes		BN_clear_free(dhg.g);
16792555Sdes		BN_clear_free(dhg.p);
16869587Sgreen
16976259Sgreen		if (dhg.size > max || dhg.size < min)
17076259Sgreen			continue;
17176259Sgreen
17276259Sgreen		if ((dhg.size > wantbits && dhg.size < best) ||
17376259Sgreen		    (dhg.size > best && best < wantbits)) {
17469587Sgreen			best = dhg.size;
17569587Sgreen			bestcount = 0;
17669587Sgreen		}
17769587Sgreen		if (dhg.size == best)
17869587Sgreen			bestcount++;
17969587Sgreen	}
18092555Sdes	rewind(f);
18169587Sgreen
18269587Sgreen	if (bestcount == 0) {
18392555Sdes		fclose(f);
184323129Sdes		logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
185294336Sdes		return (dh_new_group_fallback(max));
18669587Sgreen	}
18769587Sgreen
18869587Sgreen	linenum = 0;
189181111Sdes	which = arc4random_uniform(bestcount);
19069587Sgreen	while (fgets(line, sizeof(line), f)) {
19169587Sgreen		if (!parse_prime(linenum, line, &dhg))
19269587Sgreen			continue;
19376259Sgreen		if ((dhg.size > max || dhg.size < min) ||
19476259Sgreen		    dhg.size != best ||
19576259Sgreen		    linenum++ != which) {
19692555Sdes			BN_clear_free(dhg.g);
19792555Sdes			BN_clear_free(dhg.p);
19869587Sgreen			continue;
19969587Sgreen		}
20069587Sgreen		break;
20169587Sgreen	}
20269587Sgreen	fclose(f);
203294332Sdes	if (linenum != which+1) {
204294332Sdes		logit("WARNING: line %d disappeared in %s, giving up",
205323129Sdes		    which, _PATH_DH_MODULI);
206294336Sdes		return (dh_new_group_fallback(max));
207294332Sdes	}
20869587Sgreen
20969587Sgreen	return (dh_new_group(dhg.g, dhg.p));
21069587Sgreen}
21176259Sgreen
212137015Sdes/* diffie-hellman-groupN-sha1 */
21376259Sgreen
21476259Sgreenint
21576259Sgreendh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
21676259Sgreen{
21776259Sgreen	int i;
21876259Sgreen	int n = BN_num_bits(dh_pub);
21976259Sgreen	int bits_set = 0;
220162852Sdes	BIGNUM *tmp;
22176259Sgreen
22276259Sgreen	if (dh_pub->neg) {
223181111Sdes		logit("invalid public DH value: negative");
22476259Sgreen		return 0;
22576259Sgreen	}
226162852Sdes	if (BN_cmp(dh_pub, BN_value_one()) != 1) {	/* pub_exp <= 1 */
227162852Sdes		logit("invalid public DH value: <= 1");
228162852Sdes		return 0;
229162852Sdes	}
230162852Sdes
231181111Sdes	if ((tmp = BN_new()) == NULL) {
232181111Sdes		error("%s: BN_new failed", __func__);
233181111Sdes		return 0;
234181111Sdes	}
235162852Sdes	if (!BN_sub(tmp, dh->p, BN_value_one()) ||
236162852Sdes	    BN_cmp(dh_pub, tmp) != -1) {		/* pub_exp > p-2 */
237162852Sdes		BN_clear_free(tmp);
238162852Sdes		logit("invalid public DH value: >= p-1");
239162852Sdes		return 0;
240162852Sdes	}
241162852Sdes	BN_clear_free(tmp);
242162852Sdes
24376259Sgreen	for (i = 0; i <= n; i++)
24476259Sgreen		if (BN_is_bit_set(dh_pub, i))
24576259Sgreen			bits_set++;
246113908Sdes	debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
24776259Sgreen
248323129Sdes	/*
249323129Sdes	 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
250323129Sdes	 */
251323129Sdes	if (bits_set < 4) {
252323129Sdes		logit("invalid public DH value (%d/%d)",
253323129Sdes		   bits_set, BN_num_bits(dh->p));
254323129Sdes		return 0;
255323129Sdes	}
256323129Sdes	return 1;
25776259Sgreen}
25876259Sgreen
259294332Sdesint
26076259Sgreendh_gen_key(DH *dh, int need)
26176259Sgreen{
262261320Sdes	int pbits;
26376259Sgreen
264294332Sdes	if (need < 0 || dh->p == NULL ||
265294332Sdes	    (pbits = BN_num_bits(dh->p)) <= 0 ||
266294336Sdes	    need > INT_MAX / 2 || 2 * need > pbits)
267294332Sdes		return SSH_ERR_INVALID_ARGUMENT;
268323129Sdes	if (need < 256)
269323129Sdes		need = 256;
270323129Sdes	/*
271323129Sdes	 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
272323129Sdes	 * so double requested need here.
273323129Sdes	 */
274323134Sdes	dh->length = MINIMUM(need * 2, pbits - 1);
275294332Sdes	if (DH_generate_key(dh) == 0 ||
276294332Sdes	    !dh_pub_is_valid(dh, dh->pub_key)) {
277294332Sdes		BN_clear_free(dh->priv_key);
278294332Sdes		return SSH_ERR_LIBCRYPTO_ERROR;
279294332Sdes	}
280294332Sdes	return 0;
28176259Sgreen}
28276259Sgreen
28376259SgreenDH *
28476259Sgreendh_new_group_asc(const char *gen, const char *modulus)
28576259Sgreen{
28676259Sgreen	DH *dh;
28776259Sgreen
28892555Sdes	if ((dh = DH_new()) == NULL)
289294332Sdes		return NULL;
290294332Sdes	if (BN_hex2bn(&dh->p, modulus) == 0 ||
291294332Sdes	    BN_hex2bn(&dh->g, gen) == 0) {
292294332Sdes		DH_free(dh);
293294332Sdes		return NULL;
294294332Sdes	}
29576259Sgreen	return (dh);
29676259Sgreen}
29776259Sgreen
29876259Sgreen/*
29976259Sgreen * This just returns the group, we still need to generate the exchange
30076259Sgreen * value.
30176259Sgreen */
30276259Sgreen
30376259SgreenDH *
30476259Sgreendh_new_group(BIGNUM *gen, BIGNUM *modulus)
30576259Sgreen{
30676259Sgreen	DH *dh;
30776259Sgreen
30892555Sdes	if ((dh = DH_new()) == NULL)
309294332Sdes		return NULL;
31076259Sgreen	dh->p = modulus;
31176259Sgreen	dh->g = gen;
31276259Sgreen
31376259Sgreen	return (dh);
31476259Sgreen}
31576259Sgreen
316323129Sdes/* rfc2409 "Second Oakley Group" (1024 bits) */
31776259SgreenDH *
31876259Sgreendh_new_group1(void)
31976259Sgreen{
32076259Sgreen	static char *gen = "2", *group1 =
32176259Sgreen	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
32276259Sgreen	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
32376259Sgreen	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
32476259Sgreen	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
32576259Sgreen	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
32676259Sgreen	    "FFFFFFFF" "FFFFFFFF";
32776259Sgreen
32876259Sgreen	return (dh_new_group_asc(gen, group1));
32976259Sgreen}
33076259Sgreen
331323129Sdes/* rfc3526 group 14 "2048-bit MODP Group" */
332137015SdesDH *
333137015Sdesdh_new_group14(void)
334137015Sdes{
335137015Sdes	static char *gen = "2", *group14 =
336137015Sdes	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
337137015Sdes	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
338137015Sdes	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
339137015Sdes	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
340137015Sdes	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
341137015Sdes	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
342137015Sdes	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
343137015Sdes	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
344137015Sdes	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
345137015Sdes	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
346137015Sdes	    "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
347137015Sdes
348137015Sdes	return (dh_new_group_asc(gen, group14));
349137015Sdes}
350137015Sdes
351323129Sdes/* rfc3526 group 16 "4096-bit MODP Group" */
352294336SdesDH *
353323129Sdesdh_new_group16(void)
354294336Sdes{
355294336Sdes	static char *gen = "2", *group16 =
356294336Sdes	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
357294336Sdes	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
358294336Sdes	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
359294336Sdes	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
360294336Sdes	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
361294336Sdes	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
362294336Sdes	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
363294336Sdes	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
364294336Sdes	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
365294336Sdes	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
366294336Sdes	    "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
367294336Sdes	    "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
368294336Sdes	    "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
369294336Sdes	    "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
370294336Sdes	    "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
371294336Sdes	    "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
372294336Sdes	    "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
373294336Sdes	    "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
374294336Sdes	    "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
375294336Sdes	    "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
376294336Sdes	    "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
377294336Sdes	    "FFFFFFFF" "FFFFFFFF";
378294336Sdes
379323129Sdes	return (dh_new_group_asc(gen, group16));
380323129Sdes}
381323129Sdes
382323129Sdes/* rfc3526 group 18 "8192-bit MODP Group" */
383323129SdesDH *
384323129Sdesdh_new_group18(void)
385323129Sdes{
386323129Sdes	static char *gen = "2", *group16 =
387323129Sdes	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
388323129Sdes	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
389323129Sdes	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
390323129Sdes	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
391323129Sdes	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
392323129Sdes	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
393323129Sdes	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
394323129Sdes	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
395323129Sdes	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
396323129Sdes	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
397323129Sdes	    "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
398323129Sdes	    "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
399323129Sdes	    "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
400323129Sdes	    "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
401323129Sdes	    "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
402323129Sdes	    "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
403323129Sdes	    "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
404323129Sdes	    "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
405323129Sdes	    "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
406323129Sdes	    "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
407323129Sdes	    "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
408323129Sdes	    "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
409323129Sdes	    "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
410323129Sdes	    "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
411323129Sdes	    "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
412323129Sdes	    "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
413323129Sdes	    "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
414323129Sdes	    "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
415323129Sdes	    "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
416323129Sdes	    "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
417323129Sdes	    "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
418323129Sdes	    "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
419323129Sdes	    "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
420323129Sdes	    "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
421323129Sdes	    "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
422323129Sdes	    "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
423323129Sdes	    "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
424323129Sdes	    "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
425323129Sdes	    "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
426323129Sdes	    "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
427323129Sdes	    "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
428323129Sdes	    "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
429323129Sdes	    "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
430323129Sdes
431323129Sdes	return (dh_new_group_asc(gen, group16));
432323129Sdes}
433323129Sdes
434323129Sdes/* Select fallback group used by DH-GEX if moduli file cannot be read. */
435323129SdesDH *
436323129Sdesdh_new_group_fallback(int max)
437323129Sdes{
438323129Sdes	debug3("%s: requested max size %d", __func__, max);
439323129Sdes	if (max < 3072) {
440323129Sdes		debug3("using 2k bit group 14");
441294336Sdes		return dh_new_group14();
442323129Sdes	} else if (max < 6144) {
443323129Sdes		debug3("using 4k bit group 16");
444323129Sdes		return dh_new_group16();
445294336Sdes	}
446323129Sdes	debug3("using 8k bit group 18");
447323129Sdes	return dh_new_group18();
448294336Sdes}
449294336Sdes
450294336Sdes/*
45176259Sgreen * Estimates the group order for a Diffie-Hellman group that has an
452261320Sdes * attack complexity approximately the same as O(2**bits).
453261320Sdes * Values from NIST Special Publication 800-57: Recommendation for Key
454261320Sdes * Management Part 1 (rev 3) limited by the recommended maximum value
455261320Sdes * from RFC4419 section 3.
45676259Sgreen */
457294332Sdesu_int
45876259Sgreendh_estimate(int bits)
45976259Sgreen{
460261320Sdes	if (bits <= 112)
461261320Sdes		return 2048;
462126274Sdes	if (bits <= 128)
463261320Sdes		return 3072;
464126274Sdes	if (bits <= 192)
465261320Sdes		return 7680;
466261320Sdes	return 8192;
46776259Sgreen}
468