Commit f12fdd62 authored by Nick Mathewson's avatar Nick Mathewson 👁
Browse files

Be smarter about getting key matter from DH.

Formerly, once we had g^xy, we took the last N bytes from g^xy.

Now, we take SHA(g^xy || [0]) || SHA1(g^xy || [1]) || ... , in order
to use all bits from g^xy equally, and generate as much key material
as we need.


svn:r370
parent ab0f263f
......@@ -798,22 +798,41 @@ int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey, int pubkey_len)
return 0;
}
#undef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
int crypto_dh_compute_secret(crypto_dh_env_t *dh,
char *pubkey, int pubkey_len,
char *secret_out)
char *secret_out, int secret_bytes_out)
{
BIGNUM *pubkey_bn;
unsigned char hash[20];
unsigned char *secret_tmp = NULL;
BIGNUM *pubkey_bn = NULL;
int secret_len;
int i;
assert(dh);
assert(secret_bytes_out/20 <= 255);
if (!(pubkey_bn = BN_bin2bn(pubkey, pubkey_len, NULL)))
return -1;
secret_len = DH_compute_key(secret_out, pubkey_bn, dh->dh);
BN_free(pubkey_bn);
if (secret_len == -1)
return -1;
goto error;
secret_tmp = tor_malloc(crypto_dh_get_bytes(dh)+1);
secret_len = DH_compute_key(secret_tmp, pubkey_bn, dh->dh);
for (i = 0; i < secret_bytes_out; i += 20) {
secret_tmp[secret_len] = (unsigned char) i/20;
if (crypto_SHA_digest(secret_tmp, secret_len+1, hash))
goto error;
memcpy(secret_out+i, hash, MIN(20, secret_bytes_out-i));
}
secret_len = secret_bytes_out;
goto done;
error:
secret_len = -1;
done:
if (pubkey_bn)
BN_free(pubkey_bn);
if (secret_tmp)
free(secret_tmp);
return secret_len;
}
void crypto_dh_free(crypto_dh_env_t *dh)
......
......@@ -81,7 +81,7 @@ int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out,
int pubkey_out_len);
int crypto_dh_compute_secret(crypto_dh_env_t *dh,
char *pubkey, int pubkey_len,
char *secret_out);
char *secret_out, int secret_out_len);
void crypto_dh_free(crypto_dh_env_t *dh);
/* symmetric crypto */
......
......@@ -8,6 +8,21 @@
#include "or.h"
#include "../common/test.h"
void
dump_hex(char *s, int len)
{
static const char TABLE[] = "0123456789ABCDEF";
unsigned char *d = s;
int i, j, nyb;
for(i=0;i<len;++i) {
for (j=1;j>=0;--j) {
nyb = (((int) d[i]) >> (j*4)) & 0x0f;
assert(0<=nyb && nyb <=15);
putchar(TABLE[nyb]);
}
}
}
void
setup_directory() {
char buf[256];
......@@ -178,8 +193,8 @@ test_crypto_dh()
memset(s1, 0, CRYPTO_DH_SIZE);
memset(s2, 0xFF, CRYPTO_DH_SIZE);
s1len = crypto_dh_compute_secret(dh1, p2, CRYPTO_DH_SIZE, s1);
s2len = crypto_dh_compute_secret(dh2, p1, CRYPTO_DH_SIZE, s2);
s1len = crypto_dh_compute_secret(dh1, p2, CRYPTO_DH_SIZE, s1, 50);
s2len = crypto_dh_compute_secret(dh2, p1, CRYPTO_DH_SIZE, s2, 50);
test_assert(s1len > 0);
test_eq(s1len, s2len);
test_memeq(s1, s2, s1len);
......@@ -443,7 +458,6 @@ test_onion_handshake() {
crypto_dh_free(c_dh);
/* FIXME sometimes (infrequently) the following fails! Why? */
if (memcmp(c_keys, s_keys, 40)) {
puts("Aiiiie");
exit(1);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment