xref: /freebsd/crypto/openssh/dh.c (revision 076ad2f836d5f49dc1375f1677335a48fe0d4b82)
1*076ad2f8SDag-Erling Smørgrav /* $OpenBSD: dh.c,v 1.60 2016/05/02 10:26:04 djm Exp $ */
25b9b2fafSBrian Feldman /*
35b9b2fafSBrian Feldman  * Copyright (c) 2000 Niels Provos.  All rights reserved.
45b9b2fafSBrian Feldman  *
55b9b2fafSBrian Feldman  * Redistribution and use in source and binary forms, with or without
65b9b2fafSBrian Feldman  * modification, are permitted provided that the following conditions
75b9b2fafSBrian Feldman  * are met:
85b9b2fafSBrian Feldman  * 1. Redistributions of source code must retain the above copyright
95b9b2fafSBrian Feldman  *    notice, this list of conditions and the following disclaimer.
105b9b2fafSBrian Feldman  * 2. Redistributions in binary form must reproduce the above copyright
115b9b2fafSBrian Feldman  *    notice, this list of conditions and the following disclaimer in the
125b9b2fafSBrian Feldman  *    documentation and/or other materials provided with the distribution.
135b9b2fafSBrian Feldman  *
145b9b2fafSBrian Feldman  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
155b9b2fafSBrian Feldman  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
165b9b2fafSBrian Feldman  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
175b9b2fafSBrian Feldman  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
185b9b2fafSBrian Feldman  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
195b9b2fafSBrian Feldman  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
205b9b2fafSBrian Feldman  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
215b9b2fafSBrian Feldman  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225b9b2fafSBrian Feldman  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
235b9b2fafSBrian Feldman  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245b9b2fafSBrian Feldman  */
255b9b2fafSBrian Feldman 
265b9b2fafSBrian Feldman #include "includes.h"
275b9b2fafSBrian Feldman 
28bc5531deSDag-Erling Smørgrav #include <sys/param.h>	/* MIN */
295b9b2fafSBrian Feldman 
305b9b2fafSBrian Feldman #include <openssl/bn.h>
315b9b2fafSBrian Feldman #include <openssl/dh.h>
325b9b2fafSBrian Feldman 
33*076ad2f8SDag-Erling Smørgrav #include <errno.h>
34761efaa7SDag-Erling Smørgrav #include <stdarg.h>
35761efaa7SDag-Erling Smørgrav #include <stdio.h>
36761efaa7SDag-Erling Smørgrav #include <stdlib.h>
37761efaa7SDag-Erling Smørgrav #include <string.h>
38bc5531deSDag-Erling Smørgrav #include <limits.h>
39761efaa7SDag-Erling Smørgrav 
405b9b2fafSBrian Feldman #include "dh.h"
411e8db6e2SBrian Feldman #include "pathnames.h"
421e8db6e2SBrian Feldman #include "log.h"
431e8db6e2SBrian Feldman #include "misc.h"
44bc5531deSDag-Erling Smørgrav #include "ssherr.h"
455b9b2fafSBrian Feldman 
46ae1f160dSDag-Erling Smørgrav static int
475b9b2fafSBrian Feldman parse_prime(int linenum, char *line, struct dhgroup *dhg)
485b9b2fafSBrian Feldman {
495b9b2fafSBrian Feldman 	char *cp, *arg;
505b9b2fafSBrian Feldman 	char *strsize, *gen, *prime;
51761efaa7SDag-Erling Smørgrav 	const char *errstr = NULL;
52d4af9e69SDag-Erling Smørgrav 	long long n;
535b9b2fafSBrian Feldman 
54e4a9863fSDag-Erling Smørgrav 	dhg->p = dhg->g = NULL;
555b9b2fafSBrian Feldman 	cp = line;
56761efaa7SDag-Erling Smørgrav 	if ((arg = strdelim(&cp)) == NULL)
57761efaa7SDag-Erling Smørgrav 		return 0;
585b9b2fafSBrian Feldman 	/* Ignore leading whitespace */
595b9b2fafSBrian Feldman 	if (*arg == '\0')
605b9b2fafSBrian Feldman 		arg = strdelim(&cp);
614b17dab0SDag-Erling Smørgrav 	if (!arg || !*arg || *arg == '#')
625b9b2fafSBrian Feldman 		return 0;
635b9b2fafSBrian Feldman 
645b9b2fafSBrian Feldman 	/* time */
655b9b2fafSBrian Feldman 	if (cp == NULL || *arg == '\0')
66e4a9863fSDag-Erling Smørgrav 		goto truncated;
675b9b2fafSBrian Feldman 	arg = strsep(&cp, " "); /* type */
685b9b2fafSBrian Feldman 	if (cp == NULL || *arg == '\0')
69e4a9863fSDag-Erling Smørgrav 		goto truncated;
70d4af9e69SDag-Erling Smørgrav 	/* Ensure this is a safe prime */
71d4af9e69SDag-Erling Smørgrav 	n = strtonum(arg, 0, 5, &errstr);
72e4a9863fSDag-Erling Smørgrav 	if (errstr != NULL || n != MODULI_TYPE_SAFE) {
73e4a9863fSDag-Erling Smørgrav 		error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
74d4af9e69SDag-Erling Smørgrav 		goto fail;
75e4a9863fSDag-Erling Smørgrav 	}
765b9b2fafSBrian Feldman 	arg = strsep(&cp, " "); /* tests */
775b9b2fafSBrian Feldman 	if (cp == NULL || *arg == '\0')
78e4a9863fSDag-Erling Smørgrav 		goto truncated;
79d4af9e69SDag-Erling Smørgrav 	/* Ensure prime has been tested and is not composite */
80d4af9e69SDag-Erling Smørgrav 	n = strtonum(arg, 0, 0x1f, &errstr);
81d4af9e69SDag-Erling Smørgrav 	if (errstr != NULL ||
82e4a9863fSDag-Erling Smørgrav 	    (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
83e4a9863fSDag-Erling Smørgrav 		error("moduli:%d: invalid moduli tests flag", linenum);
84d4af9e69SDag-Erling Smørgrav 		goto fail;
85e4a9863fSDag-Erling Smørgrav 	}
865b9b2fafSBrian Feldman 	arg = strsep(&cp, " "); /* tries */
875b9b2fafSBrian Feldman 	if (cp == NULL || *arg == '\0')
88e4a9863fSDag-Erling Smørgrav 		goto truncated;
89d4af9e69SDag-Erling Smørgrav 	n = strtonum(arg, 0, 1<<30, &errstr);
90e4a9863fSDag-Erling Smørgrav 	if (errstr != NULL || n == 0) {
91e4a9863fSDag-Erling Smørgrav 		error("moduli:%d: invalid primality trial count", linenum);
92d4af9e69SDag-Erling Smørgrav 		goto fail;
93e4a9863fSDag-Erling Smørgrav 	}
945b9b2fafSBrian Feldman 	strsize = strsep(&cp, " "); /* size */
955b9b2fafSBrian Feldman 	if (cp == NULL || *strsize == '\0' ||
96b15c8340SDag-Erling Smørgrav 	    (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
97e4a9863fSDag-Erling Smørgrav 	    errstr) {
98e4a9863fSDag-Erling Smørgrav 		error("moduli:%d: invalid prime length", linenum);
995b9b2fafSBrian Feldman 		goto fail;
100e4a9863fSDag-Erling Smørgrav 	}
1011e8db6e2SBrian Feldman 	/* The whole group is one bit larger */
1021e8db6e2SBrian Feldman 	dhg->size++;
1035b9b2fafSBrian Feldman 	gen = strsep(&cp, " "); /* gen */
1045b9b2fafSBrian Feldman 	if (cp == NULL || *gen == '\0')
105e4a9863fSDag-Erling Smørgrav 		goto truncated;
1065b9b2fafSBrian Feldman 	prime = strsep(&cp, " "); /* prime */
107e4a9863fSDag-Erling Smørgrav 	if (cp != NULL || *prime == '\0') {
108e4a9863fSDag-Erling Smørgrav  truncated:
109e4a9863fSDag-Erling Smørgrav 		error("moduli:%d: truncated", linenum);
1105b9b2fafSBrian Feldman 		goto fail;
111e4a9863fSDag-Erling Smørgrav 	}
1125b9b2fafSBrian Feldman 
113bc5531deSDag-Erling Smørgrav 	if ((dhg->g = BN_new()) == NULL ||
114bc5531deSDag-Erling Smørgrav 	    (dhg->p = BN_new()) == NULL) {
115bc5531deSDag-Erling Smørgrav 		error("parse_prime: BN_new failed");
116bc5531deSDag-Erling Smørgrav 		goto fail;
117bc5531deSDag-Erling Smørgrav 	}
118e4a9863fSDag-Erling Smørgrav 	if (BN_hex2bn(&dhg->g, gen) == 0) {
119e4a9863fSDag-Erling Smørgrav 		error("moduli:%d: could not parse generator value", linenum);
120e4a9863fSDag-Erling Smørgrav 		goto fail;
121e4a9863fSDag-Erling Smørgrav 	}
122e4a9863fSDag-Erling Smørgrav 	if (BN_hex2bn(&dhg->p, prime) == 0) {
123e4a9863fSDag-Erling Smørgrav 		error("moduli:%d: could not parse prime value", linenum);
124e4a9863fSDag-Erling Smørgrav 		goto fail;
125e4a9863fSDag-Erling Smørgrav 	}
126e4a9863fSDag-Erling Smørgrav 	if (BN_num_bits(dhg->p) != dhg->size) {
127e4a9863fSDag-Erling Smørgrav 		error("moduli:%d: prime has wrong size: actual %d listed %d",
128e4a9863fSDag-Erling Smørgrav 		    linenum, BN_num_bits(dhg->p), dhg->size - 1);
129e4a9863fSDag-Erling Smørgrav 		goto fail;
130e4a9863fSDag-Erling Smørgrav 	}
131e4a9863fSDag-Erling Smørgrav 	if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
132e4a9863fSDag-Erling Smørgrav 		error("moduli:%d: generator is invalid", linenum);
133e4a9863fSDag-Erling Smørgrav 		goto fail;
134e4a9863fSDag-Erling Smørgrav 	}
135e4a9863fSDag-Erling Smørgrav 	return 1;
1361e8db6e2SBrian Feldman 
1375b9b2fafSBrian Feldman  fail:
138e4a9863fSDag-Erling Smørgrav 	if (dhg->g != NULL)
139e4a9863fSDag-Erling Smørgrav 		BN_clear_free(dhg->g);
140e4a9863fSDag-Erling Smørgrav 	if (dhg->p != NULL)
141e4a9863fSDag-Erling Smørgrav 		BN_clear_free(dhg->p);
142e4a9863fSDag-Erling Smørgrav 	dhg->g = dhg->p = NULL;
143e4a9863fSDag-Erling Smørgrav 	return 0;
1445b9b2fafSBrian Feldman }
1455b9b2fafSBrian Feldman 
1465b9b2fafSBrian Feldman DH *
1471e8db6e2SBrian Feldman choose_dh(int min, int wantbits, int max)
1485b9b2fafSBrian Feldman {
1495b9b2fafSBrian Feldman 	FILE *f;
15052028650SDag-Erling Smørgrav 	char line[4096];
1515b9b2fafSBrian Feldman 	int best, bestcount, which;
1525b9b2fafSBrian Feldman 	int linenum;
1535b9b2fafSBrian Feldman 	struct dhgroup dhg;
1545b9b2fafSBrian Feldman 
155*076ad2f8SDag-Erling Smørgrav 	if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
156*076ad2f8SDag-Erling Smørgrav 		logit("WARNING: could open open %s (%s), using fixed modulus",
157*076ad2f8SDag-Erling Smørgrav 		    _PATH_DH_MODULI, strerror(errno));
158557f75e5SDag-Erling Smørgrav 		return (dh_new_group_fallback(max));
1595b9b2fafSBrian Feldman 	}
1605b9b2fafSBrian Feldman 
1615b9b2fafSBrian Feldman 	linenum = 0;
1625b9b2fafSBrian Feldman 	best = bestcount = 0;
1635b9b2fafSBrian Feldman 	while (fgets(line, sizeof(line), f)) {
1645b9b2fafSBrian Feldman 		linenum++;
1655b9b2fafSBrian Feldman 		if (!parse_prime(linenum, line, &dhg))
1665b9b2fafSBrian Feldman 			continue;
167ae1f160dSDag-Erling Smørgrav 		BN_clear_free(dhg.g);
168ae1f160dSDag-Erling Smørgrav 		BN_clear_free(dhg.p);
1695b9b2fafSBrian Feldman 
1701e8db6e2SBrian Feldman 		if (dhg.size > max || dhg.size < min)
1711e8db6e2SBrian Feldman 			continue;
1721e8db6e2SBrian Feldman 
1731e8db6e2SBrian Feldman 		if ((dhg.size > wantbits && dhg.size < best) ||
1741e8db6e2SBrian Feldman 		    (dhg.size > best && best < wantbits)) {
1755b9b2fafSBrian Feldman 			best = dhg.size;
1765b9b2fafSBrian Feldman 			bestcount = 0;
1775b9b2fafSBrian Feldman 		}
1785b9b2fafSBrian Feldman 		if (dhg.size == best)
1795b9b2fafSBrian Feldman 			bestcount++;
1805b9b2fafSBrian Feldman 	}
181ae1f160dSDag-Erling Smørgrav 	rewind(f);
1825b9b2fafSBrian Feldman 
1835b9b2fafSBrian Feldman 	if (bestcount == 0) {
184ae1f160dSDag-Erling Smørgrav 		fclose(f);
185*076ad2f8SDag-Erling Smørgrav 		logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
186557f75e5SDag-Erling Smørgrav 		return (dh_new_group_fallback(max));
1875b9b2fafSBrian Feldman 	}
1885b9b2fafSBrian Feldman 
1895b9b2fafSBrian Feldman 	linenum = 0;
190d4af9e69SDag-Erling Smørgrav 	which = arc4random_uniform(bestcount);
1915b9b2fafSBrian Feldman 	while (fgets(line, sizeof(line), f)) {
1925b9b2fafSBrian Feldman 		if (!parse_prime(linenum, line, &dhg))
1935b9b2fafSBrian Feldman 			continue;
1941e8db6e2SBrian Feldman 		if ((dhg.size > max || dhg.size < min) ||
1951e8db6e2SBrian Feldman 		    dhg.size != best ||
1961e8db6e2SBrian Feldman 		    linenum++ != which) {
197ae1f160dSDag-Erling Smørgrav 			BN_clear_free(dhg.g);
198ae1f160dSDag-Erling Smørgrav 			BN_clear_free(dhg.p);
1995b9b2fafSBrian Feldman 			continue;
2005b9b2fafSBrian Feldman 		}
2015b9b2fafSBrian Feldman 		break;
2025b9b2fafSBrian Feldman 	}
2035b9b2fafSBrian Feldman 	fclose(f);
204bc5531deSDag-Erling Smørgrav 	if (linenum != which+1) {
205bc5531deSDag-Erling Smørgrav 		logit("WARNING: line %d disappeared in %s, giving up",
206*076ad2f8SDag-Erling Smørgrav 		    which, _PATH_DH_MODULI);
207557f75e5SDag-Erling Smørgrav 		return (dh_new_group_fallback(max));
208bc5531deSDag-Erling Smørgrav 	}
2095b9b2fafSBrian Feldman 
2105b9b2fafSBrian Feldman 	return (dh_new_group(dhg.g, dhg.p));
2115b9b2fafSBrian Feldman }
2121e8db6e2SBrian Feldman 
213d74d50a8SDag-Erling Smørgrav /* diffie-hellman-groupN-sha1 */
2141e8db6e2SBrian Feldman 
2151e8db6e2SBrian Feldman int
2161e8db6e2SBrian Feldman dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
2171e8db6e2SBrian Feldman {
2181e8db6e2SBrian Feldman 	int i;
2191e8db6e2SBrian Feldman 	int n = BN_num_bits(dh_pub);
2201e8db6e2SBrian Feldman 	int bits_set = 0;
221761efaa7SDag-Erling Smørgrav 	BIGNUM *tmp;
2221e8db6e2SBrian Feldman 
2231e8db6e2SBrian Feldman 	if (dh_pub->neg) {
224d4af9e69SDag-Erling Smørgrav 		logit("invalid public DH value: negative");
2251e8db6e2SBrian Feldman 		return 0;
2261e8db6e2SBrian Feldman 	}
227761efaa7SDag-Erling Smørgrav 	if (BN_cmp(dh_pub, BN_value_one()) != 1) {	/* pub_exp <= 1 */
228761efaa7SDag-Erling Smørgrav 		logit("invalid public DH value: <= 1");
229761efaa7SDag-Erling Smørgrav 		return 0;
230761efaa7SDag-Erling Smørgrav 	}
231761efaa7SDag-Erling Smørgrav 
232d4af9e69SDag-Erling Smørgrav 	if ((tmp = BN_new()) == NULL) {
233d4af9e69SDag-Erling Smørgrav 		error("%s: BN_new failed", __func__);
234d4af9e69SDag-Erling Smørgrav 		return 0;
235d4af9e69SDag-Erling Smørgrav 	}
236761efaa7SDag-Erling Smørgrav 	if (!BN_sub(tmp, dh->p, BN_value_one()) ||
237761efaa7SDag-Erling Smørgrav 	    BN_cmp(dh_pub, tmp) != -1) {		/* pub_exp > p-2 */
238761efaa7SDag-Erling Smørgrav 		BN_clear_free(tmp);
239761efaa7SDag-Erling Smørgrav 		logit("invalid public DH value: >= p-1");
240761efaa7SDag-Erling Smørgrav 		return 0;
241761efaa7SDag-Erling Smørgrav 	}
242761efaa7SDag-Erling Smørgrav 	BN_clear_free(tmp);
243761efaa7SDag-Erling Smørgrav 
2441e8db6e2SBrian Feldman 	for (i = 0; i <= n; i++)
2451e8db6e2SBrian Feldman 		if (BN_is_bit_set(dh_pub, i))
2461e8db6e2SBrian Feldman 			bits_set++;
247d0c8c0bcSDag-Erling Smørgrav 	debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
2481e8db6e2SBrian Feldman 
249*076ad2f8SDag-Erling Smørgrav 	/*
250*076ad2f8SDag-Erling Smørgrav 	 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
251*076ad2f8SDag-Erling Smørgrav 	 */
252*076ad2f8SDag-Erling Smørgrav 	if (bits_set < 4) {
253*076ad2f8SDag-Erling Smørgrav 		logit("invalid public DH value (%d/%d)",
254*076ad2f8SDag-Erling Smørgrav 		   bits_set, BN_num_bits(dh->p));
2551e8db6e2SBrian Feldman 		return 0;
2561e8db6e2SBrian Feldman 	}
257*076ad2f8SDag-Erling Smørgrav 	return 1;
258*076ad2f8SDag-Erling Smørgrav }
2591e8db6e2SBrian Feldman 
260bc5531deSDag-Erling Smørgrav int
2611e8db6e2SBrian Feldman dh_gen_key(DH *dh, int need)
2621e8db6e2SBrian Feldman {
263f7167e0eSDag-Erling Smørgrav 	int pbits;
2641e8db6e2SBrian Feldman 
265bc5531deSDag-Erling Smørgrav 	if (need < 0 || dh->p == NULL ||
266bc5531deSDag-Erling Smørgrav 	    (pbits = BN_num_bits(dh->p)) <= 0 ||
267557f75e5SDag-Erling Smørgrav 	    need > INT_MAX / 2 || 2 * need > pbits)
268bc5531deSDag-Erling Smørgrav 		return SSH_ERR_INVALID_ARGUMENT;
269*076ad2f8SDag-Erling Smørgrav 	if (need < 256)
270*076ad2f8SDag-Erling Smørgrav 		need = 256;
271*076ad2f8SDag-Erling Smørgrav 	/*
272*076ad2f8SDag-Erling Smørgrav 	 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
273*076ad2f8SDag-Erling Smørgrav 	 * so double requested need here.
274*076ad2f8SDag-Erling Smørgrav 	 */
275f7167e0eSDag-Erling Smørgrav 	dh->length = MIN(need * 2, pbits - 1);
276bc5531deSDag-Erling Smørgrav 	if (DH_generate_key(dh) == 0 ||
277bc5531deSDag-Erling Smørgrav 	    !dh_pub_is_valid(dh, dh->pub_key)) {
278bc5531deSDag-Erling Smørgrav 		BN_clear_free(dh->priv_key);
279bc5531deSDag-Erling Smørgrav 		return SSH_ERR_LIBCRYPTO_ERROR;
280bc5531deSDag-Erling Smørgrav 	}
281bc5531deSDag-Erling Smørgrav 	return 0;
2821e8db6e2SBrian Feldman }
2831e8db6e2SBrian Feldman 
2841e8db6e2SBrian Feldman DH *
2851e8db6e2SBrian Feldman dh_new_group_asc(const char *gen, const char *modulus)
2861e8db6e2SBrian Feldman {
2871e8db6e2SBrian Feldman 	DH *dh;
2881e8db6e2SBrian Feldman 
289ae1f160dSDag-Erling Smørgrav 	if ((dh = DH_new()) == NULL)
290bc5531deSDag-Erling Smørgrav 		return NULL;
291bc5531deSDag-Erling Smørgrav 	if (BN_hex2bn(&dh->p, modulus) == 0 ||
292bc5531deSDag-Erling Smørgrav 	    BN_hex2bn(&dh->g, gen) == 0) {
293bc5531deSDag-Erling Smørgrav 		DH_free(dh);
294bc5531deSDag-Erling Smørgrav 		return NULL;
295bc5531deSDag-Erling Smørgrav 	}
2961e8db6e2SBrian Feldman 	return (dh);
2971e8db6e2SBrian Feldman }
2981e8db6e2SBrian Feldman 
2991e8db6e2SBrian Feldman /*
3001e8db6e2SBrian Feldman  * This just returns the group, we still need to generate the exchange
3011e8db6e2SBrian Feldman  * value.
3021e8db6e2SBrian Feldman  */
3031e8db6e2SBrian Feldman 
3041e8db6e2SBrian Feldman DH *
3051e8db6e2SBrian Feldman dh_new_group(BIGNUM *gen, BIGNUM *modulus)
3061e8db6e2SBrian Feldman {
3071e8db6e2SBrian Feldman 	DH *dh;
3081e8db6e2SBrian Feldman 
309ae1f160dSDag-Erling Smørgrav 	if ((dh = DH_new()) == NULL)
310bc5531deSDag-Erling Smørgrav 		return NULL;
3111e8db6e2SBrian Feldman 	dh->p = modulus;
3121e8db6e2SBrian Feldman 	dh->g = gen;
3131e8db6e2SBrian Feldman 
3141e8db6e2SBrian Feldman 	return (dh);
3151e8db6e2SBrian Feldman }
3161e8db6e2SBrian Feldman 
317*076ad2f8SDag-Erling Smørgrav /* rfc2409 "Second Oakley Group" (1024 bits) */
3181e8db6e2SBrian Feldman DH *
3191e8db6e2SBrian Feldman dh_new_group1(void)
3201e8db6e2SBrian Feldman {
3211e8db6e2SBrian Feldman 	static char *gen = "2", *group1 =
3221e8db6e2SBrian Feldman 	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
3231e8db6e2SBrian Feldman 	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
3241e8db6e2SBrian Feldman 	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
3251e8db6e2SBrian Feldman 	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
3261e8db6e2SBrian Feldman 	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
3271e8db6e2SBrian Feldman 	    "FFFFFFFF" "FFFFFFFF";
3281e8db6e2SBrian Feldman 
3291e8db6e2SBrian Feldman 	return (dh_new_group_asc(gen, group1));
3301e8db6e2SBrian Feldman }
3311e8db6e2SBrian Feldman 
332*076ad2f8SDag-Erling Smørgrav /* rfc3526 group 14 "2048-bit MODP Group" */
333d74d50a8SDag-Erling Smørgrav DH *
334d74d50a8SDag-Erling Smørgrav dh_new_group14(void)
335d74d50a8SDag-Erling Smørgrav {
336d74d50a8SDag-Erling Smørgrav 	static char *gen = "2", *group14 =
337d74d50a8SDag-Erling Smørgrav 	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
338d74d50a8SDag-Erling Smørgrav 	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
339d74d50a8SDag-Erling Smørgrav 	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
340d74d50a8SDag-Erling Smørgrav 	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
341d74d50a8SDag-Erling Smørgrav 	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
342d74d50a8SDag-Erling Smørgrav 	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
343d74d50a8SDag-Erling Smørgrav 	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
344d74d50a8SDag-Erling Smørgrav 	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
345d74d50a8SDag-Erling Smørgrav 	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
346d74d50a8SDag-Erling Smørgrav 	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
347d74d50a8SDag-Erling Smørgrav 	    "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
348d74d50a8SDag-Erling Smørgrav 
349d74d50a8SDag-Erling Smørgrav 	return (dh_new_group_asc(gen, group14));
350d74d50a8SDag-Erling Smørgrav }
351d74d50a8SDag-Erling Smørgrav 
352*076ad2f8SDag-Erling Smørgrav /* rfc3526 group 16 "4096-bit MODP Group" */
353557f75e5SDag-Erling Smørgrav DH *
354*076ad2f8SDag-Erling Smørgrav dh_new_group16(void)
355557f75e5SDag-Erling Smørgrav {
356557f75e5SDag-Erling Smørgrav 	static char *gen = "2", *group16 =
357557f75e5SDag-Erling Smørgrav 	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
358557f75e5SDag-Erling Smørgrav 	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
359557f75e5SDag-Erling Smørgrav 	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
360557f75e5SDag-Erling Smørgrav 	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
361557f75e5SDag-Erling Smørgrav 	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
362557f75e5SDag-Erling Smørgrav 	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
363557f75e5SDag-Erling Smørgrav 	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
364557f75e5SDag-Erling Smørgrav 	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
365557f75e5SDag-Erling Smørgrav 	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
366557f75e5SDag-Erling Smørgrav 	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
367557f75e5SDag-Erling Smørgrav 	    "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
368557f75e5SDag-Erling Smørgrav 	    "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
369557f75e5SDag-Erling Smørgrav 	    "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
370557f75e5SDag-Erling Smørgrav 	    "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
371557f75e5SDag-Erling Smørgrav 	    "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
372557f75e5SDag-Erling Smørgrav 	    "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
373557f75e5SDag-Erling Smørgrav 	    "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
374557f75e5SDag-Erling Smørgrav 	    "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
375557f75e5SDag-Erling Smørgrav 	    "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
376557f75e5SDag-Erling Smørgrav 	    "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
377557f75e5SDag-Erling Smørgrav 	    "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
378557f75e5SDag-Erling Smørgrav 	    "FFFFFFFF" "FFFFFFFF";
379557f75e5SDag-Erling Smørgrav 
380557f75e5SDag-Erling Smørgrav 	return (dh_new_group_asc(gen, group16));
381557f75e5SDag-Erling Smørgrav }
382557f75e5SDag-Erling Smørgrav 
383*076ad2f8SDag-Erling Smørgrav /* rfc3526 group 18 "8192-bit MODP Group" */
384*076ad2f8SDag-Erling Smørgrav DH *
385*076ad2f8SDag-Erling Smørgrav dh_new_group18(void)
386*076ad2f8SDag-Erling Smørgrav {
387*076ad2f8SDag-Erling Smørgrav 	static char *gen = "2", *group16 =
388*076ad2f8SDag-Erling Smørgrav 	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
389*076ad2f8SDag-Erling Smørgrav 	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
390*076ad2f8SDag-Erling Smørgrav 	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
391*076ad2f8SDag-Erling Smørgrav 	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
392*076ad2f8SDag-Erling Smørgrav 	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
393*076ad2f8SDag-Erling Smørgrav 	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
394*076ad2f8SDag-Erling Smørgrav 	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
395*076ad2f8SDag-Erling Smørgrav 	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
396*076ad2f8SDag-Erling Smørgrav 	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
397*076ad2f8SDag-Erling Smørgrav 	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
398*076ad2f8SDag-Erling Smørgrav 	    "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
399*076ad2f8SDag-Erling Smørgrav 	    "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
400*076ad2f8SDag-Erling Smørgrav 	    "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
401*076ad2f8SDag-Erling Smørgrav 	    "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
402*076ad2f8SDag-Erling Smørgrav 	    "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
403*076ad2f8SDag-Erling Smørgrav 	    "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
404*076ad2f8SDag-Erling Smørgrav 	    "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
405*076ad2f8SDag-Erling Smørgrav 	    "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
406*076ad2f8SDag-Erling Smørgrav 	    "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
407*076ad2f8SDag-Erling Smørgrav 	    "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
408*076ad2f8SDag-Erling Smørgrav 	    "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
409*076ad2f8SDag-Erling Smørgrav 	    "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
410*076ad2f8SDag-Erling Smørgrav 	    "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
411*076ad2f8SDag-Erling Smørgrav 	    "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
412*076ad2f8SDag-Erling Smørgrav 	    "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
413*076ad2f8SDag-Erling Smørgrav 	    "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
414*076ad2f8SDag-Erling Smørgrav 	    "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
415*076ad2f8SDag-Erling Smørgrav 	    "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
416*076ad2f8SDag-Erling Smørgrav 	    "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
417*076ad2f8SDag-Erling Smørgrav 	    "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
418*076ad2f8SDag-Erling Smørgrav 	    "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
419*076ad2f8SDag-Erling Smørgrav 	    "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
420*076ad2f8SDag-Erling Smørgrav 	    "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
421*076ad2f8SDag-Erling Smørgrav 	    "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
422*076ad2f8SDag-Erling Smørgrav 	    "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
423*076ad2f8SDag-Erling Smørgrav 	    "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
424*076ad2f8SDag-Erling Smørgrav 	    "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
425*076ad2f8SDag-Erling Smørgrav 	    "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
426*076ad2f8SDag-Erling Smørgrav 	    "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
427*076ad2f8SDag-Erling Smørgrav 	    "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
428*076ad2f8SDag-Erling Smørgrav 	    "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
429*076ad2f8SDag-Erling Smørgrav 	    "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
430*076ad2f8SDag-Erling Smørgrav 	    "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
431*076ad2f8SDag-Erling Smørgrav 
432*076ad2f8SDag-Erling Smørgrav 	return (dh_new_group_asc(gen, group16));
433*076ad2f8SDag-Erling Smørgrav }
434*076ad2f8SDag-Erling Smørgrav 
435*076ad2f8SDag-Erling Smørgrav /* Select fallback group used by DH-GEX if moduli file cannot be read. */
436*076ad2f8SDag-Erling Smørgrav DH *
437*076ad2f8SDag-Erling Smørgrav dh_new_group_fallback(int max)
438*076ad2f8SDag-Erling Smørgrav {
439*076ad2f8SDag-Erling Smørgrav 	debug3("%s: requested max size %d", __func__, max);
440*076ad2f8SDag-Erling Smørgrav 	if (max < 3072) {
441*076ad2f8SDag-Erling Smørgrav 		debug3("using 2k bit group 14");
442*076ad2f8SDag-Erling Smørgrav 		return dh_new_group14();
443*076ad2f8SDag-Erling Smørgrav 	} else if (max < 6144) {
444*076ad2f8SDag-Erling Smørgrav 		debug3("using 4k bit group 16");
445*076ad2f8SDag-Erling Smørgrav 		return dh_new_group16();
446*076ad2f8SDag-Erling Smørgrav 	}
447*076ad2f8SDag-Erling Smørgrav 	debug3("using 8k bit group 18");
448*076ad2f8SDag-Erling Smørgrav 	return dh_new_group18();
449*076ad2f8SDag-Erling Smørgrav }
450*076ad2f8SDag-Erling Smørgrav 
451557f75e5SDag-Erling Smørgrav /*
4521e8db6e2SBrian Feldman  * Estimates the group order for a Diffie-Hellman group that has an
453f7167e0eSDag-Erling Smørgrav  * attack complexity approximately the same as O(2**bits).
454f7167e0eSDag-Erling Smørgrav  * Values from NIST Special Publication 800-57: Recommendation for Key
455f7167e0eSDag-Erling Smørgrav  * Management Part 1 (rev 3) limited by the recommended maximum value
456f7167e0eSDag-Erling Smørgrav  * from RFC4419 section 3.
4571e8db6e2SBrian Feldman  */
458bc5531deSDag-Erling Smørgrav u_int
4591e8db6e2SBrian Feldman dh_estimate(int bits)
4601e8db6e2SBrian Feldman {
461f7167e0eSDag-Erling Smørgrav 	if (bits <= 112)
462f7167e0eSDag-Erling Smørgrav 		return 2048;
463efcad6b7SDag-Erling Smørgrav 	if (bits <= 128)
464f7167e0eSDag-Erling Smørgrav 		return 3072;
465efcad6b7SDag-Erling Smørgrav 	if (bits <= 192)
466f7167e0eSDag-Erling Smørgrav 		return 7680;
467f7167e0eSDag-Erling Smørgrav 	return 8192;
4681e8db6e2SBrian Feldman }
469