diff --git a/ChangeLog b/ChangeLog index 98700e1ea027cadaa61a3bdb66d8871c6e443c9f..8aacc0c99462493316b08b15147062db54a7b829 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2010-07-24 Niels M�ller <nisse@lysator.liu.se> + * aes.h (aes_invert_key): Declare it. + + * aes-set-decrypt-key.c (aes_invert_key): New function, key + inversion code extracted from aes_set_decrypt_key. + (aes_set_decrypt_key): Use aes_invert_key. + * camellia-set-encrypt-key.c (camellia_setup128): Generate unmodified subkeys according to the spec. Moved clever combination of subkeys to camellia_set_encrypt_key. diff --git a/aes-set-decrypt-key.c b/aes-set-decrypt-key.c index b8d01da4c0e10de74639c8f9171fe8fd67aa689b..ec44118acde6a11b3390847eb47d4b491b4df7a6 100644 --- a/aes-set-decrypt-key.c +++ b/aes-set-decrypt-key.c @@ -137,28 +137,50 @@ inv_mix_column(uint32_t *a) #define SWAP(a, b) \ do { uint32_t t_swap = (a); (a) = (b); (b) = t_swap; } while(0) +void +aes_invert_key(struct aes_ctx *dst, + const struct aes_ctx *src) +{ + unsigned nrounds; + unsigned i; + + nrounds = src->nrounds; + + /* Reverse the order of subkeys, in groups of 4. */ + /* FIXME: Instead of reordering the subkeys, change the access order + of aes_decrypt, since it's a separate function anyway? */ + if (src == dst) + { + unsigned j, k; + + for (i = 0, j = nrounds * 4; + i < j; + i += 4, j -= 4) + for (k = 0; k<4; k++) + SWAP(dst->keys[i+k], dst->keys[j+k]); + } + else + { + unsigned k; + + dst->nrounds = nrounds; + for (i = 0; i <= nrounds * 4; i += 4) + for (k = 0; k < 4; k++) + dst->keys[i+k] = src->keys[nrounds * 4 - i + k]; + } + + /* Transform all subkeys but the first and last. */ + for (i = 4; i < 4 * nrounds; i += 4) + inv_mix_column(dst->keys + i); +} + void aes_set_decrypt_key(struct aes_ctx *ctx, unsigned keysize, const uint8_t *key) { - unsigned nkeys; - unsigned i, j, k; - /* We first create subkeys for encryption, * then modify the subkeys for decryption. */ aes_set_encrypt_key(ctx, keysize, key); - - nkeys = (AES_BLOCK_SIZE/4) * (ctx->nrounds + 1); - - /* Reverse the order of subkeys */ - for (i = 0, j = ctx->nrounds * 4; - i < j; - i += 4, j -= 4) - for (k = 0; k<4; k++) - SWAP(ctx->keys[i+k], ctx->keys[j+k]); - - /* Transform all subkeys but the first and last. */ - for (i = 4; i < 4 * ctx->nrounds; i += 4) - inv_mix_column(ctx->keys + i); + aes_invert_key(ctx, ctx); } diff --git a/aes.h b/aes.h index e5155ed8de8a3aa9fe8385fc786bff2a87b15d72..23cc0cfe20a8e780b876a29febba22ab11a996ab 100644 --- a/aes.h +++ b/aes.h @@ -35,6 +35,7 @@ extern "C" { /* Name mangling */ #define aes_set_encrypt_key nettle_aes_set_encrypt_key #define aes_set_decrypt_key nettle_aes_set_decrypt_key +#define aes_invert_key nettle_aes_invert_key #define aes_encrypt nettle_aes_encrypt #define aes_decrypt nettle_aes_decrypt @@ -47,6 +48,9 @@ extern "C" { #define AES_KEY_SIZE 32 +/* FIXME: Change to put nrounds first, to make it possible to use a + truncated ctx struct, with less subkeys, for the shorter key + sizes? */ struct aes_ctx { uint32_t keys[60]; /* maximum size of key schedule */ @@ -56,10 +60,15 @@ struct aes_ctx void aes_set_encrypt_key(struct aes_ctx *ctx, unsigned length, const uint8_t *key); + void aes_set_decrypt_key(struct aes_ctx *ctx, unsigned length, const uint8_t *key); +void +aes_invert_key(struct aes_ctx *dst, + const struct aes_ctx *src); + void aes_encrypt(const struct aes_ctx *ctx, unsigned length, uint8_t *dst,