diff options
Diffstat (limited to 'dh.c')
-rw-r--r-- | dh.c | 116 |
1 files changed, 93 insertions, 23 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: dh.c,v 1.57 2015/05/27 23:39:18 dtucker Exp $ */ | 1 | /* $OpenBSD: dh.c,v 1.60 2016/05/02 10:26:04 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Niels Provos. All rights reserved. | 3 | * Copyright (c) 2000 Niels Provos. All rights reserved. |
4 | * | 4 | * |
@@ -30,6 +30,7 @@ | |||
30 | #include <openssl/bn.h> | 30 | #include <openssl/bn.h> |
31 | #include <openssl/dh.h> | 31 | #include <openssl/dh.h> |
32 | 32 | ||
33 | #include <errno.h> | ||
33 | #include <stdarg.h> | 34 | #include <stdarg.h> |
34 | #include <stdio.h> | 35 | #include <stdio.h> |
35 | #include <stdlib.h> | 36 | #include <stdlib.h> |
@@ -151,10 +152,9 @@ choose_dh(int min, int wantbits, int max) | |||
151 | int linenum; | 152 | int linenum; |
152 | struct dhgroup dhg; | 153 | struct dhgroup dhg; |
153 | 154 | ||
154 | if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL && | 155 | if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) { |
155 | (f = fopen(_PATH_DH_PRIMES, "r")) == NULL) { | 156 | logit("WARNING: could open open %s (%s), using fixed modulus", |
156 | logit("WARNING: %s does not exist, using fixed modulus", | 157 | _PATH_DH_MODULI, strerror(errno)); |
157 | _PATH_DH_MODULI); | ||
158 | return (dh_new_group_fallback(max)); | 158 | return (dh_new_group_fallback(max)); |
159 | } | 159 | } |
160 | 160 | ||
@@ -182,7 +182,7 @@ choose_dh(int min, int wantbits, int max) | |||
182 | 182 | ||
183 | if (bestcount == 0) { | 183 | if (bestcount == 0) { |
184 | fclose(f); | 184 | fclose(f); |
185 | logit("WARNING: no suitable primes in %s", _PATH_DH_PRIMES); | 185 | logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI); |
186 | return (dh_new_group_fallback(max)); | 186 | return (dh_new_group_fallback(max)); |
187 | } | 187 | } |
188 | 188 | ||
@@ -203,7 +203,7 @@ choose_dh(int min, int wantbits, int max) | |||
203 | fclose(f); | 203 | fclose(f); |
204 | if (linenum != which+1) { | 204 | if (linenum != which+1) { |
205 | logit("WARNING: line %d disappeared in %s, giving up", | 205 | logit("WARNING: line %d disappeared in %s, giving up", |
206 | which, _PATH_DH_PRIMES); | 206 | which, _PATH_DH_MODULI); |
207 | return (dh_new_group_fallback(max)); | 207 | return (dh_new_group_fallback(max)); |
208 | } | 208 | } |
209 | 209 | ||
@@ -246,12 +246,15 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) | |||
246 | bits_set++; | 246 | bits_set++; |
247 | debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); | 247 | debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); |
248 | 248 | ||
249 | /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ | 249 | /* |
250 | if (bits_set > 1) | 250 | * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial |
251 | return 1; | 251 | */ |
252 | 252 | if (bits_set < 4) { | |
253 | logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); | 253 | logit("invalid public DH value (%d/%d)", |
254 | return 0; | 254 | bits_set, BN_num_bits(dh->p)); |
255 | return 0; | ||
256 | } | ||
257 | return 1; | ||
255 | } | 258 | } |
256 | 259 | ||
257 | int | 260 | int |
@@ -263,6 +266,12 @@ dh_gen_key(DH *dh, int need) | |||
263 | (pbits = BN_num_bits(dh->p)) <= 0 || | 266 | (pbits = BN_num_bits(dh->p)) <= 0 || |
264 | need > INT_MAX / 2 || 2 * need > pbits) | 267 | need > INT_MAX / 2 || 2 * need > pbits) |
265 | return SSH_ERR_INVALID_ARGUMENT; | 268 | return SSH_ERR_INVALID_ARGUMENT; |
269 | if (need < 256) | ||
270 | need = 256; | ||
271 | /* | ||
272 | * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), | ||
273 | * so double requested need here. | ||
274 | */ | ||
266 | dh->length = MIN(need * 2, pbits - 1); | 275 | dh->length = MIN(need * 2, pbits - 1); |
267 | if (DH_generate_key(dh) == 0 || | 276 | if (DH_generate_key(dh) == 0 || |
268 | !dh_pub_is_valid(dh, dh->pub_key)) { | 277 | !dh_pub_is_valid(dh, dh->pub_key)) { |
@@ -305,6 +314,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus) | |||
305 | return (dh); | 314 | return (dh); |
306 | } | 315 | } |
307 | 316 | ||
317 | /* rfc2409 "Second Oakley Group" (1024 bits) */ | ||
308 | DH * | 318 | DH * |
309 | dh_new_group1(void) | 319 | dh_new_group1(void) |
310 | { | 320 | { |
@@ -319,6 +329,7 @@ dh_new_group1(void) | |||
319 | return (dh_new_group_asc(gen, group1)); | 329 | return (dh_new_group_asc(gen, group1)); |
320 | } | 330 | } |
321 | 331 | ||
332 | /* rfc3526 group 14 "2048-bit MODP Group" */ | ||
322 | DH * | 333 | DH * |
323 | dh_new_group14(void) | 334 | dh_new_group14(void) |
324 | { | 335 | { |
@@ -338,12 +349,9 @@ dh_new_group14(void) | |||
338 | return (dh_new_group_asc(gen, group14)); | 349 | return (dh_new_group_asc(gen, group14)); |
339 | } | 350 | } |
340 | 351 | ||
341 | /* | 352 | /* rfc3526 group 16 "4096-bit MODP Group" */ |
342 | * 4k bit fallback group used by DH-GEX if moduli file cannot be read. | ||
343 | * Source: MODP group 16 from RFC3526. | ||
344 | */ | ||
345 | DH * | 353 | DH * |
346 | dh_new_group_fallback(int max) | 354 | dh_new_group16(void) |
347 | { | 355 | { |
348 | static char *gen = "2", *group16 = | 356 | static char *gen = "2", *group16 = |
349 | "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" | 357 | "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" |
@@ -369,12 +377,75 @@ dh_new_group_fallback(int max) | |||
369 | "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199" | 377 | "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199" |
370 | "FFFFFFFF" "FFFFFFFF"; | 378 | "FFFFFFFF" "FFFFFFFF"; |
371 | 379 | ||
372 | if (max < 4096) { | 380 | return (dh_new_group_asc(gen, group16)); |
373 | debug3("requested max size %d, using 2k bit group 14", max); | 381 | } |
382 | |||
383 | /* rfc3526 group 18 "8192-bit MODP Group" */ | ||
384 | DH * | ||
385 | dh_new_group18(void) | ||
386 | { | ||
387 | static char *gen = "2", *group16 = | ||
388 | "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" | ||
389 | "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" | ||
390 | "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" | ||
391 | "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" | ||
392 | "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" | ||
393 | "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" | ||
394 | "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" | ||
395 | "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" | ||
396 | "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" | ||
397 | "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" | ||
398 | "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" | ||
399 | "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" | ||
400 | "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" | ||
401 | "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" | ||
402 | "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" | ||
403 | "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" | ||
404 | "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA" | ||
405 | "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6" | ||
406 | "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED" | ||
407 | "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" | ||
408 | "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492" | ||
409 | "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD" | ||
410 | "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831" | ||
411 | "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B" | ||
412 | "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF" | ||
413 | "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6" | ||
414 | "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3" | ||
415 | "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA" | ||
416 | "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328" | ||
417 | "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C" | ||
418 | "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE" | ||
419 | "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4" | ||
420 | "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300" | ||
421 | "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568" | ||
422 | "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9" | ||
423 | "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B" | ||
424 | "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A" | ||
425 | "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36" | ||
426 | "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1" | ||
427 | "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92" | ||
428 | "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47" | ||
429 | "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71" | ||
430 | "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF"; | ||
431 | |||
432 | return (dh_new_group_asc(gen, group16)); | ||
433 | } | ||
434 | |||
435 | /* Select fallback group used by DH-GEX if moduli file cannot be read. */ | ||
436 | DH * | ||
437 | dh_new_group_fallback(int max) | ||
438 | { | ||
439 | debug3("%s: requested max size %d", __func__, max); | ||
440 | if (max < 3072) { | ||
441 | debug3("using 2k bit group 14"); | ||
374 | return dh_new_group14(); | 442 | return dh_new_group14(); |
443 | } else if (max < 6144) { | ||
444 | debug3("using 4k bit group 16"); | ||
445 | return dh_new_group16(); | ||
375 | } | 446 | } |
376 | debug3("using 4k bit group 16"); | 447 | debug3("using 8k bit group 18"); |
377 | return (dh_new_group_asc(gen, group16)); | 448 | return dh_new_group18(); |
378 | } | 449 | } |
379 | 450 | ||
380 | /* | 451 | /* |
@@ -384,7 +455,6 @@ dh_new_group_fallback(int max) | |||
384 | * Management Part 1 (rev 3) limited by the recommended maximum value | 455 | * Management Part 1 (rev 3) limited by the recommended maximum value |
385 | * from RFC4419 section 3. | 456 | * from RFC4419 section 3. |
386 | */ | 457 | */ |
387 | |||
388 | u_int | 458 | u_int |
389 | dh_estimate(int bits) | 459 | dh_estimate(int bits) |
390 | { | 460 | { |