[tor-commits] [tor/master] Use preferred key-expansion means for pbkdf2, scrypt.
nickm at torproject.org
nickm at torproject.org
Thu Sep 25 16:06:16 UTC 2014
commit 05a6439f1f2265a22ea6c52ba10c86925e72d2ac
Author: Nick Mathewson <nickm at torproject.org>
Date: Sat Aug 30 12:03:20 2014 -0400
Use preferred key-expansion means for pbkdf2, scrypt.
Use HKDF for RFC2440 s2k only.
---
src/common/crypto_s2k.c | 58 ++++++++++++++++++-----------------------------
src/test/test_crypto.c | 2 +-
2 files changed, 23 insertions(+), 37 deletions(-)
diff --git a/src/common/crypto_s2k.c b/src/common/crypto_s2k.c
index 658a773..93c96e7 100644
--- a/src/common/crypto_s2k.c
+++ b/src/common/crypto_s2k.c
@@ -173,7 +173,7 @@ make_specifier(uint8_t *spec_out, uint8_t type, unsigned flags)
* <b>secret_len</b>-byte <b>secret</b> into a <b>key_out_len</b> byte
* <b>key_out</b>. As in RFC2440, the first 8 bytes of s2k_specifier
* are a salt; the 9th byte describes how much iteration to do.
- * Does not support <b>key_out_len</b> > DIGEST_LEN.
+ * If <b>key_out_len</b> > DIGEST_LEN, use HDKF to expand the result.
*/
void
secret_to_key_rfc2440(char *key_out, size_t key_out_len, const char *secret,
@@ -183,6 +183,7 @@ secret_to_key_rfc2440(char *key_out, size_t key_out_len, const char *secret,
uint8_t c;
size_t count, tmplen;
char *tmp;
+ uint8_t buf[DIGEST_LEN];
tor_assert(key_out_len < SIZE_T_CEILING);
#define EXPBIAS 6
@@ -190,8 +191,6 @@ secret_to_key_rfc2440(char *key_out, size_t key_out_len, const char *secret,
count = ((uint32_t)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
#undef EXPBIAS
- tor_assert(key_out_len <= DIGEST_LEN);
-
d = crypto_digest_new();
tmplen = 8+secret_len;
tmp = tor_malloc(tmplen);
@@ -207,8 +206,18 @@ secret_to_key_rfc2440(char *key_out, size_t key_out_len, const char *secret,
count = 0;
}
}
- crypto_digest_get_digest(d, key_out, key_out_len);
+ crypto_digest_get_digest(d, (char*)buf, sizeof(buf));
+
+ if (key_out_len <= sizeof(buf)) {
+ memcpy(key_out, buf, key_out_len);
+ } else {
+ crypto_expand_key_material_rfc5869_sha256(buf, DIGEST_LEN,
+ (const uint8_t*)s2k_specifier, 8,
+ (const uint8_t*)"EXPAND", 6,
+ (uint8_t*)key_out, key_out_len);
+ }
memwipe(tmp, 0, tmplen);
+ memwipe(buf, 0, sizeof(buf));
tor_free(tmp);
crypto_digest_free(d);
}
@@ -228,17 +237,18 @@ secret_to_key_compute_key(uint8_t *key_out, size_t key_out_len,
int type)
{
int rv;
+ if (key_out_len > INT_MAX)
+ return S2K_BAD_LEN;
switch (type) {
case S2K_TYPE_RFC2440:
- secret_to_key_rfc2440((char*)key_out, DIGEST_LEN, secret, secret_len,
+ secret_to_key_rfc2440((char*)key_out, key_out_len, secret, secret_len,
(const char*)spec);
- return DIGEST_LEN;
+ return (int)key_out_len;
case S2K_TYPE_PBKDF2: {
uint8_t log_iters;
- if (spec_len < 1 || secret_len > INT_MAX || spec_len > INT_MAX ||
- key_out_len > INT_MAX)
+ if (spec_len < 1 || secret_len > INT_MAX || spec_len > INT_MAX)
return S2K_BAD_LEN;
log_iters = spec[spec_len-1];
if (log_iters > 31)
@@ -257,8 +267,6 @@ secret_to_key_compute_key(uint8_t *key_out, size_t key_out_len,
uint8_t log_N, log_r, log_p;
uint64_t N;
uint32_t r, p;
- if (key_out_len > INT_MAX)
- return S2K_BAD_LEN;
if (spec_len < 2)
return S2K_BAD_LEN;
log_N = spec[spec_len-2];
@@ -299,8 +307,7 @@ secret_to_key_derivekey(uint8_t *key_out, size_t key_out_len,
{
int legacy_format = 0;
int type = secret_to_key_get_type(spec, spec_len, 0, &legacy_format);
- int keylen, r;
- uint8_t buf[32];
+ int r;
if (type < 0)
return type;
@@ -314,33 +321,12 @@ secret_to_key_derivekey(uint8_t *key_out, size_t key_out_len,
--spec_len;
}
- keylen = secret_to_key_key_len(type);
- tor_assert(keylen > 0);
- tor_assert(keylen <= (int)sizeof(buf));
-
- r = secret_to_key_compute_key(buf, keylen, spec, spec_len,
+ r = secret_to_key_compute_key(key_out, key_out_len, spec, spec_len,
secret, secret_len, type);
if (r < 0)
return r;
-
- tor_assert(r == keylen);
- if (key_out_len <= sizeof(buf)) {
- memcpy(key_out, buf, key_out_len);
- r = S2K_OKAY;
- } else {
- r = crypto_expand_key_material_rfc5869_sha256(buf, keylen,
- spec, spec_len,
- (const uint8_t*)"EXPAND", 6,
- key_out, key_out_len);
- if (r < 0)
- r = S2K_FAILED;
- else
- r = S2K_OKAY;
- }
-
- memwipe(buf, 0, sizeof(buf));
-
- return r;
+ else
+ return S2K_OKAY;
}
/**
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 5b80246..3672684 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -776,7 +776,7 @@ run_s2k_tests(const unsigned flags, const unsigned type,
secret_to_key_derivekey(buf2, sizeof(buf2), buf, speclen,
pw1, strlen(pw1)));
- tt_mem_op(buf2, !=, buf3, keylen);
+ tt_mem_op(buf2, !=, buf3, sizeof(buf2));
memset(buf3, 0, sizeof(buf3));
tt_int_op(S2K_OKAY, ==,
More information about the tor-commits
mailing list