1323124Sdes/* $OpenBSD: dh.c,v 1.60 2016/05/02 10:26:04 djm 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
28295367Sdes#include <sys/param.h>	/* MIN */
2969587Sgreen
3069587Sgreen#include <openssl/bn.h>
3169587Sgreen#include <openssl/dh.h>
3269587Sgreen
33323124Sdes#include <errno.h>
34162852Sdes#include <stdarg.h>
35162852Sdes#include <stdio.h>
36162852Sdes#include <stdlib.h>
37162852Sdes#include <string.h>
38295367Sdes#include <limits.h>
39162852Sdes
4069587Sgreen#include "dh.h"
4176259Sgreen#include "pathnames.h"
4276259Sgreen#include "log.h"
4376259Sgreen#include "misc.h"
44295367Sdes#include "ssherr.h"
4569587Sgreen
4692555Sdesstatic int
4769587Sgreenparse_prime(int linenum, char *line, struct dhgroup *dhg)
4869587Sgreen{
4969587Sgreen	char *cp, *arg;
5069587Sgreen	char *strsize, *gen, *prime;
51162852Sdes	const char *errstr = NULL;
52181111Sdes	long long n;
5369587Sgreen
54255767Sdes	dhg->p = dhg->g = NULL;
5569587Sgreen	cp = line;
56162852Sdes	if ((arg = strdelim(&cp)) == NULL)
57162852Sdes		return 0;
5869587Sgreen	/* Ignore leading whitespace */
5969587Sgreen	if (*arg == '\0')
6069587Sgreen		arg = strdelim(&cp);
61106121Sdes	if (!arg || !*arg || *arg == '#')
6269587Sgreen		return 0;
6369587Sgreen
6469587Sgreen	/* time */
6569587Sgreen	if (cp == NULL || *arg == '\0')
66255767Sdes		goto truncated;
6769587Sgreen	arg = strsep(&cp, " "); /* type */
6869587Sgreen	if (cp == NULL || *arg == '\0')
69255767Sdes		goto truncated;
70181111Sdes	/* Ensure this is a safe prime */
71181111Sdes	n = strtonum(arg, 0, 5, &errstr);
72255767Sdes	if (errstr != NULL || n != MODULI_TYPE_SAFE) {
73255767Sdes		error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
74181111Sdes		goto fail;
75255767Sdes	}
7669587Sgreen	arg = strsep(&cp, " "); /* tests */
7769587Sgreen	if (cp == NULL || *arg == '\0')
78255767Sdes		goto truncated;
79181111Sdes	/* Ensure prime has been tested and is not composite */
80181111Sdes	n = strtonum(arg, 0, 0x1f, &errstr);
81181111Sdes	if (errstr != NULL ||
82255767Sdes	    (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
83255767Sdes		error("moduli:%d: invalid moduli tests flag", linenum);
84181111Sdes		goto fail;
85255767Sdes	}
8669587Sgreen	arg = strsep(&cp, " "); /* tries */
8769587Sgreen	if (cp == NULL || *arg == '\0')
88255767Sdes		goto truncated;
89181111Sdes	n = strtonum(arg, 0, 1<<30, &errstr);
90255767Sdes	if (errstr != NULL || n == 0) {
91255767Sdes		error("moduli:%d: invalid primality trial count", linenum);
92181111Sdes		goto fail;
93255767Sdes	}
9469587Sgreen	strsize = strsep(&cp, " "); /* size */
9569587Sgreen	if (cp == NULL || *strsize == '\0' ||
96204917Sdes	    (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
97255767Sdes	    errstr) {
98255767Sdes		error("moduli:%d: invalid prime length", linenum);
9969587Sgreen		goto fail;
100255767Sdes	}
10176259Sgreen	/* The whole group is one bit larger */
10276259Sgreen	dhg->size++;
10369587Sgreen	gen = strsep(&cp, " "); /* gen */
10469587Sgreen	if (cp == NULL || *gen == '\0')
105255767Sdes		goto truncated;
10669587Sgreen	prime = strsep(&cp, " "); /* prime */
107255767Sdes	if (cp != NULL || *prime == '\0') {
108255767Sdes truncated:
109255767Sdes		error("moduli:%d: truncated", linenum);
11069587Sgreen		goto fail;
111255767Sdes	}
11269587Sgreen
113295367Sdes	if ((dhg->g = BN_new()) == NULL ||
114295367Sdes	    (dhg->p = BN_new()) == NULL) {
115295367Sdes		error("parse_prime: BN_new failed");
116295367Sdes		goto fail;
117295367Sdes	}
118255767Sdes	if (BN_hex2bn(&dhg->g, gen) == 0) {
119255767Sdes		error("moduli:%d: could not parse generator value", linenum);
120255767Sdes		goto fail;
121255767Sdes	}
122255767Sdes	if (BN_hex2bn(&dhg->p, prime) == 0) {
123255767Sdes		error("moduli:%d: could not parse prime value", linenum);
124255767Sdes		goto fail;
125255767Sdes	}
126255767Sdes	if (BN_num_bits(dhg->p) != dhg->size) {
127255767Sdes		error("moduli:%d: prime has wrong size: actual %d listed %d",
128255767Sdes		    linenum, BN_num_bits(dhg->p), dhg->size - 1);
129255767Sdes		goto fail;
130255767Sdes	}
131255767Sdes	if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
132255767Sdes		error("moduli:%d: generator is invalid", linenum);
133255767Sdes		goto fail;
134255767Sdes	}
135255767Sdes	return 1;
13676259Sgreen
13769587Sgreen fail:
138255767Sdes	if (dhg->g != NULL)
139255767Sdes		BN_clear_free(dhg->g);
140255767Sdes	if (dhg->p != NULL)
141255767Sdes		BN_clear_free(dhg->p);
142255767Sdes	dhg->g = dhg->p = NULL;
143255767Sdes	return 0;
14469587Sgreen}
14569587Sgreen
14669587SgreenDH *
14776259Sgreenchoose_dh(int min, int wantbits, int max)
14869587Sgreen{
14969587Sgreen	FILE *f;
150128456Sdes	char line[4096];
15169587Sgreen	int best, bestcount, which;
15269587Sgreen	int linenum;
15369587Sgreen	struct dhgroup dhg;
15469587Sgreen
155323124Sdes	if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
156323124Sdes		logit("WARNING: could open open %s (%s), using fixed modulus",
157323124Sdes		    _PATH_DH_MODULI, strerror(errno));
158295367Sdes		return (dh_new_group_fallback(max));
15969587Sgreen	}
16069587Sgreen
16169587Sgreen	linenum = 0;
16269587Sgreen	best = bestcount = 0;
16369587Sgreen	while (fgets(line, sizeof(line), f)) {
16469587Sgreen		linenum++;
16569587Sgreen		if (!parse_prime(linenum, line, &dhg))
16669587Sgreen			continue;
16792555Sdes		BN_clear_free(dhg.g);
16892555Sdes		BN_clear_free(dhg.p);
16969587Sgreen
17076259Sgreen		if (dhg.size > max || dhg.size < min)
17176259Sgreen			continue;
17276259Sgreen
17376259Sgreen		if ((dhg.size > wantbits && dhg.size < best) ||
17476259Sgreen		    (dhg.size > best && best < wantbits)) {
17569587Sgreen			best = dhg.size;
17669587Sgreen			bestcount = 0;
17769587Sgreen		}
17869587Sgreen		if (dhg.size == best)
17969587Sgreen			bestcount++;
18069587Sgreen	}
18192555Sdes	rewind(f);
18269587Sgreen
18369587Sgreen	if (bestcount == 0) {
18492555Sdes		fclose(f);
185323124Sdes		logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
186295367Sdes		return (dh_new_group_fallback(max));
18769587Sgreen	}
18869587Sgreen
18969587Sgreen	linenum = 0;
190181111Sdes	which = arc4random_uniform(bestcount);
19169587Sgreen	while (fgets(line, sizeof(line), f)) {
19269587Sgreen		if (!parse_prime(linenum, line, &dhg))
19369587Sgreen			continue;
19476259Sgreen		if ((dhg.size > max || dhg.size < min) ||
19576259Sgreen		    dhg.size != best ||
19676259Sgreen		    linenum++ != which) {
19792555Sdes			BN_clear_free(dhg.g);
19892555Sdes			BN_clear_free(dhg.p);
19969587Sgreen			continue;
20069587Sgreen		}
20169587Sgreen		break;
20269587Sgreen	}
20369587Sgreen	fclose(f);
204295367Sdes	if (linenum != which+1) {
205295367Sdes		logit("WARNING: line %d disappeared in %s, giving up",
206323124Sdes		    which, _PATH_DH_MODULI);
207295367Sdes		return (dh_new_group_fallback(max));
208295367Sdes	}
20969587Sgreen
21069587Sgreen	return (dh_new_group(dhg.g, dhg.p));
21169587Sgreen}
21276259Sgreen
213137015Sdes/* diffie-hellman-groupN-sha1 */
21476259Sgreen
21576259Sgreenint
21676259Sgreendh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
21776259Sgreen{
21876259Sgreen	int i;
21976259Sgreen	int n = BN_num_bits(dh_pub);
22076259Sgreen	int bits_set = 0;
221162852Sdes	BIGNUM *tmp;
22276259Sgreen
22376259Sgreen	if (dh_pub->neg) {
224181111Sdes		logit("invalid public DH value: negative");
22576259Sgreen		return 0;
22676259Sgreen	}
227162852Sdes	if (BN_cmp(dh_pub, BN_value_one()) != 1) {	/* pub_exp <= 1 */
228162852Sdes		logit("invalid public DH value: <= 1");
229162852Sdes		return 0;
230162852Sdes	}
231162852Sdes
232181111Sdes	if ((tmp = BN_new()) == NULL) {
233181111Sdes		error("%s: BN_new failed", __func__);
234181111Sdes		return 0;
235181111Sdes	}
236162852Sdes	if (!BN_sub(tmp, dh->p, BN_value_one()) ||
237162852Sdes	    BN_cmp(dh_pub, tmp) != -1) {		/* pub_exp > p-2 */
238162852Sdes		BN_clear_free(tmp);
239162852Sdes		logit("invalid public DH value: >= p-1");
240162852Sdes		return 0;
241162852Sdes	}
242162852Sdes	BN_clear_free(tmp);
243162852Sdes
24476259Sgreen	for (i = 0; i <= n; i++)
24576259Sgreen		if (BN_is_bit_set(dh_pub, i))
24676259Sgreen			bits_set++;
247113908Sdes	debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
24876259Sgreen
249323124Sdes	/*
250323124Sdes	 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
251323124Sdes	 */
252323124Sdes	if (bits_set < 4) {
253323124Sdes		logit("invalid public DH value (%d/%d)",
254323124Sdes		   bits_set, BN_num_bits(dh->p));
255323124Sdes		return 0;
256323124Sdes	}
257323124Sdes	return 1;
25876259Sgreen}
25976259Sgreen
260295367Sdesint
26176259Sgreendh_gen_key(DH *dh, int need)
26276259Sgreen{
263262566Sdes	int pbits;
26476259Sgreen
265295367Sdes	if (need < 0 || dh->p == NULL ||
266295367Sdes	    (pbits = BN_num_bits(dh->p)) <= 0 ||
267295367Sdes	    need > INT_MAX / 2 || 2 * need > pbits)
268295367Sdes		return SSH_ERR_INVALID_ARGUMENT;
269323124Sdes	if (need < 256)
270323124Sdes		need = 256;
271323124Sdes	/*
272323124Sdes	 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
273323124Sdes	 * so double requested need here.
274323124Sdes	 */
275262566Sdes	dh->length = MIN(need * 2, pbits - 1);
276295367Sdes	if (DH_generate_key(dh) == 0 ||
277295367Sdes	    !dh_pub_is_valid(dh, dh->pub_key)) {
278295367Sdes		BN_clear_free(dh->priv_key);
279295367Sdes		return SSH_ERR_LIBCRYPTO_ERROR;
280295367Sdes	}
281295367Sdes	return 0;
28276259Sgreen}
28376259Sgreen
28476259SgreenDH *
28576259Sgreendh_new_group_asc(const char *gen, const char *modulus)
28676259Sgreen{
28776259Sgreen	DH *dh;
28876259Sgreen
28992555Sdes	if ((dh = DH_new()) == NULL)
290295367Sdes		return NULL;
291295367Sdes	if (BN_hex2bn(&dh->p, modulus) == 0 ||
292295367Sdes	    BN_hex2bn(&dh->g, gen) == 0) {
293295367Sdes		DH_free(dh);
294295367Sdes		return NULL;
295295367Sdes	}
29676259Sgreen	return (dh);
29776259Sgreen}
29876259Sgreen
29976259Sgreen/*
30076259Sgreen * This just returns the group, we still need to generate the exchange
30176259Sgreen * value.
30276259Sgreen */
30376259Sgreen
30476259SgreenDH *
30576259Sgreendh_new_group(BIGNUM *gen, BIGNUM *modulus)
30676259Sgreen{
30776259Sgreen	DH *dh;
30876259Sgreen
30992555Sdes	if ((dh = DH_new()) == NULL)
310295367Sdes		return NULL;
31176259Sgreen	dh->p = modulus;
31276259Sgreen	dh->g = gen;
31376259Sgreen
31476259Sgreen	return (dh);
31576259Sgreen}
31676259Sgreen
317323124Sdes/* rfc2409 "Second Oakley Group" (1024 bits) */
31876259SgreenDH *
31976259Sgreendh_new_group1(void)
32076259Sgreen{
32176259Sgreen	static char *gen = "2", *group1 =
32276259Sgreen	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
32376259Sgreen	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
32476259Sgreen	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
32576259Sgreen	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
32676259Sgreen	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
32776259Sgreen	    "FFFFFFFF" "FFFFFFFF";
32876259Sgreen
32976259Sgreen	return (dh_new_group_asc(gen, group1));
33076259Sgreen}
33176259Sgreen
332323124Sdes/* rfc3526 group 14 "2048-bit MODP Group" */
333137015SdesDH *
334137015Sdesdh_new_group14(void)
335137015Sdes{
336137015Sdes	static char *gen = "2", *group14 =
337137015Sdes	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
338137015Sdes	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
339137015Sdes	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
340137015Sdes	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
341137015Sdes	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
342137015Sdes	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
343137015Sdes	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
344137015Sdes	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
345137015Sdes	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
346137015Sdes	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
347137015Sdes	    "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
348137015Sdes
349137015Sdes	return (dh_new_group_asc(gen, group14));
350137015Sdes}
351137015Sdes
352323124Sdes/* rfc3526 group 16 "4096-bit MODP Group" */
353295367SdesDH *
354323124Sdesdh_new_group16(void)
355295367Sdes{
356295367Sdes	static char *gen = "2", *group16 =
357295367Sdes	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
358295367Sdes	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
359295367Sdes	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
360295367Sdes	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
361295367Sdes	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
362295367Sdes	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
363295367Sdes	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
364295367Sdes	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
365295367Sdes	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
366295367Sdes	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
367295367Sdes	    "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
368295367Sdes	    "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
369295367Sdes	    "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
370295367Sdes	    "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
371295367Sdes	    "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
372295367Sdes	    "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
373295367Sdes	    "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
374295367Sdes	    "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
375295367Sdes	    "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
376295367Sdes	    "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
377295367Sdes	    "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
378295367Sdes	    "FFFFFFFF" "FFFFFFFF";
379295367Sdes
380323124Sdes	return (dh_new_group_asc(gen, group16));
381323124Sdes}
382323124Sdes
383323124Sdes/* rfc3526 group 18 "8192-bit MODP Group" */
384323124SdesDH *
385323124Sdesdh_new_group18(void)
386323124Sdes{
387323124Sdes	static char *gen = "2", *group16 =
388323124Sdes	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
389323124Sdes	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
390323124Sdes	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
391323124Sdes	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
392323124Sdes	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
393323124Sdes	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
394323124Sdes	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
395323124Sdes	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
396323124Sdes	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
397323124Sdes	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
398323124Sdes	    "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
399323124Sdes	    "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
400323124Sdes	    "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
401323124Sdes	    "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
402323124Sdes	    "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
403323124Sdes	    "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
404323124Sdes	    "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
405323124Sdes	    "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
406323124Sdes	    "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
407323124Sdes	    "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
408323124Sdes	    "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
409323124Sdes	    "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
410323124Sdes	    "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
411323124Sdes	    "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
412323124Sdes	    "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
413323124Sdes	    "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
414323124Sdes	    "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
415323124Sdes	    "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
416323124Sdes	    "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
417323124Sdes	    "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
418323124Sdes	    "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
419323124Sdes	    "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
420323124Sdes	    "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
421323124Sdes	    "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
422323124Sdes	    "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
423323124Sdes	    "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
424323124Sdes	    "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
425323124Sdes	    "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
426323124Sdes	    "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
427323124Sdes	    "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
428323124Sdes	    "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
429323124Sdes	    "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
430323124Sdes	    "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
431323124Sdes
432323124Sdes	return (dh_new_group_asc(gen, group16));
433323124Sdes}
434323124Sdes
435323124Sdes/* Select fallback group used by DH-GEX if moduli file cannot be read. */
436323124SdesDH *
437323124Sdesdh_new_group_fallback(int max)
438323124Sdes{
439323124Sdes	debug3("%s: requested max size %d", __func__, max);
440323124Sdes	if (max < 3072) {
441323124Sdes		debug3("using 2k bit group 14");
442295367Sdes		return dh_new_group14();
443323124Sdes	} else if (max < 6144) {
444323124Sdes		debug3("using 4k bit group 16");
445323124Sdes		return dh_new_group16();
446295367Sdes	}
447323124Sdes	debug3("using 8k bit group 18");
448323124Sdes	return dh_new_group18();
449295367Sdes}
450295367Sdes
451295367Sdes/*
45276259Sgreen * Estimates the group order for a Diffie-Hellman group that has an
453262566Sdes * attack complexity approximately the same as O(2**bits).
454262566Sdes * Values from NIST Special Publication 800-57: Recommendation for Key
455262566Sdes * Management Part 1 (rev 3) limited by the recommended maximum value
456262566Sdes * from RFC4419 section 3.
45776259Sgreen */
458295367Sdesu_int
45976259Sgreendh_estimate(int bits)
46076259Sgreen{
461262566Sdes	if (bits <= 112)
462262566Sdes		return 2048;
463126274Sdes	if (bits <= 128)
464262566Sdes		return 3072;
465126274Sdes	if (bits <= 192)
466262566Sdes		return 7680;
467262566Sdes	return 8192;
46876259Sgreen}
469