summaryrefslogtreecommitdiff
path: root/dh.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-09-13 02:08:33 +0000
committerDamien Miller <djm@mindrot.org>2018-09-13 12:12:33 +1000
commit482d23bcacdd3664f21cc82a5135f66fc598275f (patch)
tree362f697a94da0a765d1dabcfbf33370b2a4df121 /dh.c
parentd70d061828730a56636ab6f1f24fe4a8ccefcfc1 (diff)
upstream: hold our collective noses and use the openssl-1.1.x API in
OpenSSH; feedback and ok tb@ jsing@ markus@ OpenBSD-Commit-ID: cacbcac87ce5da0d3ca7ef1b38a6f7fb349e4417
Diffstat (limited to 'dh.c')
-rw-r--r--dh.c60
1 files changed, 37 insertions, 23 deletions
diff --git a/dh.c b/dh.c
index ac8d5a0ae..d0d4527b1 100644
--- a/dh.c
+++ b/dh.c
@@ -216,14 +216,17 @@ choose_dh(int min, int wantbits, int max)
216/* diffie-hellman-groupN-sha1 */ 216/* diffie-hellman-groupN-sha1 */
217 217
218int 218int
219dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) 219dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
220{ 220{
221 int i; 221 int i;
222 int n = BN_num_bits(dh_pub); 222 int n = BN_num_bits(dh_pub);
223 int bits_set = 0; 223 int bits_set = 0;
224 BIGNUM *tmp; 224 BIGNUM *tmp;
225 const BIGNUM *dh_p;
225 226
226 if (dh_pub->neg) { 227 DH_get0_pqg(dh, &dh_p, NULL, NULL);
228
229 if (BN_is_negative(dh_pub)) {
227 logit("invalid public DH value: negative"); 230 logit("invalid public DH value: negative");
228 return 0; 231 return 0;
229 } 232 }
@@ -236,7 +239,7 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
236 error("%s: BN_new failed", __func__); 239 error("%s: BN_new failed", __func__);
237 return 0; 240 return 0;
238 } 241 }
239 if (!BN_sub(tmp, dh->p, BN_value_one()) || 242 if (!BN_sub(tmp, dh_p, BN_value_one()) ||
240 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ 243 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
241 BN_clear_free(tmp); 244 BN_clear_free(tmp);
242 logit("invalid public DH value: >= p-1"); 245 logit("invalid public DH value: >= p-1");
@@ -247,14 +250,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
247 for (i = 0; i <= n; i++) 250 for (i = 0; i <= n; i++)
248 if (BN_is_bit_set(dh_pub, i)) 251 if (BN_is_bit_set(dh_pub, i))
249 bits_set++; 252 bits_set++;
250 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); 253 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p));
251 254
252 /* 255 /*
253 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial 256 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
254 */ 257 */
255 if (bits_set < 4) { 258 if (bits_set < 4) {
256 logit("invalid public DH value (%d/%d)", 259 logit("invalid public DH value (%d/%d)",
257 bits_set, BN_num_bits(dh->p)); 260 bits_set, BN_num_bits(dh_p));
258 return 0; 261 return 0;
259 } 262 }
260 return 1; 263 return 1;
@@ -264,9 +267,12 @@ int
264dh_gen_key(DH *dh, int need) 267dh_gen_key(DH *dh, int need)
265{ 268{
266 int pbits; 269 int pbits;
270 const BIGNUM *dh_p, *pub_key;
271
272 DH_get0_pqg(dh, &dh_p, NULL, NULL);
267 273
268 if (need < 0 || dh->p == NULL || 274 if (need < 0 || dh_p == NULL ||
269 (pbits = BN_num_bits(dh->p)) <= 0 || 275 (pbits = BN_num_bits(dh_p)) <= 0 ||
270 need > INT_MAX / 2 || 2 * need > pbits) 276 need > INT_MAX / 2 || 2 * need > pbits)
271 return SSH_ERR_INVALID_ARGUMENT; 277 return SSH_ERR_INVALID_ARGUMENT;
272 if (need < 256) 278 if (need < 256)
@@ -275,13 +281,14 @@ dh_gen_key(DH *dh, int need)
275 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), 281 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
276 * so double requested need here. 282 * so double requested need here.
277 */ 283 */
278 dh->length = MINIMUM(need * 2, pbits - 1); 284 if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
279 if (DH_generate_key(dh) == 0 ||
280 !dh_pub_is_valid(dh, dh->pub_key)) {
281 BN_clear_free(dh->priv_key);
282 dh->priv_key = NULL;
283 return SSH_ERR_LIBCRYPTO_ERROR; 285 return SSH_ERR_LIBCRYPTO_ERROR;
284 } 286
287 if (DH_generate_key(dh) == 0)
288 return SSH_ERR_LIBCRYPTO_ERROR;
289 DH_get0_key(dh, &pub_key, NULL);
290 if (!dh_pub_is_valid(dh, pub_key))
291 return SSH_ERR_INVALID_FORMAT;
285 return 0; 292 return 0;
286} 293}
287 294
@@ -289,22 +296,27 @@ DH *
289dh_new_group_asc(const char *gen, const char *modulus) 296dh_new_group_asc(const char *gen, const char *modulus)
290{ 297{
291 DH *dh; 298 DH *dh;
299 BIGNUM *dh_p = NULL, *dh_g = NULL;
292 300
293 if ((dh = DH_new()) == NULL) 301 if ((dh = DH_new()) == NULL)
294 return NULL; 302 return NULL;
295 if (BN_hex2bn(&dh->p, modulus) == 0 || 303 if (BN_hex2bn(&dh_p, modulus) == 0 ||
296 BN_hex2bn(&dh->g, gen) == 0) { 304 BN_hex2bn(&dh_g, gen) == 0)
297 DH_free(dh); 305 goto fail;
298 return NULL; 306 if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
299 } 307 goto fail;
300 return (dh); 308 return dh;
309 fail:
310 DH_free(dh);
311 BN_clear_free(dh_p);
312 BN_clear_free(dh_g);
313 return NULL;
301} 314}
302 315
303/* 316/*
304 * This just returns the group, we still need to generate the exchange 317 * This just returns the group, we still need to generate the exchange
305 * value. 318 * value.
306 */ 319 */
307
308DH * 320DH *
309dh_new_group(BIGNUM *gen, BIGNUM *modulus) 321dh_new_group(BIGNUM *gen, BIGNUM *modulus)
310{ 322{
@@ -312,10 +324,12 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus)
312 324
313 if ((dh = DH_new()) == NULL) 325 if ((dh = DH_new()) == NULL)
314 return NULL; 326 return NULL;
315 dh->p = modulus; 327 if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
316 dh->g = gen; 328 DH_free(dh);
329 return NULL;
330 }
317 331
318 return (dh); 332 return dh;
319} 333}
320 334
321/* rfc2409 "Second Oakley Group" (1024 bits) */ 335/* rfc2409 "Second Oakley Group" (1024 bits) */