diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-09-23 14:47:23 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-09-25 11:58:14 -0400 |
commit | 301114940143b0d950b3a8dd69e2d6ee0bc6244d (patch) | |
tree | 4e252b4bc1537c704a00dab621b3207a48ad8136 /src/common/crypto_pwbox.c | |
parent | d0f5d2b662c3d24f1e704d55d598c43c8d1df0db (diff) | |
download | tor-301114940143b0d950b3a8dd69e2d6ee0bc6244d.tar.gz tor-301114940143b0d950b3a8dd69e2d6ee0bc6244d.zip |
Adjust pwbox format: use a random IV each time
Suggested by yawning
Diffstat (limited to 'src/common/crypto_pwbox.c')
-rw-r--r-- | src/common/crypto_pwbox.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/common/crypto_pwbox.c b/src/common/crypto_pwbox.c index 61b6ebe96f..c021974632 100644 --- a/src/common/crypto_pwbox.c +++ b/src/common/crypto_pwbox.c @@ -8,6 +8,7 @@ /* 7 bytes "TORBOX0" 1 byte: header len (H) H bytes: header, denoting secret key algorithm. + 16 bytes: IV Round up to multiple of 128 bytes, then encrypt: 4 bytes: data len data @@ -15,7 +16,7 @@ 32 bytes: HMAC-SHA256 of all previous bytes. */ -#define MAX_OVERHEAD (S2K_MAXLEN + 8 + 32) +#define MAX_OVERHEAD (S2K_MAXLEN + 8 + 32 + CIPHER_IV_LEN) /** * Make an authenticated passphrase-encrypted blob to encode the @@ -31,7 +32,7 @@ crypto_pwbox(uint8_t **out, size_t *outlen_out, const char *secret, size_t secret_len, unsigned s2k_flags) { - uint8_t *result, *encrypted_portion, *hmac; + uint8_t *result, *encrypted_portion, *hmac, *iv; size_t encrypted_len = 128 * CEIL_DIV(input_len+4, 128); size_t result_len = encrypted_len + MAX_OVERHEAD; int spec_len; @@ -51,9 +52,10 @@ crypto_pwbox(uint8_t **out, size_t *outlen_out, goto err; result[7] = (uint8_t) spec_len; - tor_assert(8 + spec_len + encrypted_len <= result_len); + tor_assert(8 + spec_len + CIPHER_IV_LEN + encrypted_len <= result_len); - encrypted_portion = result + 8 + spec_len; + iv = result + 8 + spec_len; + encrypted_portion = result + 8 + spec_len + CIPHER_IV_LEN; hmac = encrypted_portion + encrypted_len; set_uint32(encrypted_portion, htonl(input_len)); @@ -66,17 +68,20 @@ crypto_pwbox(uint8_t **out, size_t *outlen_out, secret, secret_len) < 0) goto err; - cipher = crypto_cipher_new((char*)keys); + crypto_rand((char*)iv, CIPHER_IV_LEN); + + cipher = crypto_cipher_new_with_iv((char*)keys, (char*)iv); crypto_cipher_crypt_inplace(cipher, (char*)encrypted_portion, encrypted_len); crypto_cipher_free(cipher); crypto_hmac_sha256((char*)hmac, (const char*)keys + CIPHER_KEY_LEN, sizeof(keys)-CIPHER_KEY_LEN, - (const char*)result, 8 + spec_len + encrypted_len); + (const char*)result, + 8 + CIPHER_IV_LEN + spec_len + encrypted_len); *out = result; - *outlen_out = 8 + spec_len + encrypted_len + DIGEST256_LEN; + *outlen_out = 8 + CIPHER_IV_LEN + spec_len + encrypted_len + DIGEST256_LEN; rv = 0; goto out; @@ -104,7 +109,7 @@ crypto_unpwbox(uint8_t **out, size_t *outlen_out, const char *secret, size_t secret_len) { uint8_t *result = NULL; - const uint8_t *encrypted; + const uint8_t *encrypted, *iv; uint8_t keys[CIPHER_KEY_LEN + DIGEST256_LEN]; size_t spec_bytes; uint8_t hmac[DIGEST256_LEN]; @@ -137,10 +142,11 @@ crypto_unpwbox(uint8_t **out, size_t *outlen_out, goto err; } - encrypted = inp + 8 + spec_bytes; + iv = inp + 8 + spec_bytes; + encrypted = inp + 8 + spec_bytes + CIPHER_IV_LEN; /* How long is the plaintext? */ - cipher = crypto_cipher_new((char*)keys); + cipher = crypto_cipher_new_with_iv((char*)keys, (char*)iv); crypto_cipher_decrypt(cipher, (char*)&result_len, (char*)encrypted, 4); result_len = ntohl(result_len); if (input_len < 8 + spec_bytes + 4 + result_len + 32) |