summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-09-19 15:53:38 +0000
committerNick Mathewson <nickm@torproject.org>2007-09-19 15:53:38 +0000
commit7e93139a85b6f912c11d8e26bc512d9330008278 (patch)
treeb693e86a7e4e32349938e94bddf082fed266d684
parent5e81b0ecb8ef0b6747491fe91051097dc3526b4d (diff)
downloadtor-7e93139a85b6f912c11d8e26bc512d9330008278.tar.gz
tor-7e93139a85b6f912c11d8e26bc512d9330008278.zip
r15171@catbus: nickm | 2007-09-19 11:44:54 -0400
Switch our AES implementation from "128 bit counter with to 64 bits set to 0" to a proper implementation of counter mode. Also, add an aes_set_iv function to initialize the counter to a nonzero value. svn:r11518
-rw-r--r--src/common/aes.c49
-rw-r--r--src/common/aes.h3
2 files changed, 46 insertions, 6 deletions
diff --git a/src/common/aes.c b/src/common/aes.c
index 5707e86c3d..fcf37346c4 100644
--- a/src/common/aes.c
+++ b/src/common/aes.c
@@ -137,6 +137,8 @@ struct aes_cnt_cipher {
u32 rk[4*(MAXNR+1)];
int nr;
#endif
+ u32 counter3;
+ u32 counter2;
u32 counter1;
u32 counter0;
u8 buf[16];
@@ -158,12 +160,14 @@ _aes_fill_buf(aes_cnt_cipher_t *cipher)
*/
#if defined(USE_BUILTIN_AES) && defined(USE_RIJNDAEL_COUNTER_OPTIMIZATION)
rijndaelEncrypt(cipher->rk, cipher->nr,
+ cipher->counter3, cipher->counter2,
cipher->counter1, cipher->counter0, cipher->buf);
#else
u32 counter0 = cipher->counter0;
u32 counter1 = cipher->counter1;
+ u32 counter2 = cipher->counter2;
+ u32 counter3 = cipher->counter3;
u8 buf[16];
- memset(buf, 0, 8);
buf[15] = (counter0 >> 0) & 0xff;
buf[14] = (counter0 >> 8) & 0xff;
buf[13] = (counter0 >> 16) & 0xff;
@@ -172,6 +176,14 @@ _aes_fill_buf(aes_cnt_cipher_t *cipher)
buf[10] = (counter1 >> 8) & 0xff;
buf[ 9] = (counter1 >> 16) & 0xff;
buf[ 8] = (counter1 >> 24) & 0xff;
+ buf[ 7] = (counter2 >> 0) & 0xff;
+ buf[ 6] = (counter2 >> 8) & 0xff;
+ buf[ 5] = (counter2 >> 16) & 0xff;
+ buf[ 4] = (counter2 >> 24) & 0xff;
+ buf[ 3] = (counter3 >> 0) & 0xff;
+ buf[ 2] = (counter3 >> 8) & 0xff;
+ buf[ 1] = (counter3 >> 16) & 0xff;
+ buf[ 0] = (counter3 >> 24) & 0xff;
#if defined(USE_OPENSSL_EVP)
{
@@ -221,6 +233,8 @@ aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits)
#endif
cipher->counter0 = 0;
cipher->counter1 = 0;
+ cipher->counter2 = 0;
+ cipher->counter3 = 0;
cipher->pos = 0;
_aes_fill_buf(cipher);
}
@@ -259,12 +273,18 @@ aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
*(output++) = *(input++) ^ cipher->buf[c];
} while (++c != 16);
cipher->pos = c = 0;
- if (! ++cipher->counter0)
- ++cipher->counter1;
+ if (PREDICT_UNLIKELY(! ++cipher->counter0)) {
+ if (PREDICT_UNLIKELY(! ++cipher->counter1)) {
+ if (PREDICT_UNLIKELY(! ++cipher->counter2)) {
+ ++cipher->counter3;
+ }
+ }
+ }
_aes_fill_buf(cipher);
}
}
+#if 0
/** Return the current value of <b>cipher</b>'s counter. */
u64
aes_get_counter(aes_cnt_cipher_t *cipher)
@@ -282,9 +302,25 @@ aes_set_counter(aes_cnt_cipher_t *cipher, u64 counter)
cipher->pos = (u8)(counter & 0x0f);
cipher->counter0 = (u32) ((counter >> 4) & 0xffffffff);
cipher->counter1 = (u32) (counter >> 36);
+
+ _aes_fill_buf(cipher);
+}
+#endif
+
+/** DOCDOC */
+void
+aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv)
+{
+ cipher->counter3 = ntohl(get_uint32(iv));
+ cipher->counter2 = ntohl(get_uint32(iv+4));
+ cipher->counter1 = ntohl(get_uint32(iv+8));
+ cipher->counter0 = ntohl(get_uint32(iv+12));
+ cipher->pos = 0;
+
_aes_fill_buf(cipher);
}
+#if 0
/** Increment <b>cipher</b>'s counter by <b>delta</b>. */
void
aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta)
@@ -293,6 +329,7 @@ aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta)
counter += delta;
aes_set_counter(cipher, counter);
}
+#endif
#ifdef USE_BUILTIN_AES
/*======================================================================*/
@@ -776,7 +813,7 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)
#ifdef USE_RIJNDAEL_COUNTER_OPTIMIZATION
static void
-rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, u32 ctr1, u32 ctr0, u8 ct[16])
+rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, u32 ctr3, u32 ctr2, u32 ctr1, u32 ctr0, u8 ct[16])
#else
static void
rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16])
@@ -792,8 +829,8 @@ rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]
* and add initial round key:
*/
#ifdef USE_RIJNDAEL_COUNTER_OPTIMIZATION
- s0 = rk[0];
- s1 = rk[1];
+ s0 = ctr3 ^ rk[0];
+ s1 = ctr2 ^ rk[1];
s2 = ctr1 ^ rk[2];
s3 = ctr0 ^ rk[3];
#else
diff --git a/src/common/aes.h b/src/common/aes.h
index 0962e7261b..264cf8c1b4 100644
--- a/src/common/aes.h
+++ b/src/common/aes.h
@@ -24,9 +24,12 @@ void aes_free_cipher(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_set_iv(aes_cnt_cipher_t *cipher, const char *iv);
+#if 0
uint64_t aes_get_counter(aes_cnt_cipher_t *cipher);
void aes_set_counter(aes_cnt_cipher_t *cipher, uint64_t counter);
void aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta);
+#endif
#endif