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
This commit is contained in:
Nick Mathewson 2007-09-19 15:53:38 +00:00
parent 5e81b0ecb8
commit 7e93139a85
2 changed files with 46 additions and 6 deletions

View File

@ -137,6 +137,8 @@ struct aes_cnt_cipher {
u32 rk[4*(MAXNR+1)]; u32 rk[4*(MAXNR+1)];
int nr; int nr;
#endif #endif
u32 counter3;
u32 counter2;
u32 counter1; u32 counter1;
u32 counter0; u32 counter0;
u8 buf[16]; 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) #if defined(USE_BUILTIN_AES) && defined(USE_RIJNDAEL_COUNTER_OPTIMIZATION)
rijndaelEncrypt(cipher->rk, cipher->nr, rijndaelEncrypt(cipher->rk, cipher->nr,
cipher->counter3, cipher->counter2,
cipher->counter1, cipher->counter0, cipher->buf); cipher->counter1, cipher->counter0, cipher->buf);
#else #else
u32 counter0 = cipher->counter0; u32 counter0 = cipher->counter0;
u32 counter1 = cipher->counter1; u32 counter1 = cipher->counter1;
u32 counter2 = cipher->counter2;
u32 counter3 = cipher->counter3;
u8 buf[16]; u8 buf[16];
memset(buf, 0, 8);
buf[15] = (counter0 >> 0) & 0xff; buf[15] = (counter0 >> 0) & 0xff;
buf[14] = (counter0 >> 8) & 0xff; buf[14] = (counter0 >> 8) & 0xff;
buf[13] = (counter0 >> 16) & 0xff; buf[13] = (counter0 >> 16) & 0xff;
@ -172,6 +176,14 @@ _aes_fill_buf(aes_cnt_cipher_t *cipher)
buf[10] = (counter1 >> 8) & 0xff; buf[10] = (counter1 >> 8) & 0xff;
buf[ 9] = (counter1 >> 16) & 0xff; buf[ 9] = (counter1 >> 16) & 0xff;
buf[ 8] = (counter1 >> 24) & 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) #if defined(USE_OPENSSL_EVP)
{ {
@ -221,6 +233,8 @@ aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits)
#endif #endif
cipher->counter0 = 0; cipher->counter0 = 0;
cipher->counter1 = 0; cipher->counter1 = 0;
cipher->counter2 = 0;
cipher->counter3 = 0;
cipher->pos = 0; cipher->pos = 0;
_aes_fill_buf(cipher); _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]; *(output++) = *(input++) ^ cipher->buf[c];
} while (++c != 16); } while (++c != 16);
cipher->pos = c = 0; cipher->pos = c = 0;
if (! ++cipher->counter0) if (PREDICT_UNLIKELY(! ++cipher->counter0)) {
++cipher->counter1; if (PREDICT_UNLIKELY(! ++cipher->counter1)) {
if (PREDICT_UNLIKELY(! ++cipher->counter2)) {
++cipher->counter3;
}
}
}
_aes_fill_buf(cipher); _aes_fill_buf(cipher);
} }
} }
#if 0
/** Return the current value of <b>cipher</b>'s counter. */ /** Return the current value of <b>cipher</b>'s counter. */
u64 u64
aes_get_counter(aes_cnt_cipher_t *cipher) 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->pos = (u8)(counter & 0x0f);
cipher->counter0 = (u32) ((counter >> 4) & 0xffffffff); cipher->counter0 = (u32) ((counter >> 4) & 0xffffffff);
cipher->counter1 = (u32) (counter >> 36); 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); _aes_fill_buf(cipher);
} }
#if 0
/** Increment <b>cipher</b>'s counter by <b>delta</b>. */ /** Increment <b>cipher</b>'s counter by <b>delta</b>. */
void void
aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta) 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; counter += delta;
aes_set_counter(cipher, counter); aes_set_counter(cipher, counter);
} }
#endif
#ifdef USE_BUILTIN_AES #ifdef USE_BUILTIN_AES
/*======================================================================*/ /*======================================================================*/
@ -776,7 +813,7 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)
#ifdef USE_RIJNDAEL_COUNTER_OPTIMIZATION #ifdef USE_RIJNDAEL_COUNTER_OPTIMIZATION
static void 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 #else
static void static void
rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) 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: * and add initial round key:
*/ */
#ifdef USE_RIJNDAEL_COUNTER_OPTIMIZATION #ifdef USE_RIJNDAEL_COUNTER_OPTIMIZATION
s0 = rk[0]; s0 = ctr3 ^ rk[0];
s1 = rk[1]; s1 = ctr2 ^ rk[1];
s2 = ctr1 ^ rk[2]; s2 = ctr1 ^ rk[2];
s3 = ctr0 ^ rk[3]; s3 = ctr0 ^ rk[3];
#else #else

View File

@ -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_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, void aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
char *output); 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); uint64_t aes_get_counter(aes_cnt_cipher_t *cipher);
void aes_set_counter(aes_cnt_cipher_t *cipher, uint64_t counter); void aes_set_counter(aes_cnt_cipher_t *cipher, uint64_t counter);
void aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta); void aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta);
#endif
#endif #endif