1 /* $OpenBSD: dh.c,v 1.69 2018/11/09 02:56:22 djm Exp $ */ 2 /* 3 * Copyright (c) 2000 Niels Provos. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "includes.h" 27 28 #ifdef WITH_OPENSSL 29 30 #include <openssl/bn.h> 31 #include <openssl/dh.h> 32 33 #include <errno.h> 34 #include <stdarg.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <limits.h> 39 40 #include "dh.h" 41 #include "pathnames.h" 42 #include "log.h" 43 #include "misc.h" 44 #include "ssherr.h" 45 46 #include "openbsd-compat/openssl-compat.h" 47 48 static int 49 parse_prime(int linenum, char *line, struct dhgroup *dhg) 50 { 51 char *cp, *arg; 52 char *strsize, *gen, *prime; 53 const char *errstr = NULL; 54 long long n; 55 56 dhg->p = dhg->g = NULL; 57 cp = line; 58 if ((arg = strdelim(&cp)) == NULL) 59 return 0; 60 /* Ignore leading whitespace */ 61 if (*arg == '\0') 62 arg = strdelim(&cp); 63 if (!arg || !*arg || *arg == '#') 64 return 0; 65 66 /* time */ 67 if (cp == NULL || *arg == '\0') 68 goto truncated; 69 arg = strsep(&cp, " "); /* type */ 70 if (cp == NULL || *arg == '\0') 71 goto truncated; 72 /* Ensure this is a safe prime */ 73 n = strtonum(arg, 0, 5, &errstr); 74 if (errstr != NULL || n != MODULI_TYPE_SAFE) { 75 error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE); 76 goto fail; 77 } 78 arg = strsep(&cp, " "); /* tests */ 79 if (cp == NULL || *arg == '\0') 80 goto truncated; 81 /* Ensure prime has been tested and is not composite */ 82 n = strtonum(arg, 0, 0x1f, &errstr); 83 if (errstr != NULL || 84 (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) { 85 error("moduli:%d: invalid moduli tests flag", linenum); 86 goto fail; 87 } 88 arg = strsep(&cp, " "); /* tries */ 89 if (cp == NULL || *arg == '\0') 90 goto truncated; 91 n = strtonum(arg, 0, 1<<30, &errstr); 92 if (errstr != NULL || n == 0) { 93 error("moduli:%d: invalid primality trial count", linenum); 94 goto fail; 95 } 96 strsize = strsep(&cp, " "); /* size */ 97 if (cp == NULL || *strsize == '\0' || 98 (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || 99 errstr) { 100 error("moduli:%d: invalid prime length", linenum); 101 goto fail; 102 } 103 /* The whole group is one bit larger */ 104 dhg->size++; 105 gen = strsep(&cp, " "); /* gen */ 106 if (cp == NULL || *gen == '\0') 107 goto truncated; 108 prime = strsep(&cp, " "); /* prime */ 109 if (cp != NULL || *prime == '\0') { 110 truncated: 111 error("moduli:%d: truncated", linenum); 112 goto fail; 113 } 114 115 if ((dhg->g = BN_new()) == NULL || 116 (dhg->p = BN_new()) == NULL) { 117 error("parse_prime: BN_new failed"); 118 goto fail; 119 } 120 if (BN_hex2bn(&dhg->g, gen) == 0) { 121 error("moduli:%d: could not parse generator value", linenum); 122 goto fail; 123 } 124 if (BN_hex2bn(&dhg->p, prime) == 0) { 125 error("moduli:%d: could not parse prime value", linenum); 126 goto fail; 127 } 128 if (BN_num_bits(dhg->p) != dhg->size) { 129 error("moduli:%d: prime has wrong size: actual %d listed %d", 130 linenum, BN_num_bits(dhg->p), dhg->size - 1); 131 goto fail; 132 } 133 if (BN_cmp(dhg->g, BN_value_one()) <= 0) { 134 error("moduli:%d: generator is invalid", linenum); 135 goto fail; 136 } 137 return 1; 138 139 fail: 140 BN_clear_free(dhg->g); 141 BN_clear_free(dhg->p); 142 dhg->g = dhg->p = NULL; 143 return 0; 144 } 145 146 DH * 147 choose_dh(int min, int wantbits, int max) 148 { 149 FILE *f; 150 char *line = NULL; 151 size_t linesize = 0; 152 int best, bestcount, which, linenum; 153 struct dhgroup dhg; 154 155 if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) { 156 logit("WARNING: could not open %s (%s), using fixed modulus", 157 _PATH_DH_MODULI, strerror(errno)); 158 return (dh_new_group_fallback(max)); 159 } 160 161 linenum = 0; 162 best = bestcount = 0; 163 while (getline(&line, &linesize, f) != -1) { 164 linenum++; 165 if (!parse_prime(linenum, line, &dhg)) 166 continue; 167 BN_clear_free(dhg.g); 168 BN_clear_free(dhg.p); 169 170 if (dhg.size > max || dhg.size < min) 171 continue; 172 173 if ((dhg.size > wantbits && dhg.size < best) || 174 (dhg.size > best && best < wantbits)) { 175 best = dhg.size; 176 bestcount = 0; 177 } 178 if (dhg.size == best) 179 bestcount++; 180 } 181 free(line); 182 line = NULL; 183 linesize = 0; 184 rewind(f); 185 186 if (bestcount == 0) { 187 fclose(f); 188 logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI); 189 return (dh_new_group_fallback(max)); 190 } 191 which = arc4random_uniform(bestcount); 192 193 linenum = 0; 194 bestcount = 0; 195 while (getline(&line, &linesize, f) != -1) { 196 linenum++; 197 if (!parse_prime(linenum, line, &dhg)) 198 continue; 199 if ((dhg.size > max || dhg.size < min) || 200 dhg.size != best || 201 bestcount++ != which) { 202 BN_clear_free(dhg.g); 203 BN_clear_free(dhg.p); 204 continue; 205 } 206 break; 207 } 208 free(line); 209 line = NULL; 210 fclose(f); 211 if (bestcount != which + 1) { 212 logit("WARNING: selected prime disappeared in %s, giving up", 213 _PATH_DH_MODULI); 214 return (dh_new_group_fallback(max)); 215 } 216 217 return (dh_new_group(dhg.g, dhg.p)); 218 } 219 220 /* diffie-hellman-groupN-sha1 */ 221 222 int 223 dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub) 224 { 225 int i; 226 int n = BN_num_bits(dh_pub); 227 int bits_set = 0; 228 BIGNUM *tmp; 229 const BIGNUM *dh_p; 230 231 DH_get0_pqg(dh, &dh_p, NULL, NULL); 232 233 if (BN_is_negative(dh_pub)) { 234 logit("invalid public DH value: negative"); 235 return 0; 236 } 237 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */ 238 logit("invalid public DH value: <= 1"); 239 return 0; 240 } 241 242 if ((tmp = BN_new()) == NULL) { 243 error("%s: BN_new failed", __func__); 244 return 0; 245 } 246 if (!BN_sub(tmp, dh_p, BN_value_one()) || 247 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ 248 BN_clear_free(tmp); 249 logit("invalid public DH value: >= p-1"); 250 return 0; 251 } 252 BN_clear_free(tmp); 253 254 for (i = 0; i <= n; i++) 255 if (BN_is_bit_set(dh_pub, i)) 256 bits_set++; 257 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p)); 258 259 /* 260 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial 261 */ 262 if (bits_set < 4) { 263 logit("invalid public DH value (%d/%d)", 264 bits_set, BN_num_bits(dh_p)); 265 return 0; 266 } 267 return 1; 268 } 269 270 int 271 dh_gen_key(DH *dh, int need) 272 { 273 int pbits; 274 const BIGNUM *dh_p, *pub_key; 275 276 DH_get0_pqg(dh, &dh_p, NULL, NULL); 277 278 if (need < 0 || dh_p == NULL || 279 (pbits = BN_num_bits(dh_p)) <= 0 || 280 need > INT_MAX / 2 || 2 * need > pbits) 281 return SSH_ERR_INVALID_ARGUMENT; 282 if (need < 256) 283 need = 256; 284 /* 285 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), 286 * so double requested need here. 287 */ 288 if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1))) 289 return SSH_ERR_LIBCRYPTO_ERROR; 290 291 if (DH_generate_key(dh) == 0) 292 return SSH_ERR_LIBCRYPTO_ERROR; 293 DH_get0_key(dh, &pub_key, NULL); 294 if (!dh_pub_is_valid(dh, pub_key)) 295 return SSH_ERR_INVALID_FORMAT; 296 return 0; 297 } 298 299 DH * 300 dh_new_group_asc(const char *gen, const char *modulus) 301 { 302 DH *dh; 303 BIGNUM *dh_p = NULL, *dh_g = NULL; 304 305 if ((dh = DH_new()) == NULL) 306 return NULL; 307 if (BN_hex2bn(&dh_p, modulus) == 0 || 308 BN_hex2bn(&dh_g, gen) == 0) 309 goto fail; 310 if (!DH_set0_pqg(dh, dh_p, NULL, dh_g)) 311 goto fail; 312 return dh; 313 fail: 314 DH_free(dh); 315 BN_clear_free(dh_p); 316 BN_clear_free(dh_g); 317 return NULL; 318 } 319 320 /* 321 * This just returns the group, we still need to generate the exchange 322 * value. 323 */ 324 DH * 325 dh_new_group(BIGNUM *gen, BIGNUM *modulus) 326 { 327 DH *dh; 328 329 if ((dh = DH_new()) == NULL) 330 return NULL; 331 if (!DH_set0_pqg(dh, modulus, NULL, gen)) { 332 DH_free(dh); 333 return NULL; 334 } 335 336 return dh; 337 } 338 339 /* rfc2409 "Second Oakley Group" (1024 bits) */ 340 DH * 341 dh_new_group1(void) 342 { 343 static char *gen = "2", *group1 = 344 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 345 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 346 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 347 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 348 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" 349 "FFFFFFFF" "FFFFFFFF"; 350 351 return (dh_new_group_asc(gen, group1)); 352 } 353 354 /* rfc3526 group 14 "2048-bit MODP Group" */ 355 DH * 356 dh_new_group14(void) 357 { 358 static char *gen = "2", *group14 = 359 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 360 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 361 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 362 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 363 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" 364 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" 365 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" 366 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" 367 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" 368 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" 369 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"; 370 371 return (dh_new_group_asc(gen, group14)); 372 } 373 374 /* rfc3526 group 16 "4096-bit MODP Group" */ 375 DH * 376 dh_new_group16(void) 377 { 378 static char *gen = "2", *group16 = 379 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 380 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 381 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 382 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 383 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" 384 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" 385 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" 386 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" 387 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" 388 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" 389 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" 390 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" 391 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" 392 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" 393 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" 394 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" 395 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA" 396 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6" 397 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED" 398 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" 399 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199" 400 "FFFFFFFF" "FFFFFFFF"; 401 402 return (dh_new_group_asc(gen, group16)); 403 } 404 405 /* rfc3526 group 18 "8192-bit MODP Group" */ 406 DH * 407 dh_new_group18(void) 408 { 409 static char *gen = "2", *group18 = 410 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 411 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 412 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 413 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 414 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" 415 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" 416 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" 417 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" 418 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" 419 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" 420 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" 421 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" 422 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" 423 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" 424 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" 425 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" 426 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA" 427 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6" 428 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED" 429 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" 430 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492" 431 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD" 432 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831" 433 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B" 434 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF" 435 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6" 436 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3" 437 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA" 438 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328" 439 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C" 440 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE" 441 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4" 442 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300" 443 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568" 444 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9" 445 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B" 446 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A" 447 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36" 448 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1" 449 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92" 450 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47" 451 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71" 452 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF"; 453 454 return (dh_new_group_asc(gen, group18)); 455 } 456 457 /* Select fallback group used by DH-GEX if moduli file cannot be read. */ 458 DH * 459 dh_new_group_fallback(int max) 460 { 461 debug3("%s: requested max size %d", __func__, max); 462 if (max < 3072) { 463 debug3("using 2k bit group 14"); 464 return dh_new_group14(); 465 } else if (max < 6144) { 466 debug3("using 4k bit group 16"); 467 return dh_new_group16(); 468 } 469 debug3("using 8k bit group 18"); 470 return dh_new_group18(); 471 } 472 473 /* 474 * Estimates the group order for a Diffie-Hellman group that has an 475 * attack complexity approximately the same as O(2**bits). 476 * Values from NIST Special Publication 800-57: Recommendation for Key 477 * Management Part 1 (rev 3) limited by the recommended maximum value 478 * from RFC4419 section 3. 479 */ 480 u_int 481 dh_estimate(int bits) 482 { 483 if (bits <= 112) 484 return 2048; 485 if (bits <= 128) 486 return 3072; 487 if (bits <= 192) 488 return 7680; 489 return 8192; 490 } 491 492 #endif /* WITH_OPENSSL */ 493