]> andersk Git - openssh.git/blame - dh.c
- stevesk@cvs.openbsd.org 2006/07/18 22:27:55
[openssh.git] / dh.c
CommitLineData
62e12ffe 1/* $OpenBSD: dh.c,v 1.37 2006/07/18 22:27:55 stevesk Exp $ */
94ec8c6b 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"
94ec8c6b 27
94ec8c6b 28#include <openssl/bn.h>
29#include <openssl/dh.h>
94ec8c6b 30
94ec8c6b 31#include "dh.h"
42f11eb2 32#include "pathnames.h"
33#include "log.h"
34#include "misc.h"
94ec8c6b 35
396c147e 36static int
94ec8c6b 37parse_prime(int linenum, char *line, struct dhgroup *dhg)
38{
39 char *cp, *arg;
40 char *strsize, *gen, *prime;
fd06fbe0 41 const char *errstr = NULL;
94ec8c6b 42
43 cp = line;
88299971 44 if ((arg = strdelim(&cp)) == NULL)
45 return 0;
94ec8c6b 46 /* Ignore leading whitespace */
47 if (*arg == '\0')
48 arg = strdelim(&cp);
f11fe301 49 if (!arg || !*arg || *arg == '#')
94ec8c6b 50 return 0;
51
52 /* time */
53 if (cp == NULL || *arg == '\0')
54 goto fail;
55 arg = strsep(&cp, " "); /* type */
56 if (cp == NULL || *arg == '\0')
57 goto fail;
58 arg = strsep(&cp, " "); /* tests */
59 if (cp == NULL || *arg == '\0')
60 goto fail;
61 arg = strsep(&cp, " "); /* tries */
62 if (cp == NULL || *arg == '\0')
63 goto fail;
64 strsize = strsep(&cp, " "); /* size */
65 if (cp == NULL || *strsize == '\0' ||
fd06fbe0 66 (dhg->size = (u_int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
67 errstr)
94ec8c6b 68 goto fail;
db1cd2f3 69 /* The whole group is one bit larger */
70 dhg->size++;
94ec8c6b 71 gen = strsep(&cp, " "); /* gen */
72 if (cp == NULL || *gen == '\0')
73 goto fail;
74 prime = strsep(&cp, " "); /* prime */
75 if (cp != NULL || *prime == '\0')
76 goto fail;
77
b775c6f2 78 if ((dhg->g = BN_new()) == NULL)
79 fatal("parse_prime: BN_new failed");
80 if ((dhg->p = BN_new()) == NULL)
81 fatal("parse_prime: BN_new failed");
ec1f12d3 82 if (BN_hex2bn(&dhg->g, gen) == 0)
c8682232 83 goto failclean;
84
ec1f12d3 85 if (BN_hex2bn(&dhg->p, prime) == 0)
c8682232 86 goto failclean;
87
88 if (BN_num_bits(dhg->p) != dhg->size)
89 goto failclean;
94ec8c6b 90
8b0a55ac 91 if (BN_is_zero(dhg->g) || BN_is_one(dhg->g))
92 goto failclean;
93
94ec8c6b 94 return (1);
c8682232 95
96 failclean:
108d362e 97 BN_clear_free(dhg->g);
98 BN_clear_free(dhg->p);
94ec8c6b 99 fail:
54b974dc 100 error("Bad prime description in line %d", linenum);
94ec8c6b 101 return (0);
102}
103
104DH *
db1cd2f3 105choose_dh(int min, int wantbits, int max)
94ec8c6b 106{
107 FILE *f;
cd744742 108 char line[4096];
94ec8c6b 109 int best, bestcount, which;
110 int linenum;
111 struct dhgroup dhg;
112
e2854364 113 if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL &&
114 (f = fopen(_PATH_DH_PRIMES, "r")) == NULL) {
41e5bd9a 115 logit("WARNING: %s does not exist, using fixed modulus",
116 _PATH_DH_MODULI);
117 return (dh_new_group14());
94ec8c6b 118 }
119
120 linenum = 0;
121 best = bestcount = 0;
122 while (fgets(line, sizeof(line), f)) {
123 linenum++;
124 if (!parse_prime(linenum, line, &dhg))
125 continue;
108d362e 126 BN_clear_free(dhg.g);
127 BN_clear_free(dhg.p);
94ec8c6b 128
db1cd2f3 129 if (dhg.size > max || dhg.size < min)
130 continue;
131
132 if ((dhg.size > wantbits && dhg.size < best) ||
133 (dhg.size > best && best < wantbits)) {
94ec8c6b 134 best = dhg.size;
135 bestcount = 0;
136 }
137 if (dhg.size == best)
138 bestcount++;
139 }
826676b3 140 rewind(f);
94ec8c6b 141
142 if (bestcount == 0) {
826676b3 143 fclose(f);
bbe88b6d 144 logit("WARNING: no suitable primes in %s", _PATH_DH_PRIMES);
0875a0a2 145 return (dh_new_group14());
94ec8c6b 146 }
147
94ec8c6b 148 linenum = 0;
149 which = arc4random() % bestcount;
150 while (fgets(line, sizeof(line), f)) {
151 if (!parse_prime(linenum, line, &dhg))
152 continue;
a7ca6275 153 if ((dhg.size > max || dhg.size < min) ||
154 dhg.size != best ||
155 linenum++ != which) {
108d362e 156 BN_clear_free(dhg.g);
157 BN_clear_free(dhg.p);
94ec8c6b 158 continue;
159 }
160 break;
161 }
162 fclose(f);
a7ca6275 163 if (linenum != which+1)
164 fatal("WARNING: line %d disappeared in %s, giving up",
165 which, _PATH_DH_PRIMES);
94ec8c6b 166
167 return (dh_new_group(dhg.g, dhg.p));
168}
03b8f8be 169
41e5bd9a 170/* diffie-hellman-groupN-sha1 */
03b8f8be 171
172int
173dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
174{
175 int i;
176 int n = BN_num_bits(dh_pub);
177 int bits_set = 0;
397d64d2 178 BIGNUM *tmp;
03b8f8be 179
180 if (dh_pub->neg) {
bbe88b6d 181 logit("invalid public DH value: negativ");
03b8f8be 182 return 0;
183 }
397d64d2 184 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
185 logit("invalid public DH value: <= 1");
186 return 0;
187 }
188
189 if ((tmp = BN_new()) == NULL)
190 return (-1);
191 if (!BN_sub(tmp, dh->p, BN_value_one()) ||
192 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
193 BN_clear_free(tmp);
194 logit("invalid public DH value: >= p-1");
195 return 0;
196 }
197 BN_clear_free(tmp);
198
03b8f8be 199 for (i = 0; i <= n; i++)
200 if (BN_is_bit_set(dh_pub, i))
201 bits_set++;
35efb24c 202 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
03b8f8be 203
204 /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
397d64d2 205 if (bits_set > 1)
03b8f8be 206 return 1;
397d64d2 207
bbe88b6d 208 logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
03b8f8be 209 return 0;
210}
211
212void
213dh_gen_key(DH *dh, int need)
214{
e24bb7d5 215 int i, bits_set, tries = 0;
03b8f8be 216
217 if (dh->p == NULL)
218 fatal("dh_gen_key: dh->p == NULL");
bb92e5cc 219 if (need > INT_MAX / 2 || 2 * need >= BN_num_bits(dh->p))
03b8f8be 220 fatal("dh_gen_key: group too small: %d (2*need %d)",
221 BN_num_bits(dh->p), 2*need);
222 do {
223 if (dh->priv_key != NULL)
108d362e 224 BN_clear_free(dh->priv_key);
b775c6f2 225 if ((dh->priv_key = BN_new()) == NULL)
03b8f8be 226 fatal("dh_gen_key: BN_new failed");
227 /* generate a 2*need bits random private exponent */
83a9aa63 228 if (!BN_rand(dh->priv_key, 2*need, 0, 0))
229 fatal("dh_gen_key: BN_rand failed");
03b8f8be 230 if (DH_generate_key(dh) == 0)
231 fatal("DH_generate_key");
e24bb7d5 232 for (i = 0, bits_set = 0; i <= BN_num_bits(dh->priv_key); i++)
03b8f8be 233 if (BN_is_bit_set(dh->priv_key, i))
234 bits_set++;
35efb24c 235 debug2("dh_gen_key: priv key bits set: %d/%d",
03b8f8be 236 bits_set, BN_num_bits(dh->priv_key));
237 if (tries++ > 10)
238 fatal("dh_gen_key: too many bad keys: giving up");
239 } while (!dh_pub_is_valid(dh, dh->pub_key));
240}
241
242DH *
243dh_new_group_asc(const char *gen, const char *modulus)
244{
245 DH *dh;
03b8f8be 246
b775c6f2 247 if ((dh = DH_new()) == NULL)
248 fatal("dh_new_group_asc: DH_new");
03b8f8be 249
ec1f12d3 250 if (BN_hex2bn(&dh->p, modulus) == 0)
03b8f8be 251 fatal("BN_hex2bn p");
ec1f12d3 252 if (BN_hex2bn(&dh->g, gen) == 0)
03b8f8be 253 fatal("BN_hex2bn g");
254
255 return (dh);
256}
257
258/*
259 * This just returns the group, we still need to generate the exchange
260 * value.
261 */
262
263DH *
264dh_new_group(BIGNUM *gen, BIGNUM *modulus)
265{
266 DH *dh;
267
b775c6f2 268 if ((dh = DH_new()) == NULL)
269 fatal("dh_new_group: DH_new");
03b8f8be 270 dh->p = modulus;
271 dh->g = gen;
272
273 return (dh);
274}
275
276DH *
277dh_new_group1(void)
278{
279 static char *gen = "2", *group1 =
280 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
281 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
282 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
283 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
284 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
285 "FFFFFFFF" "FFFFFFFF";
286
287 return (dh_new_group_asc(gen, group1));
288}
a5c9ffdb 289
41e5bd9a 290DH *
291dh_new_group14(void)
292{
293 static char *gen = "2", *group14 =
294 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
295 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
296 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
297 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
298 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
299 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
300 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
301 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
302 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
303 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
304 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
305
306 return (dh_new_group_asc(gen, group14));
307}
308
a5c9ffdb 309/*
310 * Estimates the group order for a Diffie-Hellman group that has an
311 * attack complexity approximately the same as O(2**bits). Estimate
312 * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
313 */
314
315int
316dh_estimate(int bits)
317{
318
b3c35b71 319 if (bits <= 128)
a5c9ffdb 320 return (1024); /* O(2**86) */
b3c35b71 321 if (bits <= 192)
a5c9ffdb 322 return (2048); /* O(2**116) */
323 return (4096); /* O(2**156) */
324}
This page took 0.220482 seconds and 5 git commands to generate.