diff --git a/src/common/crypto.c b/src/common/crypto.c index e80e09ad57..8299173e71 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1436,60 +1436,28 @@ crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey, size_t pubkey_len) } /** Check for bad diffie-hellman public keys (g^x). Return 0 if the key is - * okay, or -1 if it's bad. + * okay (in the subgroup [2,p-2]), or -1 if it's bad. * See http://www.cl.cam.ac.uk/ftp/users/rja14/psandqs.ps.gz for some tips. */ static int tor_check_dh_key(BIGNUM *bn) { - /* There are about 2^116 ways to have a 1024-bit key with <= 16 bits set, - * and similarly for <= 16 bits unset. This is negligible compared to the - * 2^1024 entry keyspace. */ -#define MIN_DIFFERING_BITS 16 - /* This covers another 2^25 keys, which is still negligible. */ -#define MIN_DIST_FROM_EDGE (1<<24) - /* XXXX Note that this is basically voodoo. Really, we only care about 0, - * 1, and p-1. The "number of bits set" business is inherited from some - * dire warnings in the OpenSSH comments. Real Cryptographers assure us - * that these dire warnings are misplaced. - * - * Still, it can't hurt. -NM We will likely remove all the crud from this - * function in a future version, though. -RD - */ - int i, n_bits, n_set; - BIGNUM *x = NULL; + BIGNUM *x; char *s; tor_assert(bn); x = BN_new(); + tor_assert(x); if (!dh_param_p) init_dh_param(); - if (bn->neg) { - warn(LD_CRYPTO, "Rejecting DH key < 0"); - return -1; - } - if (BN_cmp(bn, dh_param_p)>=0) { - warn(LD_CRYPTO, "Rejecting DH key >= p"); - return -1; - } - n_bits = BN_num_bits(bn); - n_set = 0; - for (i=0; i <= n_bits; ++i) { - if (BN_is_bit_set(bn, i)) - ++n_set; - } - if (n_set < MIN_DIFFERING_BITS || n_set >= n_bits-MIN_DIFFERING_BITS) { - warn(LD_CRYPTO, "Too few/many bits in DH key (%d)", n_set); - goto err; - } - BN_set_word(x, MIN_DIST_FROM_EDGE); + BN_set_word(x, 1); if (BN_cmp(bn,x)<=0) { - warn(LD_CRYPTO, "DH key is too close to 0"); + warn(LD_CRYPTO, "DH key must be at least 2."); goto err; } BN_copy(x,dh_param_p); - BN_sub_word(x, MIN_DIST_FROM_EDGE); + BN_sub_word(x, 1); if (BN_cmp(bn,x)>=0) { - warn(LD_CRYPTO, "DH key is too close to p"); + warn(LD_CRYPTO, "DH key must be at most p-2."); goto err; } BN_free(x); @@ -1497,7 +1465,7 @@ tor_check_dh_key(BIGNUM *bn) err: BN_free(x); s = BN_bn2hex(bn); - warn(LD_CRYPTO, "Rejecting invalid DH key [%s]", s); + warn(LD_CRYPTO, "Rejecting insecure DH key [%s]", s); OPENSSL_free(s); return -1; }