[tor-commits] [tor/master] Refactor the API for setting up a block cipher.

nickm at torproject.org nickm at torproject.org
Wed Mar 28 02:39:12 UTC 2012


commit de0dca0de76d9d50aeb5955fe3f435c6c190f8d7
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Mar 20 15:35:43 2012 -0400

    Refactor the API for setting up a block cipher.
    
    It allows us more flexibility on the backend if the user needs to
    specify the key and IV at setup time.
---
 changes/crypto_api     |    3 +
 src/common/aes.c       |   16 ++++-
 src/common/aes.h       |    4 +-
 src/common/crypto.c    |  158 +++++++++++------------------------------------
 src/common/crypto.h    |   17 +----
 src/or/circuitbuild.c  |    4 +-
 src/or/rendcommon.c    |   13 ++---
 src/or/routerparse.c   |   15 ++---
 src/test/bench.c       |   17 ++----
 src/test/test_crypto.c |  135 ++++++++++++++++-------------------------
 10 files changed, 129 insertions(+), 253 deletions(-)

diff --git a/changes/crypto_api b/changes/crypto_api
new file mode 100644
index 0000000..608999f
--- /dev/null
+++ b/changes/crypto_api
@@ -0,0 +1,3 @@
+  o Code refactoring:
+    - Change the symmetric cipher interface so that creating and
+      initializing a stream cipher are no longer separate functions.
diff --git a/src/common/aes.c b/src/common/aes.c
index cfd931f..3121891 100644
--- a/src/common/aes.c
+++ b/src/common/aes.c
@@ -209,14 +209,22 @@ _aes_fill_buf(aes_cnt_cipher_t *cipher)
   }
 }
 
+static void aes_set_key(aes_cnt_cipher_t *cipher, const char *key,
+                        int key_bits);
+static void aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv);
+
 /**
- * Return a newly allocated counter-mode AES128 cipher implementation.
+ * Return a newly allocated counter-mode AES128 cipher implementation,
+ * using the 128-bit key <b>key</b> and the 128-bit IV <b>iv</b>.
  */
 aes_cnt_cipher_t*
-aes_new_cipher(void)
+aes_new_cipher(const char *key, const char *iv)
 {
   aes_cnt_cipher_t* result = tor_malloc_zero(sizeof(aes_cnt_cipher_t));
 
+  aes_set_key(result, key, 128);
+  aes_set_iv(result, iv);
+
   return result;
 }
 
@@ -224,7 +232,7 @@ aes_new_cipher(void)
  * <b>key_bits</b> bits long (must be 128, 192, or 256).  Also resets
  * the counter to 0.
  */
-void
+static void
 aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits)
 {
   if (should_use_EVP) {
@@ -398,7 +406,7 @@ aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len)
 
 /** Reset the 128-bit counter of <b>cipher</b> to the 16-bit big-endian value
  * in <b>iv</b>. */
-void
+static void
 aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv)
 {
 #ifdef USING_COUNTER_VARS
diff --git a/src/common/aes.h b/src/common/aes.h
index f9de68a..04b424e 100644
--- a/src/common/aes.h
+++ b/src/common/aes.h
@@ -16,13 +16,11 @@
 struct aes_cnt_cipher;
 typedef struct aes_cnt_cipher aes_cnt_cipher_t;
 
-aes_cnt_cipher_t* aes_new_cipher(void);
+aes_cnt_cipher_t* aes_new_cipher(const char *key, const char *iv);
 void aes_cipher_free(aes_cnt_cipher_t *cipher);
-void aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits);
 void aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
                char *output);
 void aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len);
-void aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv);
 
 int evaluate_evp_for_aes(int force_value);
 int evaluate_ctr_for_aes(void);
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 02f3d2f..2bd2e1e 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -119,6 +119,7 @@ struct crypto_pk_t
 struct crypto_cipher_t
 {
   char key[CIPHER_KEY_LEN]; /**< The raw key. */
+  char iv[CIPHER_IV_LEN]; /**< The initial IV. */
   aes_cnt_cipher_t *cipher; /**< The key in format usable for counter-mode AES
                              * encryption */
 };
@@ -383,48 +384,37 @@ crypto_pk_free(crypto_pk_t *env)
   tor_free(env);
 }
 
-/** Create a new symmetric cipher for a given key and encryption flag
- * (1=encrypt, 0=decrypt).  Return the crypto object on success; NULL
- * on failure.
+/** Allocate and return a new symmetric cipher using the provided key and iv.
+ * The key is CIPHER_KEY_LEN bytes; the IV is CIPHER_IV_LEN bytes.  If you
+ * provide NULL in place of either one, it is generated at random.
  */
 crypto_cipher_t *
-crypto_create_init_cipher(const char *key, int encrypt_mode)
+crypto_cipher_new_with_iv(const char *key, const char *iv)
 {
-  int r;
-  crypto_cipher_t *crypto = NULL;
-
-  if (! (crypto = crypto_cipher_new())) {
-    log_warn(LD_CRYPTO, "Unable to allocate crypto object");
-    return NULL;
-  }
+  crypto_cipher_t *env;
 
-  crypto_cipher_set_key(crypto, key);
+  env = tor_malloc_zero(sizeof(crypto_cipher_t));
 
-  if (encrypt_mode)
-    r = crypto_cipher_encrypt_init_cipher(crypto);
+  if (key == NULL)
+    crypto_rand(env->key, CIPHER_KEY_LEN);
+  else
+    memcpy(env->key, key, CIPHER_KEY_LEN);
+  if (iv == NULL)
+    crypto_rand(env->iv, CIPHER_IV_LEN);
   else
-    r = crypto_cipher_decrypt_init_cipher(crypto);
+    memcpy(env->iv, iv, CIPHER_IV_LEN);
 
-  if (r)
-    goto error;
-  return crypto;
+  env->cipher = aes_new_cipher(env->key, env->iv);
 
- error:
-  if (crypto)
-    crypto_cipher_free(crypto);
-  return NULL;
+  return env;
 }
 
-/** Allocate and return a new symmetric cipher.
- */
 crypto_cipher_t *
-crypto_cipher_new(void)
+crypto_cipher_new(const char *key)
 {
-  crypto_cipher_t *env;
-
-  env = tor_malloc_zero(sizeof(crypto_cipher_t));
-  env->cipher = aes_new_cipher();
-  return env;
+  char zeroiv[CIPHER_IV_LEN];
+  memset(zeroiv, 0, sizeof(zeroiv));
+  return crypto_cipher_new_with_iv(key, zeroiv);
 }
 
 /** Free a symmetric cipher.
@@ -1043,12 +1033,8 @@ crypto_pk_public_hybrid_encrypt(crypto_pk_t *env,
   tor_assert(tolen >= fromlen + overhead + CIPHER_KEY_LEN);
   tor_assert(tolen >= pkeylen);
 
-  cipher = crypto_cipher_new();
-  if (!cipher) return -1;
-  if (crypto_cipher_generate_key(cipher)<0)
-    goto err;
-  if (crypto_cipher_encrypt_init_cipher(cipher)<0)
-    goto err;
+  cipher = crypto_cipher_new(NULL); /* generate a new key. */
+
   buf = tor_malloc(pkeylen+1);
   memcpy(buf, cipher->key, CIPHER_KEY_LEN);
   memcpy(buf+CIPHER_KEY_LEN, from, pkeylen-overhead-CIPHER_KEY_LEN);
@@ -1113,7 +1099,7 @@ crypto_pk_private_hybrid_decrypt(crypto_pk_t *env,
            "No room for a symmetric key");
     goto err;
   }
-  cipher = crypto_create_init_cipher(buf, 0);
+  cipher = crypto_cipher_new(buf);
   if (!cipher) {
     goto err;
   }
@@ -1301,49 +1287,6 @@ crypto_pk_check_fingerprint_syntax(const char *s)
 
 /* symmetric crypto */
 
-/** Generate a new random key for the symmetric cipher in <b>env</b>.
- * Return 0 on success, -1 on failure.  Does not initialize the cipher.
- */
-int
-crypto_cipher_generate_key(crypto_cipher_t *env)
-{
-  tor_assert(env);
-
-  return crypto_rand(env->key, CIPHER_KEY_LEN);
-}
-
-/** Set the symmetric key for the cipher in <b>env</b> to the first
- * CIPHER_KEY_LEN bytes of <b>key</b>. Does not initialize the cipher.
- */
-void
-crypto_cipher_set_key(crypto_cipher_t *env, const char *key)
-{
-  tor_assert(env);
-  tor_assert(key);
-
-  memcpy(env->key, key, CIPHER_KEY_LEN);
-}
-
-/** Generate an initialization vector for our AES-CTR cipher; store it
- * in the first CIPHER_IV_LEN bytes of <b>iv_out</b>. */
-void
-crypto_cipher_generate_iv(char *iv_out)
-{
-  crypto_rand(iv_out, CIPHER_IV_LEN);
-}
-
-/** Adjust the counter of <b>env</b> to point to the first byte of the block
- * corresponding to the encryption of the CIPHER_IV_LEN bytes at
- * <b>iv</b>.  */
-int
-crypto_cipher_set_iv(crypto_cipher_t *env, const char *iv)
-{
-  tor_assert(env);
-  tor_assert(iv);
-  aes_set_iv(env->cipher, iv);
-  return 0;
-}
-
 /** Return a pointer to the key set for the cipher in <b>env</b>.
  */
 const char *
@@ -1352,30 +1295,6 @@ crypto_cipher_get_key(crypto_cipher_t *env)
   return env->key;
 }
 
-/** Initialize the cipher in <b>env</b> for encryption.  Return 0 on
- * success, -1 on failure.
- */
-int
-crypto_cipher_encrypt_init_cipher(crypto_cipher_t *env)
-{
-  tor_assert(env);
-
-  aes_set_key(env->cipher, env->key, CIPHER_KEY_LEN*8);
-  return 0;
-}
-
-/** Initialize the cipher in <b>env</b> for decryption. Return 0 on
- * success, -1 on failure.
- */
-int
-crypto_cipher_decrypt_init_cipher(crypto_cipher_t *env)
-{
-  tor_assert(env);
-
-  aes_set_key(env->cipher, env->key, CIPHER_KEY_LEN*8);
-  return 0;
-}
-
 /** Encrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
  * <b>env</b>; on success, store the result to <b>to</b> and return 0.
  * On failure, return -1.
@@ -1424,20 +1343,17 @@ crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
 }
 
 /** Encrypt <b>fromlen</b> bytes (at least 1) from <b>from</b> with the key in
- * <b>cipher</b> to the buffer in <b>to</b> of length
+ * <b>key</b> to the buffer in <b>to</b> of length
  * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> plus
  * CIPHER_IV_LEN bytes for the initialization vector. On success, return the
  * number of bytes written, on failure, return -1.
- *
- * This function adjusts the current position of the counter in <b>cipher</b>
- * to immediately after the encrypted data.
  */
 int
-crypto_cipher_encrypt_with_iv(crypto_cipher_t *cipher,
+crypto_cipher_encrypt_with_iv(const char *key,
                               char *to, size_t tolen,
                               const char *from, size_t fromlen)
 {
-  tor_assert(cipher);
+  crypto_cipher_t *cipher;
   tor_assert(from);
   tor_assert(to);
   tor_assert(fromlen < INT_MAX);
@@ -1447,28 +1363,27 @@ crypto_cipher_encrypt_with_iv(crypto_cipher_t *cipher,
   if (tolen < fromlen + CIPHER_IV_LEN)
     return -1;
 
-  crypto_cipher_generate_iv(to);
-  if (crypto_cipher_set_iv(cipher, to)<0)
-    return -1;
+  cipher = crypto_cipher_new_with_iv(key, NULL);
+
+  memcpy(to, cipher->iv, CIPHER_IV_LEN);
   crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen);
+  crypto_cipher_free(cipher);
   return (int)(fromlen + CIPHER_IV_LEN);
 }
 
 /** Decrypt <b>fromlen</b> bytes (at least 1+CIPHER_IV_LEN) from <b>from</b>
- * with the key in <b>cipher</b> to the buffer in <b>to</b> of length
+ * with the key in <b>key</b> to the buffer in <b>to</b> of length
  * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> minus
  * CIPHER_IV_LEN bytes for the initialization vector. On success, return the
  * number of bytes written, on failure, return -1.
- *
- * This function adjusts the current position of the counter in <b>cipher</b>
- * to immediately after the decrypted data.
  */
 int
-crypto_cipher_decrypt_with_iv(crypto_cipher_t *cipher,
+crypto_cipher_decrypt_with_iv(const char *key,
                               char *to, size_t tolen,
                               const char *from, size_t fromlen)
 {
-  tor_assert(cipher);
+  crypto_cipher_t *cipher;
+  tor_assert(key);
   tor_assert(from);
   tor_assert(to);
   tor_assert(fromlen < INT_MAX);
@@ -1478,9 +1393,10 @@ crypto_cipher_decrypt_with_iv(crypto_cipher_t *cipher,
   if (tolen < fromlen - CIPHER_IV_LEN)
     return -1;
 
-  if (crypto_cipher_set_iv(cipher, from)<0)
-    return -1;
+  cipher = crypto_cipher_new_with_iv(key, from);
+
   crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN);
+  crypto_cipher_free(cipher);
   return (int)(fromlen - CIPHER_IV_LEN);
 }
 
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 1c5ee0d..00ac26b 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -125,11 +125,8 @@ void crypto_pk_free(crypto_pk_t *env);
 
 void crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname);
 
-/* convenience function: wraps crypto_cipher_new, set_key, and init. */
-crypto_cipher_t *crypto_create_init_cipher(const char *key,
-                                               int encrypt_mode);
-
-crypto_cipher_t *crypto_cipher_new(void);
+crypto_cipher_t *crypto_cipher_new(const char *key);
+crypto_cipher_t *crypto_cipher_new_with_iv(const char *key, const char *iv);
 void crypto_cipher_free(crypto_cipher_t *env);
 
 /* public key crypto */
@@ -189,13 +186,7 @@ int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space);
 int crypto_pk_check_fingerprint_syntax(const char *s);
 
 /* symmetric crypto */
-int crypto_cipher_generate_key(crypto_cipher_t *env);
-void crypto_cipher_set_key(crypto_cipher_t *env, const char *key);
-void crypto_cipher_generate_iv(char *iv_out);
-int crypto_cipher_set_iv(crypto_cipher_t *env, const char *iv);
 const char *crypto_cipher_get_key(crypto_cipher_t *env);
-int crypto_cipher_encrypt_init_cipher(crypto_cipher_t *env);
-int crypto_cipher_decrypt_init_cipher(crypto_cipher_t *env);
 
 int crypto_cipher_encrypt(crypto_cipher_t *env, char *to,
                           const char *from, size_t fromlen);
@@ -203,10 +194,10 @@ int crypto_cipher_decrypt(crypto_cipher_t *env, char *to,
                           const char *from, size_t fromlen);
 int crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *d, size_t len);
 
-int crypto_cipher_encrypt_with_iv(crypto_cipher_t *env,
+int crypto_cipher_encrypt_with_iv(const char *key,
                                   char *to, size_t tolen,
                                   const char *from, size_t fromlen);
-int crypto_cipher_decrypt_with_iv(crypto_cipher_t *env,
+int crypto_cipher_decrypt_with_iv(const char *key,
                                   char *to, size_t tolen,
                                   const char *from, size_t fromlen);
 
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 3948008..1c7367a 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2334,12 +2334,12 @@ circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data,
   crypto_digest_add_bytes(cpath->b_digest, key_data+DIGEST_LEN, DIGEST_LEN);
 
   if (!(cpath->f_crypto =
-        crypto_create_init_cipher(key_data+(2*DIGEST_LEN),1))) {
+        crypto_cipher_new(key_data+(2*DIGEST_LEN)))) {
     log_warn(LD_BUG,"Forward cipher initialization failed.");
     return -1;
   }
   if (!(cpath->b_crypto =
-        crypto_create_init_cipher(key_data+(2*DIGEST_LEN)+CIPHER_KEY_LEN,0))) {
+        crypto_cipher_new(key_data+(2*DIGEST_LEN)+CIPHER_KEY_LEN))) {
     log_warn(LD_BUG,"Backward cipher initialization failed.");
     return -1;
   }
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index 9c7bf51..20bbdaf 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -290,11 +290,10 @@ rend_encrypt_v2_intro_points_basic(char **encrypted_out,
   enc[1] = (uint8_t)client_blocks;
 
   /* Encrypt with random session key. */
-  cipher = crypto_create_init_cipher(session_key, 1);
-  enclen = crypto_cipher_encrypt_with_iv(cipher,
+  enclen = crypto_cipher_encrypt_with_iv(session_key,
       enc + 2 + client_entries_len,
       CIPHER_IV_LEN + strlen(encoded), encoded, strlen(encoded));
-  crypto_cipher_free(cipher);
+
   if (enclen < 0) {
     log_warn(LD_REND, "Could not encrypt introduction point string.");
     goto done;
@@ -307,7 +306,7 @@ rend_encrypt_v2_intro_points_basic(char **encrypted_out,
   SMARTLIST_FOREACH_BEGIN(client_cookies, const char *, cookie) {
     client_part = tor_malloc_zero(REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
     /* Encrypt session key. */
-    cipher = crypto_create_init_cipher(cookie, 1);
+    cipher = crypto_cipher_new(cookie);
     if (crypto_cipher_encrypt(cipher, client_part +
                                   REND_BASIC_AUTH_CLIENT_ID_LEN,
                               session_key, CIPHER_KEY_LEN) < 0) {
@@ -374,18 +373,16 @@ rend_encrypt_v2_intro_points_stealth(char **encrypted_out,
                                      const char *descriptor_cookie)
 {
   int r = -1, enclen;
-  crypto_cipher_t *cipher;
   char *enc;
   tor_assert(encoded);
   tor_assert(descriptor_cookie);
 
   enc = tor_malloc_zero(1 + CIPHER_IV_LEN + strlen(encoded));
   enc[0] = 0x02; /* Auth type */
-  cipher = crypto_create_init_cipher(descriptor_cookie, 1);
-  enclen = crypto_cipher_encrypt_with_iv(cipher, enc + 1,
+  enclen = crypto_cipher_encrypt_with_iv(descriptor_cookie,
+                                         enc + 1,
                                          CIPHER_IV_LEN+strlen(encoded),
                                          encoded, strlen(encoded));
-  crypto_cipher_free(cipher);
   if (enclen < 0) {
     log_warn(LD_REND, "Could not encrypt introduction point string.");
     goto done;
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 95cef93..0aae0aa 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -4887,7 +4887,7 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
       if (tor_memeq(ipos_encrypted + pos, client_id,
                   REND_BASIC_AUTH_CLIENT_ID_LEN)) {
         /* Attempt to decrypt introduction points. */
-        cipher = crypto_create_init_cipher(descriptor_cookie, 0);
+        cipher = crypto_cipher_new(descriptor_cookie);
         if (crypto_cipher_decrypt(cipher, session_key, ipos_encrypted
                                   + pos + REND_BASIC_AUTH_CLIENT_ID_LEN,
                                   CIPHER_KEY_LEN) < 0) {
@@ -4896,13 +4896,13 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
           return -1;
         }
         crypto_cipher_free(cipher);
-        cipher = crypto_create_init_cipher(session_key, 0);
+
         len = ipos_encrypted_size - 2 - client_entries_len - CIPHER_IV_LEN;
         dec = tor_malloc(len);
-        declen = crypto_cipher_decrypt_with_iv(cipher, dec, len,
+        declen = crypto_cipher_decrypt_with_iv(session_key, dec, len,
             ipos_encrypted + 2 + client_entries_len,
             ipos_encrypted_size - 2 - client_entries_len);
-        crypto_cipher_free(cipher);
+
         if (declen < 0) {
           log_warn(LD_REND, "Could not decrypt introduction point string.");
           tor_free(dec);
@@ -4923,7 +4923,6 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
              "check your authorization for this service!");
     return -1;
   } else if (ipos_encrypted[0] == (int)REND_STEALTH_AUTH) {
-    crypto_cipher_t *cipher;
     char *dec;
     int declen;
     if (ipos_encrypted_size < CIPHER_IV_LEN + 2) {
@@ -4932,13 +4931,13 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
       return -1;
     }
     dec = tor_malloc_zero(ipos_encrypted_size - CIPHER_IV_LEN - 1);
-    cipher = crypto_create_init_cipher(descriptor_cookie, 0);
-    declen = crypto_cipher_decrypt_with_iv(cipher, dec,
+
+    declen = crypto_cipher_decrypt_with_iv(descriptor_cookie, dec,
                                            ipos_encrypted_size -
                                                CIPHER_IV_LEN - 1,
                                            ipos_encrypted + 1,
                                            ipos_encrypted_size - 1);
-    crypto_cipher_free(cipher);
+
     if (declen < 0) {
       log_warn(LD_REND, "Decrypting introduction points failed!");
       tor_free(dec);
diff --git a/src/test/bench.c b/src/test/bench.c
index a662bd2..3081814 100644
--- a/src/test/bench.c
+++ b/src/test/bench.c
@@ -77,9 +77,8 @@ bench_aes(void)
   uint64_t start, end;
   const int bytes_per_iter = (1<<24);
   reset_perftime();
-  c = crypto_cipher_new();
-  crypto_cipher_generate_key(c);
-  crypto_cipher_encrypt_init_cipher(c);
+  c = crypto_cipher_new(NULL);
+
   for (len = 1; len <= 8192; len *= 2) {
     int iters = bytes_per_iter / len;
     b1 = tor_malloc_zero(len);
@@ -108,9 +107,7 @@ bench_cell_aes(void)
   crypto_cipher_t *c;
   int i, misalign;
 
-  c = crypto_cipher_new();
-  crypto_cipher_generate_key(c);
-  crypto_cipher_encrypt_init_cipher(c);
+  c = crypto_cipher_new(NULL);
 
   reset_perftime();
   for (misalign = 0; misalign <= max_misalign; ++misalign) {
@@ -221,12 +218,8 @@ bench_cell_ops(void)
   or_circ->_base.purpose = CIRCUIT_PURPOSE_OR;
 
   /* Initialize crypto */
-  or_circ->p_crypto = crypto_cipher_new();
-  crypto_cipher_generate_key(or_circ->p_crypto);
-  crypto_cipher_encrypt_init_cipher(or_circ->p_crypto);
-  or_circ->n_crypto = crypto_cipher_new();
-  crypto_cipher_generate_key(or_circ->n_crypto);
-  crypto_cipher_encrypt_init_cipher(or_circ->n_crypto);
+  or_circ->p_crypto = crypto_cipher_new(NULL);
+  or_circ->n_crypto = crypto_cipher_new(NULL);
   or_circ->p_digest = crypto_digest_new();
   or_circ->n_digest = crypto_digest_new();
 
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 3f9029a..95a3361 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -118,14 +118,10 @@ test_crypto_aes(void *arg)
 
   memset(data2, 0, 1024);
   memset(data3, 0, 1024);
-  env1 = crypto_cipher_new();
+  env1 = crypto_cipher_new(NULL);
   test_neq(env1, 0);
-  env2 = crypto_cipher_new();
+  env2 = crypto_cipher_new(crypto_cipher_get_key(env1));
   test_neq(env2, 0);
-  j = crypto_cipher_generate_key(env1);
-  crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
-  crypto_cipher_encrypt_init_cipher(env1);
-  crypto_cipher_decrypt_init_cipher(env2);
 
   /* Try encrypting 512 chars. */
   crypto_cipher_encrypt(env1, data2, data1, 512);
@@ -155,10 +151,8 @@ test_crypto_aes(void *arg)
   env2 = NULL;
 
   memset(data3, 0, 1024);
-  env2 = crypto_cipher_new();
+  env2 = crypto_cipher_new(crypto_cipher_get_key(env1));
   test_neq(env2, 0);
-  crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
-  crypto_cipher_encrypt_init_cipher(env2);
   for (j = 0; j < 1024-16; j += 17) {
     crypto_cipher_encrypt(env2, data3+j, data1+j, 17);
   }
@@ -174,10 +168,9 @@ test_crypto_aes(void *arg)
   env2 = NULL;
 
   /* NIST test vector for aes. */
-  env1 = crypto_cipher_new(); /* IV starts at 0 */
-  crypto_cipher_set_key(env1, "\x80\x00\x00\x00\x00\x00\x00\x00"
-                              "\x00\x00\x00\x00\x00\x00\x00\x00");
-  crypto_cipher_encrypt_init_cipher(env1);
+  /* IV starts at 0 */
+  env1 = crypto_cipher_new("\x80\x00\x00\x00\x00\x00\x00\x00"
+                           "\x00\x00\x00\x00\x00\x00\x00\x00");
   crypto_cipher_encrypt(env1, data1,
                         "\x00\x00\x00\x00\x00\x00\x00\x00"
                         "\x00\x00\x00\x00\x00\x00\x00\x00", 16);
@@ -185,37 +178,55 @@ test_crypto_aes(void *arg)
 
   /* Now test rollover.  All these values are originally from a python
    * script. */
-  crypto_cipher_set_iv(env1, "\x00\x00\x00\x00\x00\x00\x00\x00"
-                             "\xff\xff\xff\xff\xff\xff\xff\xff");
+  crypto_cipher_free(env1);
+  env1 = crypto_cipher_new_with_iv(
+                                   "\x80\x00\x00\x00\x00\x00\x00\x00"
+                                   "\x00\x00\x00\x00\x00\x00\x00\x00",
+                                   "\x00\x00\x00\x00\x00\x00\x00\x00"
+                                   "\xff\xff\xff\xff\xff\xff\xff\xff");
   memset(data2, 0,  1024);
   crypto_cipher_encrypt(env1, data1, data2, 32);
   test_memeq_hex(data1, "335fe6da56f843199066c14a00a40231"
                         "cdd0b917dbc7186908a6bfb5ffd574d3");
-
-  crypto_cipher_set_iv(env1, "\x00\x00\x00\x00\xff\xff\xff\xff"
-                             "\xff\xff\xff\xff\xff\xff\xff\xff");
+  crypto_cipher_free(env1);
+  env1 = crypto_cipher_new_with_iv(
+                                   "\x80\x00\x00\x00\x00\x00\x00\x00"
+                                   "\x00\x00\x00\x00\x00\x00\x00\x00",
+                                   "\x00\x00\x00\x00\xff\xff\xff\xff"
+                                   "\xff\xff\xff\xff\xff\xff\xff\xff");
   memset(data2, 0,  1024);
   crypto_cipher_encrypt(env1, data1, data2, 32);
   test_memeq_hex(data1, "e627c6423fa2d77832a02b2794094b73"
                         "3e63c721df790d2c6469cc1953a3ffac");
-
-  crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff"
-                             "\xff\xff\xff\xff\xff\xff\xff\xff");
+  crypto_cipher_free(env1);
+  env1 = crypto_cipher_new_with_iv(
+                                   "\x80\x00\x00\x00\x00\x00\x00\x00"
+                                   "\x00\x00\x00\x00\x00\x00\x00\x00",
+                                   "\xff\xff\xff\xff\xff\xff\xff\xff"
+                                   "\xff\xff\xff\xff\xff\xff\xff\xff");
   memset(data2, 0,  1024);
   crypto_cipher_encrypt(env1, data1, data2, 32);
   test_memeq_hex(data1, "2aed2bff0de54f9328efd070bf48f70a"
                         "0EDD33D3C621E546455BD8BA1418BEC8");
 
   /* Now check rollover on inplace cipher. */
-  crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff"
-                             "\xff\xff\xff\xff\xff\xff\xff\xff");
+  crypto_cipher_free(env1);
+  env1 = crypto_cipher_new_with_iv(
+                                   "\x80\x00\x00\x00\x00\x00\x00\x00"
+                                   "\x00\x00\x00\x00\x00\x00\x00\x00",
+                                   "\xff\xff\xff\xff\xff\xff\xff\xff"
+                                   "\xff\xff\xff\xff\xff\xff\xff\xff");
   crypto_cipher_crypt_inplace(env1, data2, 64);
   test_memeq_hex(data2, "2aed2bff0de54f9328efd070bf48f70a"
                         "0EDD33D3C621E546455BD8BA1418BEC8"
                         "93e2c5243d6839eac58503919192f7ae"
                         "1908e67cafa08d508816659c2e693191");
-  crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff"
-                             "\xff\xff\xff\xff\xff\xff\xff\xff");
+  crypto_cipher_free(env1);
+  env1 = crypto_cipher_new_with_iv(
+                                   "\x80\x00\x00\x00\x00\x00\x00\x00"
+                                   "\x00\x00\x00\x00\x00\x00\x00\x00",
+                                   "\xff\xff\xff\xff\xff\xff\xff\xff"
+                                   "\xff\xff\xff\xff\xff\xff\xff\xff");
   crypto_cipher_crypt_inplace(env1, data2, 64);
   test_assert(tor_mem_is_zero(data2, 64));
 
@@ -674,7 +685,6 @@ test_crypto_s2k(void)
 static void
 test_crypto_aes_iv(void *arg)
 {
-  crypto_cipher_t *cipher;
   char *plain, *encrypted1, *encrypted2, *decrypted1, *decrypted2;
   char plain_1[1], plain_15[15], plain_16[16], plain_17[17];
   char key1[16], key2[16];
@@ -698,113 +708,76 @@ test_crypto_aes_iv(void *arg)
   crypto_rand(plain_17, 17);
   key1[0] = key2[0] + 128; /* Make sure that contents are different. */
   /* Encrypt and decrypt with the same key. */
-  cipher = crypto_create_init_cipher(key1, 1);
-  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 4095,
+  encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 4095,
                                                  plain, 4095);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
+
   test_eq(encrypted_size, 16 + 4095);
   tt_assert(encrypted_size > 0); /* This is obviously true, since 4111 is
                                    * greater than 0, but its truth is not
                                    * obvious to all analysis tools. */
-  cipher = crypto_create_init_cipher(key1, 0);
-  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095,
+  decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 4095,
                                              encrypted1, encrypted_size);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
+
   test_eq(decrypted_size, 4095);
   tt_assert(decrypted_size > 0);
   test_memeq(plain, decrypted1, 4095);
   /* Encrypt a second time (with a new random initialization vector). */
-  cipher = crypto_create_init_cipher(key1, 1);
-  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted2, 16 + 4095,
+  encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted2, 16 + 4095,
                                              plain, 4095);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
+
   test_eq(encrypted_size, 16 + 4095);
   tt_assert(encrypted_size > 0);
-  cipher = crypto_create_init_cipher(key1, 0);
-  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095,
+  decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted2, 4095,
                                              encrypted2, encrypted_size);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_eq(decrypted_size, 4095);
   tt_assert(decrypted_size > 0);
   test_memeq(plain, decrypted2, 4095);
   test_memneq(encrypted1, encrypted2, encrypted_size);
   /* Decrypt with the wrong key. */
-  cipher = crypto_create_init_cipher(key2, 0);
-  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095,
+  decrypted_size = crypto_cipher_decrypt_with_iv(key2, decrypted2, 4095,
                                              encrypted1, encrypted_size);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_memneq(plain, decrypted2, encrypted_size);
   /* Alter the initialization vector. */
   encrypted1[0] += 42;
-  cipher = crypto_create_init_cipher(key1, 0);
-  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095,
+  decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 4095,
                                              encrypted1, encrypted_size);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_memneq(plain, decrypted2, 4095);
   /* Special length case: 1. */
-  cipher = crypto_create_init_cipher(key1, 1);
-  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 1,
+  encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 1,
                                              plain_1, 1);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_eq(encrypted_size, 16 + 1);
   tt_assert(encrypted_size > 0);
-  cipher = crypto_create_init_cipher(key1, 0);
-  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 1,
+  decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 1,
                                              encrypted1, encrypted_size);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_eq(decrypted_size, 1);
   tt_assert(decrypted_size > 0);
   test_memeq(plain_1, decrypted1, 1);
   /* Special length case: 15. */
-  cipher = crypto_create_init_cipher(key1, 1);
-  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 15,
+  encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 15,
                                              plain_15, 15);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_eq(encrypted_size, 16 + 15);
   tt_assert(encrypted_size > 0);
-  cipher = crypto_create_init_cipher(key1, 0);
-  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 15,
+  decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 15,
                                              encrypted1, encrypted_size);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_eq(decrypted_size, 15);
   tt_assert(decrypted_size > 0);
   test_memeq(plain_15, decrypted1, 15);
   /* Special length case: 16. */
-  cipher = crypto_create_init_cipher(key1, 1);
-  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 16,
+  encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 16,
                                              plain_16, 16);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_eq(encrypted_size, 16 + 16);
   tt_assert(encrypted_size > 0);
-  cipher = crypto_create_init_cipher(key1, 0);
-  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 16,
+  decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 16,
                                              encrypted1, encrypted_size);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_eq(decrypted_size, 16);
   tt_assert(decrypted_size > 0);
   test_memeq(plain_16, decrypted1, 16);
   /* Special length case: 17. */
-  cipher = crypto_create_init_cipher(key1, 1);
-  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 17,
+  encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 17,
                                              plain_17, 17);
-  crypto_cipher_free(cipher);
-  cipher = NULL;
   test_eq(encrypted_size, 16 + 17);
   tt_assert(encrypted_size > 0);
-  cipher = crypto_create_init_cipher(key1, 0);
-  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 17,
+  decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 17,
                                              encrypted1, encrypted_size);
   test_eq(decrypted_size, 17);
   tt_assert(decrypted_size > 0);
@@ -817,8 +790,6 @@ test_crypto_aes_iv(void *arg)
   tor_free(encrypted2);
   tor_free(decrypted1);
   tor_free(decrypted2);
-  if (cipher)
-    crypto_cipher_free(cipher);
 }
 
 /** Test base32 decoding. */





More information about the tor-commits mailing list