[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r11538: Patch from karsten: remove cbc and make unit tests handle ae (in tor/trunk: . src/common src/or)



Author: nickm
Date: 2007-09-20 16:08:47 -0400 (Thu, 20 Sep 2007)
New Revision: 11538

Modified:
   tor/trunk/
   tor/trunk/src/common/crypto.c
   tor/trunk/src/common/crypto.h
   tor/trunk/src/or/test.c
Log:
 r15231@catbus:  nickm | 2007-09-20 16:04:30 -0400
 Patch from karsten: remove cbc and make unit tests handle aes-ctr-with-iv.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r15231] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/src/common/crypto.c
===================================================================
--- tor/trunk/src/common/crypto.c	2007-09-20 17:28:07 UTC (rev 11537)
+++ tor/trunk/src/common/crypto.c	2007-09-20 20:08:47 UTC (rev 11538)
@@ -1077,15 +1077,17 @@
   return 0;
 }
 
-/** DOCDOC */
+/** 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)
 {
-  /* XXXX020 It's possible we want to get fancier here. */
   crypto_rand(iv_out, CIPHER_IV_LEN);
 }
 
-/** DOCDOC */
+/** 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_env_t *env, const char *iv)
 {
@@ -1161,7 +1163,6 @@
   return 0;
 }
 
-
 /** 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>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> plus
@@ -1180,6 +1181,8 @@
   tor_assert(from);
   tor_assert(to);
 
+  if (fromlen < 1)
+    return -1;
   if (tolen < fromlen + CIPHER_IV_LEN)
     return -1;
 
@@ -1187,11 +1190,10 @@
   if (crypto_cipher_set_iv(cipher, to)<0)
     return -1;
   crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen);
-  crypto_free_cipher_env(cipher);
   return fromlen + CIPHER_IV_LEN;
 }
 
-/** Encrypt <b>fromlen</b> bytes (at least 1+CIPHER_IV_LEN) from <b>from</b>
+/** 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
  * <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
@@ -1209,7 +1211,7 @@
   tor_assert(from);
   tor_assert(to);
 
-  if (fromlen < CIPHER_IV_LEN)
+  if (fromlen <= CIPHER_IV_LEN)
     return -1;
   if (tolen < fromlen - CIPHER_IV_LEN)
     return -1;
@@ -1217,173 +1219,9 @@
   if (crypto_cipher_set_iv(cipher, from)<0)
     return -1;
   crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN);
-  crypto_free_cipher_env(cipher);
   return fromlen - CIPHER_IV_LEN;
 }
 
-#define AES_CIPHER_BLOCK_SIZE 16
-#define AES_IV_SIZE 16
-
-/** Encrypt <b>fromlen</b> bytes (at least 1) from <b>from</b> with the
- * symmetric key <b>key</b> of 16 bytes length to <b>to</b> of length
- * <b>tolen</b> which needs to be <b>fromlen</b>, padded to the next 16
- * bytes, plus exactly 16 bytes for the initialization vector. On success,
- * return the number of bytes written, on failure, return -1.
- */
-int
-crypto_cipher_encrypt_cbc(const char *key, char *to, size_t tolen,
-                          const char *from, size_t fromlen)
-{
-
-  EVP_CIPHER_CTX ctx_msg, ctx_iv; /* cipher contexts for message and IV */
-  unsigned char iv[AES_IV_SIZE]; /* initialization vector */
-  int outlen, tmplen; /* length of encrypted strings (w/ and w/o final data) */
-
-  tor_assert(key);
-  tor_assert(to);
-  tor_assert(tolen >= fromlen + AES_IV_SIZE +
-                    (AES_CIPHER_BLOCK_SIZE - fromlen % AES_CIPHER_BLOCK_SIZE));
-  tor_assert(from);
-  tor_assert(fromlen > 0);
-
-  /* generate random initialization vector */
-  crypto_rand((char *)iv, AES_IV_SIZE);
-
-  /* initialize cipher context for the initialization vector */
-  EVP_CIPHER_CTX_init(&ctx_iv);
-
-  /* disable padding for encryption of initialization vector */
-  EVP_CIPHER_CTX_set_padding(&ctx_iv, 0);
-
-  /* set up cipher context for the initialization vector for encryption with
-   * cipher type AES-128 in ECB mode, default implementation, given key, and
-   * no initialization vector */
-  EVP_EncryptInit_ex(&ctx_iv, EVP_aes_128_ecb(), NULL, (unsigned char *)key,
-                     NULL);
-
-  /* encrypt initialization vector (no padding necessary) and write it to the
-   * first 16 bytes of the result */
-  if (!EVP_EncryptUpdate(&ctx_iv, (unsigned char *)to, &outlen, iv,
-                         AES_IV_SIZE)) {
-    crypto_log_errors(LOG_WARN, "encrypting initialization vector");
-    return -1;
-  }
-
-  /* clear all information from cipher context for the initialization vector
-   * and free up any allocated memory associated with it */
-  EVP_CIPHER_CTX_cleanup(&ctx_iv);
-
-  /* initialize cipher context for the message */
-  EVP_CIPHER_CTX_init(&ctx_msg);
-
-  /* set up cipher context for encryption with cipher type AES-128 in CBC mode,
-   * default implementation, given key, and initialization vector */
-  EVP_EncryptInit_ex(&ctx_msg, EVP_aes_128_cbc(), NULL, (unsigned char *)key,
-                     iv);
-
-  /* encrypt fromlen bytes from buffer from and write the encrypted version to
-   * buffer to */
-  if (!EVP_EncryptUpdate(&ctx_msg,
-                        ((unsigned char *)to) + AES_IV_SIZE, &outlen,
-                        (const unsigned char *)from, (int)fromlen)) {
-    crypto_log_errors(LOG_WARN, "encrypting");
-    return -1;
-  }
-
-  /* encrypt the final data */
-  if (!EVP_EncryptFinal_ex(&ctx_msg,
-                        ((unsigned char *)to) + AES_IV_SIZE + outlen,
-                        &tmplen)) {
-    crypto_log_errors(LOG_WARN, "encrypting the final data");
-    return -1;
-  }
-  outlen += tmplen;
-
-  /* clear all information from cipher context and free up any allocated memory
-   * associated with it */
-  EVP_CIPHER_CTX_cleanup(&ctx_msg);
-
-  /* return number of written bytes */
-  return outlen + AES_IV_SIZE;
-}
-
-/** Decrypt <b>fromlen</b> bytes (at least 1) from <b>from</b> with the
- * symmetric key <b>key</b> of 16 bytes length to <b>to</b> of length
- * <b>tolen</b> which may be <b>fromlen</b> minus 16 for the initialization
- * vector (the size of padding cannot be determined in advance). On success,
- * return the number of bytes written, on failure (NOT including providing
- * the wrong key, which occasionally returns the correct length!), return -1.
- */
-int
-crypto_cipher_decrypt_cbc(const char *key, char *to, size_t tolen,
-                          const char *from, size_t fromlen)
-{
-  EVP_CIPHER_CTX ctx_msg, ctx_iv; /* cipher contexts for message and IV */
-  unsigned char iv[AES_IV_SIZE]; /* initialization vector */
-  int outlen, tmplen; /* length of decrypted strings (w/ and wo/ final data) */
-
-  tor_assert(key);
-  tor_assert(to);
-  tor_assert(tolen >= fromlen - AES_IV_SIZE);
-  tor_assert(from);
-  tor_assert(fromlen > 0);
-
-  /* initialize cipher context for the initialization vector */
-  EVP_CIPHER_CTX_init(&ctx_iv);
-
-  /* disable padding for decryption of initialization vector */
-  EVP_CIPHER_CTX_set_padding(&ctx_iv, 0);
-
-  /* set up cipher context for the initialization vector for decryption with
-   * cipher type AES-128 in ECB mode, default implementation, given key, and
-   * no initialization vector */
-  EVP_DecryptInit_ex(&ctx_iv, EVP_aes_128_ecb(), NULL, (unsigned char *)key,
-                     NULL);
-
-  /* decrypt initialization vector (is not padded) */
-  if (!EVP_DecryptUpdate(&ctx_iv, iv, &outlen, (const unsigned char *)from,
-                         AES_IV_SIZE)) {
-    crypto_log_errors(LOG_WARN, "decrypting initialization vector");
-    return -1;
-  }
-
-  /* clear all information from cipher context for the initialization vector
-   * and free up any allocated memory associate with it */
-  EVP_CIPHER_CTX_cleanup(&ctx_iv);
-
-  /* initialize cipher context for the message */
-  EVP_CIPHER_CTX_init(&ctx_msg);
-
-  /* set up cipher context for decryption with cipher type AES-128 in CBC mode,
-   * default implementation, given key, and initialization vector */
-  EVP_DecryptInit_ex(&ctx_msg, EVP_aes_128_cbc(), NULL, (unsigned char *)key,
-                     iv);
-
-  /* decrypt fromlen-16 bytes from buffer from and write the decrypted version
-   * to buffer to */
-  if (!EVP_DecryptUpdate(&ctx_msg, (unsigned char *)to, &outlen,
-                        ((const unsigned char *)from) + AES_IV_SIZE,
-                        (int)fromlen - AES_IV_SIZE)) {
-    crypto_log_errors(LOG_INFO, "decrypting");
-    return -1;
-  }
-
-  /* decrypt the final data */
-  if (!EVP_DecryptFinal_ex(&ctx_msg, ((unsigned char *)to) + outlen,
-                           &tmplen)) {
-    crypto_log_errors(LOG_INFO, "decrypting the final data");
-    return -1;
-  }
-  outlen += tmplen;
-
-  /* clear all information from cipher context and free up any allocated memory
-   * associate with it */
-  EVP_CIPHER_CTX_cleanup(&ctx_msg);
-
-  /* return number of written bytes */
-  return outlen;
-}
-
 /* SHA-1 */
 
 /** Compute the SHA1 digest of <b>len</b> bytes in data stored in

Modified: tor/trunk/src/common/crypto.h
===================================================================
--- tor/trunk/src/common/crypto.h	2007-09-20 17:28:07 UTC (rev 11537)
+++ tor/trunk/src/common/crypto.h	2007-09-20 20:08:47 UTC (rev 11538)
@@ -135,11 +135,6 @@
                                   char *to, size_t tolen,
                                   const char *from, size_t fromlen);
 
-int crypto_cipher_encrypt_cbc(const char *key, char *to, size_t tolen,
-                              const char *from, size_t fromlen);
-int crypto_cipher_decrypt_cbc(const char *key, char *to, size_t tolen,
-                              const char *from, size_t fromlen);
-
 /* SHA-1 */
 int crypto_digest(char *digest, const char *m, size_t len);
 crypto_digest_env_t *crypto_new_digest_env(void);

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2007-09-20 17:28:07 UTC (rev 11537)
+++ tor/trunk/src/or/test.c	2007-09-20 20:08:47 UTC (rev 11538)
@@ -3033,10 +3033,11 @@
   smartlist_free(allocated);
 }
 
-/* Test AES-CBC encryption and decryption. */
+/* Test AES-CTR encryption and decryption with IV. */
 static void
-test_crypto_aes_cbc(void)
+test_crypto_aes_iv(void)
 {
+  crypto_cipher_env_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];
@@ -3055,61 +3056,88 @@
   crypto_rand(plain_17, 17);
   key1[0] = key2[0] + 128; /* Make sure that contents are different. */
   /* Encrypt and decrypt with the same key. */
-  encrypted_size = crypto_cipher_encrypt_cbc(key1, encrypted1, 4095 + 1 + 16,
+  cipher = crypto_create_init_cipher(key1, 1);
+  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 4095,
                                              plain, 4095);
-  test_eq(encrypted_size, 4095 + 1 + 16);
-  decrypted_size = crypto_cipher_decrypt_cbc(key1, decrypted1, 4095 + 1,
+  crypto_free_cipher_env(cipher);
+  test_eq(encrypted_size, 16 + 4095);
+  cipher = crypto_create_init_cipher(key1, 0);
+  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095,
                                              encrypted1, encrypted_size);
+  crypto_free_cipher_env(cipher);
   test_eq(decrypted_size, 4095);
   test_memeq(plain, decrypted1, 4095);
   /* Encrypt a second time (with a new random initialization vector). */
-  encrypted_size = crypto_cipher_encrypt_cbc(key1, encrypted2, 4095 + 1 + 16,
+  cipher = crypto_create_init_cipher(key1, 1);
+  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted2, 16 + 4095,
                                              plain, 4095);
-  test_eq(encrypted_size, 4095 + 1 + 16);
-  decrypted_size = crypto_cipher_decrypt_cbc(key1, decrypted2, 4095 + 1,
+  crypto_free_cipher_env(cipher);
+  test_eq(encrypted_size, 16 + 4095);
+  cipher = crypto_create_init_cipher(key1, 0);
+  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095,
                                              encrypted2, encrypted_size);
+  crypto_free_cipher_env(cipher);
   test_eq(decrypted_size, 4095);
   test_memeq(plain, decrypted2, 4095);
   test_memneq(encrypted1, encrypted2, encrypted_size);
   /* Decrypt with the wrong key. */
-  decrypted_size = crypto_cipher_decrypt_cbc(key2, decrypted2, 4095 + 1,
+  cipher = crypto_create_init_cipher(key2, 0);
+  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095,
                                              encrypted1, encrypted_size);
+  crypto_free_cipher_env(cipher);
   test_memneq(plain, decrypted2, encrypted_size);
   /* Alter the initialization vector. */
   encrypted1[0] += 42;
-  decrypted_size = crypto_cipher_decrypt_cbc(key1, decrypted1, 4095 + 1,
+  cipher = crypto_create_init_cipher(key1, 0);
+  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095,
                                              encrypted1, encrypted_size);
+  crypto_free_cipher_env(cipher);
   test_memneq(plain, decrypted2, 4095);
   /* Special length case: 1. */
-  encrypted_size = crypto_cipher_encrypt_cbc(key1, encrypted1, 32,
+  cipher = crypto_create_init_cipher(key1, 1);
+  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 1,
                                              plain_1, 1);
-  test_eq(encrypted_size, 32);
-  decrypted_size = crypto_cipher_decrypt_cbc(key1, decrypted1, 16,
-                                             encrypted1, 32);
+  crypto_free_cipher_env(cipher);
+  test_eq(encrypted_size, 16 + 1);
+  cipher = crypto_create_init_cipher(key1, 0);
+  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 1,
+                                             encrypted1, encrypted_size);
+  crypto_free_cipher_env(cipher);
   test_eq(decrypted_size, 1);
   test_memeq(plain_1, decrypted1, 1);
   /* Special length case: 15. */
-  encrypted_size = crypto_cipher_encrypt_cbc(key1, encrypted1, 32,
+  cipher = crypto_create_init_cipher(key1, 1);
+  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 15,
                                              plain_15, 15);
-  test_eq(encrypted_size, 32);
-  decrypted_size = crypto_cipher_decrypt_cbc(key1, decrypted1, 16,
-                                             encrypted1, 32);
+  crypto_free_cipher_env(cipher);
+  test_eq(encrypted_size, 16 + 15);
+  cipher = crypto_create_init_cipher(key1, 0);
+  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 15,
+                                             encrypted1, encrypted_size);
+  crypto_free_cipher_env(cipher);
   test_eq(decrypted_size, 15);
   test_memeq(plain_15, decrypted1, 15);
   /* Special length case: 16. */
-  encrypted_size = crypto_cipher_encrypt_cbc(key1, encrypted1, 48,
+  cipher = crypto_create_init_cipher(key1, 1);
+  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 16,
                                              plain_16, 16);
-  test_eq(encrypted_size, 48);
-  decrypted_size = crypto_cipher_decrypt_cbc(key1, decrypted1, 32,
-                                             encrypted1, 48);
+  crypto_free_cipher_env(cipher);
+  test_eq(encrypted_size, 16 + 16);
+  cipher = crypto_create_init_cipher(key1, 0);
+  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 16,
+                                             encrypted1, encrypted_size);
   test_eq(decrypted_size, 16);
   test_memeq(plain_16, decrypted1, 16);
   /* Special length case: 17. */
-  encrypted_size = crypto_cipher_encrypt_cbc(key1, encrypted1, 48,
+  cipher = crypto_create_init_cipher(key1, 1);
+  encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 17,
                                              plain_17, 17);
-  test_eq(encrypted_size, 48);
-  decrypted_size = crypto_cipher_decrypt_cbc(key1, decrypted1, 32,
-                                             encrypted1, 48);
+  crypto_free_cipher_env(cipher);
+  test_eq(encrypted_size, 16 + 17);
+  cipher = crypto_create_init_cipher(key1, 0);
+  decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 17,
+                                             encrypted1, encrypted_size);
+  crypto_free_cipher_env(cipher);
   test_eq(decrypted_size, 17);
   test_memeq(plain_17, decrypted1, 17);
   /* Free memory. */
@@ -3155,7 +3183,7 @@
   ENT(crypto),
   SUBENT(crypto, dh),
   SUBENT(crypto, s2k),
-  SUBENT(crypto, aes_cbc),
+  SUBENT(crypto, aes_iv),
   SUBENT(crypto, base32_decode),
   ENT(util),
   SUBENT(util, ip6_helpers),