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