diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-12-08 17:38:32 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-12-08 17:38:32 +0000 |
commit | e9b66ec906895753fc8374c634c8b708933c2762 (patch) | |
tree | ca5557f31ce9fbb052a3b0319fc771d197f00231 /src/common/crypto.c | |
parent | 25303172b815789ce3ee1bde0ed765a4b61ffa74 (diff) | |
download | tor-e9b66ec906895753fc8374c634c8b708933c2762.tar.gz tor-e9b66ec906895753fc8374c634c8b708933c2762.zip |
Document CREATE_FAST better in the code. Move our key expansion algorithm into a separate function in crypto.c
svn:r5530
Diffstat (limited to 'src/common/crypto.c')
-rw-r--r-- | src/common/crypto.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c index 8299173e71..9374103014 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1487,11 +1487,9 @@ crypto_dh_compute_secret(crypto_dh_env_t *dh, const char *pubkey, size_t pubkey_len, char *secret_out, size_t secret_bytes_out) { - char hash[DIGEST_LEN]; char *secret_tmp = NULL; BIGNUM *pubkey_bn = NULL; size_t secret_len=0; - unsigned int i; int result=0; tor_assert(dh); tor_assert(secret_bytes_out/DIGEST_LEN <= 255); @@ -1503,7 +1501,7 @@ crypto_dh_compute_secret(crypto_dh_env_t *dh, warn(LD_CRYPTO,"Rejected invalid g^x"); goto error; } - secret_tmp = tor_malloc(crypto_dh_get_bytes(dh)+1); + secret_tmp = tor_malloc(crypto_dh_get_bytes(dh)); result = DH_compute_key((unsigned char*)secret_tmp, pubkey_bn, dh->dh); if (result < 0) { warn(LD_CRYPTO,"DH_compute_key() failed."); @@ -1517,12 +1515,9 @@ crypto_dh_compute_secret(crypto_dh_env_t *dh, * bytes long. * What are the security implications here? */ - for (i = 0; i < secret_bytes_out; i += DIGEST_LEN) { - secret_tmp[secret_len] = (unsigned char) i/DIGEST_LEN; - if (crypto_digest(hash, secret_tmp, secret_len+1)) - goto error; - memcpy(secret_out+i, hash, MIN(DIGEST_LEN, secret_bytes_out-i)); - } + if (crypto_expand_key_material(secret_tmp, secret_len, + secret_out, secret_bytes_out)<0) + goto error; secret_len = secret_bytes_out; goto done; @@ -1539,6 +1534,44 @@ crypto_dh_compute_secret(crypto_dh_env_t *dh, return secret_len; } +/** Given <b>key_in_len</b> bytes of negotiated randomness in <b>key_in</b> + * ("K"), expand it into <b>key_out_len</b> bytes of negotiated key material in + * <b>key_out</b> by taking the first key_out_len bytes of + * H(K | [00]) | H(K | [01]) | .... + * + * Return 0 on success, -1 on failure. + */ +int +crypto_expand_key_material(const char *key_in, size_t key_in_len, + char *key_out, size_t key_out_len) +{ + int i; + char *cp, *tmp = tor_malloc(key_in_len+1); + char digest[DIGEST_LEN]; + + /* If we try to get more than this amount of key data, we'll repeat blocks.*/ + tor_assert(key_out_len <= DIGEST_LEN*256); + + memcpy(tmp, key_in, key_in_len); + for (cp = key_out, i=0; key_out_len; ++i, cp += DIGEST_LEN) { + tmp[key_in_len] = i; + if (crypto_digest(digest, tmp, key_in_len+1)) + goto err; + memcpy(cp, digest, MIN(DIGEST_LEN, key_out_len)); + if (key_out_len < DIGEST_LEN) + break; + key_out_len -= DIGEST_LEN; + } + memset(tmp, 0, key_in_len+1); + tor_free(tmp); + return 0; + + err: + memset(tmp, 0, key_in_len+1); + tor_free(tmp); + return -1; +} + /** Free a DH key exchange object. */ void |