[tor-commits] [tor/master] Adjust pwbox format: use a random IV each time

nickm at torproject.org nickm at torproject.org
Thu Sep 25 16:06:16 UTC 2014


commit 301114940143b0d950b3a8dd69e2d6ee0bc6244d
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Sep 23 14:47:23 2014 -0400

    Adjust pwbox format: use a random IV each time
    
    Suggested by yawning
---
 src/common/crypto_pwbox.c |   26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/common/crypto_pwbox.c b/src/common/crypto_pwbox.c
index 61b6ebe..c021974 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)





More information about the tor-commits mailing list