1*557f75e5SDag-Erling Smørgrav /* $OpenBSD: dh.c,v 1.57 2015/05/27 23:39:18 dtucker 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 33761efaa7SDag-Erling Smørgrav #include <stdarg.h> 34761efaa7SDag-Erling Smørgrav #include <stdio.h> 35761efaa7SDag-Erling Smørgrav #include <stdlib.h> 36761efaa7SDag-Erling Smørgrav #include <string.h> 37bc5531deSDag-Erling Smørgrav #include <limits.h> 38761efaa7SDag-Erling Smørgrav 395b9b2fafSBrian Feldman #include "dh.h" 401e8db6e2SBrian Feldman #include "pathnames.h" 411e8db6e2SBrian Feldman #include "log.h" 421e8db6e2SBrian Feldman #include "misc.h" 43bc5531deSDag-Erling Smørgrav #include "ssherr.h" 445b9b2fafSBrian Feldman 45ae1f160dSDag-Erling Smørgrav static int 465b9b2fafSBrian Feldman parse_prime(int linenum, char *line, struct dhgroup *dhg) 475b9b2fafSBrian Feldman { 485b9b2fafSBrian Feldman char *cp, *arg; 495b9b2fafSBrian Feldman char *strsize, *gen, *prime; 50761efaa7SDag-Erling Smørgrav const char *errstr = NULL; 51d4af9e69SDag-Erling Smørgrav long long n; 525b9b2fafSBrian Feldman 53e4a9863fSDag-Erling Smørgrav dhg->p = dhg->g = NULL; 545b9b2fafSBrian Feldman cp = line; 55761efaa7SDag-Erling Smørgrav if ((arg = strdelim(&cp)) == NULL) 56761efaa7SDag-Erling Smørgrav return 0; 575b9b2fafSBrian Feldman /* Ignore leading whitespace */ 585b9b2fafSBrian Feldman if (*arg == '\0') 595b9b2fafSBrian Feldman arg = strdelim(&cp); 604b17dab0SDag-Erling Smørgrav if (!arg || !*arg || *arg == '#') 615b9b2fafSBrian Feldman return 0; 625b9b2fafSBrian Feldman 635b9b2fafSBrian Feldman /* time */ 645b9b2fafSBrian Feldman if (cp == NULL || *arg == '\0') 65e4a9863fSDag-Erling Smørgrav goto truncated; 665b9b2fafSBrian Feldman arg = strsep(&cp, " "); /* type */ 675b9b2fafSBrian Feldman if (cp == NULL || *arg == '\0') 68e4a9863fSDag-Erling Smørgrav goto truncated; 69d4af9e69SDag-Erling Smørgrav /* Ensure this is a safe prime */ 70d4af9e69SDag-Erling Smørgrav n = strtonum(arg, 0, 5, &errstr); 71e4a9863fSDag-Erling Smørgrav if (errstr != NULL || n != MODULI_TYPE_SAFE) { 72e4a9863fSDag-Erling Smørgrav error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE); 73d4af9e69SDag-Erling Smørgrav goto fail; 74e4a9863fSDag-Erling Smørgrav } 755b9b2fafSBrian Feldman arg = strsep(&cp, " "); /* tests */ 765b9b2fafSBrian Feldman if (cp == NULL || *arg == '\0') 77e4a9863fSDag-Erling Smørgrav goto truncated; 78d4af9e69SDag-Erling Smørgrav /* Ensure prime has been tested and is not composite */ 79d4af9e69SDag-Erling Smørgrav n = strtonum(arg, 0, 0x1f, &errstr); 80d4af9e69SDag-Erling Smørgrav if (errstr != NULL || 81e4a9863fSDag-Erling Smørgrav (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) { 82e4a9863fSDag-Erling Smørgrav error("moduli:%d: invalid moduli tests flag", linenum); 83d4af9e69SDag-Erling Smørgrav goto fail; 84e4a9863fSDag-Erling Smørgrav } 855b9b2fafSBrian Feldman arg = strsep(&cp, " "); /* tries */ 865b9b2fafSBrian Feldman if (cp == NULL || *arg == '\0') 87e4a9863fSDag-Erling Smørgrav goto truncated; 88d4af9e69SDag-Erling Smørgrav n = strtonum(arg, 0, 1<<30, &errstr); 89e4a9863fSDag-Erling Smørgrav if (errstr != NULL || n == 0) { 90e4a9863fSDag-Erling Smørgrav error("moduli:%d: invalid primality trial count", linenum); 91d4af9e69SDag-Erling Smørgrav goto fail; 92e4a9863fSDag-Erling Smørgrav } 935b9b2fafSBrian Feldman strsize = strsep(&cp, " "); /* size */ 945b9b2fafSBrian Feldman if (cp == NULL || *strsize == '\0' || 95b15c8340SDag-Erling Smørgrav (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || 96e4a9863fSDag-Erling Smørgrav errstr) { 97e4a9863fSDag-Erling Smørgrav error("moduli:%d: invalid prime length", linenum); 985b9b2fafSBrian Feldman goto fail; 99e4a9863fSDag-Erling Smørgrav } 1001e8db6e2SBrian Feldman /* The whole group is one bit larger */ 1011e8db6e2SBrian Feldman dhg->size++; 1025b9b2fafSBrian Feldman gen = strsep(&cp, " "); /* gen */ 1035b9b2fafSBrian Feldman if (cp == NULL || *gen == '\0') 104e4a9863fSDag-Erling Smørgrav goto truncated; 1055b9b2fafSBrian Feldman prime = strsep(&cp, " "); /* prime */ 106e4a9863fSDag-Erling Smørgrav if (cp != NULL || *prime == '\0') { 107e4a9863fSDag-Erling Smørgrav truncated: 108e4a9863fSDag-Erling Smørgrav error("moduli:%d: truncated", linenum); 1095b9b2fafSBrian Feldman goto fail; 110e4a9863fSDag-Erling Smørgrav } 1115b9b2fafSBrian Feldman 112bc5531deSDag-Erling Smørgrav if ((dhg->g = BN_new()) == NULL || 113bc5531deSDag-Erling Smørgrav (dhg->p = BN_new()) == NULL) { 114bc5531deSDag-Erling Smørgrav error("parse_prime: BN_new failed"); 115bc5531deSDag-Erling Smørgrav goto fail; 116bc5531deSDag-Erling Smørgrav } 117e4a9863fSDag-Erling Smørgrav if (BN_hex2bn(&dhg->g, gen) == 0) { 118e4a9863fSDag-Erling Smørgrav error("moduli:%d: could not parse generator value", linenum); 119e4a9863fSDag-Erling Smørgrav goto fail; 120e4a9863fSDag-Erling Smørgrav } 121e4a9863fSDag-Erling Smørgrav if (BN_hex2bn(&dhg->p, prime) == 0) { 122e4a9863fSDag-Erling Smørgrav error("moduli:%d: could not parse prime value", linenum); 123e4a9863fSDag-Erling Smørgrav goto fail; 124e4a9863fSDag-Erling Smørgrav } 125e4a9863fSDag-Erling Smørgrav if (BN_num_bits(dhg->p) != dhg->size) { 126e4a9863fSDag-Erling Smørgrav error("moduli:%d: prime has wrong size: actual %d listed %d", 127e4a9863fSDag-Erling Smørgrav linenum, BN_num_bits(dhg->p), dhg->size - 1); 128e4a9863fSDag-Erling Smørgrav goto fail; 129e4a9863fSDag-Erling Smørgrav } 130e4a9863fSDag-Erling Smørgrav if (BN_cmp(dhg->g, BN_value_one()) <= 0) { 131e4a9863fSDag-Erling Smørgrav error("moduli:%d: generator is invalid", linenum); 132e4a9863fSDag-Erling Smørgrav goto fail; 133e4a9863fSDag-Erling Smørgrav } 134e4a9863fSDag-Erling Smørgrav return 1; 1351e8db6e2SBrian Feldman 1365b9b2fafSBrian Feldman fail: 137e4a9863fSDag-Erling Smørgrav if (dhg->g != NULL) 138e4a9863fSDag-Erling Smørgrav BN_clear_free(dhg->g); 139e4a9863fSDag-Erling Smørgrav if (dhg->p != NULL) 140e4a9863fSDag-Erling Smørgrav BN_clear_free(dhg->p); 141e4a9863fSDag-Erling Smørgrav dhg->g = dhg->p = NULL; 142e4a9863fSDag-Erling Smørgrav return 0; 1435b9b2fafSBrian Feldman } 1445b9b2fafSBrian Feldman 1455b9b2fafSBrian Feldman DH * 1461e8db6e2SBrian Feldman choose_dh(int min, int wantbits, int max) 1475b9b2fafSBrian Feldman { 1485b9b2fafSBrian Feldman FILE *f; 14952028650SDag-Erling Smørgrav char line[4096]; 1505b9b2fafSBrian Feldman int best, bestcount, which; 1515b9b2fafSBrian Feldman int linenum; 1525b9b2fafSBrian Feldman struct dhgroup dhg; 1535b9b2fafSBrian Feldman 154ae1f160dSDag-Erling Smørgrav if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL && 155ae1f160dSDag-Erling Smørgrav (f = fopen(_PATH_DH_PRIMES, "r")) == NULL) { 156d74d50a8SDag-Erling Smørgrav logit("WARNING: %s does not exist, using fixed modulus", 157d74d50a8SDag-Erling Smørgrav _PATH_DH_MODULI); 158*557f75e5SDag-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); 185d95e11bfSDag-Erling Smørgrav logit("WARNING: no suitable primes in %s", _PATH_DH_PRIMES); 186*557f75e5SDag-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", 2061e8db6e2SBrian Feldman which, _PATH_DH_PRIMES); 207*557f75e5SDag-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 2491e8db6e2SBrian Feldman /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ 250761efaa7SDag-Erling Smørgrav if (bits_set > 1) 2511e8db6e2SBrian Feldman return 1; 252761efaa7SDag-Erling Smørgrav 253d95e11bfSDag-Erling Smørgrav logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); 2541e8db6e2SBrian Feldman return 0; 2551e8db6e2SBrian Feldman } 2561e8db6e2SBrian Feldman 257bc5531deSDag-Erling Smørgrav int 2581e8db6e2SBrian Feldman dh_gen_key(DH *dh, int need) 2591e8db6e2SBrian Feldman { 260f7167e0eSDag-Erling Smørgrav int pbits; 2611e8db6e2SBrian Feldman 262bc5531deSDag-Erling Smørgrav if (need < 0 || dh->p == NULL || 263bc5531deSDag-Erling Smørgrav (pbits = BN_num_bits(dh->p)) <= 0 || 264*557f75e5SDag-Erling Smørgrav need > INT_MAX / 2 || 2 * need > pbits) 265bc5531deSDag-Erling Smørgrav return SSH_ERR_INVALID_ARGUMENT; 266f7167e0eSDag-Erling Smørgrav dh->length = MIN(need * 2, pbits - 1); 267bc5531deSDag-Erling Smørgrav if (DH_generate_key(dh) == 0 || 268bc5531deSDag-Erling Smørgrav !dh_pub_is_valid(dh, dh->pub_key)) { 269bc5531deSDag-Erling Smørgrav BN_clear_free(dh->priv_key); 270bc5531deSDag-Erling Smørgrav return SSH_ERR_LIBCRYPTO_ERROR; 271bc5531deSDag-Erling Smørgrav } 272bc5531deSDag-Erling Smørgrav return 0; 2731e8db6e2SBrian Feldman } 2741e8db6e2SBrian Feldman 2751e8db6e2SBrian Feldman DH * 2761e8db6e2SBrian Feldman dh_new_group_asc(const char *gen, const char *modulus) 2771e8db6e2SBrian Feldman { 2781e8db6e2SBrian Feldman DH *dh; 2791e8db6e2SBrian Feldman 280ae1f160dSDag-Erling Smørgrav if ((dh = DH_new()) == NULL) 281bc5531deSDag-Erling Smørgrav return NULL; 282bc5531deSDag-Erling Smørgrav if (BN_hex2bn(&dh->p, modulus) == 0 || 283bc5531deSDag-Erling Smørgrav BN_hex2bn(&dh->g, gen) == 0) { 284bc5531deSDag-Erling Smørgrav DH_free(dh); 285bc5531deSDag-Erling Smørgrav return NULL; 286bc5531deSDag-Erling Smørgrav } 2871e8db6e2SBrian Feldman return (dh); 2881e8db6e2SBrian Feldman } 2891e8db6e2SBrian Feldman 2901e8db6e2SBrian Feldman /* 2911e8db6e2SBrian Feldman * This just returns the group, we still need to generate the exchange 2921e8db6e2SBrian Feldman * value. 2931e8db6e2SBrian Feldman */ 2941e8db6e2SBrian Feldman 2951e8db6e2SBrian Feldman DH * 2961e8db6e2SBrian Feldman dh_new_group(BIGNUM *gen, BIGNUM *modulus) 2971e8db6e2SBrian Feldman { 2981e8db6e2SBrian Feldman DH *dh; 2991e8db6e2SBrian Feldman 300ae1f160dSDag-Erling Smørgrav if ((dh = DH_new()) == NULL) 301bc5531deSDag-Erling Smørgrav return NULL; 3021e8db6e2SBrian Feldman dh->p = modulus; 3031e8db6e2SBrian Feldman dh->g = gen; 3041e8db6e2SBrian Feldman 3051e8db6e2SBrian Feldman return (dh); 3061e8db6e2SBrian Feldman } 3071e8db6e2SBrian Feldman 3081e8db6e2SBrian Feldman DH * 3091e8db6e2SBrian Feldman dh_new_group1(void) 3101e8db6e2SBrian Feldman { 3111e8db6e2SBrian Feldman static char *gen = "2", *group1 = 3121e8db6e2SBrian Feldman "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 3131e8db6e2SBrian Feldman "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 3141e8db6e2SBrian Feldman "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 3151e8db6e2SBrian Feldman "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 3161e8db6e2SBrian Feldman "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" 3171e8db6e2SBrian Feldman "FFFFFFFF" "FFFFFFFF"; 3181e8db6e2SBrian Feldman 3191e8db6e2SBrian Feldman return (dh_new_group_asc(gen, group1)); 3201e8db6e2SBrian Feldman } 3211e8db6e2SBrian Feldman 322d74d50a8SDag-Erling Smørgrav DH * 323d74d50a8SDag-Erling Smørgrav dh_new_group14(void) 324d74d50a8SDag-Erling Smørgrav { 325d74d50a8SDag-Erling Smørgrav static char *gen = "2", *group14 = 326d74d50a8SDag-Erling Smørgrav "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 327d74d50a8SDag-Erling Smørgrav "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 328d74d50a8SDag-Erling Smørgrav "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 329d74d50a8SDag-Erling Smørgrav "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 330d74d50a8SDag-Erling Smørgrav "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" 331d74d50a8SDag-Erling Smørgrav "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" 332d74d50a8SDag-Erling Smørgrav "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" 333d74d50a8SDag-Erling Smørgrav "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" 334d74d50a8SDag-Erling Smørgrav "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" 335d74d50a8SDag-Erling Smørgrav "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" 336d74d50a8SDag-Erling Smørgrav "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"; 337d74d50a8SDag-Erling Smørgrav 338d74d50a8SDag-Erling Smørgrav return (dh_new_group_asc(gen, group14)); 339d74d50a8SDag-Erling Smørgrav } 340d74d50a8SDag-Erling Smørgrav 3411e8db6e2SBrian Feldman /* 342*557f75e5SDag-Erling Smørgrav * 4k bit fallback group used by DH-GEX if moduli file cannot be read. 343*557f75e5SDag-Erling Smørgrav * Source: MODP group 16 from RFC3526. 344*557f75e5SDag-Erling Smørgrav */ 345*557f75e5SDag-Erling Smørgrav DH * 346*557f75e5SDag-Erling Smørgrav dh_new_group_fallback(int max) 347*557f75e5SDag-Erling Smørgrav { 348*557f75e5SDag-Erling Smørgrav static char *gen = "2", *group16 = 349*557f75e5SDag-Erling Smørgrav "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 350*557f75e5SDag-Erling Smørgrav "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 351*557f75e5SDag-Erling Smørgrav "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 352*557f75e5SDag-Erling Smørgrav "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 353*557f75e5SDag-Erling Smørgrav "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" 354*557f75e5SDag-Erling Smørgrav "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" 355*557f75e5SDag-Erling Smørgrav "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" 356*557f75e5SDag-Erling Smørgrav "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" 357*557f75e5SDag-Erling Smørgrav "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" 358*557f75e5SDag-Erling Smørgrav "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" 359*557f75e5SDag-Erling Smørgrav "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" 360*557f75e5SDag-Erling Smørgrav "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" 361*557f75e5SDag-Erling Smørgrav "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" 362*557f75e5SDag-Erling Smørgrav "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" 363*557f75e5SDag-Erling Smørgrav "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" 364*557f75e5SDag-Erling Smørgrav "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" 365*557f75e5SDag-Erling Smørgrav "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA" 366*557f75e5SDag-Erling Smørgrav "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6" 367*557f75e5SDag-Erling Smørgrav "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED" 368*557f75e5SDag-Erling Smørgrav "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" 369*557f75e5SDag-Erling Smørgrav "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199" 370*557f75e5SDag-Erling Smørgrav "FFFFFFFF" "FFFFFFFF"; 371*557f75e5SDag-Erling Smørgrav 372*557f75e5SDag-Erling Smørgrav if (max < 4096) { 373*557f75e5SDag-Erling Smørgrav debug3("requested max size %d, using 2k bit group 14", max); 374*557f75e5SDag-Erling Smørgrav return dh_new_group14(); 375*557f75e5SDag-Erling Smørgrav } 376*557f75e5SDag-Erling Smørgrav debug3("using 4k bit group 16"); 377*557f75e5SDag-Erling Smørgrav return (dh_new_group_asc(gen, group16)); 378*557f75e5SDag-Erling Smørgrav } 379*557f75e5SDag-Erling Smørgrav 380*557f75e5SDag-Erling Smørgrav /* 3811e8db6e2SBrian Feldman * Estimates the group order for a Diffie-Hellman group that has an 382f7167e0eSDag-Erling Smørgrav * attack complexity approximately the same as O(2**bits). 383f7167e0eSDag-Erling Smørgrav * Values from NIST Special Publication 800-57: Recommendation for Key 384f7167e0eSDag-Erling Smørgrav * Management Part 1 (rev 3) limited by the recommended maximum value 385f7167e0eSDag-Erling Smørgrav * from RFC4419 section 3. 3861e8db6e2SBrian Feldman */ 3871e8db6e2SBrian Feldman 388bc5531deSDag-Erling Smørgrav u_int 3891e8db6e2SBrian Feldman dh_estimate(int bits) 3901e8db6e2SBrian Feldman { 391f7167e0eSDag-Erling Smørgrav if (bits <= 112) 392f7167e0eSDag-Erling Smørgrav return 2048; 393efcad6b7SDag-Erling Smørgrav if (bits <= 128) 394f7167e0eSDag-Erling Smørgrav return 3072; 395efcad6b7SDag-Erling Smørgrav if (bits <= 192) 396f7167e0eSDag-Erling Smørgrav return 7680; 397f7167e0eSDag-Erling Smørgrav return 8192; 3981e8db6e2SBrian Feldman } 399