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,