diff --git a/ChangeLog b/ChangeLog
index 9fddab7f2cf810564db4f9a469dfb92fdeaccd63..1306b308b13366f8f668239f90cd7a6e5ac182c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2013-06-25  Niels Möller  <nisse@lysator.liu.se>
+
+	* aes.h (struct aes128_ctx): New aes128 declarations.
+	* aes-decrypt.c (aes128_decrypt): New function.
+	* aes-encrypt.c (aes128_encrypt): New function.
+	* aes128-meta.c: New file.
+	* aes128-set-encrypt-key.c (aes128_set_encrypt_key): New file and
+	function.
+	* aes128-set-decrypt-key.c (aes128_set_decrypt_key)
+	(aes128_invert_key): New file and functions.
+	* Makefile.in (nettle_SOURCES): Added aes128-set-encrypt-key.c,
+	aes128-set-decrypt-key.c and aes128-meta.c.
+
+	* nettle-internal.c (nettle_unified_aes128): For testing the old
+	AES interface.
+	* testsuite/aes-test.c (test_cipher2): New function.
+	(test_main): Test both nettle_aes128 and nettle_unified_aes128.
+
 2013-05-22  Niels Möller  <nisse@lysator.liu.se>
 
 	* Makefile.in (nettle_SOURCES): Added aes-invert-internal.c and
diff --git a/Makefile.in b/Makefile.in
index 05857f7a7da307f2e38c8a2acdbc69c864f915fe..99eb564fc4eda622b933fe622f6a119a2fe3781b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -65,6 +65,8 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
 		 aes-encrypt-internal.c aes-encrypt.c aes-encrypt-table.c \
 		 aes-invert-internal.c aes-set-key-internal.c \
 		 aes-set-encrypt-key.c aes-set-decrypt-key.c aes-meta.c \
+		 aes128-set-encrypt-key.c aes128-set-decrypt-key.c \
+		 aes128-meta.c \
 		 arcfour.c arcfour-crypt.c arcfour-meta.c \
 		 arctwo.c arctwo-meta.c gosthash94-meta.c \
 		 base16-encode.c base16-decode.c base16-meta.c \
diff --git a/aes-decrypt.c b/aes-decrypt.c
index d08eac348752ca9743c17d3742845b6ad8f1e0bb..e8696bf536aca8e0166a58b68c767d76a1528144 100644
--- a/aes-decrypt.c
+++ b/aes-decrypt.c
@@ -345,3 +345,13 @@ aes_decrypt(const struct aes_ctx *ctx,
   _aes_decrypt(ctx->rounds, ctx->keys, &_aes_decrypt_table,
 	       length, dst, src);
 }
+
+void
+aes128_decrypt(const struct aes128_ctx *ctx,
+	       size_t length, uint8_t *dst,
+	       const uint8_t *src)
+{
+  assert(!(length % AES_BLOCK_SIZE) );
+  _aes_decrypt(_AES128_ROUNDS, ctx->keys, &_aes_decrypt_table,
+	       length, dst, src);
+}
diff --git a/aes-encrypt.c b/aes-encrypt.c
index 0077693a2b410d7c1e7d8c14c4abb3d908737694..643276afef3e36dadd9bb2b09a93baba911a8c9a 100644
--- a/aes-encrypt.c
+++ b/aes-encrypt.c
@@ -43,3 +43,13 @@ aes_encrypt(const struct aes_ctx *ctx,
   _aes_encrypt(ctx->rounds, ctx->keys, &_aes_encrypt_table,
 	       length, dst, src);
 }
+
+void
+aes128_encrypt(const struct aes128_ctx *ctx,
+	       size_t length, uint8_t *dst,
+	       const uint8_t *src)
+{
+  assert(!(length % AES_BLOCK_SIZE) );
+  _aes_encrypt(_AES128_ROUNDS, ctx->keys, &_aes_encrypt_table,
+	       length, dst, src);
+}
diff --git a/aes-meta.c b/aes-meta.c
index 7b9af273ed2086661e5a93db5172064e1e10f1ff..3db85f672575a012541b1d808ccbdab380ed6c39 100644
--- a/aes-meta.c
+++ b/aes-meta.c
@@ -28,9 +28,6 @@
 
 #include "aes.h"
 
-const struct nettle_cipher nettle_aes128
-= _NETTLE_CIPHER_SEP(aes, AES, 128);
-
 const struct nettle_cipher nettle_aes192
 = _NETTLE_CIPHER_SEP(aes, AES, 192);
 
diff --git a/aes.h b/aes.h
index 95f7aa5d8504c9d4a0de127ba6b3c742dfffcbc8..74b3fd67b9cf59bd1063b51b21b9fea99d31755e 100644
--- a/aes.h
+++ b/aes.h
@@ -38,6 +38,11 @@ extern "C" {
 #define aes_invert_key nettle_aes_invert_key
 #define aes_encrypt nettle_aes_encrypt
 #define aes_decrypt nettle_aes_decrypt
+#define aes128_set_encrypt_key nettle_aes128set_encrypt_key
+#define aes128_set_decrypt_key nettle_aes128set_decrypt_key
+#define aes128_invert_key nettle_aes128invert_key
+#define aes128_encrypt nettle_aes128encrypt
+#define aes128_decrypt nettle_aes128decrypt
 
 #define AES_BLOCK_SIZE 16
 
@@ -53,6 +58,8 @@ extern "C" {
 #define AES_MIN_KEY_SIZE AES128_KEY_SIZE
 #define AES_MAX_KEY_SIZE AES256_KEY_SIZE
 
+/* Older nettle-2.7 interface */
+
 #define AES_KEY_SIZE 32
 
 struct aes_ctx
@@ -82,6 +89,27 @@ aes_decrypt(const struct aes_ctx *ctx,
 	    size_t length, uint8_t *dst,
 	    const uint8_t *src);
 
+struct aes128_ctx
+{
+  uint32_t keys[4 * (_AES128_ROUNDS + 1)];
+};
+
+void
+aes128_set_encrypt_key(struct aes128_ctx *ctx, const uint8_t *key);
+void
+aes128_set_decrypt_key(struct aes128_ctx *ctx, const uint8_t *key);
+void
+aes128_invert_key(struct aes128_ctx *dst,
+		  const struct aes128_ctx *src);
+void
+aes128_encrypt(const struct aes128_ctx *ctx,
+	       size_t length, uint8_t *dst,
+	       const uint8_t *src);
+void
+aes128_decrypt(const struct aes128_ctx *ctx,
+	       size_t length, uint8_t *dst,
+	       const uint8_t *src);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/aes128-meta.c b/aes128-meta.c
new file mode 100644
index 0000000000000000000000000000000000000000..c3068990392ae4744f0a87e7913daea329f96859
--- /dev/null
+++ b/aes128-meta.c
@@ -0,0 +1,57 @@
+/* aes128-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "nettle-meta.h"
+
+#include "aes.h"
+
+static nettle_set_key_func aes128_set_encrypt_key_wrapper;
+static nettle_set_key_func aes128_set_decrypt_key_wrapper;
+
+static void
+aes128_set_encrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
+{
+  assert (length == AES128_KEY_SIZE);
+  aes128_set_encrypt_key (ctx, key);
+}
+
+static void
+aes128_set_decrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
+{
+  assert (length == AES128_KEY_SIZE);
+  aes128_set_decrypt_key (ctx, key);
+}
+
+const struct nettle_cipher nettle_aes128 =
+  { "aes128", sizeof(struct aes128_ctx),
+    AES_BLOCK_SIZE, AES128_KEY_SIZE,
+    aes128_set_encrypt_key_wrapper,
+    aes128_set_decrypt_key_wrapper,
+    (nettle_crypt_func *) aes128_encrypt,
+    (nettle_crypt_func *) aes128_decrypt
+  };
diff --git a/aes128-set-decrypt-key.c b/aes128-set-decrypt-key.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee3425693a036798d6a39ad86105982b4db1001a
--- /dev/null
+++ b/aes128-set-decrypt-key.c
@@ -0,0 +1,46 @@
+/* aes128-set-decrypt-key.c
+ *
+ * Key setup for the aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013, Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "aes-internal.h"
+#include "macros.h"
+
+void
+aes128_invert_key (struct aes128_ctx *dst, const struct aes128_ctx *src)
+{
+  _aes_invert (_AES128_ROUNDS, dst->keys, src->keys); 
+}
+
+void
+aes128_set_decrypt_key(struct aes128_ctx *ctx, const uint8_t *key)
+{
+  aes128_set_encrypt_key (ctx, key);
+  aes128_invert_key (ctx, ctx);
+}
diff --git a/aes128-set-encrypt-key.c b/aes128-set-encrypt-key.c
new file mode 100644
index 0000000000000000000000000000000000000000..e9413cb70e4bb9fac8380548c7b69e1e4ca9c5b3
--- /dev/null
+++ b/aes128-set-encrypt-key.c
@@ -0,0 +1,38 @@
+/* aes128-set-encrypt-key.c
+ *
+ * Key setup for the aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013, Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "aes-internal.h"
+
+void
+aes128_set_encrypt_key(struct aes128_ctx *ctx, const uint8_t *key)
+{
+  _aes_set_key (_AES128_ROUNDS, AES128_KEY_SIZE / 4, ctx->keys, key);
+}
diff --git a/nettle-internal.c b/nettle-internal.c
index 5cd582884d0c9355a5e1fdbd803d06cb9565b6c9..e5a7271df54c7bfc60719e0ae93efc0ae099fd62 100644
--- a/nettle-internal.c
+++ b/nettle-internal.c
@@ -112,3 +112,8 @@ const struct nettle_aead
 nettle_gcm_aes192 = _NETTLE_AEAD(gcm, GCM, aes, 192);
 const struct nettle_aead
 nettle_gcm_aes256 = _NETTLE_AEAD(gcm, GCM, aes, 256);
+
+/* Old, unified, interface */
+const struct nettle_cipher nettle_unified_aes128
+= _NETTLE_CIPHER_SEP(aes, AES, 128);
+
diff --git a/nettle-internal.h b/nettle-internal.h
index e094064f6f32c6daf7f33324b288d96f1b0cf6e3..ec26fe3cba00039bb58792849ba81356d06b7afe 100644
--- a/nettle-internal.h
+++ b/nettle-internal.h
@@ -64,6 +64,8 @@ extern const struct nettle_cipher nettle_blowfish128;
 extern const struct nettle_cipher nettle_salsa20;
 extern const struct nettle_cipher nettle_salsa20r12;
 
+extern const struct nettle_cipher nettle_unified_aes128;
+
 /* Glue to openssl, for comparative benchmarking. Code in
  * examples/nettle-openssl.c. */
 extern const struct nettle_cipher nettle_openssl_aes128;
diff --git a/testsuite/aes-test.c b/testsuite/aes-test.c
index 62936d1b74c3612da06d4e6300a20106d73c7d49..1304e8b05a93161409ab46b188a8110dcffe950f 100644
--- a/testsuite/aes-test.c
+++ b/testsuite/aes-test.c
@@ -1,5 +1,6 @@
 #include "testutils.h"
 #include "aes.h"
+#include "nettle-internal.h"
 
 static void
 test_invert(const struct tstring *key,
@@ -45,29 +46,42 @@ test_invert(const struct tstring *key,
   free (data);
 }
 
+static void
+test_cipher2(const struct nettle_cipher *c1,
+	     const struct nettle_cipher *c2,	     
+	     const struct tstring *key,
+	     const struct tstring *cleartext,
+	     const struct tstring *ciphertext)
+{
+  test_cipher (c1, key, cleartext, ciphertext);
+  test_cipher (c2, key, cleartext, ciphertext);
+}
+
 void
 test_main(void)
 {
+  /* Test both the new interface and the older unified interface. */
+
   /* 128 bit keys */
-  test_cipher(&nettle_aes128, 
-	      SHEX("0001020305060708 0A0B0C0D0F101112"),
-	      SHEX("506812A45F08C889 B97F5980038B8359"),
-	      SHEX("D8F532538289EF7D 06B506A4FD5BE9C9"));
+  test_cipher2(&nettle_aes128, &nettle_unified_aes128,
+	       SHEX("0001020305060708 0A0B0C0D0F101112"),
+	       SHEX("506812A45F08C889 B97F5980038B8359"),
+	       SHEX("D8F532538289EF7D 06B506A4FD5BE9C9"));
   
-  test_cipher(&nettle_aes128, 
-	      SHEX("14151617191A1B1C 1E1F202123242526"),
-	      SHEX("5C6D71CA30DE8B8B 00549984D2EC7D4B"),
-	      SHEX("59AB30F4D4EE6E4F F9907EF65B1FB68C"));
-
-  test_cipher(&nettle_aes128, 
-	      SHEX("28292A2B2D2E2F30 323334353738393A"),
-	      SHEX("53F3F4C64F8616E4 E7C56199F48F21F6"),
-	      SHEX("BF1ED2FCB2AF3FD4 1443B56D85025CB1"));
+  test_cipher2(&nettle_aes128, &nettle_unified_aes128,
+	       SHEX("14151617191A1B1C 1E1F202123242526"),
+	       SHEX("5C6D71CA30DE8B8B 00549984D2EC7D4B"),
+	       SHEX("59AB30F4D4EE6E4F F9907EF65B1FB68C"));
+
+  test_cipher2(&nettle_aes128, &nettle_unified_aes128,
+	       SHEX("28292A2B2D2E2F30 323334353738393A"),
+	       SHEX("53F3F4C64F8616E4 E7C56199F48F21F6"),
+	       SHEX("BF1ED2FCB2AF3FD4 1443B56D85025CB1"));
   
-  test_cipher(&nettle_aes128, 
-	      SHEX("A0A1A2A3A5A6A7A8 AAABACADAFB0B1B2"),
-	      SHEX("F5F4F7F684878689 A6A7A0A1D2CDCCCF"),
-	      SHEX("CE52AF650D088CA5 59425223F4D32694"));
+  test_cipher2(&nettle_aes128, &nettle_unified_aes128,
+	       SHEX("A0A1A2A3A5A6A7A8 AAABACADAFB0B1B2"),
+	       SHEX("F5F4F7F684878689 A6A7A0A1D2CDCCCF"),
+	       SHEX("CE52AF650D088CA5 59425223F4D32694"));
 
   /* 192 bit keys */
   
@@ -104,16 +118,16 @@ test_main(void)
    * F.1.1 ECB-AES128-Encrypt
    */
 
-  test_cipher(&nettle_aes128,
-	      SHEX("2b7e151628aed2a6abf7158809cf4f3c"),
-	      SHEX("6bc1bee22e409f96e93d7e117393172a"
-		   "ae2d8a571e03ac9c9eb76fac45af8e51"
-		   "30c81c46a35ce411e5fbc1191a0a52ef"
-		   "f69f2445df4f9b17ad2b417be66c3710"),
-	      SHEX("3ad77bb40d7a3660a89ecaf32466ef97"
-		   "f5d3d58503b9699de785895a96fdbaaf"
-		   "43b1cd7f598ece23881b00e3ed030688"
-		   "7b0c785e27e8ad3f8223207104725dd4"));
+  test_cipher2(&nettle_aes128, &nettle_unified_aes128,
+	       SHEX("2b7e151628aed2a6abf7158809cf4f3c"),
+	       SHEX("6bc1bee22e409f96e93d7e117393172a"
+		    "ae2d8a571e03ac9c9eb76fac45af8e51"
+		    "30c81c46a35ce411e5fbc1191a0a52ef"
+		    "f69f2445df4f9b17ad2b417be66c3710"),
+	       SHEX("3ad77bb40d7a3660a89ecaf32466ef97"
+		    "f5d3d58503b9699de785895a96fdbaaf"
+		    "43b1cd7f598ece23881b00e3ed030688"
+		    "7b0c785e27e8ad3f8223207104725dd4"));
 
   /* F.1.3 ECB-AES192-Encrypt */