1 /* $OpenBSD: dh.c,v 1.74 2021/04/03 06:18:40 djm Exp $ */
3 * Copyright (c) 2000 Niels Provos. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
37 #include <openssl/bn.h>
38 #include <openssl/dh.h>
41 #include "pathnames.h"
46 #include "openbsd-compat/openssl-compat.h"
48 static const char *moduli_filename
;
50 void dh_set_moduli_file(const char *filename
)
52 moduli_filename
= filename
;
55 static const char * get_moduli_filename(void)
57 return moduli_filename
? moduli_filename
: _PATH_DH_MODULI
;
61 parse_prime(int linenum
, char *line
, struct dhgroup
*dhg
)
64 char *strsize
, *gen
, *prime
;
65 const char *errstr
= NULL
;
68 dhg
->p
= dhg
->g
= NULL
;
70 if ((arg
= strdelim(&cp
)) == NULL
)
72 /* Ignore leading whitespace */
75 if (!arg
|| !*arg
|| *arg
== '#')
79 if (cp
== NULL
|| *arg
== '\0')
81 arg
= strsep(&cp
, " "); /* type */
82 if (cp
== NULL
|| *arg
== '\0')
84 /* Ensure this is a safe prime */
85 n
= strtonum(arg
, 0, 5, &errstr
);
86 if (errstr
!= NULL
|| n
!= MODULI_TYPE_SAFE
) {
87 error("moduli:%d: type is not %d", linenum
, MODULI_TYPE_SAFE
);
90 arg
= strsep(&cp
, " "); /* tests */
91 if (cp
== NULL
|| *arg
== '\0')
93 /* Ensure prime has been tested and is not composite */
94 n
= strtonum(arg
, 0, 0x1f, &errstr
);
96 (n
& MODULI_TESTS_COMPOSITE
) || !(n
& ~MODULI_TESTS_COMPOSITE
)) {
97 error("moduli:%d: invalid moduli tests flag", linenum
);
100 arg
= strsep(&cp
, " "); /* tries */
101 if (cp
== NULL
|| *arg
== '\0')
103 n
= strtonum(arg
, 0, 1<<30, &errstr
);
104 if (errstr
!= NULL
|| n
== 0) {
105 error("moduli:%d: invalid primality trial count", linenum
);
108 strsize
= strsep(&cp
, " "); /* size */
109 if (cp
== NULL
|| *strsize
== '\0' ||
110 (dhg
->size
= (int)strtonum(strsize
, 0, 64*1024, &errstr
)) == 0 ||
112 error("moduli:%d: invalid prime length", linenum
);
115 /* The whole group is one bit larger */
117 gen
= strsep(&cp
, " "); /* gen */
118 if (cp
== NULL
|| *gen
== '\0')
120 prime
= strsep(&cp
, " "); /* prime */
121 if (cp
!= NULL
|| *prime
== '\0') {
123 error("moduli:%d: truncated", linenum
);
127 if ((dhg
->g
= BN_new()) == NULL
||
128 (dhg
->p
= BN_new()) == NULL
) {
129 error("parse_prime: BN_new failed");
132 if (BN_hex2bn(&dhg
->g
, gen
) == 0) {
133 error("moduli:%d: could not parse generator value", linenum
);
136 if (BN_hex2bn(&dhg
->p
, prime
) == 0) {
137 error("moduli:%d: could not parse prime value", linenum
);
140 if (BN_num_bits(dhg
->p
) != dhg
->size
) {
141 error("moduli:%d: prime has wrong size: actual %d listed %d",
142 linenum
, BN_num_bits(dhg
->p
), dhg
->size
- 1);
145 if (BN_cmp(dhg
->g
, BN_value_one()) <= 0) {
146 error("moduli:%d: generator is invalid", linenum
);
152 BN_clear_free(dhg
->g
);
153 BN_clear_free(dhg
->p
);
154 dhg
->g
= dhg
->p
= NULL
;
159 choose_dh(int min
, int wantbits
, int max
)
164 int best
, bestcount
, which
, linenum
;
167 if ((f
= fopen(get_moduli_filename(), "r")) == NULL
) {
168 logit("WARNING: could not open %s (%s), using fixed modulus",
169 get_moduli_filename(), strerror(errno
));
170 return (dh_new_group_fallback(max
));
174 best
= bestcount
= 0;
175 while (getline(&line
, &linesize
, f
) != -1) {
177 if (!parse_prime(linenum
, line
, &dhg
))
179 BN_clear_free(dhg
.g
);
180 BN_clear_free(dhg
.p
);
182 if (dhg
.size
> max
|| dhg
.size
< min
)
185 if ((dhg
.size
> wantbits
&& dhg
.size
< best
) ||
186 (dhg
.size
> best
&& best
< wantbits
)) {
190 if (dhg
.size
== best
)
198 if (bestcount
== 0) {
200 logit("WARNING: no suitable primes in %s",
201 get_moduli_filename());
202 return (dh_new_group_fallback(max
));
204 which
= arc4random_uniform(bestcount
);
208 while (getline(&line
, &linesize
, f
) != -1) {
210 if (!parse_prime(linenum
, line
, &dhg
))
212 if ((dhg
.size
> max
|| dhg
.size
< min
) ||
214 bestcount
++ != which
) {
215 BN_clear_free(dhg
.g
);
216 BN_clear_free(dhg
.p
);
224 if (bestcount
!= which
+ 1) {
225 logit("WARNING: selected prime disappeared in %s, giving up",
226 get_moduli_filename());
227 return (dh_new_group_fallback(max
));
230 return (dh_new_group(dhg
.g
, dhg
.p
));
233 /* diffie-hellman-groupN-sha1 */
236 dh_pub_is_valid(const DH
*dh
, const BIGNUM
*dh_pub
)
239 int n
= BN_num_bits(dh_pub
);
244 DH_get0_pqg(dh
, &dh_p
, NULL
, NULL
);
246 if (BN_is_negative(dh_pub
)) {
247 logit("invalid public DH value: negative");
250 if (BN_cmp(dh_pub
, BN_value_one()) != 1) { /* pub_exp <= 1 */
251 logit("invalid public DH value: <= 1");
255 if ((tmp
= BN_new()) == NULL
) {
256 error_f("BN_new failed");
259 if (!BN_sub(tmp
, dh_p
, BN_value_one()) ||
260 BN_cmp(dh_pub
, tmp
) != -1) { /* pub_exp > p-2 */
262 logit("invalid public DH value: >= p-1");
267 for (i
= 0; i
<= n
; i
++)
268 if (BN_is_bit_set(dh_pub
, i
))
270 debug2("bits set: %d/%d", bits_set
, BN_num_bits(dh_p
));
273 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
276 logit("invalid public DH value (%d/%d)",
277 bits_set
, BN_num_bits(dh_p
));
284 dh_gen_key(DH
*dh
, int need
)
287 const BIGNUM
*dh_p
, *pub_key
;
289 DH_get0_pqg(dh
, &dh_p
, NULL
, NULL
);
291 if (need
< 0 || dh_p
== NULL
||
292 (pbits
= BN_num_bits(dh_p
)) <= 0 ||
293 need
> INT_MAX
/ 2 || 2 * need
> pbits
)
294 return SSH_ERR_INVALID_ARGUMENT
;
298 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
299 * so double requested need here.
301 if (!DH_set_length(dh
, MINIMUM(need
* 2, pbits
- 1)))
302 return SSH_ERR_LIBCRYPTO_ERROR
;
304 if (DH_generate_key(dh
) == 0)
305 return SSH_ERR_LIBCRYPTO_ERROR
;
306 DH_get0_key(dh
, &pub_key
, NULL
);
307 if (!dh_pub_is_valid(dh
, pub_key
))
308 return SSH_ERR_INVALID_FORMAT
;
313 dh_new_group_asc(const char *gen
, const char *modulus
)
316 BIGNUM
*dh_p
= NULL
, *dh_g
= NULL
;
318 if ((dh
= DH_new()) == NULL
)
320 if (BN_hex2bn(&dh_p
, modulus
) == 0 ||
321 BN_hex2bn(&dh_g
, gen
) == 0)
323 if (!DH_set0_pqg(dh
, dh_p
, NULL
, dh_g
))
334 * This just returns the group, we still need to generate the exchange
338 dh_new_group(BIGNUM
*gen
, BIGNUM
*modulus
)
342 if ((dh
= DH_new()) == NULL
)
344 if (!DH_set0_pqg(dh
, modulus
, NULL
, gen
)) {
352 /* rfc2409 "Second Oakley Group" (1024 bits) */
356 static char *gen
= "2", *group1
=
357 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
358 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
359 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
360 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
361 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
362 "FFFFFFFF" "FFFFFFFF";
364 return (dh_new_group_asc(gen
, group1
));
367 /* rfc3526 group 14 "2048-bit MODP Group" */
371 static char *gen
= "2", *group14
=
372 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
373 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
374 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
375 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
376 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
377 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
378 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
379 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
380 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
381 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
382 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
384 return (dh_new_group_asc(gen
, group14
));
387 /* rfc3526 group 16 "4096-bit MODP Group" */
391 static char *gen
= "2", *group16
=
392 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
393 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
394 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
395 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
396 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
397 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
398 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
399 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
400 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
401 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
402 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
403 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
404 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
405 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
406 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
407 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
408 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
409 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
410 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
411 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
412 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
413 "FFFFFFFF" "FFFFFFFF";
415 return (dh_new_group_asc(gen
, group16
));
418 /* rfc3526 group 18 "8192-bit MODP Group" */
422 static char *gen
= "2", *group18
=
423 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
424 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
425 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
426 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
427 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
428 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
429 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
430 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
431 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
432 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
433 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
434 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
435 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
436 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
437 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
438 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
439 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
440 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
441 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
442 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
443 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
444 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
445 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
446 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
447 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
448 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
449 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
450 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
451 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
452 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
453 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
454 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
455 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
456 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
457 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
458 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
459 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
460 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
461 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
462 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
463 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
464 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
465 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
467 return (dh_new_group_asc(gen
, group18
));
470 /* Select fallback group used by DH-GEX if moduli file cannot be read. */
472 dh_new_group_fallback(int max
)
474 debug3_f("requested max size %d", max
);
476 debug3("using 2k bit group 14");
477 return dh_new_group14();
478 } else if (max
< 6144) {
479 debug3("using 4k bit group 16");
480 return dh_new_group16();
482 debug3("using 8k bit group 18");
483 return dh_new_group18();
487 * Estimates the group order for a Diffie-Hellman group that has an
488 * attack complexity approximately the same as O(2**bits).
489 * Values from NIST Special Publication 800-57: Recommendation for Key
490 * Management Part 1 (rev 3) limited by the recommended maximum value
491 * from RFC4419 section 3.
494 dh_estimate(int bits
)
505 #endif /* WITH_OPENSSL */