openssh-5.9p1-xauthlocalhostname.diff
[platform/upstream/openssh.git] / dh.c
diff --git a/dh.c b/dh.c
index d943ca1..3331cda 100644 (file)
--- a/dh.c
+++ b/dh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.c,v 1.49 2011/12/07 05:44:38 djm Exp $ */
+/* $OpenBSD: dh.c,v 1.53 2013/11/21 00:45:44 djm Exp $ */
 /*
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  *
@@ -48,6 +48,7 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
        const char *errstr = NULL;
        long long n;
 
+       dhg->p = dhg->g = NULL;
        cp = line;
        if ((arg = strdelim(&cp)) == NULL)
                return 0;
@@ -59,66 +60,85 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
 
        /* time */
        if (cp == NULL || *arg == '\0')
-               goto fail;
+               goto truncated;
        arg = strsep(&cp, " "); /* type */
        if (cp == NULL || *arg == '\0')
-               goto fail;
+               goto truncated;
        /* Ensure this is a safe prime */
        n = strtonum(arg, 0, 5, &errstr);
-       if (errstr != NULL || n != MODULI_TYPE_SAFE)
+       if (errstr != NULL || n != MODULI_TYPE_SAFE) {
+               error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
                goto fail;
+       }
        arg = strsep(&cp, " "); /* tests */
        if (cp == NULL || *arg == '\0')
-               goto fail;
+               goto truncated;
        /* Ensure prime has been tested and is not composite */
        n = strtonum(arg, 0, 0x1f, &errstr);
        if (errstr != NULL ||
-           (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE))
+           (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
+               error("moduli:%d: invalid moduli tests flag", linenum);
                goto fail;
+       }
        arg = strsep(&cp, " "); /* tries */
        if (cp == NULL || *arg == '\0')
-               goto fail;
+               goto truncated;
        n = strtonum(arg, 0, 1<<30, &errstr);
-       if (errstr != NULL || n == 0)
+       if (errstr != NULL || n == 0) {
+               error("moduli:%d: invalid primality trial count", linenum);
                goto fail;
+       }
        strsize = strsep(&cp, " "); /* size */
        if (cp == NULL || *strsize == '\0' ||
            (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
-           errstr)
+           errstr) {
+               error("moduli:%d: invalid prime length", linenum);
                goto fail;
+       }
        /* The whole group is one bit larger */
        dhg->size++;
        gen = strsep(&cp, " "); /* gen */
        if (cp == NULL || *gen == '\0')
-               goto fail;
+               goto truncated;
        prime = strsep(&cp, " "); /* prime */
-       if (cp != NULL || *prime == '\0')
+       if (cp != NULL || *prime == '\0') {
+ truncated:
+               error("moduli:%d: truncated", linenum);
                goto fail;
+       }
 
        if ((dhg->g = BN_new()) == NULL)
                fatal("parse_prime: BN_new failed");
        if ((dhg->p = BN_new()) == NULL)
                fatal("parse_prime: BN_new failed");
-       if (BN_hex2bn(&dhg->g, gen) == 0)
-               goto failclean;
-
-       if (BN_hex2bn(&dhg->p, prime) == 0)
-               goto failclean;
-
-       if (BN_num_bits(dhg->p) != dhg->size)
-               goto failclean;
-
-       if (BN_is_zero(dhg->g) || BN_is_one(dhg->g))
-               goto failclean;
+       if (BN_hex2bn(&dhg->g, gen) == 0) {
+               error("moduli:%d: could not parse generator value", linenum);
+               goto fail;
+       }
+       if (BN_hex2bn(&dhg->p, prime) == 0) {
+               error("moduli:%d: could not parse prime value", linenum);
+               goto fail;
+       }
+       if (BN_num_bits(dhg->p) != dhg->size) {
+               error("moduli:%d: prime has wrong size: actual %d listed %d",
+                   linenum, BN_num_bits(dhg->p), dhg->size - 1);
+               goto fail;
+       }
+       if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
+               error("moduli:%d: generator is invalid", linenum);
+               goto fail;
+       }
 
-       return (1);
+       return 1;
 
- failclean:
-       BN_clear_free(dhg->g);
-       BN_clear_free(dhg->p);
  fail:
+       if (dhg->g != NULL)
+               BN_clear_free(dhg->g);
+       if (dhg->p != NULL)
+               BN_clear_free(dhg->p);
+       dhg->g = dhg->p = NULL;
        error("Bad prime description in line %d", linenum);
-       return (0);
+       return 0;
 }
 
 DH *
@@ -234,33 +254,19 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
 void
 dh_gen_key(DH *dh, int need)
 {
-       int i, bits_set, tries = 0;
+       int pbits;
 
-       if (need < 0)
-               fatal("dh_gen_key: need < 0");
+       if (need <= 0)
+               fatal("%s: need <= 0", __func__);
        if (dh->p == NULL)
-               fatal("dh_gen_key: dh->p == NULL");
-       if (need > INT_MAX / 2 || 2 * need >= BN_num_bits(dh->p))
-               fatal("dh_gen_key: group too small: %d (2*need %d)",
-                   BN_num_bits(dh->p), 2*need);
-       do {
-               if (dh->priv_key != NULL)
-                       BN_clear_free(dh->priv_key);
-               if ((dh->priv_key = BN_new()) == NULL)
-                       fatal("dh_gen_key: BN_new failed");
-               /* generate a 2*need bits random private exponent */
-               if (!BN_rand(dh->priv_key, 2*need, 0, 0))
-                       fatal("dh_gen_key: BN_rand failed");
-               if (DH_generate_key(dh) == 0)
-                       fatal("DH_generate_key");
-               for (i = 0, bits_set = 0; i <= BN_num_bits(dh->priv_key); i++)
-                       if (BN_is_bit_set(dh->priv_key, i))
-                               bits_set++;
-               debug2("dh_gen_key: priv key bits set: %d/%d",
-                   bits_set, BN_num_bits(dh->priv_key));
-               if (tries++ > 10)
-                       fatal("dh_gen_key: too many bad keys: giving up");
-       } while (!dh_pub_is_valid(dh, dh->pub_key));
+               fatal("%s: dh->p == NULL", __func__);
+       if ((pbits = BN_num_bits(dh->p)) <= 0)
+               fatal("%s: bits(p) <= 0", __func__);
+       dh->length = MIN(need * 2, pbits - 1);
+       if (DH_generate_key(dh) == 0)
+               fatal("%s: key generation failed", __func__);
+       if (!dh_pub_is_valid(dh, dh->pub_key))
+               fatal("%s: generated invalid key", __func__);
 }
 
 DH *
@@ -332,17 +338,20 @@ dh_new_group14(void)
 
 /*
  * Estimates the group order for a Diffie-Hellman group that has an
- * attack complexity approximately the same as O(2**bits).  Estimate
- * with:  O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
+ * attack complexity approximately the same as O(2**bits).
+ * Values from NIST Special Publication 800-57: Recommendation for Key
+ * Management Part 1 (rev 3) limited by the recommended maximum value
+ * from RFC4419 section 3.
  */
 
 int
 dh_estimate(int bits)
 {
-
+       if (bits <= 112)
+               return 2048;
        if (bits <= 128)
-               return (1024);  /* O(2**86) */
+               return 3072;
        if (bits <= 192)
-               return (2048);  /* O(2**116) */
-       return (4096);          /* O(2**156) */
+               return 7680;
+       return 8192;
 }