xref: /dflybsd-src/crypto/openssh/dh.c (revision 50a69bb51183a7916e776f2c9f5fa64c999f1a2f)
1*50a69bb5SSascha Wildner /* $OpenBSD: dh.c,v 1.74 2021/04/03 06:18:40 djm Exp $ */
218de8d7fSPeter Avalos /*
318de8d7fSPeter Avalos  * Copyright (c) 2000 Niels Provos.  All rights reserved.
418de8d7fSPeter Avalos  *
518de8d7fSPeter Avalos  * Redistribution and use in source and binary forms, with or without
618de8d7fSPeter Avalos  * modification, are permitted provided that the following conditions
718de8d7fSPeter Avalos  * are met:
818de8d7fSPeter Avalos  * 1. Redistributions of source code must retain the above copyright
918de8d7fSPeter Avalos  *    notice, this list of conditions and the following disclaimer.
1018de8d7fSPeter Avalos  * 2. Redistributions in binary form must reproduce the above copyright
1118de8d7fSPeter Avalos  *    notice, this list of conditions and the following disclaimer in the
1218de8d7fSPeter Avalos  *    documentation and/or other materials provided with the distribution.
1318de8d7fSPeter Avalos  *
1418de8d7fSPeter Avalos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1518de8d7fSPeter Avalos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1618de8d7fSPeter Avalos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1718de8d7fSPeter Avalos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1818de8d7fSPeter Avalos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1918de8d7fSPeter Avalos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2018de8d7fSPeter Avalos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2118de8d7fSPeter Avalos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2218de8d7fSPeter Avalos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2318de8d7fSPeter Avalos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2418de8d7fSPeter Avalos  */
2518de8d7fSPeter Avalos 
2618de8d7fSPeter Avalos #include "includes.h"
2718de8d7fSPeter Avalos 
28664f4763Szrj #ifdef WITH_OPENSSL
2918de8d7fSPeter Avalos 
30e9778795SPeter Avalos #include <errno.h>
3118de8d7fSPeter Avalos #include <stdarg.h>
3218de8d7fSPeter Avalos #include <stdio.h>
3318de8d7fSPeter Avalos #include <stdlib.h>
3418de8d7fSPeter Avalos #include <string.h>
35e9778795SPeter Avalos #include <limits.h>
3618de8d7fSPeter Avalos 
370cbfa66cSDaniel Fojt #include <openssl/bn.h>
380cbfa66cSDaniel Fojt #include <openssl/dh.h>
390cbfa66cSDaniel Fojt 
4018de8d7fSPeter Avalos #include "dh.h"
4118de8d7fSPeter Avalos #include "pathnames.h"
4218de8d7fSPeter Avalos #include "log.h"
4318de8d7fSPeter Avalos #include "misc.h"
44e9778795SPeter Avalos #include "ssherr.h"
4518de8d7fSPeter Avalos 
46664f4763Szrj #include "openbsd-compat/openssl-compat.h"
47664f4763Szrj 
48*50a69bb5SSascha Wildner static const char *moduli_filename;
49*50a69bb5SSascha Wildner 
dh_set_moduli_file(const char * filename)50*50a69bb5SSascha Wildner void dh_set_moduli_file(const char *filename)
51*50a69bb5SSascha Wildner {
52*50a69bb5SSascha Wildner 	moduli_filename = filename;
53*50a69bb5SSascha Wildner }
54*50a69bb5SSascha Wildner 
get_moduli_filename(void)55*50a69bb5SSascha Wildner static const char * get_moduli_filename(void)
56*50a69bb5SSascha Wildner {
57*50a69bb5SSascha Wildner 	return moduli_filename ? moduli_filename : _PATH_DH_MODULI;
58*50a69bb5SSascha Wildner }
59*50a69bb5SSascha Wildner 
6018de8d7fSPeter Avalos static int
parse_prime(int linenum,char * line,struct dhgroup * dhg)6118de8d7fSPeter Avalos parse_prime(int linenum, char *line, struct dhgroup *dhg)
6218de8d7fSPeter Avalos {
6318de8d7fSPeter Avalos 	char *cp, *arg;
6418de8d7fSPeter Avalos 	char *strsize, *gen, *prime;
6518de8d7fSPeter Avalos 	const char *errstr = NULL;
6618de8d7fSPeter Avalos 	long long n;
6718de8d7fSPeter Avalos 
6836e94dc5SPeter Avalos 	dhg->p = dhg->g = NULL;
6918de8d7fSPeter Avalos 	cp = line;
7018de8d7fSPeter Avalos 	if ((arg = strdelim(&cp)) == NULL)
7118de8d7fSPeter Avalos 		return 0;
7218de8d7fSPeter Avalos 	/* Ignore leading whitespace */
7318de8d7fSPeter Avalos 	if (*arg == '\0')
7418de8d7fSPeter Avalos 		arg = strdelim(&cp);
7518de8d7fSPeter Avalos 	if (!arg || !*arg || *arg == '#')
7618de8d7fSPeter Avalos 		return 0;
7718de8d7fSPeter Avalos 
7818de8d7fSPeter Avalos 	/* time */
7918de8d7fSPeter Avalos 	if (cp == NULL || *arg == '\0')
8036e94dc5SPeter Avalos 		goto truncated;
8118de8d7fSPeter Avalos 	arg = strsep(&cp, " "); /* type */
8218de8d7fSPeter Avalos 	if (cp == NULL || *arg == '\0')
8336e94dc5SPeter Avalos 		goto truncated;
8418de8d7fSPeter Avalos 	/* Ensure this is a safe prime */
8518de8d7fSPeter Avalos 	n = strtonum(arg, 0, 5, &errstr);
8636e94dc5SPeter Avalos 	if (errstr != NULL || n != MODULI_TYPE_SAFE) {
8736e94dc5SPeter Avalos 		error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
8818de8d7fSPeter Avalos 		goto fail;
8936e94dc5SPeter Avalos 	}
9018de8d7fSPeter Avalos 	arg = strsep(&cp, " "); /* tests */
9118de8d7fSPeter Avalos 	if (cp == NULL || *arg == '\0')
9236e94dc5SPeter Avalos 		goto truncated;
9318de8d7fSPeter Avalos 	/* Ensure prime has been tested and is not composite */
9418de8d7fSPeter Avalos 	n = strtonum(arg, 0, 0x1f, &errstr);
9518de8d7fSPeter Avalos 	if (errstr != NULL ||
9636e94dc5SPeter Avalos 	    (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
9736e94dc5SPeter Avalos 		error("moduli:%d: invalid moduli tests flag", linenum);
9818de8d7fSPeter Avalos 		goto fail;
9936e94dc5SPeter Avalos 	}
10018de8d7fSPeter Avalos 	arg = strsep(&cp, " "); /* tries */
10118de8d7fSPeter Avalos 	if (cp == NULL || *arg == '\0')
10236e94dc5SPeter Avalos 		goto truncated;
10318de8d7fSPeter Avalos 	n = strtonum(arg, 0, 1<<30, &errstr);
10436e94dc5SPeter Avalos 	if (errstr != NULL || n == 0) {
10536e94dc5SPeter Avalos 		error("moduli:%d: invalid primality trial count", linenum);
10618de8d7fSPeter Avalos 		goto fail;
10736e94dc5SPeter Avalos 	}
10818de8d7fSPeter Avalos 	strsize = strsep(&cp, " "); /* size */
10918de8d7fSPeter Avalos 	if (cp == NULL || *strsize == '\0' ||
110856ea928SPeter Avalos 	    (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
11136e94dc5SPeter Avalos 	    errstr) {
11236e94dc5SPeter Avalos 		error("moduli:%d: invalid prime length", linenum);
11318de8d7fSPeter Avalos 		goto fail;
11436e94dc5SPeter Avalos 	}
11518de8d7fSPeter Avalos 	/* The whole group is one bit larger */
11618de8d7fSPeter Avalos 	dhg->size++;
11718de8d7fSPeter Avalos 	gen = strsep(&cp, " "); /* gen */
11818de8d7fSPeter Avalos 	if (cp == NULL || *gen == '\0')
11936e94dc5SPeter Avalos 		goto truncated;
12018de8d7fSPeter Avalos 	prime = strsep(&cp, " "); /* prime */
12136e94dc5SPeter Avalos 	if (cp != NULL || *prime == '\0') {
12236e94dc5SPeter Avalos  truncated:
12336e94dc5SPeter Avalos 		error("moduli:%d: truncated", linenum);
12418de8d7fSPeter Avalos 		goto fail;
12536e94dc5SPeter Avalos 	}
12618de8d7fSPeter Avalos 
127e9778795SPeter Avalos 	if ((dhg->g = BN_new()) == NULL ||
128e9778795SPeter Avalos 	    (dhg->p = BN_new()) == NULL) {
129e9778795SPeter Avalos 		error("parse_prime: BN_new failed");
130e9778795SPeter Avalos 		goto fail;
131e9778795SPeter Avalos 	}
13236e94dc5SPeter Avalos 	if (BN_hex2bn(&dhg->g, gen) == 0) {
13336e94dc5SPeter Avalos 		error("moduli:%d: could not parse generator value", linenum);
13436e94dc5SPeter Avalos 		goto fail;
13536e94dc5SPeter Avalos 	}
13636e94dc5SPeter Avalos 	if (BN_hex2bn(&dhg->p, prime) == 0) {
13736e94dc5SPeter Avalos 		error("moduli:%d: could not parse prime value", linenum);
13836e94dc5SPeter Avalos 		goto fail;
13936e94dc5SPeter Avalos 	}
14036e94dc5SPeter Avalos 	if (BN_num_bits(dhg->p) != dhg->size) {
14136e94dc5SPeter Avalos 		error("moduli:%d: prime has wrong size: actual %d listed %d",
14236e94dc5SPeter Avalos 		    linenum, BN_num_bits(dhg->p), dhg->size - 1);
14336e94dc5SPeter Avalos 		goto fail;
14436e94dc5SPeter Avalos 	}
14536e94dc5SPeter Avalos 	if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
14636e94dc5SPeter Avalos 		error("moduli:%d: generator is invalid", linenum);
14736e94dc5SPeter Avalos 		goto fail;
14836e94dc5SPeter Avalos 	}
14936e94dc5SPeter Avalos 	return 1;
15018de8d7fSPeter Avalos 
15118de8d7fSPeter Avalos  fail:
15236e94dc5SPeter Avalos 	BN_clear_free(dhg->g);
15336e94dc5SPeter Avalos 	BN_clear_free(dhg->p);
15436e94dc5SPeter Avalos 	dhg->g = dhg->p = NULL;
15536e94dc5SPeter Avalos 	return 0;
15618de8d7fSPeter Avalos }
15718de8d7fSPeter Avalos 
15818de8d7fSPeter Avalos DH *
choose_dh(int min,int wantbits,int max)15918de8d7fSPeter Avalos choose_dh(int min, int wantbits, int max)
16018de8d7fSPeter Avalos {
16118de8d7fSPeter Avalos 	FILE *f;
162664f4763Szrj 	char *line = NULL;
163664f4763Szrj 	size_t linesize = 0;
164664f4763Szrj 	int best, bestcount, which, linenum;
16518de8d7fSPeter Avalos 	struct dhgroup dhg;
16618de8d7fSPeter Avalos 
167*50a69bb5SSascha Wildner 	if ((f = fopen(get_moduli_filename(), "r")) == NULL) {
168ce74bacaSMatthew Dillon 		logit("WARNING: could not open %s (%s), using fixed modulus",
169*50a69bb5SSascha Wildner 		    get_moduli_filename(), strerror(errno));
170e9778795SPeter Avalos 		return (dh_new_group_fallback(max));
17118de8d7fSPeter Avalos 	}
17218de8d7fSPeter Avalos 
17318de8d7fSPeter Avalos 	linenum = 0;
17418de8d7fSPeter Avalos 	best = bestcount = 0;
175664f4763Szrj 	while (getline(&line, &linesize, f) != -1) {
17618de8d7fSPeter Avalos 		linenum++;
17718de8d7fSPeter Avalos 		if (!parse_prime(linenum, line, &dhg))
17818de8d7fSPeter Avalos 			continue;
17918de8d7fSPeter Avalos 		BN_clear_free(dhg.g);
18018de8d7fSPeter Avalos 		BN_clear_free(dhg.p);
18118de8d7fSPeter Avalos 
18218de8d7fSPeter Avalos 		if (dhg.size > max || dhg.size < min)
18318de8d7fSPeter Avalos 			continue;
18418de8d7fSPeter Avalos 
18518de8d7fSPeter Avalos 		if ((dhg.size > wantbits && dhg.size < best) ||
18618de8d7fSPeter Avalos 		    (dhg.size > best && best < wantbits)) {
18718de8d7fSPeter Avalos 			best = dhg.size;
18818de8d7fSPeter Avalos 			bestcount = 0;
18918de8d7fSPeter Avalos 		}
19018de8d7fSPeter Avalos 		if (dhg.size == best)
19118de8d7fSPeter Avalos 			bestcount++;
19218de8d7fSPeter Avalos 	}
193664f4763Szrj 	free(line);
194664f4763Szrj 	line = NULL;
195664f4763Szrj 	linesize = 0;
19618de8d7fSPeter Avalos 	rewind(f);
19718de8d7fSPeter Avalos 
19818de8d7fSPeter Avalos 	if (bestcount == 0) {
19918de8d7fSPeter Avalos 		fclose(f);
200*50a69bb5SSascha Wildner 		logit("WARNING: no suitable primes in %s",
201*50a69bb5SSascha Wildner 		    get_moduli_filename());
202e9778795SPeter Avalos 		return (dh_new_group_fallback(max));
20318de8d7fSPeter Avalos 	}
204664f4763Szrj 	which = arc4random_uniform(bestcount);
20518de8d7fSPeter Avalos 
20618de8d7fSPeter Avalos 	linenum = 0;
207664f4763Szrj 	bestcount = 0;
208664f4763Szrj 	while (getline(&line, &linesize, f) != -1) {
209664f4763Szrj 		linenum++;
21018de8d7fSPeter Avalos 		if (!parse_prime(linenum, line, &dhg))
21118de8d7fSPeter Avalos 			continue;
21218de8d7fSPeter Avalos 		if ((dhg.size > max || dhg.size < min) ||
21318de8d7fSPeter Avalos 		    dhg.size != best ||
214664f4763Szrj 		    bestcount++ != which) {
21518de8d7fSPeter Avalos 			BN_clear_free(dhg.g);
21618de8d7fSPeter Avalos 			BN_clear_free(dhg.p);
21718de8d7fSPeter Avalos 			continue;
21818de8d7fSPeter Avalos 		}
21918de8d7fSPeter Avalos 		break;
22018de8d7fSPeter Avalos 	}
221664f4763Szrj 	free(line);
222664f4763Szrj 	line = NULL;
22318de8d7fSPeter Avalos 	fclose(f);
224664f4763Szrj 	if (bestcount != which + 1) {
225664f4763Szrj 		logit("WARNING: selected prime disappeared in %s, giving up",
226*50a69bb5SSascha Wildner 		    get_moduli_filename());
227e9778795SPeter Avalos 		return (dh_new_group_fallback(max));
228e9778795SPeter Avalos 	}
22918de8d7fSPeter Avalos 
23018de8d7fSPeter Avalos 	return (dh_new_group(dhg.g, dhg.p));
23118de8d7fSPeter Avalos }
23218de8d7fSPeter Avalos 
23318de8d7fSPeter Avalos /* diffie-hellman-groupN-sha1 */
23418de8d7fSPeter Avalos 
23518de8d7fSPeter Avalos int
dh_pub_is_valid(const DH * dh,const BIGNUM * dh_pub)236664f4763Szrj dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
23718de8d7fSPeter Avalos {
23818de8d7fSPeter Avalos 	int i;
23918de8d7fSPeter Avalos 	int n = BN_num_bits(dh_pub);
24018de8d7fSPeter Avalos 	int bits_set = 0;
24118de8d7fSPeter Avalos 	BIGNUM *tmp;
242664f4763Szrj 	const BIGNUM *dh_p;
24318de8d7fSPeter Avalos 
244664f4763Szrj 	DH_get0_pqg(dh, &dh_p, NULL, NULL);
245664f4763Szrj 
246664f4763Szrj 	if (BN_is_negative(dh_pub)) {
24718de8d7fSPeter Avalos 		logit("invalid public DH value: negative");
24818de8d7fSPeter Avalos 		return 0;
24918de8d7fSPeter Avalos 	}
25018de8d7fSPeter Avalos 	if (BN_cmp(dh_pub, BN_value_one()) != 1) {	/* pub_exp <= 1 */
25118de8d7fSPeter Avalos 		logit("invalid public DH value: <= 1");
25218de8d7fSPeter Avalos 		return 0;
25318de8d7fSPeter Avalos 	}
25418de8d7fSPeter Avalos 
25518de8d7fSPeter Avalos 	if ((tmp = BN_new()) == NULL) {
256*50a69bb5SSascha Wildner 		error_f("BN_new failed");
25718de8d7fSPeter Avalos 		return 0;
25818de8d7fSPeter Avalos 	}
259664f4763Szrj 	if (!BN_sub(tmp, dh_p, BN_value_one()) ||
26018de8d7fSPeter Avalos 	    BN_cmp(dh_pub, tmp) != -1) {		/* pub_exp > p-2 */
26118de8d7fSPeter Avalos 		BN_clear_free(tmp);
26218de8d7fSPeter Avalos 		logit("invalid public DH value: >= p-1");
26318de8d7fSPeter Avalos 		return 0;
26418de8d7fSPeter Avalos 	}
26518de8d7fSPeter Avalos 	BN_clear_free(tmp);
26618de8d7fSPeter Avalos 
26718de8d7fSPeter Avalos 	for (i = 0; i <= n; i++)
26818de8d7fSPeter Avalos 		if (BN_is_bit_set(dh_pub, i))
26918de8d7fSPeter Avalos 			bits_set++;
270664f4763Szrj 	debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p));
27118de8d7fSPeter Avalos 
272e9778795SPeter Avalos 	/*
273e9778795SPeter Avalos 	 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
274e9778795SPeter Avalos 	 */
275e9778795SPeter Avalos 	if (bits_set < 4) {
276e9778795SPeter Avalos 		logit("invalid public DH value (%d/%d)",
277664f4763Szrj 		    bits_set, BN_num_bits(dh_p));
27818de8d7fSPeter Avalos 		return 0;
27918de8d7fSPeter Avalos 	}
280e9778795SPeter Avalos 	return 1;
281e9778795SPeter Avalos }
28218de8d7fSPeter Avalos 
283e9778795SPeter Avalos int
dh_gen_key(DH * dh,int need)28418de8d7fSPeter Avalos dh_gen_key(DH *dh, int need)
28518de8d7fSPeter Avalos {
28636e94dc5SPeter Avalos 	int pbits;
287664f4763Szrj 	const BIGNUM *dh_p, *pub_key;
28818de8d7fSPeter Avalos 
289664f4763Szrj 	DH_get0_pqg(dh, &dh_p, NULL, NULL);
290664f4763Szrj 
291664f4763Szrj 	if (need < 0 || dh_p == NULL ||
292664f4763Szrj 	    (pbits = BN_num_bits(dh_p)) <= 0 ||
293e9778795SPeter Avalos 	    need > INT_MAX / 2 || 2 * need > pbits)
294e9778795SPeter Avalos 		return SSH_ERR_INVALID_ARGUMENT;
295e9778795SPeter Avalos 	if (need < 256)
296e9778795SPeter Avalos 		need = 256;
297e9778795SPeter Avalos 	/*
298e9778795SPeter Avalos 	 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
299e9778795SPeter Avalos 	 * so double requested need here.
300e9778795SPeter Avalos 	 */
301664f4763Szrj 	if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
302e9778795SPeter Avalos 		return SSH_ERR_LIBCRYPTO_ERROR;
303664f4763Szrj 
304664f4763Szrj 	if (DH_generate_key(dh) == 0)
305664f4763Szrj 		return SSH_ERR_LIBCRYPTO_ERROR;
306664f4763Szrj 	DH_get0_key(dh, &pub_key, NULL);
307664f4763Szrj 	if (!dh_pub_is_valid(dh, pub_key))
308664f4763Szrj 		return SSH_ERR_INVALID_FORMAT;
309e9778795SPeter Avalos 	return 0;
31018de8d7fSPeter Avalos }
31118de8d7fSPeter Avalos 
31218de8d7fSPeter Avalos DH *
dh_new_group_asc(const char * gen,const char * modulus)31318de8d7fSPeter Avalos dh_new_group_asc(const char *gen, const char *modulus)
31418de8d7fSPeter Avalos {
31518de8d7fSPeter Avalos 	DH *dh;
316664f4763Szrj 	BIGNUM *dh_p = NULL, *dh_g = NULL;
31718de8d7fSPeter Avalos 
31818de8d7fSPeter Avalos 	if ((dh = DH_new()) == NULL)
319e9778795SPeter Avalos 		return NULL;
320664f4763Szrj 	if (BN_hex2bn(&dh_p, modulus) == 0 ||
321664f4763Szrj 	    BN_hex2bn(&dh_g, gen) == 0)
322664f4763Szrj 		goto fail;
323664f4763Szrj 	if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
324664f4763Szrj 		goto fail;
325664f4763Szrj 	return dh;
326664f4763Szrj  fail:
327e9778795SPeter Avalos 	DH_free(dh);
328664f4763Szrj 	BN_clear_free(dh_p);
329664f4763Szrj 	BN_clear_free(dh_g);
330e9778795SPeter Avalos 	return NULL;
331e9778795SPeter Avalos }
33218de8d7fSPeter Avalos 
33318de8d7fSPeter Avalos /*
33418de8d7fSPeter Avalos  * This just returns the group, we still need to generate the exchange
33518de8d7fSPeter Avalos  * value.
33618de8d7fSPeter Avalos  */
33718de8d7fSPeter Avalos DH *
dh_new_group(BIGNUM * gen,BIGNUM * modulus)33818de8d7fSPeter Avalos dh_new_group(BIGNUM *gen, BIGNUM *modulus)
33918de8d7fSPeter Avalos {
34018de8d7fSPeter Avalos 	DH *dh;
34118de8d7fSPeter Avalos 
34218de8d7fSPeter Avalos 	if ((dh = DH_new()) == NULL)
343e9778795SPeter Avalos 		return NULL;
344664f4763Szrj 	if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
345664f4763Szrj 		DH_free(dh);
346664f4763Szrj 		return NULL;
347664f4763Szrj 	}
34818de8d7fSPeter Avalos 
349664f4763Szrj 	return dh;
35018de8d7fSPeter Avalos }
35118de8d7fSPeter Avalos 
352e9778795SPeter Avalos /* rfc2409 "Second Oakley Group" (1024 bits) */
35318de8d7fSPeter Avalos DH *
dh_new_group1(void)35418de8d7fSPeter Avalos dh_new_group1(void)
35518de8d7fSPeter Avalos {
35618de8d7fSPeter Avalos 	static char *gen = "2", *group1 =
35718de8d7fSPeter Avalos 	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
35818de8d7fSPeter Avalos 	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
35918de8d7fSPeter Avalos 	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
36018de8d7fSPeter Avalos 	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
36118de8d7fSPeter Avalos 	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
36218de8d7fSPeter Avalos 	    "FFFFFFFF" "FFFFFFFF";
36318de8d7fSPeter Avalos 
36418de8d7fSPeter Avalos 	return (dh_new_group_asc(gen, group1));
36518de8d7fSPeter Avalos }
36618de8d7fSPeter Avalos 
367e9778795SPeter Avalos /* rfc3526 group 14 "2048-bit MODP Group" */
36818de8d7fSPeter Avalos DH *
dh_new_group14(void)36918de8d7fSPeter Avalos dh_new_group14(void)
37018de8d7fSPeter Avalos {
37118de8d7fSPeter Avalos 	static char *gen = "2", *group14 =
37218de8d7fSPeter Avalos 	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
37318de8d7fSPeter Avalos 	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
37418de8d7fSPeter Avalos 	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
37518de8d7fSPeter Avalos 	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
37618de8d7fSPeter Avalos 	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
37718de8d7fSPeter Avalos 	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
37818de8d7fSPeter Avalos 	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
37918de8d7fSPeter Avalos 	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
38018de8d7fSPeter Avalos 	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
38118de8d7fSPeter Avalos 	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
38218de8d7fSPeter Avalos 	    "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
38318de8d7fSPeter Avalos 
38418de8d7fSPeter Avalos 	return (dh_new_group_asc(gen, group14));
38518de8d7fSPeter Avalos }
38618de8d7fSPeter Avalos 
387e9778795SPeter Avalos /* rfc3526 group 16 "4096-bit MODP Group" */
388e9778795SPeter Avalos DH *
dh_new_group16(void)389e9778795SPeter Avalos dh_new_group16(void)
390e9778795SPeter Avalos {
391e9778795SPeter Avalos 	static char *gen = "2", *group16 =
392e9778795SPeter Avalos 	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
393e9778795SPeter Avalos 	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
394e9778795SPeter Avalos 	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
395e9778795SPeter Avalos 	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
396e9778795SPeter Avalos 	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
397e9778795SPeter Avalos 	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
398e9778795SPeter Avalos 	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
399e9778795SPeter Avalos 	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
400e9778795SPeter Avalos 	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
401e9778795SPeter Avalos 	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
402e9778795SPeter Avalos 	    "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
403e9778795SPeter Avalos 	    "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
404e9778795SPeter Avalos 	    "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
405e9778795SPeter Avalos 	    "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
406e9778795SPeter Avalos 	    "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
407e9778795SPeter Avalos 	    "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
408e9778795SPeter Avalos 	    "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
409e9778795SPeter Avalos 	    "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
410e9778795SPeter Avalos 	    "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
411e9778795SPeter Avalos 	    "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
412e9778795SPeter Avalos 	    "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
413e9778795SPeter Avalos 	    "FFFFFFFF" "FFFFFFFF";
414e9778795SPeter Avalos 
415e9778795SPeter Avalos 	return (dh_new_group_asc(gen, group16));
416e9778795SPeter Avalos }
417e9778795SPeter Avalos 
418e9778795SPeter Avalos /* rfc3526 group 18 "8192-bit MODP Group" */
419e9778795SPeter Avalos DH *
dh_new_group18(void)420e9778795SPeter Avalos dh_new_group18(void)
421e9778795SPeter Avalos {
422664f4763Szrj 	static char *gen = "2", *group18 =
423e9778795SPeter Avalos 	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
424e9778795SPeter Avalos 	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
425e9778795SPeter Avalos 	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
426e9778795SPeter Avalos 	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
427e9778795SPeter Avalos 	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
428e9778795SPeter Avalos 	    "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
429e9778795SPeter Avalos 	    "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
430e9778795SPeter Avalos 	    "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
431e9778795SPeter Avalos 	    "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
432e9778795SPeter Avalos 	    "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
433e9778795SPeter Avalos 	    "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
434e9778795SPeter Avalos 	    "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
435e9778795SPeter Avalos 	    "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
436e9778795SPeter Avalos 	    "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
437e9778795SPeter Avalos 	    "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
438e9778795SPeter Avalos 	    "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
439e9778795SPeter Avalos 	    "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
440e9778795SPeter Avalos 	    "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
441e9778795SPeter Avalos 	    "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
442e9778795SPeter Avalos 	    "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
443e9778795SPeter Avalos 	    "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
444e9778795SPeter Avalos 	    "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
445e9778795SPeter Avalos 	    "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
446e9778795SPeter Avalos 	    "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
447e9778795SPeter Avalos 	    "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
448e9778795SPeter Avalos 	    "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
449e9778795SPeter Avalos 	    "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
450e9778795SPeter Avalos 	    "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
451e9778795SPeter Avalos 	    "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
452e9778795SPeter Avalos 	    "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
453e9778795SPeter Avalos 	    "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
454e9778795SPeter Avalos 	    "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
455e9778795SPeter Avalos 	    "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
456e9778795SPeter Avalos 	    "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
457e9778795SPeter Avalos 	    "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
458e9778795SPeter Avalos 	    "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
459e9778795SPeter Avalos 	    "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
460e9778795SPeter Avalos 	    "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
461e9778795SPeter Avalos 	    "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
462e9778795SPeter Avalos 	    "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
463e9778795SPeter Avalos 	    "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
464e9778795SPeter Avalos 	    "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
465e9778795SPeter Avalos 	    "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
466e9778795SPeter Avalos 
467664f4763Szrj 	return (dh_new_group_asc(gen, group18));
468e9778795SPeter Avalos }
469e9778795SPeter Avalos 
470e9778795SPeter Avalos /* Select fallback group used by DH-GEX if moduli file cannot be read. */
471e9778795SPeter Avalos DH *
dh_new_group_fallback(int max)472e9778795SPeter Avalos dh_new_group_fallback(int max)
473e9778795SPeter Avalos {
474*50a69bb5SSascha Wildner 	debug3_f("requested max size %d", max);
475e9778795SPeter Avalos 	if (max < 3072) {
476e9778795SPeter Avalos 		debug3("using 2k bit group 14");
477e9778795SPeter Avalos 		return dh_new_group14();
478e9778795SPeter Avalos 	} else if (max < 6144) {
479e9778795SPeter Avalos 		debug3("using 4k bit group 16");
480e9778795SPeter Avalos 		return dh_new_group16();
481e9778795SPeter Avalos 	}
482e9778795SPeter Avalos 	debug3("using 8k bit group 18");
483e9778795SPeter Avalos 	return dh_new_group18();
484e9778795SPeter Avalos }
485e9778795SPeter Avalos 
48618de8d7fSPeter Avalos /*
48718de8d7fSPeter Avalos  * Estimates the group order for a Diffie-Hellman group that has an
48836e94dc5SPeter Avalos  * attack complexity approximately the same as O(2**bits).
48936e94dc5SPeter Avalos  * Values from NIST Special Publication 800-57: Recommendation for Key
49036e94dc5SPeter Avalos  * Management Part 1 (rev 3) limited by the recommended maximum value
49136e94dc5SPeter Avalos  * from RFC4419 section 3.
49218de8d7fSPeter Avalos  */
493e9778795SPeter Avalos u_int
dh_estimate(int bits)49418de8d7fSPeter Avalos dh_estimate(int bits)
49518de8d7fSPeter Avalos {
49636e94dc5SPeter Avalos 	if (bits <= 112)
49736e94dc5SPeter Avalos 		return 2048;
49818de8d7fSPeter Avalos 	if (bits <= 128)
49936e94dc5SPeter Avalos 		return 3072;
50018de8d7fSPeter Avalos 	if (bits <= 192)
50136e94dc5SPeter Avalos 		return 7680;
50236e94dc5SPeter Avalos 	return 8192;
50318de8d7fSPeter Avalos }
504664f4763Szrj 
505664f4763Szrj #endif /* WITH_OPENSSL */
506