1*2f513db7SEd Maste /* $OpenBSD: dh.c,v 1.68 2018/09/17 15:40:14 millert 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 2847dd1d1bSDag-Erling Smørgrav #ifdef WITH_OPENSSL 295b9b2fafSBrian Feldman 305b9b2fafSBrian Feldman #include <openssl/bn.h> 315b9b2fafSBrian Feldman #include <openssl/dh.h> 325b9b2fafSBrian Feldman 33076ad2f8SDag-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 462a01feabSEd Maste #include "openbsd-compat/openssl-compat.h" 472a01feabSEd Maste 48ae1f160dSDag-Erling Smørgrav static int 495b9b2fafSBrian Feldman parse_prime(int linenum, char *line, struct dhgroup *dhg) 505b9b2fafSBrian Feldman { 515b9b2fafSBrian Feldman char *cp, *arg; 525b9b2fafSBrian Feldman char *strsize, *gen, *prime; 53761efaa7SDag-Erling Smørgrav const char *errstr = NULL; 54d4af9e69SDag-Erling Smørgrav long long n; 555b9b2fafSBrian Feldman 56e4a9863fSDag-Erling Smørgrav dhg->p = dhg->g = NULL; 575b9b2fafSBrian Feldman cp = line; 58761efaa7SDag-Erling Smørgrav if ((arg = strdelim(&cp)) == NULL) 59761efaa7SDag-Erling Smørgrav return 0; 605b9b2fafSBrian Feldman /* Ignore leading whitespace */ 615b9b2fafSBrian Feldman if (*arg == '\0') 625b9b2fafSBrian Feldman arg = strdelim(&cp); 634b17dab0SDag-Erling Smørgrav if (!arg || !*arg || *arg == '#') 645b9b2fafSBrian Feldman return 0; 655b9b2fafSBrian Feldman 665b9b2fafSBrian Feldman /* time */ 675b9b2fafSBrian Feldman if (cp == NULL || *arg == '\0') 68e4a9863fSDag-Erling Smørgrav goto truncated; 695b9b2fafSBrian Feldman arg = strsep(&cp, " "); /* type */ 705b9b2fafSBrian Feldman if (cp == NULL || *arg == '\0') 71e4a9863fSDag-Erling Smørgrav goto truncated; 72d4af9e69SDag-Erling Smørgrav /* Ensure this is a safe prime */ 73d4af9e69SDag-Erling Smørgrav n = strtonum(arg, 0, 5, &errstr); 74e4a9863fSDag-Erling Smørgrav if (errstr != NULL || n != MODULI_TYPE_SAFE) { 75e4a9863fSDag-Erling Smørgrav error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE); 76d4af9e69SDag-Erling Smørgrav goto fail; 77e4a9863fSDag-Erling Smørgrav } 785b9b2fafSBrian Feldman arg = strsep(&cp, " "); /* tests */ 795b9b2fafSBrian Feldman if (cp == NULL || *arg == '\0') 80e4a9863fSDag-Erling Smørgrav goto truncated; 81d4af9e69SDag-Erling Smørgrav /* Ensure prime has been tested and is not composite */ 82d4af9e69SDag-Erling Smørgrav n = strtonum(arg, 0, 0x1f, &errstr); 83d4af9e69SDag-Erling Smørgrav if (errstr != NULL || 84e4a9863fSDag-Erling Smørgrav (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) { 85e4a9863fSDag-Erling Smørgrav error("moduli:%d: invalid moduli tests flag", linenum); 86d4af9e69SDag-Erling Smørgrav goto fail; 87e4a9863fSDag-Erling Smørgrav } 885b9b2fafSBrian Feldman arg = strsep(&cp, " "); /* tries */ 895b9b2fafSBrian Feldman if (cp == NULL || *arg == '\0') 90e4a9863fSDag-Erling Smørgrav goto truncated; 91d4af9e69SDag-Erling Smørgrav n = strtonum(arg, 0, 1<<30, &errstr); 92e4a9863fSDag-Erling Smørgrav if (errstr != NULL || n == 0) { 93e4a9863fSDag-Erling Smørgrav error("moduli:%d: invalid primality trial count", linenum); 94d4af9e69SDag-Erling Smørgrav goto fail; 95e4a9863fSDag-Erling Smørgrav } 965b9b2fafSBrian Feldman strsize = strsep(&cp, " "); /* size */ 975b9b2fafSBrian Feldman if (cp == NULL || *strsize == '\0' || 98b15c8340SDag-Erling Smørgrav (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || 99e4a9863fSDag-Erling Smørgrav errstr) { 100e4a9863fSDag-Erling Smørgrav error("moduli:%d: invalid prime length", linenum); 1015b9b2fafSBrian Feldman goto fail; 102e4a9863fSDag-Erling Smørgrav } 1031e8db6e2SBrian Feldman /* The whole group is one bit larger */ 1041e8db6e2SBrian Feldman dhg->size++; 1055b9b2fafSBrian Feldman gen = strsep(&cp, " "); /* gen */ 1065b9b2fafSBrian Feldman if (cp == NULL || *gen == '\0') 107e4a9863fSDag-Erling Smørgrav goto truncated; 1085b9b2fafSBrian Feldman prime = strsep(&cp, " "); /* prime */ 109e4a9863fSDag-Erling Smørgrav if (cp != NULL || *prime == '\0') { 110e4a9863fSDag-Erling Smørgrav truncated: 111e4a9863fSDag-Erling Smørgrav error("moduli:%d: truncated", linenum); 1125b9b2fafSBrian Feldman goto fail; 113e4a9863fSDag-Erling Smørgrav } 1145b9b2fafSBrian Feldman 115bc5531deSDag-Erling Smørgrav if ((dhg->g = BN_new()) == NULL || 116bc5531deSDag-Erling Smørgrav (dhg->p = BN_new()) == NULL) { 117bc5531deSDag-Erling Smørgrav error("parse_prime: BN_new failed"); 118bc5531deSDag-Erling Smørgrav goto fail; 119bc5531deSDag-Erling Smørgrav } 120e4a9863fSDag-Erling Smørgrav if (BN_hex2bn(&dhg->g, gen) == 0) { 121e4a9863fSDag-Erling Smørgrav error("moduli:%d: could not parse generator value", linenum); 122e4a9863fSDag-Erling Smørgrav goto fail; 123e4a9863fSDag-Erling Smørgrav } 124e4a9863fSDag-Erling Smørgrav if (BN_hex2bn(&dhg->p, prime) == 0) { 125e4a9863fSDag-Erling Smørgrav error("moduli:%d: could not parse prime value", linenum); 126e4a9863fSDag-Erling Smørgrav goto fail; 127e4a9863fSDag-Erling Smørgrav } 128e4a9863fSDag-Erling Smørgrav if (BN_num_bits(dhg->p) != dhg->size) { 129e4a9863fSDag-Erling Smørgrav error("moduli:%d: prime has wrong size: actual %d listed %d", 130e4a9863fSDag-Erling Smørgrav linenum, BN_num_bits(dhg->p), dhg->size - 1); 131e4a9863fSDag-Erling Smørgrav goto fail; 132e4a9863fSDag-Erling Smørgrav } 133e4a9863fSDag-Erling Smørgrav if (BN_cmp(dhg->g, BN_value_one()) <= 0) { 134e4a9863fSDag-Erling Smørgrav error("moduli:%d: generator is invalid", linenum); 135e4a9863fSDag-Erling Smørgrav goto fail; 136e4a9863fSDag-Erling Smørgrav } 137e4a9863fSDag-Erling Smørgrav return 1; 1381e8db6e2SBrian Feldman 1395b9b2fafSBrian Feldman fail: 140e4a9863fSDag-Erling Smørgrav BN_clear_free(dhg->g); 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; 150190cef3dSDag-Erling Smørgrav char *line = NULL; 151190cef3dSDag-Erling Smørgrav size_t linesize = 0; 152190cef3dSDag-Erling Smørgrav int best, bestcount, which, linenum; 1535b9b2fafSBrian Feldman struct dhgroup dhg; 1545b9b2fafSBrian Feldman 155076ad2f8SDag-Erling Smørgrav if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) { 156ca86bcf2SDag-Erling Smørgrav logit("WARNING: could not open %s (%s), using fixed modulus", 157076ad2f8SDag-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; 163190cef3dSDag-Erling Smørgrav while (getline(&line, &linesize, f) != -1) { 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 } 181190cef3dSDag-Erling Smørgrav free(line); 182190cef3dSDag-Erling Smørgrav line = NULL; 183190cef3dSDag-Erling Smørgrav linesize = 0; 184ae1f160dSDag-Erling Smørgrav rewind(f); 1855b9b2fafSBrian Feldman 1865b9b2fafSBrian Feldman if (bestcount == 0) { 187ae1f160dSDag-Erling Smørgrav fclose(f); 188076ad2f8SDag-Erling Smørgrav logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI); 189557f75e5SDag-Erling Smørgrav return (dh_new_group_fallback(max)); 1905b9b2fafSBrian Feldman } 191*2f513db7SEd Maste which = arc4random_uniform(bestcount); 1925b9b2fafSBrian Feldman 1935b9b2fafSBrian Feldman linenum = 0; 194*2f513db7SEd Maste bestcount = 0; 195190cef3dSDag-Erling Smørgrav while (getline(&line, &linesize, f) != -1) { 196*2f513db7SEd Maste linenum++; 1975b9b2fafSBrian Feldman if (!parse_prime(linenum, line, &dhg)) 1985b9b2fafSBrian Feldman continue; 1991e8db6e2SBrian Feldman if ((dhg.size > max || dhg.size < min) || 2001e8db6e2SBrian Feldman dhg.size != best || 201*2f513db7SEd Maste bestcount++ != which) { 202ae1f160dSDag-Erling Smørgrav BN_clear_free(dhg.g); 203ae1f160dSDag-Erling Smørgrav BN_clear_free(dhg.p); 2045b9b2fafSBrian Feldman continue; 2055b9b2fafSBrian Feldman } 2065b9b2fafSBrian Feldman break; 2075b9b2fafSBrian Feldman } 208190cef3dSDag-Erling Smørgrav free(line); 209190cef3dSDag-Erling Smørgrav line = NULL; 2105b9b2fafSBrian Feldman fclose(f); 211*2f513db7SEd Maste if (bestcount != which + 1) { 212*2f513db7SEd Maste logit("WARNING: selected prime disappeared in %s, giving up", 213*2f513db7SEd Maste _PATH_DH_MODULI); 214557f75e5SDag-Erling Smørgrav return (dh_new_group_fallback(max)); 215bc5531deSDag-Erling Smørgrav } 2165b9b2fafSBrian Feldman 2175b9b2fafSBrian Feldman return (dh_new_group(dhg.g, dhg.p)); 2185b9b2fafSBrian Feldman } 2191e8db6e2SBrian Feldman 220d74d50a8SDag-Erling Smørgrav /* diffie-hellman-groupN-sha1 */ 2211e8db6e2SBrian Feldman 2221e8db6e2SBrian Feldman int 2232a01feabSEd Maste dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub) 2241e8db6e2SBrian Feldman { 2251e8db6e2SBrian Feldman int i; 2261e8db6e2SBrian Feldman int n = BN_num_bits(dh_pub); 2271e8db6e2SBrian Feldman int bits_set = 0; 228761efaa7SDag-Erling Smørgrav BIGNUM *tmp; 2292a01feabSEd Maste const BIGNUM *dh_p; 2301e8db6e2SBrian Feldman 2312a01feabSEd Maste DH_get0_pqg(dh, &dh_p, NULL, NULL); 2322a01feabSEd Maste 2332a01feabSEd Maste if (BN_is_negative(dh_pub)) { 234d4af9e69SDag-Erling Smørgrav logit("invalid public DH value: negative"); 2351e8db6e2SBrian Feldman return 0; 2361e8db6e2SBrian Feldman } 237761efaa7SDag-Erling Smørgrav if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */ 238761efaa7SDag-Erling Smørgrav logit("invalid public DH value: <= 1"); 239761efaa7SDag-Erling Smørgrav return 0; 240761efaa7SDag-Erling Smørgrav } 241761efaa7SDag-Erling Smørgrav 242d4af9e69SDag-Erling Smørgrav if ((tmp = BN_new()) == NULL) { 243d4af9e69SDag-Erling Smørgrav error("%s: BN_new failed", __func__); 244d4af9e69SDag-Erling Smørgrav return 0; 245d4af9e69SDag-Erling Smørgrav } 2462a01feabSEd Maste if (!BN_sub(tmp, dh_p, BN_value_one()) || 247761efaa7SDag-Erling Smørgrav BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ 248761efaa7SDag-Erling Smørgrav BN_clear_free(tmp); 249761efaa7SDag-Erling Smørgrav logit("invalid public DH value: >= p-1"); 250761efaa7SDag-Erling Smørgrav return 0; 251761efaa7SDag-Erling Smørgrav } 252761efaa7SDag-Erling Smørgrav BN_clear_free(tmp); 253761efaa7SDag-Erling Smørgrav 2541e8db6e2SBrian Feldman for (i = 0; i <= n; i++) 2551e8db6e2SBrian Feldman if (BN_is_bit_set(dh_pub, i)) 2561e8db6e2SBrian Feldman bits_set++; 2572a01feabSEd Maste debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p)); 2581e8db6e2SBrian Feldman 259076ad2f8SDag-Erling Smørgrav /* 260076ad2f8SDag-Erling Smørgrav * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial 261076ad2f8SDag-Erling Smørgrav */ 262076ad2f8SDag-Erling Smørgrav if (bits_set < 4) { 263076ad2f8SDag-Erling Smørgrav logit("invalid public DH value (%d/%d)", 2642a01feabSEd Maste bits_set, BN_num_bits(dh_p)); 2651e8db6e2SBrian Feldman return 0; 2661e8db6e2SBrian Feldman } 267076ad2f8SDag-Erling Smørgrav return 1; 268076ad2f8SDag-Erling Smørgrav } 2691e8db6e2SBrian Feldman 270bc5531deSDag-Erling Smørgrav int 2711e8db6e2SBrian Feldman dh_gen_key(DH *dh, int need) 2721e8db6e2SBrian Feldman { 273f7167e0eSDag-Erling Smørgrav int pbits; 2742a01feabSEd Maste const BIGNUM *dh_p, *pub_key; 2751e8db6e2SBrian Feldman 2762a01feabSEd Maste DH_get0_pqg(dh, &dh_p, NULL, NULL); 2772a01feabSEd Maste 2782a01feabSEd Maste if (need < 0 || dh_p == NULL || 2792a01feabSEd Maste (pbits = BN_num_bits(dh_p)) <= 0 || 280557f75e5SDag-Erling Smørgrav need > INT_MAX / 2 || 2 * need > pbits) 281bc5531deSDag-Erling Smørgrav return SSH_ERR_INVALID_ARGUMENT; 282076ad2f8SDag-Erling Smørgrav if (need < 256) 283076ad2f8SDag-Erling Smørgrav need = 256; 284076ad2f8SDag-Erling Smørgrav /* 285076ad2f8SDag-Erling Smørgrav * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), 286076ad2f8SDag-Erling Smørgrav * so double requested need here. 287076ad2f8SDag-Erling Smørgrav */ 2882a01feabSEd Maste if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1))) 289bc5531deSDag-Erling Smørgrav return SSH_ERR_LIBCRYPTO_ERROR; 2902a01feabSEd Maste 2912a01feabSEd Maste if (DH_generate_key(dh) == 0) 2922a01feabSEd Maste return SSH_ERR_LIBCRYPTO_ERROR; 2932a01feabSEd Maste DH_get0_key(dh, &pub_key, NULL); 2942a01feabSEd Maste if (!dh_pub_is_valid(dh, pub_key)) 2952a01feabSEd Maste return SSH_ERR_INVALID_FORMAT; 296bc5531deSDag-Erling Smørgrav return 0; 2971e8db6e2SBrian Feldman } 2981e8db6e2SBrian Feldman 2991e8db6e2SBrian Feldman DH * 3001e8db6e2SBrian Feldman dh_new_group_asc(const char *gen, const char *modulus) 3011e8db6e2SBrian Feldman { 3021e8db6e2SBrian Feldman DH *dh; 3032a01feabSEd Maste BIGNUM *dh_p = NULL, *dh_g = NULL; 3041e8db6e2SBrian Feldman 305ae1f160dSDag-Erling Smørgrav if ((dh = DH_new()) == NULL) 306bc5531deSDag-Erling Smørgrav return NULL; 3072a01feabSEd Maste if (BN_hex2bn(&dh_p, modulus) == 0 || 3082a01feabSEd Maste BN_hex2bn(&dh_g, gen) == 0) 3092a01feabSEd Maste goto fail; 3102a01feabSEd Maste if (!DH_set0_pqg(dh, dh_p, NULL, dh_g)) 3112a01feabSEd Maste goto fail; 3122a01feabSEd Maste return dh; 3132a01feabSEd Maste fail: 314bc5531deSDag-Erling Smørgrav DH_free(dh); 3152a01feabSEd Maste BN_clear_free(dh_p); 3162a01feabSEd Maste BN_clear_free(dh_g); 317bc5531deSDag-Erling Smørgrav return NULL; 318bc5531deSDag-Erling Smørgrav } 3191e8db6e2SBrian Feldman 3201e8db6e2SBrian Feldman /* 3211e8db6e2SBrian Feldman * This just returns the group, we still need to generate the exchange 3221e8db6e2SBrian Feldman * value. 3231e8db6e2SBrian Feldman */ 3241e8db6e2SBrian Feldman DH * 3251e8db6e2SBrian Feldman dh_new_group(BIGNUM *gen, BIGNUM *modulus) 3261e8db6e2SBrian Feldman { 3271e8db6e2SBrian Feldman DH *dh; 3281e8db6e2SBrian Feldman 329ae1f160dSDag-Erling Smørgrav if ((dh = DH_new()) == NULL) 330bc5531deSDag-Erling Smørgrav return NULL; 3312a01feabSEd Maste if (!DH_set0_pqg(dh, modulus, NULL, gen)) { 3322a01feabSEd Maste DH_free(dh); 3332a01feabSEd Maste return NULL; 3342a01feabSEd Maste } 3351e8db6e2SBrian Feldman 3362a01feabSEd Maste return dh; 3371e8db6e2SBrian Feldman } 3381e8db6e2SBrian Feldman 339076ad2f8SDag-Erling Smørgrav /* rfc2409 "Second Oakley Group" (1024 bits) */ 3401e8db6e2SBrian Feldman DH * 3411e8db6e2SBrian Feldman dh_new_group1(void) 3421e8db6e2SBrian Feldman { 3431e8db6e2SBrian Feldman static char *gen = "2", *group1 = 3441e8db6e2SBrian Feldman "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 3451e8db6e2SBrian Feldman "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 3461e8db6e2SBrian Feldman "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 3471e8db6e2SBrian Feldman "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 3481e8db6e2SBrian Feldman "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" 3491e8db6e2SBrian Feldman "FFFFFFFF" "FFFFFFFF"; 3501e8db6e2SBrian Feldman 3511e8db6e2SBrian Feldman return (dh_new_group_asc(gen, group1)); 3521e8db6e2SBrian Feldman } 3531e8db6e2SBrian Feldman 354076ad2f8SDag-Erling Smørgrav /* rfc3526 group 14 "2048-bit MODP Group" */ 355d74d50a8SDag-Erling Smørgrav DH * 356d74d50a8SDag-Erling Smørgrav dh_new_group14(void) 357d74d50a8SDag-Erling Smørgrav { 358d74d50a8SDag-Erling Smørgrav static char *gen = "2", *group14 = 359d74d50a8SDag-Erling Smørgrav "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 360d74d50a8SDag-Erling Smørgrav "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 361d74d50a8SDag-Erling Smørgrav "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 362d74d50a8SDag-Erling Smørgrav "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 363d74d50a8SDag-Erling Smørgrav "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" 364d74d50a8SDag-Erling Smørgrav "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" 365d74d50a8SDag-Erling Smørgrav "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" 366d74d50a8SDag-Erling Smørgrav "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" 367d74d50a8SDag-Erling Smørgrav "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" 368d74d50a8SDag-Erling Smørgrav "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" 369d74d50a8SDag-Erling Smørgrav "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"; 370d74d50a8SDag-Erling Smørgrav 371d74d50a8SDag-Erling Smørgrav return (dh_new_group_asc(gen, group14)); 372d74d50a8SDag-Erling Smørgrav } 373d74d50a8SDag-Erling Smørgrav 374076ad2f8SDag-Erling Smørgrav /* rfc3526 group 16 "4096-bit MODP Group" */ 375557f75e5SDag-Erling Smørgrav DH * 376076ad2f8SDag-Erling Smørgrav dh_new_group16(void) 377557f75e5SDag-Erling Smørgrav { 378557f75e5SDag-Erling Smørgrav static char *gen = "2", *group16 = 379557f75e5SDag-Erling Smørgrav "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 380557f75e5SDag-Erling Smørgrav "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 381557f75e5SDag-Erling Smørgrav "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 382557f75e5SDag-Erling Smørgrav "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 383557f75e5SDag-Erling Smørgrav "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" 384557f75e5SDag-Erling Smørgrav "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" 385557f75e5SDag-Erling Smørgrav "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" 386557f75e5SDag-Erling Smørgrav "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" 387557f75e5SDag-Erling Smørgrav "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" 388557f75e5SDag-Erling Smørgrav "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" 389557f75e5SDag-Erling Smørgrav "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" 390557f75e5SDag-Erling Smørgrav "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" 391557f75e5SDag-Erling Smørgrav "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" 392557f75e5SDag-Erling Smørgrav "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" 393557f75e5SDag-Erling Smørgrav "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" 394557f75e5SDag-Erling Smørgrav "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" 395557f75e5SDag-Erling Smørgrav "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA" 396557f75e5SDag-Erling Smørgrav "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6" 397557f75e5SDag-Erling Smørgrav "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED" 398557f75e5SDag-Erling Smørgrav "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" 399557f75e5SDag-Erling Smørgrav "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199" 400557f75e5SDag-Erling Smørgrav "FFFFFFFF" "FFFFFFFF"; 401557f75e5SDag-Erling Smørgrav 402557f75e5SDag-Erling Smørgrav return (dh_new_group_asc(gen, group16)); 403557f75e5SDag-Erling Smørgrav } 404557f75e5SDag-Erling Smørgrav 405076ad2f8SDag-Erling Smørgrav /* rfc3526 group 18 "8192-bit MODP Group" */ 406076ad2f8SDag-Erling Smørgrav DH * 407076ad2f8SDag-Erling Smørgrav dh_new_group18(void) 408076ad2f8SDag-Erling Smørgrav { 409076ad2f8SDag-Erling Smørgrav static char *gen = "2", *group16 = 410076ad2f8SDag-Erling Smørgrav "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 411076ad2f8SDag-Erling Smørgrav "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 412076ad2f8SDag-Erling Smørgrav "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 413076ad2f8SDag-Erling Smørgrav "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 414076ad2f8SDag-Erling Smørgrav "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" 415076ad2f8SDag-Erling Smørgrav "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" 416076ad2f8SDag-Erling Smørgrav "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" 417076ad2f8SDag-Erling Smørgrav "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" 418076ad2f8SDag-Erling Smørgrav "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" 419076ad2f8SDag-Erling Smørgrav "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" 420076ad2f8SDag-Erling Smørgrav "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" 421076ad2f8SDag-Erling Smørgrav "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" 422076ad2f8SDag-Erling Smørgrav "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" 423076ad2f8SDag-Erling Smørgrav "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" 424076ad2f8SDag-Erling Smørgrav "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" 425076ad2f8SDag-Erling Smørgrav "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" 426076ad2f8SDag-Erling Smørgrav "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA" 427076ad2f8SDag-Erling Smørgrav "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6" 428076ad2f8SDag-Erling Smørgrav "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED" 429076ad2f8SDag-Erling Smørgrav "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" 430076ad2f8SDag-Erling Smørgrav "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492" 431076ad2f8SDag-Erling Smørgrav "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD" 432076ad2f8SDag-Erling Smørgrav "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831" 433076ad2f8SDag-Erling Smørgrav "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B" 434076ad2f8SDag-Erling Smørgrav "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF" 435076ad2f8SDag-Erling Smørgrav "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6" 436076ad2f8SDag-Erling Smørgrav "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3" 437076ad2f8SDag-Erling Smørgrav "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA" 438076ad2f8SDag-Erling Smørgrav "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328" 439076ad2f8SDag-Erling Smørgrav "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C" 440076ad2f8SDag-Erling Smørgrav "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE" 441076ad2f8SDag-Erling Smørgrav "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4" 442076ad2f8SDag-Erling Smørgrav "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300" 443076ad2f8SDag-Erling Smørgrav "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568" 444076ad2f8SDag-Erling Smørgrav "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9" 445076ad2f8SDag-Erling Smørgrav "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B" 446076ad2f8SDag-Erling Smørgrav "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A" 447076ad2f8SDag-Erling Smørgrav "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36" 448076ad2f8SDag-Erling Smørgrav "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1" 449076ad2f8SDag-Erling Smørgrav "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92" 450076ad2f8SDag-Erling Smørgrav "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47" 451076ad2f8SDag-Erling Smørgrav "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71" 452076ad2f8SDag-Erling Smørgrav "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF"; 453076ad2f8SDag-Erling Smørgrav 454076ad2f8SDag-Erling Smørgrav return (dh_new_group_asc(gen, group16)); 455076ad2f8SDag-Erling Smørgrav } 456076ad2f8SDag-Erling Smørgrav 457076ad2f8SDag-Erling Smørgrav /* Select fallback group used by DH-GEX if moduli file cannot be read. */ 458076ad2f8SDag-Erling Smørgrav DH * 459076ad2f8SDag-Erling Smørgrav dh_new_group_fallback(int max) 460076ad2f8SDag-Erling Smørgrav { 461076ad2f8SDag-Erling Smørgrav debug3("%s: requested max size %d", __func__, max); 462076ad2f8SDag-Erling Smørgrav if (max < 3072) { 463076ad2f8SDag-Erling Smørgrav debug3("using 2k bit group 14"); 464076ad2f8SDag-Erling Smørgrav return dh_new_group14(); 465076ad2f8SDag-Erling Smørgrav } else if (max < 6144) { 466076ad2f8SDag-Erling Smørgrav debug3("using 4k bit group 16"); 467076ad2f8SDag-Erling Smørgrav return dh_new_group16(); 468076ad2f8SDag-Erling Smørgrav } 469076ad2f8SDag-Erling Smørgrav debug3("using 8k bit group 18"); 470076ad2f8SDag-Erling Smørgrav return dh_new_group18(); 471076ad2f8SDag-Erling Smørgrav } 472076ad2f8SDag-Erling Smørgrav 473557f75e5SDag-Erling Smørgrav /* 4741e8db6e2SBrian Feldman * Estimates the group order for a Diffie-Hellman group that has an 475f7167e0eSDag-Erling Smørgrav * attack complexity approximately the same as O(2**bits). 476f7167e0eSDag-Erling Smørgrav * Values from NIST Special Publication 800-57: Recommendation for Key 477f7167e0eSDag-Erling Smørgrav * Management Part 1 (rev 3) limited by the recommended maximum value 478f7167e0eSDag-Erling Smørgrav * from RFC4419 section 3. 4791e8db6e2SBrian Feldman */ 480bc5531deSDag-Erling Smørgrav u_int 4811e8db6e2SBrian Feldman dh_estimate(int bits) 4821e8db6e2SBrian Feldman { 483f7167e0eSDag-Erling Smørgrav if (bits <= 112) 484f7167e0eSDag-Erling Smørgrav return 2048; 485efcad6b7SDag-Erling Smørgrav if (bits <= 128) 486f7167e0eSDag-Erling Smørgrav return 3072; 487efcad6b7SDag-Erling Smørgrav if (bits <= 192) 488f7167e0eSDag-Erling Smørgrav return 7680; 489f7167e0eSDag-Erling Smørgrav return 8192; 4901e8db6e2SBrian Feldman } 49147dd1d1bSDag-Erling Smørgrav 49247dd1d1bSDag-Erling Smørgrav #endif /* WITH_OPENSSL */ 493