diff --git a/ChangeLog b/ChangeLog
index 7602777c13dd52f7ce3d8c2a8461e23e419452ff..47e5d16b161698d75f34a04c39385c3aeb0e770f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,92 @@
+2014-01-29  Niels Möller  <nisse@lysator.liu.se>
+
+	* nettle-types.h (typedef nettle_set_key_func): Deleted length
+	argument.
+
+	* arctwo.c (arctwo40_set_key, arctwo64_set_key)
+	(arctwo128_set_key, arctwo128_set_key_gutmann): New functions.
+	* arctwo.h: Declare them.
+	* arctwo-meta.c (ARCTWO): New macro.
+	(nettle_arctwo40, nettle_arctwo64, nettle_arctwo128)
+	(nettle_arctwo_gutmann128): Use new _set_key functions.
+
+	* arcfour.h (ARCFOUR128_KEY_SIZE): New constant.
+	* arcfour.c (arcfour128_set_key): New function.
+	* arcfour-meta.c (nettle_arcfour128): Use arcfour128_set_key and
+	ARCFOUR128_KEY_SIZE.
+
+	* cast128.c (cast5_set_key): Renamed, was cast128_set_key.
+	(cast128_set_key): New definition, with fixed key size.
+	* cast128.h (CAST128_MIN_KEY_SIZE, CAST128_MAX_KEY_SIZE): Renamed
+	constants, to...
+	(CAST5_MIN_KEY_SIZE, CAST5_MAX_KEY_SIZE): ... new names.
+
+	* eax.h (EAX_SET_KEY): Deleted length argument.
+
+	* aes128-meta.c: Deleted _set_key wrappers.
+	* aes192-meta.c: Likewise.
+	* aes256-meta.c: Likewise.
+	* camellia128-meta.c: Likewise.
+	* camellia192-meta.c: Likewise.
+	* camellia256-meta.c: Likewise.
+
+	* gcm-aes128.c (gcm_aes128_set_key): Deleted length argument.
+	* gcm-aes192.c (gcm_aes192_set_key): Likewise.
+	* gcm-aes256.c (gcm_aes256_set_key): Likewise.
+	* gcm.h: Updated prototypes.
+
+	* serpent-set-key.c (serpent128_set_key, serpent192_set_key)
+	(serpent256_set_key): New functions.
+	* serpent.h: Declare new functions.
+	(SERPENT128_KEY_SIZE, SERPENT192_KEY_SIZE)
+	(SERPENT256_KEY_SIZE): New constants.
+	* serpent-meta.c (SERPENT): New macro.
+	(nettle_serpent128, nettle_serpent192, nettle_serpent256): Use new
+	_set_key functions.
+
+	* twofish-set-key.c (twofish128_set_key, twofish192_set_key)
+	(twofish256_set_key): New functions.
+	* twofish.h: Declare new functions.
+	(TWOFISH128_KEY_SIZE, TWOFISH192_KEY_SIZE)
+	(TWOFISH256_KEY_SIZE): New constants.
+	* twofish-meta.c (TWOFISH): New macro.
+	(nettle_twofish128, nettle_twofish192, nettle_twofish256): Use new
+	_set_key functions.
+
+	* nettle-internal.h (struct nettle_aead): Use
+	nettle_hash_update_func for the set_iv function pointer.
+
+	* nettle-internal.c (des_set_key_hack, des3_set_key_hack): Deleted
+	wrapper functions.
+	(chacha_set_key_hack): Deleted length argument. Use
+	chacha256_set_key.
+	(salsa20_set_key_hack): Deleted length argument. Use
+	salsa20_256_set_key.
+	(nettle_unified_aes128, nettle_unified_aes192)
+	(nettle_unified_aes256): Deleted, moved to test program.
+	(eax_aes128_set_key): Deleted length argument. Use EAX_SET_KEY.
+
+	* examples/nettle-benchmark.c: Updated for _set_key changes.
+	* examples/nettle-openssl.c: Likewise.
+	* testsuite/testutils.c: Likewise.
+	* testsuite/gcm-test.c: Likewise.
+
+	* testsuite/aes-test.c (UNIFIED_AES): New macro. Moved glue for
+	testing the old aes interface (struct aes_ctx) here.
+
+	* testsuite/arcfour-test.c (test_arcfour): New function, for key
+	sizes != 128 bits.
+	(test_main): Use it.
+
+	* testsuite/blowfish-test.c (test_blowfish): New function.
+	(test_main): Use it. Also deleted old #if:ed out code.
+
+	* testsuite/cast128-test.c (test_cast5): New function.
+	(test_main): Use it, for 40-bit and 80-bit tests.
+
+	* testsuite/serpent-test.c (test_serpent): New function.
+	(test_main): Use it.
+
 2014-01-27  Niels Möller  <nisse@lysator.liu.se>
 
 	* eax.h (struct eax_key, struct eax_ctx): Use union
diff --git a/aes128-meta.c b/aes128-meta.c
index c3068990392ae4744f0a87e7913daea329f96859..4c72d735fbe2d665e4bac25d87245236deb7e323 100644
--- a/aes128-meta.c
+++ b/aes128-meta.c
@@ -2,7 +2,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2013 Niels Möller
+ * Copyright (C) 2013, 2014 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
@@ -30,28 +30,11 @@
 
 #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_set_key_func *) aes128_set_encrypt_key,
+    (nettle_set_key_func *) aes128_set_decrypt_key,
     (nettle_crypt_func *) aes128_encrypt,
     (nettle_crypt_func *) aes128_decrypt
   };
diff --git a/aes192-meta.c b/aes192-meta.c
index 0ee0c1aa2974ffff4fcf6e4a67a4fd1b964dc3e7..807192491751ce8be3d7be3034ef49786990b9f6 100644
--- a/aes192-meta.c
+++ b/aes192-meta.c
@@ -2,7 +2,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2013 Niels Möller
+ * Copyright (C) 2013, 2014 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
@@ -30,28 +30,11 @@
 
 #include "aes.h"
 
-static nettle_set_key_func aes192_set_encrypt_key_wrapper;
-static nettle_set_key_func aes192_set_decrypt_key_wrapper;
-
-static void
-aes192_set_encrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == AES192_KEY_SIZE);
-  aes192_set_encrypt_key (ctx, key);
-}
-
-static void
-aes192_set_decrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == AES192_KEY_SIZE);
-  aes192_set_decrypt_key (ctx, key);
-}
-
 const struct nettle_cipher nettle_aes192 =
   { "aes192", sizeof(struct aes192_ctx),
     AES_BLOCK_SIZE, AES192_KEY_SIZE,
-    aes192_set_encrypt_key_wrapper,
-    aes192_set_decrypt_key_wrapper,
+    (nettle_set_key_func *) aes192_set_encrypt_key,
+    (nettle_set_key_func *) aes192_set_decrypt_key,
     (nettle_crypt_func *) aes192_encrypt,
     (nettle_crypt_func *) aes192_decrypt
   };
diff --git a/aes256-meta.c b/aes256-meta.c
index 197441e0ed529f492c4be692e325a87c8c0bae18..7f1e2e1ef028727d0cc367666fcfd3c1d3fba9de 100644
--- a/aes256-meta.c
+++ b/aes256-meta.c
@@ -2,7 +2,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2013 Niels Möller
+ * Copyright (C) 2013, 2014 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
@@ -30,28 +30,11 @@
 
 #include "aes.h"
 
-static nettle_set_key_func aes256_set_encrypt_key_wrapper;
-static nettle_set_key_func aes256_set_decrypt_key_wrapper;
-
-static void
-aes256_set_encrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == AES256_KEY_SIZE);
-  aes256_set_encrypt_key (ctx, key);
-}
-
-static void
-aes256_set_decrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == AES256_KEY_SIZE);
-  aes256_set_decrypt_key (ctx, key);
-}
-
 const struct nettle_cipher nettle_aes256 =
   { "aes256", sizeof(struct aes256_ctx),
     AES_BLOCK_SIZE, AES256_KEY_SIZE,
-    aes256_set_encrypt_key_wrapper,
-    aes256_set_decrypt_key_wrapper,
+    (nettle_set_key_func *) aes256_set_encrypt_key,
+    (nettle_set_key_func *) aes256_set_decrypt_key,
     (nettle_crypt_func *) aes256_encrypt,
     (nettle_crypt_func *) aes256_decrypt
   };
diff --git a/arcfour-meta.c b/arcfour-meta.c
index 0068efffe9e261c5c09fc576740dbe9ab08b67ea..70ec10667dec7c478780e26f25c7a00303de5894 100644
--- a/arcfour-meta.c
+++ b/arcfour-meta.c
@@ -30,9 +30,9 @@
 
 const struct nettle_cipher nettle_arcfour128 =
   { "arcfour128", sizeof(struct arcfour_ctx),
-    0, 16,
-    (nettle_set_key_func *) arcfour_set_key,
-    (nettle_set_key_func *) arcfour_set_key,
+    0, ARCFOUR128_KEY_SIZE,
+    (nettle_set_key_func *) arcfour128_set_key,
+    (nettle_set_key_func *) arcfour128_set_key,
     (nettle_crypt_func *) arcfour_crypt,
     (nettle_crypt_func *) arcfour_crypt
   };
diff --git a/arcfour.c b/arcfour.c
index 0977d09217759a0e705b0e32ae40259ea418ea42..9c06ead961bbb3474f53c58396a432f731b54475 100644
--- a/arcfour.c
+++ b/arcfour.c
@@ -5,7 +5,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2001 Niels Möller
+ * Copyright (C) 2001, 2014 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
@@ -56,3 +56,8 @@ arcfour_set_key(struct arcfour_ctx *ctx,
   ctx->i = ctx->j = 0;
 }
 
+void
+arcfour128_set_key(struct arcfour_ctx *ctx, const uint8_t *key)
+{
+  arcfour_set_key (ctx, ARCFOUR128_KEY_SIZE, key);
+}
diff --git a/arcfour.h b/arcfour.h
index cedae8b10b16e4591748a5719c2cc16d5bf2f159..cb29499444290437bdff1e6aa7500b13dbc619cc 100644
--- a/arcfour.h
+++ b/arcfour.h
@@ -5,7 +5,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2001 Niels Möller
+ * Copyright (C) 2001, 2014 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
@@ -33,6 +33,7 @@ extern "C" {
 #endif
 
 /* Name mangling */
+#define arcfour128_set_key nettle_arcfour128_set_key
 #define arcfour_set_key nettle_arcfour_set_key
 #define arcfour_crypt nettle_arcfour_crypt
 
@@ -41,6 +42,7 @@ extern "C" {
 #define ARCFOUR_MIN_KEY_SIZE 1
 #define ARCFOUR_MAX_KEY_SIZE 256
 #define ARCFOUR_KEY_SIZE 16
+#define ARCFOUR128_KEY_SIZE 16
 
 struct arcfour_ctx
 {
@@ -53,6 +55,9 @@ void
 arcfour_set_key(struct arcfour_ctx *ctx,
 		size_t length, const uint8_t *key);
 
+void
+arcfour128_set_key(struct arcfour_ctx *ctx, const uint8_t *key);
+
 void
 arcfour_crypt(struct arcfour_ctx *ctx,
 	      size_t length, uint8_t *dst,
diff --git a/arctwo-meta.c b/arctwo-meta.c
index 525c8297d91cb4e00af0df056fa4d4d5415a74c6..b234a0b6307850c81b5dbff5759f889a76743cb0 100644
--- a/arctwo-meta.c
+++ b/arctwo-meta.c
@@ -3,6 +3,7 @@
 /* nettle, low-level cryptographics library
  *
  * Copyright (C) 2004 Simon Josefsson
+ * Copyright (C) 2014 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
@@ -28,21 +29,28 @@
 
 #include "arctwo.h"
 
+#define ARCTWO(bits) {					\
+  "arctwo" #bits, sizeof (struct arctwo_ctx),		\
+  ARCTWO_BLOCK_SIZE, bits/8,				\
+  (nettle_set_key_func *) arctwo ## bits ## _set_key,	\
+  (nettle_set_key_func *) arctwo ## bits ## _set_key,	\
+  (nettle_crypt_func *) arctwo_encrypt,			\
+  (nettle_crypt_func *) arctwo_decrypt,			\
+}
 const struct nettle_cipher nettle_arctwo40
-= _NETTLE_CIPHER (arctwo, ARCTWO, 40);
-
+= ARCTWO(40);
 const struct nettle_cipher nettle_arctwo64
-= _NETTLE_CIPHER (arctwo, ARCTWO, 64);
-
+= ARCTWO(64);
 const struct nettle_cipher nettle_arctwo128
-= _NETTLE_CIPHER (arctwo, ARCTWO, 128);
-
-/* Map Gutmann variant. */
-#define arctwo_gutmann_ctx arctwo_ctx
-#define arctwo_gutmann_encrypt arctwo_encrypt
-#define arctwo_gutmann_decrypt arctwo_decrypt
-#define arctwo_gutmann_ctx arctwo_ctx
-#define arctwo_gutmann_set_key arctwo_set_key_gutmann
-
-const struct nettle_cipher nettle_arctwo_gutmann128
-= _NETTLE_CIPHER (arctwo_gutmann, ARCTWO, 128);
+= ARCTWO(128);
+
+/* Gutmann variant. */
+const struct nettle_cipher nettle_arctwo_gutmann128 =
+  {
+    "arctwo_gutmann128", sizeof (struct arctwo_ctx),
+    ARCTWO_BLOCK_SIZE, 16,
+    (nettle_set_key_func *) arctwo128_set_key_gutmann,
+    (nettle_set_key_func *) arctwo128_set_key_gutmann,
+    (nettle_crypt_func *) arctwo_encrypt,
+    (nettle_crypt_func *) arctwo_decrypt,
+  };
diff --git a/arctwo.c b/arctwo.c
index f5753a8c3d665f9c525ba66f4b628bf6e90b92ad..385194dc965c68dfef45d269ae7f2921cf4a4e7c 100644
--- a/arctwo.c
+++ b/arctwo.c
@@ -8,7 +8,7 @@
  * Copyright (C) 2004 Simon Josefsson
  * Copyright (C) 2003 Nikos Mavroyanopoulos
  * Copyright (C) 2004 Free Software Foundation, Inc.
- * Copyright (C) 2004 Niels Möller
+ * Copyright (C) 2004, 2014 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
@@ -228,3 +228,26 @@ arctwo_set_key_gutmann (struct arctwo_ctx *ctx,
 {
   arctwo_set_key_ekb (ctx, length, key, 0);
 }
+
+void
+arctwo40_set_key (struct arctwo_ctx *ctx, const uint8_t *key)
+{
+  arctwo_set_key_ekb (ctx, 5, key, 40);
+}
+void
+arctwo64_set_key (struct arctwo_ctx *ctx, const uint8_t *key)
+{
+  arctwo_set_key_ekb (ctx, 8, key, 64);
+}
+
+void
+arctwo128_set_key (struct arctwo_ctx *ctx, const uint8_t *key)
+{
+  arctwo_set_key_ekb (ctx, 16, key, 128);
+}
+void
+arctwo128_set_key_gutmann (struct arctwo_ctx *ctx,
+			   const uint8_t *key)
+{
+  arctwo_set_key_ekb (ctx, 16, key, 1024);
+}
diff --git a/arctwo.h b/arctwo.h
index 3f1a3be932e3f468d80053dd4aae6d9effdca85f..c990a0cd7bba24ccbe0a95297510ca721e21eea7 100644
--- a/arctwo.h
+++ b/arctwo.h
@@ -6,7 +6,7 @@
 /* nettle, low-level cryptographics library
  *
  * Copyright (C) 2004 Simon Josefsson
- * Copyright (C) 2002, 2004 Niels Möller
+ * Copyright (C) 2002, 2004, 2014 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
@@ -36,9 +36,13 @@ extern "C" {
 /* Name mangling */
 #define arctwo_set_key nettle_arctwo_set_key
 #define arctwo_set_key_ekb nettle_arctwo_set_key_ekb
+#define arctwo_set_key_gutmann nettle_arctwo_set_key_gutmann
+#define arctwo40_set_key nettle_arctwo40_set_key
+#define arctwo64_set_key nettle_arctwo64_set_key
+#define arctwo128_set_key nettle_arctwo128_set_key
+#define arctwo128_set_key_gutmann nettle_arctwo128_set_key_gutmann
 #define arctwo_encrypt nettle_arctwo_encrypt
 #define arctwo_decrypt nettle_arctwo_decrypt
-#define arctwo_set_key_gutmann nettle_arctwo_set_key_gutmann
 
 #define ARCTWO_BLOCK_SIZE 8
 
@@ -62,11 +66,20 @@ arctwo_set_key_ekb (struct arctwo_ctx *ctx,
 /* Equvivalent to arctwo_set_key_ekb, with ekb = 8 * length */
 void
 arctwo_set_key (struct arctwo_ctx *ctx, size_t length, const uint8_t *key);
+void
+arctwo40_set_key (struct arctwo_ctx *ctx, const uint8_t *key);
+void
+arctwo64_set_key (struct arctwo_ctx *ctx, const uint8_t *key);
+void
+arctwo128_set_key (struct arctwo_ctx *ctx, const uint8_t *key);
 
 /* Equvivalent to arctwo_set_key_ekb, with ekb = 1024 */
 void
 arctwo_set_key_gutmann (struct arctwo_ctx *ctx,
 			size_t length, const uint8_t *key);
+void
+arctwo128_set_key_gutmann (struct arctwo_ctx *ctx,
+			   const uint8_t *key);
 
 void
 arctwo_encrypt (struct arctwo_ctx *ctx,
diff --git a/camellia128-meta.c b/camellia128-meta.c
index cac7b4851dca9287acaf43d646dc31aff1aee12b..97748b0874536d4726455bcd0af169b61f5104af 100644
--- a/camellia128-meta.c
+++ b/camellia128-meta.c
@@ -2,7 +2,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2010, 2013 Niels Möller
+ * Copyright (C) 2010, 2013, 2014 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
@@ -30,25 +30,11 @@
 
 #include "camellia.h"
 
-static void
-camellia128_set_encrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == CAMELLIA128_KEY_SIZE);
-  camellia128_set_encrypt_key (ctx, key);
-}
-
-static void
-camellia128_set_decrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == CAMELLIA128_KEY_SIZE);
-  camellia128_set_decrypt_key (ctx, key);
-}
-
 const struct nettle_cipher nettle_camellia128 =
   { "camellia128", sizeof(struct camellia128_ctx),
     CAMELLIA_BLOCK_SIZE, CAMELLIA128_KEY_SIZE,
-    camellia128_set_encrypt_key_wrapper,
-    camellia128_set_decrypt_key_wrapper,
+    (nettle_set_key_func *) camellia128_set_encrypt_key,
+    (nettle_set_key_func *) camellia128_set_decrypt_key,
     (nettle_crypt_func *) camellia128_crypt,
     (nettle_crypt_func *) camellia128_crypt
   };
diff --git a/camellia192-meta.c b/camellia192-meta.c
index bdb5c130c091e391693d33c371e5d4ac2ad45561..62d9b194fb356f1d893141f16c97f8a8ea23cdad 100644
--- a/camellia192-meta.c
+++ b/camellia192-meta.c
@@ -2,7 +2,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2010, 2013 Niels Möller
+ * Copyright (C) 2010, 2013, 2014 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
@@ -30,25 +30,11 @@
 
 #include "camellia.h"
 
-static void
-camellia192_set_encrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == CAMELLIA192_KEY_SIZE);
-  camellia192_set_encrypt_key (ctx, key);
-}
-
-static void
-camellia192_set_decrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == CAMELLIA192_KEY_SIZE);
-  camellia192_set_decrypt_key (ctx, key);
-}
-
 const struct nettle_cipher nettle_camellia192 =
   { "camellia192", sizeof(struct camellia256_ctx),
     CAMELLIA_BLOCK_SIZE, CAMELLIA192_KEY_SIZE,
-    camellia192_set_encrypt_key_wrapper,
-    camellia192_set_decrypt_key_wrapper,
+    (nettle_set_key_func *) camellia192_set_encrypt_key,
+    (nettle_set_key_func *) camellia192_set_decrypt_key,
     (nettle_crypt_func *) camellia256_crypt,
     (nettle_crypt_func *) camellia256_crypt
   };
diff --git a/camellia256-meta.c b/camellia256-meta.c
index 1a1e2a2d02cd1065d4a76fbe2974496b5ab067fa..86d6278bbee476eb393a3aea88a02e82eabba06b 100644
--- a/camellia256-meta.c
+++ b/camellia256-meta.c
@@ -2,7 +2,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2010, 2013 Niels Möller
+ * Copyright (C) 2010, 2013, 2014 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
@@ -30,25 +30,11 @@
 
 #include "camellia.h"
 
-static void
-camellia256_set_encrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == CAMELLIA256_KEY_SIZE);
-  camellia256_set_encrypt_key (ctx, key);
-}
-
-static void
-camellia256_set_decrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
-{
-  assert (length == CAMELLIA256_KEY_SIZE);
-  camellia256_set_decrypt_key (ctx, key);
-}
-
 const struct nettle_cipher nettle_camellia256 =
   { "camellia256", sizeof(struct camellia256_ctx),
     CAMELLIA_BLOCK_SIZE, CAMELLIA256_KEY_SIZE,
-    camellia256_set_encrypt_key_wrapper,
-    camellia256_set_decrypt_key_wrapper,
+    (nettle_set_key_func *) camellia256_set_encrypt_key,
+    (nettle_set_key_func *) camellia256_set_decrypt_key,
     (nettle_crypt_func *) camellia256_crypt,
     (nettle_crypt_func *) camellia256_crypt
   };
diff --git a/cast128.c b/cast128.c
index 088bba0ca71314fa9db0e50e477234a9427c3ac0..ae44531a74d447c6415bff6fd33f913c23aa36a4 100644
--- a/cast128.c
+++ b/cast128.c
@@ -11,7 +11,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2001 Niels Möller
+ * Copyright (C) 2001, 2014 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
@@ -213,15 +213,15 @@ cast128_decrypt(const struct cast128_ctx *ctx,
 } while (0)
 
 void
-cast128_set_key(struct cast128_ctx *ctx,
-		size_t length, const uint8_t *key)
+cast5_set_key(struct cast128_ctx *ctx,
+	      size_t length, const uint8_t *key)
 {
   uint32_t x0, x1, x2, x3, z0, z1, z2, z3;
   uint32_t w;
   int full;
 
-  assert (length >= CAST128_MIN_KEY_SIZE);
-  assert (length <= CAST128_MAX_KEY_SIZE);
+  assert (length >= CAST5_MIN_KEY_SIZE);
+  assert (length <= CAST5_MAX_KEY_SIZE);
 
   full = (length > CAST_SMALL_KEY);
 
@@ -269,3 +269,9 @@ cast128_set_key(struct cast128_ctx *ctx,
 
   ctx->rounds = full ? 16 : 12;
 }
+
+void
+cast128_set_key(struct cast128_ctx *ctx, const uint8_t *key)
+{
+  cast5_set_key (ctx, CAST128_KEY_SIZE, key);
+}
diff --git a/cast128.h b/cast128.h
index abdf71dff83550b57ac8d963025a4e746043632d..907edb7e31113dcc545fcaae817f476343f3a0f9 100644
--- a/cast128.h
+++ b/cast128.h
@@ -11,7 +11,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2001 Niels Möller
+ * Copyright (C) 2001, 2014 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
@@ -39,6 +39,7 @@ extern "C" {
 #endif
 
 /* Name mangling */
+#define cast5_set_key nettle_cast5_set_key
 #define cast128_set_key nettle_cast128_set_key
 #define cast128_encrypt nettle_cast128_encrypt
 #define cast128_decrypt nettle_cast128_decrypt
@@ -46,8 +47,8 @@ extern "C" {
 #define CAST128_BLOCK_SIZE 8
 
 /* Variable key size between 40 and 128. */
-#define CAST128_MIN_KEY_SIZE 5
-#define CAST128_MAX_KEY_SIZE 16
+#define CAST5_MIN_KEY_SIZE 5
+#define CAST5_MAX_KEY_SIZE 16
 
 #define CAST128_KEY_SIZE 16
 
@@ -59,9 +60,13 @@ struct cast128_ctx
   uint32_t Km[16];
 };
 
+/* Using variable key size. */
 void
-cast128_set_key(struct cast128_ctx *ctx,
-		size_t length, const uint8_t *key);
+cast5_set_key(struct cast128_ctx *ctx,
+	      size_t length, const uint8_t *key);
+
+void
+cast128_set_key(struct cast128_ctx *ctx, const uint8_t *key);
 
 void
 cast128_encrypt(const struct cast128_ctx *ctx,
diff --git a/eax.h b/eax.h
index 27268c641e51670e4e788d5fb8f7ff3ab4f85a62..36238dc4ccf128196781bbf0f0ccb1abb510e027 100644
--- a/eax.h
+++ b/eax.h
@@ -102,9 +102,9 @@ eax_digest (struct eax_ctx *eax, const struct eax_key *key,
 #define EAX_CTX(type) \
   { struct eax_key key; struct eax_ctx eax; type cipher; }
 
-#define EAX_SET_KEY(ctx, set_key, encrypt, length, data)		\
+#define EAX_SET_KEY(ctx, set_key, encrypt, data)			\
   do {									\
-    (set_key)(&(ctx)->cipher, (length), (data));			\
+    (set_key)(&(ctx)->cipher, (data));					\
     if (0) (encrypt) (&(ctx)->cipher, 0, (void *) 0, (void *) 0);	\
     eax_set_key (&(ctx)->key, &(ctx)->cipher, (nettle_crypt_func *) encrypt); \
   } while (0)
diff --git a/examples/nettle-benchmark.c b/examples/nettle-benchmark.c
index 5ac6d4c4545ac5d798c9ccd3ec4eefa41c7891ef..7e15a18e76ead2b3748a6a19c88559f29a799280 100644
--- a/examples/nettle-benchmark.c
+++ b/examples/nettle-benchmark.c
@@ -427,7 +427,7 @@ time_gcm(void)
   uint8_t key[AES128_KEY_SIZE];
   uint8_t iv[GCM_IV_SIZE];
 
-  gcm_aes128_set_key(&ctx, sizeof(key), key);
+  gcm_aes128_set_key(&ctx, key);
   gcm_aes128_set_iv(&ctx, sizeof(iv), iv);
 
   hinfo.ctx = &ctx;
@@ -461,7 +461,7 @@ time_eax(void)
   uint8_t key[AES128_KEY_SIZE];
   uint8_t iv[EAX_BLOCK_SIZE];
 
-  eax_aes128_set_key (&ctx, sizeof(key), key);
+  eax_aes128_set_key (&ctx, key);
   eax_aes128_set_nonce(&ctx, sizeof(iv), iv);
 
   hinfo.ctx = &ctx;
@@ -521,7 +521,7 @@ time_cipher(const struct nettle_cipher *cipher)
     info.data = data;
     
     init_key(cipher->key_size, key);
-    cipher->set_encrypt_key(ctx, cipher->key_size, key);
+    cipher->set_encrypt_key(ctx, key);
 
     display(cipher->name, "ECB encrypt", cipher->block_size,
 	    time_function(bench_cipher, &info));
@@ -534,7 +534,7 @@ time_cipher(const struct nettle_cipher *cipher)
     info.data = data;
     
     init_key(cipher->key_size, key);
-    cipher->set_decrypt_key(ctx, cipher->key_size, key);
+    cipher->set_decrypt_key(ctx, key);
 
     display(cipher->name, "ECB decrypt", cipher->block_size,
 	    time_function(bench_cipher, &info));
@@ -555,7 +555,7 @@ time_cipher(const struct nettle_cipher *cipher)
     
         memset(iv, 0, sizeof(iv));
     
-        cipher->set_encrypt_key(ctx, cipher->key_size, key);
+        cipher->set_encrypt_key(ctx, key);
 
 	display(cipher->name, "CBC encrypt", cipher->block_size,
 		time_function(bench_cbc_encrypt, &info));
@@ -571,7 +571,7 @@ time_cipher(const struct nettle_cipher *cipher)
     
         memset(iv, 0, sizeof(iv));
 
-        cipher->set_decrypt_key(ctx, cipher->key_size, key);
+        cipher->set_decrypt_key(ctx, key);
 
 	display(cipher->name, "CBC decrypt", cipher->block_size,
 		time_function(bench_cbc_decrypt, &info));
@@ -588,7 +588,7 @@ time_cipher(const struct nettle_cipher *cipher)
     
         memset(iv, 0, sizeof(iv));
     
-        cipher->set_encrypt_key(ctx, cipher->key_size, key);
+        cipher->set_encrypt_key(ctx, key);
 
 	display(cipher->name, "CTR", cipher->block_size,
 		time_function(bench_ctr, &info));	
diff --git a/examples/nettle-openssl.c b/examples/nettle-openssl.c
index 8ef0c025be1d0ce1b1dcd259b5e4e2840440f8d5..25aa5e9719ceb0f27fe10c02d7353025a70a090c 100644
--- a/examples/nettle-openssl.c
+++ b/examples/nettle-openssl.c
@@ -50,18 +50,43 @@
 
 
 /* AES */
-static nettle_set_key_func openssl_aes_set_encrypt_key;
+static nettle_set_key_func openssl_aes128_set_encrypt_key;
+static nettle_set_key_func openssl_aes128_set_decrypt_key;
+static nettle_set_key_func openssl_aes192_set_encrypt_key;
+static nettle_set_key_func openssl_aes192_set_decrypt_key;
+static nettle_set_key_func openssl_aes256_set_encrypt_key;
+static nettle_set_key_func openssl_aes256_set_decrypt_key;
 static void
-openssl_aes_set_encrypt_key(void *ctx, size_t length, const uint8_t *key)
+openssl_aes128_set_encrypt_key(void *ctx, const uint8_t *key)
 {
-  AES_set_encrypt_key(key, length * 8, ctx);
+  AES_set_encrypt_key(key, 128, ctx);
+}
+static void
+openssl_aes128_set_decrypt_key(void *ctx, const uint8_t *key)
+{
+  AES_set_decrypt_key(key, 128, ctx);
 }
 
-static nettle_set_key_func openssl_aes_set_decrypt_key;
 static void
-openssl_aes_set_decrypt_key(void *ctx, size_t length, const uint8_t *key)
+openssl_aes192_set_encrypt_key(void *ctx, const uint8_t *key)
+{
+  AES_set_encrypt_key(key, 192, ctx);
+}
+static void
+openssl_aes192_set_decrypt_key(void *ctx, const uint8_t *key)
+{
+  AES_set_decrypt_key(key, 192, ctx);
+}
+
+static void
+openssl_aes256_set_encrypt_key(void *ctx, const uint8_t *key)
+{
+  AES_set_encrypt_key(key, 256, ctx);
+}
+static void
+openssl_aes256_set_decrypt_key(void *ctx, const uint8_t *key)
 {
-  AES_set_decrypt_key(key, length * 8, ctx);
+  AES_set_decrypt_key(key, 256, ctx);
 }
 
 static nettle_crypt_func openssl_aes_encrypt;
@@ -98,7 +123,7 @@ const struct nettle_cipher
 nettle_openssl_aes128 = {
   "openssl aes128", sizeof(AES_KEY),
   16, 16,
-  openssl_aes_set_encrypt_key, openssl_aes_set_decrypt_key,
+  openssl_aes128_set_encrypt_key, openssl_aes128_set_decrypt_key,
   openssl_aes_encrypt, openssl_aes_decrypt
 };
 
@@ -109,7 +134,7 @@ nettle_openssl_aes192 = {
    * (as openssl cipher + nettle cbc is somewhat pointless to
    * benchmark). */
   16, 24,
-  openssl_aes_set_encrypt_key, openssl_aes_set_decrypt_key,
+  openssl_aes192_set_encrypt_key, openssl_aes192_set_decrypt_key,
   openssl_aes_encrypt, openssl_aes_decrypt
 };
 
@@ -120,16 +145,16 @@ nettle_openssl_aes256 = {
    * (as openssl cipher + nettle cbc is somewhat pointless to
    * benchmark). */
   16, 32,
-  openssl_aes_set_encrypt_key, openssl_aes_set_decrypt_key,
+  openssl_aes256_set_encrypt_key, openssl_aes256_set_decrypt_key,
   openssl_aes_encrypt, openssl_aes_decrypt
 };
 
 /* Arcfour */
-static nettle_set_key_func openssl_arcfour_set_key;
+static nettle_set_key_func openssl_arcfour128_set_key;
 static void
-openssl_arcfour_set_key(void *ctx, size_t length, const uint8_t *key)
+openssl_arcfour128_set_key(void *ctx, const uint8_t *key)
 {
-  RC4_set_key(ctx, length, key);
+  RC4_set_key(ctx, 16, key);
 }
 
 static nettle_crypt_func openssl_arcfour_crypt;
@@ -144,16 +169,16 @@ const struct nettle_cipher
 nettle_openssl_arcfour128 = {
   "openssl arcfour128", sizeof(RC4_KEY),
   0, 16,
-  openssl_arcfour_set_key, openssl_arcfour_set_key,
+  openssl_arcfour128_set_key, openssl_arcfour128_set_key,
   openssl_arcfour_crypt, openssl_arcfour_crypt
 };
 
 /* Blowfish */
-static nettle_set_key_func openssl_bf_set_key;
+static nettle_set_key_func openssl_bf128_set_key;
 static void
-openssl_bf_set_key(void *ctx, size_t length, const uint8_t *key)
+openssl_bf128_set_key(void *ctx, const uint8_t *key)
 {
-  BF_set_key(ctx, length, key);
+  BF_set_key(ctx, 16, key);
 }
 
 static nettle_crypt_func openssl_bf_encrypt;
@@ -190,7 +215,7 @@ const struct nettle_cipher
 nettle_openssl_blowfish128 = {
   "openssl bf128", sizeof(BF_KEY),
   8, 16,
-  openssl_bf_set_key, openssl_bf_set_key,
+  openssl_bf128_set_key, openssl_bf128_set_key,
   openssl_bf_encrypt, openssl_bf_decrypt
 };
 
@@ -198,9 +223,8 @@ nettle_openssl_blowfish128 = {
 /* DES */
 static nettle_set_key_func openssl_des_set_key;
 static void
-openssl_des_set_key(void *ctx, size_t length, const uint8_t *key)
+openssl_des_set_key(void *ctx, const uint8_t *key)
 {
-  assert(length == 8);  
   /* Not sure what "unchecked" means. We want to ignore parity bits,
      but it would still make sense to check for weak keys. */
   /* Explicit cast used as I don't want to care about openssl's broken
@@ -250,11 +274,11 @@ nettle_openssl_des = {
 
 
 /* Cast128 */
-static nettle_set_key_func openssl_cast_set_key;
+static nettle_set_key_func openssl_cast128_set_key;
 static void
-openssl_cast_set_key(void *ctx, size_t length, const uint8_t *key)
+openssl_cast128_set_key(void *ctx, const uint8_t *key)
 {
-  CAST_set_key(ctx, length, key);
+  CAST_set_key(ctx, 16, key);
 }
 
 static nettle_crypt_func openssl_cast_encrypt;
@@ -291,7 +315,7 @@ const struct nettle_cipher
 nettle_openssl_cast128 = {
   "openssl cast128", sizeof(CAST_KEY),
   8, CAST_KEY_LENGTH,
-  openssl_cast_set_key, openssl_cast_set_key,
+  openssl_cast128_set_key, openssl_cast128_set_key,
   openssl_cast_encrypt, openssl_cast_decrypt
 };
 
diff --git a/gcm-aes128.c b/gcm-aes128.c
index 4a2ec97c4c5a1b4595f46da83aeadfa938a14666..9dcefc680379bccf4205481fb8ce5b360d1ba6d9 100644
--- a/gcm-aes128.c
+++ b/gcm-aes128.c
@@ -32,9 +32,8 @@
 #include "gcm.h"
 
 void
-gcm_aes128_set_key(struct gcm_aes128_ctx *ctx, size_t length, const uint8_t *key)
+gcm_aes128_set_key(struct gcm_aes128_ctx *ctx, const uint8_t *key)
 {
-  assert (length == AES128_KEY_SIZE);
   GCM_SET_KEY(ctx, aes128_set_encrypt_key, aes128_encrypt, key);
 }
 
diff --git a/gcm-aes192.c b/gcm-aes192.c
index 3671829dec1bdd65eb6b6b9f6d1ea3d80c8bc6f0..cd3140a1375d05e8a0bc6c1239287412c2fcdff1 100644
--- a/gcm-aes192.c
+++ b/gcm-aes192.c
@@ -32,9 +32,8 @@
 #include "gcm.h"
 
 void
-gcm_aes192_set_key(struct gcm_aes192_ctx *ctx, size_t length, const uint8_t *key)
+gcm_aes192_set_key(struct gcm_aes192_ctx *ctx, const uint8_t *key)
 {
-  assert (length == AES192_KEY_SIZE);
   GCM_SET_KEY(ctx, aes192_set_encrypt_key, aes192_encrypt, key);
 }
 
diff --git a/gcm-aes256.c b/gcm-aes256.c
index 3fb6c680f92afcaa4bbb521a2fce391677c38ff9..f15bb9ab04e9225e854c165ae983dea656258d4d 100644
--- a/gcm-aes256.c
+++ b/gcm-aes256.c
@@ -32,9 +32,8 @@
 #include "gcm.h"
 
 void
-gcm_aes256_set_key(struct gcm_aes256_ctx *ctx, size_t length, const uint8_t *key)
+gcm_aes256_set_key(struct gcm_aes256_ctx *ctx, const uint8_t *key)
 {
-  assert (length == AES256_KEY_SIZE);
   GCM_SET_KEY(ctx, aes256_set_encrypt_key, aes256_encrypt, key);
 }
 
diff --git a/gcm.h b/gcm.h
index f05485162368094e0b6e5f12c310ae9932ef3b7e..bee453184d6b63e77f6ffd29e079fe93d15ec4c0 100644
--- a/gcm.h
+++ b/gcm.h
@@ -167,8 +167,7 @@ gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
 struct gcm_aes128_ctx GCM_CTX(struct aes128_ctx);
 
 void
-gcm_aes128_set_key(struct gcm_aes128_ctx *ctx,
-		   size_t length, const uint8_t *key);
+gcm_aes128_set_key(struct gcm_aes128_ctx *ctx, const uint8_t *key);
 
 /* FIXME: Define _update and _set_iv as some kind of aliaes,
    there's nothing aes-specific. */
@@ -194,8 +193,7 @@ gcm_aes128_digest(struct gcm_aes128_ctx *ctx,
 struct gcm_aes192_ctx GCM_CTX(struct aes192_ctx);
 
 void
-gcm_aes192_set_key(struct gcm_aes192_ctx *ctx,
-		   size_t length, const uint8_t *key);
+gcm_aes192_set_key(struct gcm_aes192_ctx *ctx, const uint8_t *key);
 
 void
 gcm_aes192_update (struct gcm_aes192_ctx *ctx,
@@ -219,8 +217,7 @@ gcm_aes192_digest(struct gcm_aes192_ctx *ctx,
 struct gcm_aes256_ctx GCM_CTX(struct aes256_ctx);
 
 void
-gcm_aes256_set_key(struct gcm_aes256_ctx *ctx,
-		   size_t length, const uint8_t *key);
+gcm_aes256_set_key(struct gcm_aes256_ctx *ctx, const uint8_t *key);
 
 void
 gcm_aes256_update (struct gcm_aes256_ctx *ctx,
diff --git a/nettle-internal.c b/nettle-internal.c
index bdc9ef82c79aeadc66db5cc2054049a2361e502a..ba24dee26d551f23d8e951389b914391d714faec 100644
--- a/nettle-internal.c
+++ b/nettle-internal.c
@@ -6,7 +6,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2002 Niels Möller
+ * Copyright (C) 2002, 2014 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
@@ -39,29 +39,14 @@
 #include "chacha.h"
 #include "salsa20.h"
 
-/* DES uses a different signature for the key set function. We ignore
-   the return value indicating weak keys. */
-static void
-des_set_key_hack(void *ctx, size_t length, const uint8_t *key)
-{
-  assert(length == DES_KEY_SIZE);
-  des_set_key(ctx, key);
-}
-
-static void
-des3_set_key_hack(void *ctx, size_t length, const uint8_t *key)
-{
-  assert(length == DES3_KEY_SIZE);
-  des3_set_key(ctx, key);
-}
-
-/* NOTE: A bit ugly. Ignores weak keys, and pretends the set:key
+/* NOTE: A bit ugly. Ignores weak keys, and pretends the set_key
    functions have no return value. */
 const struct nettle_cipher
 nettle_des = {
   "des", sizeof(struct des_ctx),
   DES_BLOCK_SIZE, DES_KEY_SIZE,
-  des_set_key_hack, des_set_key_hack,
+  (nettle_set_key_func *) des_set_key,
+  (nettle_set_key_func *) des_set_key,
   (nettle_crypt_func *) des_encrypt,
   (nettle_crypt_func *) des_decrypt
 };
@@ -70,7 +55,8 @@ const struct nettle_cipher
 nettle_des3 = {
  "des3", sizeof(struct des3_ctx),
  DES3_BLOCK_SIZE, DES3_KEY_SIZE,
- des3_set_key_hack, des3_set_key_hack,
+ (nettle_set_key_func *) des3_set_key,
+ (nettle_set_key_func *) des3_set_key,
  (nettle_crypt_func *) des3_encrypt,
  (nettle_crypt_func *) des3_decrypt
 };
@@ -82,10 +68,10 @@ nettle_blowfish128 = _NETTLE_CIPHER(blowfish, BLOWFISH, 128);
 
 /* Sets a fix zero iv. For benchmarking only. */
 static void
-chacha_set_key_hack(void *ctx, size_t length, const uint8_t *key)
+chacha_set_key_hack(void *ctx, const uint8_t *key)
 {
   static const uint8_t iv[CHACHA_IV_SIZE];
-  chacha_set_key (ctx, length, key);
+  chacha256_set_key (ctx, key);
   chacha_set_iv (ctx, iv);
 }
 
@@ -93,7 +79,7 @@ chacha_set_key_hack(void *ctx, size_t length, const uint8_t *key)
 const struct nettle_cipher
 nettle_chacha = {
   "chacha", sizeof(struct chacha_ctx),
-  0, CHACHA_KEY_SIZE,
+  0, CHACHA256_KEY_SIZE,
   chacha_set_key_hack, chacha_set_key_hack,
   (nettle_crypt_func *) chacha_crypt,
   (nettle_crypt_func *) chacha_crypt
@@ -101,10 +87,10 @@ nettle_chacha = {
 
 /* Sets a fix zero iv. For benchmarking only. */
 static void
-salsa20_set_key_hack(void *ctx, size_t length, const uint8_t *key)
+salsa20_set_key_hack(void *ctx, const uint8_t *key)
 {
   static const uint8_t iv[SALSA20_IV_SIZE];
-  salsa20_set_key (ctx, length, key);
+  salsa20_256_set_key (ctx, key);
   salsa20_set_iv (ctx, iv);
 }
 
@@ -112,7 +98,7 @@ salsa20_set_key_hack(void *ctx, size_t length, const uint8_t *key)
 const struct nettle_cipher
 nettle_salsa20 = {
   "salsa20", sizeof(struct salsa20_ctx),
-  0, SALSA20_KEY_SIZE,
+  0, SALSA20_256_KEY_SIZE,
   salsa20_set_key_hack, salsa20_set_key_hack,
   (nettle_crypt_func *) salsa20_crypt,
   (nettle_crypt_func *) salsa20_crypt
@@ -121,7 +107,7 @@ nettle_salsa20 = {
 const struct nettle_cipher
 nettle_salsa20r12 = {
   "salsa20r12", sizeof(struct salsa20_ctx),
-  0, SALSA20_KEY_SIZE,
+  0, SALSA20_256_KEY_SIZE,
   salsa20_set_key_hack, salsa20_set_key_hack,
   (nettle_crypt_func *) salsa20r12_crypt,
   (nettle_crypt_func *) salsa20r12_crypt
@@ -138,28 +124,13 @@ const struct nettle_aead
 nettle_gcm_aes256 = _NETTLE_AEAD(gcm, GCM, aes256, 256);
 
 
-/* Old, unified, interface */
-const struct nettle_cipher nettle_unified_aes128
-= _NETTLE_CIPHER_SEP(aes, AES, 128);
-
-const struct nettle_cipher nettle_unified_aes192
-= _NETTLE_CIPHER_SEP(aes, AES, 192);
-
-const struct nettle_cipher nettle_unified_aes256
-= _NETTLE_CIPHER_SEP(aes, AES, 256);
-
 /* eax-aes128 */
 void
-eax_aes128_set_key(struct eax_aes128_ctx *ctx, size_t length,
-		   const uint8_t *key)
+eax_aes128_set_key(struct eax_aes128_ctx *ctx, const uint8_t *key)
 {
-  assert (length == AES128_KEY_SIZE);
-  aes128_set_encrypt_key (&ctx->cipher, key);
-  eax_set_key (&ctx->key, &ctx->cipher,
-	       (nettle_crypt_func *) aes128_encrypt);
-
-  /* Can't use EAX_SET_KEY due to aes128_set_encrypt_key /
-     nettle_crypt_func impedance mismatch */
+  EAX_SET_KEY(ctx,
+	      aes128_set_encrypt_key, aes128_encrypt,
+	      key);
 }
 
 void
diff --git a/nettle-internal.h b/nettle-internal.h
index 3528b24462d0f9e01f66777ebf93874c901d8a1a..f82c1bac38510dfb236613fc65fa1dd8348cae36 100644
--- a/nettle-internal.h
+++ b/nettle-internal.h
@@ -6,7 +6,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2002 Niels Möller
+ * Copyright (C) 2002, 2014 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
@@ -96,7 +96,7 @@ struct nettle_aead
   size_t key_size;
 
   nettle_set_key_func *set_key;
-  nettle_set_key_func *set_iv;
+  nettle_hash_update_func *set_iv;
   nettle_hash_update_func *update;
   nettle_crypt_func *encrypt;
   nettle_crypt_func *decrypt;
@@ -104,12 +104,12 @@ struct nettle_aead
 };
 
 #define _NETTLE_AEAD(type, TYPE, name, key_size) {	\
-  #type "-" #name,				\
+  #type "-" #name,					\
   sizeof(struct type##_##name##_ctx),			\
   TYPE##_BLOCK_SIZE,					\
   key_size / 8,						\
   (nettle_set_key_func *) type##_##name##_set_key,	\
-  (nettle_set_key_func *) type##_##name##_set_nonce,	\
+  (nettle_hash_update_func *) type##_##name##_set_nonce,\
   (nettle_hash_update_func *) type##_##name##_update,	\
   (nettle_crypt_func *) type##_##name##_encrypt,	\
   (nettle_crypt_func *) type##_##name##_decrypt,	\
@@ -136,8 +136,7 @@ extern const struct nettle_aead nettle_gcm_twofish256;
 struct eax_aes128_ctx EAX_CTX(struct aes128_ctx);
 
 void
-eax_aes128_set_key(struct eax_aes128_ctx *ctx,
-		   size_t length, const uint8_t *key);
+eax_aes128_set_key(struct eax_aes128_ctx *ctx, const uint8_t *key);
 
 void
 eax_aes128_set_nonce(struct eax_aes128_ctx *ctx,
diff --git a/nettle-types.h b/nettle-types.h
index 148ac4dfccaa14ca5808b7e0ac86d88061bf76e0..fe3c5246d26f45c1557e6083c50008abdb351df0 100644
--- a/nettle-types.h
+++ b/nettle-types.h
@@ -2,7 +2,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2005 Niels Möller
+ * Copyright (C) 2005, 2014 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
@@ -52,9 +52,7 @@ typedef void nettle_progress_func(void *ctx, int c);
 typedef void *nettle_realloc_func(void *ctx, void *p, size_t length);
 
 /* Ciphers */
-typedef void nettle_set_key_func(void *ctx,
-				 size_t length,
-				 const uint8_t *key);
+typedef void nettle_set_key_func(void *ctx, const uint8_t *key);
 
 /* Uses a void * for cipher contexts.
 
diff --git a/serpent-meta.c b/serpent-meta.c
index 9b9bab5b6aeedebd29df32553f7ebe0c9b5b1675..20504f72c50a59897d57bc1378fbbdbb2c61eca0 100644
--- a/serpent-meta.c
+++ b/serpent-meta.c
@@ -2,7 +2,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2002 Niels Möller
+ * Copyright (C) 2002, 2014 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
@@ -28,11 +28,20 @@
 
 #include "serpent.h"
 
-const struct nettle_cipher nettle_serpent128
-= _NETTLE_CIPHER(serpent, SERPENT, 128);
+#define SERPENT(bits) {					\
+  "serpent" #bits,					\
+  sizeof(struct serpent_ctx),				\
+  SERPENT_BLOCK_SIZE,					\
+  SERPENT ## bits ##_KEY_SIZE,				\
+  (nettle_set_key_func *) serpent ## bits ## _set_key,	\
+  (nettle_set_key_func *) serpent ## bits ## _set_key,	\
+  (nettle_crypt_func *) serpent_encrypt,		\
+  (nettle_crypt_func *) serpent_decrypt			\
+}
 
+const struct nettle_cipher nettle_serpent128
+= SERPENT(128);
 const struct nettle_cipher nettle_serpent192
-= _NETTLE_CIPHER(serpent, SERPENT, 192);
-
+= SERPENT(192);
 const struct nettle_cipher nettle_serpent256
-= _NETTLE_CIPHER(serpent, SERPENT, 256);
+= SERPENT(256);
diff --git a/serpent-set-key.c b/serpent-set-key.c
index ace575372eb85308ec0dbbfe56c78d2e4e181ba2..711a65f9aaa8a70c6a665fba89b4e49d988b892f 100644
--- a/serpent-set-key.c
+++ b/serpent-set-key.c
@@ -8,7 +8,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2011  Niels Möller
+ * Copyright (C) 2011, 2014  Niels Möller
  * Copyright (C) 2010, 2011  Simon Josefsson
  * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
  *  
@@ -313,7 +313,7 @@ serpent_key_pad (const uint8_t *key, unsigned int key_length,
     }
 }
 
-/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits.  */
+/* Initialize CONTEXT with the key KEY of LENGTH bytes.  */
 void
 serpent_set_key (struct serpent_ctx *ctx,
 		 size_t length, const uint8_t * key)
@@ -349,3 +349,21 @@ serpent_set_key (struct serpent_ctx *ctx,
     }
   assert (keys == ctx->keys + 33);
 }
+
+void
+serpent128_set_key (struct serpent_ctx *ctx, const uint8_t *key)
+{
+  serpent_set_key (ctx, SERPENT128_KEY_SIZE, key);
+}
+
+void
+serpent192_set_key (struct serpent_ctx *ctx, const uint8_t *key)
+{
+  serpent_set_key (ctx, SERPENT192_KEY_SIZE, key);
+}
+
+void
+serpent256_set_key (struct serpent_ctx *ctx, const uint8_t *key)
+{
+  serpent_set_key (ctx, SERPENT256_KEY_SIZE, key);
+}
diff --git a/serpent.h b/serpent.h
index 942628478c31df7eabb322c461932c454e234d1b..da279ecaf3e8c815abee668622f9e64c7f71f351 100644
--- a/serpent.h
+++ b/serpent.h
@@ -39,6 +39,9 @@ extern "C" {
 
 /* Name mangling */
 #define serpent_set_key nettle_serpent_set_key
+#define serpent128_set_key nettle_serpent128_set_key
+#define serpent192_set_key nettle_serpent192_set_key
+#define serpent256_set_key nettle_serpent256_set_key
 #define serpent_encrypt nettle_serpent_encrypt
 #define serpent_decrypt nettle_serpent_decrypt
 
@@ -56,6 +59,10 @@ extern "C" {
 #define SERPENT_MIN_KEY_SIZE 16
 #define SERPENT_MAX_KEY_SIZE 32
 
+#define SERPENT128_KEY_SIZE 16
+#define SERPENT192_KEY_SIZE 24
+#define SERPENT256_KEY_SIZE 32
+
 struct serpent_ctx
 {
   uint32_t keys[33][4];  /* key schedule */
@@ -64,6 +71,12 @@ struct serpent_ctx
 void
 serpent_set_key(struct serpent_ctx *ctx,
                 size_t length, const uint8_t *key);
+void
+serpent128_set_key(struct serpent_ctx *ctx, const uint8_t *key);
+void
+serpent192_set_key(struct serpent_ctx *ctx, const uint8_t *key);
+void
+serpent256_set_key(struct serpent_ctx *ctx, const uint8_t *key);
 
 void
 serpent_encrypt(const struct serpent_ctx *ctx,
diff --git a/testsuite/aes-test.c b/testsuite/aes-test.c
index 964114e3c84b0c221921b94d86e39cb75f8a4103..9f80319be388c6b739566c23ce4053b7f177c297 100644
--- a/testsuite/aes-test.c
+++ b/testsuite/aes-test.c
@@ -46,6 +46,61 @@ test_invert(const struct tstring *key,
   free (data);
 }
 
+/* Old, unified, interface */
+static nettle_set_key_func unified_aes128_set_encrypt_key;
+static nettle_set_key_func unified_aes128_set_encrypt_key;
+static nettle_set_key_func unified_aes192_set_encrypt_key;
+static nettle_set_key_func unified_aes192_set_encrypt_key;
+static nettle_set_key_func unified_aes256_set_encrypt_key;
+static nettle_set_key_func unified_aes256_set_encrypt_key;
+static void
+unified_aes128_set_encrypt_key (void *ctx, const uint8_t *key)
+{
+  aes_set_encrypt_key (ctx, AES128_KEY_SIZE, key);
+}
+static void
+unified_aes128_set_decrypt_key (void *ctx, const uint8_t *key)
+{
+  aes_set_decrypt_key (ctx, AES128_KEY_SIZE, key);
+}
+
+static void
+unified_aes192_set_encrypt_key (void *ctx, const uint8_t *key)
+{
+  aes_set_encrypt_key (ctx, AES192_KEY_SIZE, key);
+}
+static void
+unified_aes192_set_decrypt_key (void *ctx, const uint8_t *key)
+{
+  aes_set_decrypt_key (ctx, AES192_KEY_SIZE, key);
+}
+
+static void
+unified_aes256_set_encrypt_key (void *ctx, const uint8_t *key)
+{
+  aes_set_encrypt_key (ctx, AES256_KEY_SIZE, key);
+}
+static void
+unified_aes256_set_decrypt_key (void *ctx, const uint8_t *key)
+{
+  aes_set_decrypt_key (ctx, AES256_KEY_SIZE, key);
+}
+
+#define UNIFIED_AES(bits) {			\
+  "unified-aes" #bits, sizeof(struct aes_ctx),	\
+  AES_BLOCK_SIZE, AES ## bits ## _KEY_SIZE,	\
+  unified_aes ## bits ##_set_encrypt_key,	\
+  unified_aes ## bits ##_set_decrypt_key,	\
+  (nettle_crypt_func *) aes_encrypt,		\
+  (nettle_crypt_func *) aes_decrypt,		\
+}
+const struct nettle_cipher nettle_unified_aes128
+= UNIFIED_AES(128);
+const struct nettle_cipher nettle_unified_aes192
+= UNIFIED_AES(192);
+const struct nettle_cipher nettle_unified_aes256
+= UNIFIED_AES(256);
+
 static void
 test_cipher2(const struct nettle_cipher *c1,
 	     const struct nettle_cipher *c2,	     
diff --git a/testsuite/arcfour-test.c b/testsuite/arcfour-test.c
index c1443a1e06e0d90304a2c681d4e8b41776e92907..b2b039bbd57b157f3a043d739aaa427fc7605342 100644
--- a/testsuite/arcfour-test.c
+++ b/testsuite/arcfour-test.c
@@ -1,95 +1,159 @@
 #include "testutils.h"
 #include "arcfour.h"
 
+static void
+test_arcfour(const struct tstring *key,
+	     const struct tstring *cleartext,
+	     const struct tstring *ciphertext)
+{
+  size_t block;
+  struct arcfour_ctx ctx;
+
+  uint8_t *data;
+  size_t length;
+
+  ASSERT (cleartext->length == ciphertext->length);
+  length = cleartext->length;
+
+  data = xalloc(length + 1);
+
+  for (block = 1; block <= length; block++)
+    {
+      size_t i;
+
+      memset(data, 0x17, length + 1);
+      arcfour_set_key(&ctx, key->length, key->data);
+
+      for (i = 0; i + block < length; i += block)
+	{
+	  arcfour_crypt(&ctx, block, data + i, cleartext->data + i);
+	  ASSERT (data[i + block] == 0x17);
+	}
+
+      arcfour_crypt(&ctx, length - i, data + i, cleartext->data + i);
+      ASSERT (data[length] == 0x17);
+
+      if (!MEMEQ(length, data, ciphertext->data))
+	{
+	  fprintf(stderr, "Encrypt failed, block size %lu\nInput:",
+		  (unsigned long) block);
+	  tstring_print_hex(cleartext);
+	  fprintf(stderr, "\nOutput: ");
+	  print_hex(length, data);
+	  fprintf(stderr, "\nExpected:");
+	  tstring_print_hex(ciphertext);
+	  fprintf(stderr, "\n");
+	  FAIL();
+	}
+    }
+
+  arcfour_set_key(&ctx, key->length, key->data);
+  arcfour_crypt(&ctx, length, data, data);
+
+  ASSERT (data[length] == 0x17);
+
+  if (!MEMEQ(length, data, cleartext->data))
+    {
+      fprintf(stderr, "Decrypt failed\nInput:");
+      tstring_print_hex(ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      tstring_print_hex(cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  free(data);
+}
+
 void
 test_main(void)
 {
-  test_cipher_stream(&nettle_arcfour128,
-		     SHEX("01234567 89ABCDEF 00000000 00000000"),
-		     SHEX("01234567 89ABCDEF"),
-		     SHEX("69723659 1B5242B1"));
+  test_arcfour(SHEX("01234567 89ABCDEF 00000000 00000000"),
+	       SHEX("01234567 89ABCDEF"),
+	       SHEX("69723659 1B5242B1"));
 
   /* More data. This ensures that we get some collisions between the S
      accesses at index i,j and the access at si + sj. I.e. the cases
      where the ordering of loads and stores matter. */
-  test_cipher_stream(&nettle_arcfour128,
-		     SHEX("aaaaaaaa bbbbbbbb cccccccc dddddddd"),
-		     SHEX("00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
+  test_arcfour(SHEX("aaaaaaaa bbbbbbbb cccccccc dddddddd"),
+	       SHEX("00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
 			
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
 			
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
 			
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
 			
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
 			
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
 			
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"
-			  "00000000 00000000 00000000 00000000"),
-		     SHEX("a2b35dc7 bf95ae1e 1c432d15 f4fb8c1c"
-			  "f264e1d0 bd090831 6caa7d17 5401ae67"
-			  "3cfbd140 fd3dee42 1012d674 2fb69fa3"
-			  "6522631e bb3d4703 535de1ce 4a81ddce"
-
-			  "5780cfe0 b5fc9fae ebe14c96 26451bd9"
-			  "992f2204 119cbe37 cbdc453c 7afa08c7"
-			  "1380ccf8 48f81e53 a535cdfb 96c64faa"
-			  "c3f759d0 fa1ff920 008d95cf 39d52324"
-
-			  "d0aac3f9 749b22e2 6a065145 06fb249d"
-			  "ffb8e05e cb0381fe 5346a04a 63dac61c"
-			  "10b6683e 3ab427de d4c6bc60 6366545e"
-			  "77d0e121 96037717 a745d49e e72a70aa"
-
-			  "a50a612d 879b0580 fd4a89ae 3ee49871"
-			  "2cf6c98d a62dfbc7 d7b2d901 2c3aaf27"
-			  "42b7e089 ef2466ac 450b440c 138daa1a"
-			  "cf9ebef6 f66a7a64 2677b213 06640130"
-
-			  "de6651df 0065180d 4db366ba 9c377712"
-			  "53d21cac 82ed72a4 c6c4d81e 4375fea3"
-			  "1f935909 95322c83 13c64d8e 829c93a6"
-			  "d540a1b3 20f41541 96800888 1a7afc9b"
-
-			  "e39e89fc 3ac78be5 cdbbf774 33c36863"
-			  "da2a3b1b d06e54a9 aa4b7edd 70b34941"
-			  "b886f7db f36c3def f9fc4c80 7ce55ea5"
-			  "98a7257b f68a9e1d caf4bfd6 43bd9853"
-
-			  "c966629d 54e34221 6e140780 d48c69bb"
-			  "5e77e886 86f2ebcb 807732d5 d29bc384"
-			  "a4ca1c31 c7c1b5b9 85dbfcf1 8d845905"
-			  "a0ff487a b4a3f252 a75caebf 857ba48b"
-
-			  "613e3067 92cada3e 0e07f599 2f4794f3"
-			  "af01f15a 491732fb 22aa09a3 d2e1e408"
-			  "fe94bdb4 993c68b1 1bb79eb1 bb7ec446"
-			  "760ef7bf 2caa8713 479760e5 a6e143cd"));
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"
+		    "00000000 00000000 00000000 00000000"),
+	       SHEX("a2b35dc7 bf95ae1e 1c432d15 f4fb8c1c"
+		    "f264e1d0 bd090831 6caa7d17 5401ae67"
+		    "3cfbd140 fd3dee42 1012d674 2fb69fa3"
+		    "6522631e bb3d4703 535de1ce 4a81ddce"
+
+		    "5780cfe0 b5fc9fae ebe14c96 26451bd9"
+		    "992f2204 119cbe37 cbdc453c 7afa08c7"
+		    "1380ccf8 48f81e53 a535cdfb 96c64faa"
+		    "c3f759d0 fa1ff920 008d95cf 39d52324"
+
+		    "d0aac3f9 749b22e2 6a065145 06fb249d"
+		    "ffb8e05e cb0381fe 5346a04a 63dac61c"
+		    "10b6683e 3ab427de d4c6bc60 6366545e"
+		    "77d0e121 96037717 a745d49e e72a70aa"
+
+		    "a50a612d 879b0580 fd4a89ae 3ee49871"
+		    "2cf6c98d a62dfbc7 d7b2d901 2c3aaf27"
+		    "42b7e089 ef2466ac 450b440c 138daa1a"
+		    "cf9ebef6 f66a7a64 2677b213 06640130"
+
+		    "de6651df 0065180d 4db366ba 9c377712"
+		    "53d21cac 82ed72a4 c6c4d81e 4375fea3"
+		    "1f935909 95322c83 13c64d8e 829c93a6"
+		    "d540a1b3 20f41541 96800888 1a7afc9b"
+
+		    "e39e89fc 3ac78be5 cdbbf774 33c36863"
+		    "da2a3b1b d06e54a9 aa4b7edd 70b34941"
+		    "b886f7db f36c3def f9fc4c80 7ce55ea5"
+		    "98a7257b f68a9e1d caf4bfd6 43bd9853"
+
+		    "c966629d 54e34221 6e140780 d48c69bb"
+		    "5e77e886 86f2ebcb 807732d5 d29bc384"
+		    "a4ca1c31 c7c1b5b9 85dbfcf1 8d845905"
+		    "a0ff487a b4a3f252 a75caebf 857ba48b"
+
+		    "613e3067 92cada3e 0e07f599 2f4794f3"
+		    "af01f15a 491732fb 22aa09a3 d2e1e408"
+		    "fe94bdb4 993c68b1 1bb79eb1 bb7ec446"
+		    "760ef7bf 2caa8713 479760e5 a6e143cd"));
 }
diff --git a/testsuite/blowfish-test.c b/testsuite/blowfish-test.c
index 2cac994aec643e902e1e4881220ced5721af7689..cadeda5f2ba809001eb69065ee1538c2b8877b02 100644
--- a/testsuite/blowfish-test.c
+++ b/testsuite/blowfish-test.c
@@ -2,86 +2,54 @@
 #include "nettle-internal.h"
 #include "blowfish.h"
 
+static void
+test_blowfish(const struct tstring *key,
+	      const struct tstring *cleartext,
+	      const struct tstring *ciphertext)
+{
+  struct blowfish_ctx ctx;
+  uint8_t *data = xalloc(cleartext->length);
+  size_t length;
+  ASSERT (cleartext->length == ciphertext->length);
+  length = cleartext->length;
+
+  blowfish_set_key(&ctx, key->length, key->data);
+  blowfish_encrypt(&ctx, length, data, cleartext->data);
+
+  if (!MEMEQ(length, data, ciphertext->data))
+    {
+      fprintf(stderr, "Encrypt failed:\nInput:");
+      tstring_print_hex(cleartext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      tstring_print_hex(ciphertext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+  blowfish_set_key(&ctx, key->length, key->data);
+  blowfish_decrypt(&ctx, length, data, data);
+
+  if (!MEMEQ(length, data, cleartext->data))
+    {
+      fprintf(stderr, "Decrypt failed:\nInput:");
+      tstring_print_hex(ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      tstring_print_hex(cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  free(data);
+}
+
 void
 test_main(void)
 {
   /* 208 bit key. Test from GNUPG. */
-  test_cipher(&nettle_blowfish128,
-	      SDATA("abcdefghijklmnopqrstuvwxyz"),
-	      SDATA("BLOWFISH"),
-	      SHEX("32 4E D0 FE F4 13 A2 03"));
+  test_blowfish(SDATA("abcdefghijklmnopqrstuvwxyz"),
+		SDATA("BLOWFISH"),
+		SHEX("32 4E D0 FE F4 13 A2 03"));
 }
-/* FIXME: All values below are bogus. */
-#if 0
-
-/* 128 bit keys */
-H(msg, "506812A45F08C889 B97F5980038B8359");
-
-blowfish_set_key(&ctx, 16,  H("0001020305060708 0A0B0C0D0F101112"));
-blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
-if (!MEMEQ(16, cipher, H("D8F532538289EF7D 06B506A4FD5BE9C9")))
-  FAIL;
-
-blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
-if (!MEMEQ(16, msg, clear))
-  FAIL;
-
-H(msg, "5C6D71CA30DE8B8B 00549984D2EC7D4B");
-
-blowfish_set_key(&ctx, 16,  H("14151617191A1B1C 1E1F202123242526"));
-blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
-if (!MEMEQ(16, cipher, H("59AB30F4D4EE6E4F F9907EF65B1FB68C")))
-  FAIL;
-
-blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
-if (!MEMEQ(16, msg, clear))
-  FAIL;
-
-H(msg, "53F3F4C64F8616E4 E7C56199F48F21F6");
-
-blowfish_set_key(&ctx, 16,  H("28292A2B2D2E2F30 323334353738393A"));
-blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
-if (!MEMEQ(16, cipher, H("BF1ED2FCB2AF3FD4 1443B56D85025CB1")))
-  FAIL;
-
-blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
-if (!MEMEQ(16, msg, clear))
-  FAIL;
-
-H(msg, "F5F4F7F684878689 A6A7A0A1D2CDCCCF");
-
-blowfish_set_key(&ctx, 16,  H("A0A1A2A3A5A6A7A8 AAABACADAFB0B1B2"));
-blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
-if (!MEMEQ(16, cipher, H("CE52AF650D088CA5 59425223F4D32694")))
-  FAIL;
-
-blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
-if (!MEMEQ(16, msg, clear))
-  FAIL;
-
-/* 192 bit keys */
-H(msg, "2D33EEF2C0430A8A 9EBF45E809C40BB6");
-
-blowfish_set_key(&ctx, 24,  H("0001020305060708 0A0B0C0D0F101112"
-			 "14151617191A1B1C"));
-blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
-if (!MEMEQ(16, cipher, H("DFF4945E0336DF4C 1C56BC700EFF837F")))
-  FAIL;
-
-blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
-if (!MEMEQ(16, msg, clear))
-  FAIL;
-
-/* 256 bit keys */
-H(msg, "834EADFCCAC7E1B30664B1ABA44815AB");
-
-blowfish_set_key(&ctx, 32,  H("0001020305060708 0A0B0C0D0F101112"
-			 "14151617191A1B1C 1E1F202123242526"));
-blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
-if (!MEMEQ(16, cipher, H("1946DABF6A03A2A2 C3D0B05080AED6FC")))
-  FAIL;
-
-blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
-if (!MEMEQ(16, msg, clear))
-  FAIL;
-#endif
diff --git a/testsuite/cast128-test.c b/testsuite/cast128-test.c
index 60ed30b147c1cd63e39fe6d8dd4cbd0d3b2dd4ee..534eb1725e55c917a07f07811164b4bda33918b4 100644
--- a/testsuite/cast128-test.c
+++ b/testsuite/cast128-test.c
@@ -1,6 +1,49 @@
 #include "testutils.h"
 #include "cast128.h"
 
+static void
+test_cast5(const struct tstring *key,
+	      const struct tstring *cleartext,
+	      const struct tstring *ciphertext)
+{
+  struct cast128_ctx ctx;
+  uint8_t *data = xalloc(cleartext->length);
+  size_t length;
+  ASSERT (cleartext->length == ciphertext->length);
+  length = cleartext->length;
+
+  cast5_set_key(&ctx, key->length, key->data);
+  cast128_encrypt(&ctx, length, data, cleartext->data);
+
+  if (!MEMEQ(length, data, ciphertext->data))
+    {
+      fprintf(stderr, "Encrypt failed:\nInput:");
+      tstring_print_hex(cleartext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      tstring_print_hex(ciphertext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+  cast5_set_key(&ctx, key->length, key->data);
+  cast128_decrypt(&ctx, length, data, data);
+
+  if (!MEMEQ(length, data, cleartext->data))
+    {
+      fprintf(stderr, "Decrypt failed:\nInput:");
+      tstring_print_hex(ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      tstring_print_hex(cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  free(data);
+}
+
 void
 test_main(void)
 {
@@ -15,14 +58,12 @@ test_main(void)
 	      SHEX("23 8B 4F E5 84 7E 44 B2"));
   
   /* 80 bit key */
-  test_cipher(&nettle_cast128,
-	      SHEX("01 23 45 67 12 34 56 78 23 45"),
-	      SHEX("01 23 45 67 89 AB CD EF"),
-	      SHEX("EB 6A 71 1A 2C 02 27 1B"));
+  test_cast5(SHEX("01 23 45 67 12 34 56 78 23 45"),
+	     SHEX("01 23 45 67 89 AB CD EF"),
+	     SHEX("EB 6A 71 1A 2C 02 27 1B"));
 
   /* 40 bit key */
-  test_cipher(&nettle_cast128,
-	      SHEX("01 23 45 67 12"),
-	      SHEX("01 23 45 67 89 AB CD EF"),
-	      SHEX("7A C8 16 D1 6E 9B 30 2E"));
+  test_cast5(SHEX("01 23 45 67 12"),
+	     SHEX("01 23 45 67 89 AB CD EF"),
+	     SHEX("7A C8 16 D1 6E 9B 30 2E"));
 }
diff --git a/testsuite/gcm-test.c b/testsuite/gcm-test.c
index 5b7ed697fccd0011887a411cfffa99327c6f0d44..4c37516a9185d4c1be16e0cb0b6b95851f7e1653 100644
--- a/testsuite/gcm-test.c
+++ b/testsuite/gcm-test.c
@@ -10,7 +10,7 @@ test_gcm_hash (const struct tstring *msg, const struct tstring *ref)
   uint8_t digest[16];
 
   ASSERT (ref->length == sizeof(digest));
-  gcm_aes128_set_key (&ctx, 16, z16);
+  gcm_aes128_set_key (&ctx, z16);
   gcm_aes128_set_iv (&ctx, 16, z16);
   gcm_aes128_update (&ctx, msg->length, msg->data);
   gcm_aes128_digest (&ctx, sizeof(digest), digest);
@@ -26,10 +26,9 @@ test_gcm_hash (const struct tstring *msg, const struct tstring *ref)
 }
 
 static void
-gcm_aes128_set_key_wrapper (void *ctx, size_t length, const uint8_t *key)
+gcm_unified_aes128_set_key (void *ctx, uint8_t *key)
 {
-  ASSERT (length == AES128_KEY_SIZE);
-  gcm_aes_set_key (ctx, length, key);
+  gcm_aes_set_key (ctx, AES128_KEY_SIZE, key);
 }
 static const struct nettle_aead
 nettle_gcm_unified_aes128 = {
@@ -37,8 +36,8 @@ nettle_gcm_unified_aes128 = {
   sizeof (struct gcm_aes_ctx),
   GCM_BLOCK_SIZE,
   AES128_KEY_SIZE,
-  gcm_aes128_set_key_wrapper,
-  (nettle_set_key_func *) gcm_aes_set_iv,
+  (nettle_set_key_func *) gcm_unified_aes128_set_key,
+  (nettle_hash_update_func *) gcm_aes_set_iv,
   (nettle_hash_update_func *) gcm_aes_update,
   (nettle_crypt_func *) gcm_aes_encrypt,
   (nettle_crypt_func *) gcm_aes_decrypt,
diff --git a/testsuite/serpent-test.c b/testsuite/serpent-test.c
index 020fcbfd108b9ff49ca437f2a642bb2c04e9af8f..4b89a1ed3fd9990d734e1be2bddf6870e7278dbc 100644
--- a/testsuite/serpent-test.c
+++ b/testsuite/serpent-test.c
@@ -22,6 +22,50 @@ tstring_hex_reverse (const char *hex)
 
 #define RHEX(x) tstring_hex_reverse(x)
 
+/* For testing unusual key sizes. */
+static void
+test_serpent(const struct tstring *key,
+	     const struct tstring *cleartext,
+	     const struct tstring *ciphertext)
+{
+  struct serpent_ctx ctx;
+  uint8_t *data = xalloc(cleartext->length);
+  size_t length;
+  ASSERT (cleartext->length == ciphertext->length);
+  length = cleartext->length;
+
+  serpent_set_key(&ctx, key->length, key->data);
+  serpent_encrypt(&ctx, length, data, cleartext->data);
+
+  if (!MEMEQ(length, data, ciphertext->data))
+    {
+      fprintf(stderr, "Encrypt failed:\nInput:");
+      tstring_print_hex(cleartext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      tstring_print_hex(ciphertext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+  serpent_set_key(&ctx, key->length, key->data);
+  serpent_decrypt(&ctx, length, data, data);
+
+  if (!MEMEQ(length, data, cleartext->data))
+    {
+      fprintf(stderr, "Decrypt failed:\nInput:");
+      tstring_print_hex(ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      tstring_print_hex(cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  free(data);
+}
+
 void
 test_main(void)
 {
@@ -148,36 +192,32 @@ test_main(void)
 	      SHEX("0000000001000000 0200000003000000"),
 	      SHEX("C1415AC653FD7C7F D917482EE8EBFE25"));
 
-  /* Currrently, key sizes smaller than SERPENT_MIN_KEY_SIZE bytes
-     (128 bits) are not supported. */
-  test_cipher(&nettle_serpent256,
-	      SHEX("0011223344"),
-	      SHEX("0000000001000000 0200000003000000"),
-	      SHEX("C1415AC653FD7C7F D917482EE8EBFE25"));
-
-  test_cipher(&nettle_serpent256,
-	      SHEX("00112233445566778899aabbccddeeff"
-		   "00010000000000000000000000000000"),
-	      SHEX("0000000001000000 0200000003000000"),
-	      SHEX("8EB9C958EAFFDF42 009755D7B6458838"));
-
-  test_cipher(&nettle_serpent256,
-	      SHEX("00112233445566778899aabbccddeeff"
-		   "00"),
-	      SHEX("0000000001000000 0200000003000000"),
-	      SHEX("8EB9C958EAFFDF42 009755D7B6458838"));
-
-  test_cipher(&nettle_serpent256,
-	      SHEX("00112233445566778899aabbccddeeff"
-		   "00112201000000000000000000000000"),
-	      SHEX("0000000001000000 0200000003000000"),
-	      SHEX("C8A078D8212AC96D 9060E30EC5CBB5C7"));
-
-  test_cipher(&nettle_serpent256,
-	      SHEX("00112233445566778899aabbccddeeff"
-		   "001122"),
-	      SHEX("0000000001000000 0200000003000000"),
-	      SHEX("C8A078D8212AC96D 9060E30EC5CBB5C7"));
+  /* Tests with various key sizes. Currrently, key sizes smaller than
+     SERPENT_MIN_KEY_SIZE bytes (128 bits) are not publicly
+     supported. */
+  test_serpent(SHEX("0011223344"),
+	       SHEX("0000000001000000 0200000003000000"),
+	       SHEX("C1415AC653FD7C7F D917482EE8EBFE25"));
+
+  test_serpent(SHEX("00112233445566778899aabbccddeeff"
+		    "00010000000000000000000000000000"),
+	       SHEX("0000000001000000 0200000003000000"),
+	       SHEX("8EB9C958EAFFDF42 009755D7B6458838"));
+
+  test_serpent(SHEX("00112233445566778899aabbccddeeff"
+		    "00"),
+	       SHEX("0000000001000000 0200000003000000"),
+	       SHEX("8EB9C958EAFFDF42 009755D7B6458838"));
+
+  test_serpent(SHEX("00112233445566778899aabbccddeeff"
+		    "00112201000000000000000000000000"),
+	       SHEX("0000000001000000 0200000003000000"),
+	       SHEX("C8A078D8212AC96D 9060E30EC5CBB5C7"));
+
+  test_serpent(SHEX("00112233445566778899aabbccddeeff"
+		    "001122"),
+	       SHEX("0000000001000000 0200000003000000"),
+	       SHEX("C8A078D8212AC96D 9060E30EC5CBB5C7"));
 
   /* Test with multiple blocks. */
   test_cipher(&nettle_serpent128,
diff --git a/testsuite/testutils.c b/testsuite/testutils.c
index a4829c5483ce1227ba080275827738545e0ab061..8289c2460d8efb5fcaa252b5ad7abe44142627cd 100644
--- a/testsuite/testutils.c
+++ b/testsuite/testutils.c
@@ -221,7 +221,8 @@ test_cipher(const struct nettle_cipher *cipher,
   ASSERT (cleartext->length == ciphertext->length);
   length = cleartext->length;
 
-  cipher->set_encrypt_key(ctx, key->length, key->data);
+  ASSERT (key->length == cipher->key_size);
+  cipher->set_encrypt_key(ctx, key->data);
   cipher->encrypt(ctx, length, data, cleartext->data);
 
   if (!MEMEQ(length, data, ciphertext->data))
@@ -235,7 +236,7 @@ test_cipher(const struct nettle_cipher *cipher,
       fprintf(stderr, "\n");
       FAIL();
     }
-  cipher->set_decrypt_key(ctx, key->length, key->data);
+  cipher->set_decrypt_key(ctx, key->data);
   cipher->decrypt(ctx, length, data, data);
 
   if (!MEMEQ(length, data, cleartext->data))
@@ -269,10 +270,11 @@ test_cipher_cbc(const struct nettle_cipher *cipher,
   ASSERT (cleartext->length == ciphertext->length);
   length = cleartext->length;
 
+  ASSERT (key->length == cipher->key_size);
   ASSERT (iiv->length == cipher->block_size);
 
   data = xalloc(length);  
-  cipher->set_encrypt_key(ctx, key->length, key->data);
+  cipher->set_encrypt_key(ctx, key->data);
   memcpy(iv, iiv->data, cipher->block_size);
 
   cbc_encrypt(ctx, cipher->encrypt,
@@ -290,7 +292,7 @@ test_cipher_cbc(const struct nettle_cipher *cipher,
       fprintf(stderr, "\n");
       FAIL();
     }
-  cipher->set_decrypt_key(ctx, key->length, key->data);
+  cipher->set_decrypt_key(ctx, key->data);
   memcpy(iv, iiv->data, cipher->block_size);
 
   cbc_decrypt(ctx, cipher->decrypt,
@@ -331,6 +333,7 @@ test_cipher_ctr(const struct nettle_cipher *cipher,
   ASSERT (cleartext->length == ciphertext->length);
   length = cleartext->length;
 
+  ASSERT (key->length == cipher->key_size);
   ASSERT (ictr->length == cipher->block_size);
 
   /* Compute expected counter value after the operation. */
@@ -346,7 +349,7 @@ test_cipher_ctr(const struct nettle_cipher *cipher,
 
   data = xalloc(length);  
 
-  cipher->set_encrypt_key(ctx, key->length, key->data);
+  cipher->set_encrypt_key(ctx, key->data);
   memcpy(ctr, ictr->data, cipher->block_size);
 
   ctr_crypt(ctx, cipher->encrypt,
@@ -393,6 +396,7 @@ test_cipher_ctr(const struct nettle_cipher *cipher,
   free(ctr);
 }
 
+#if 0
 void
 test_cipher_stream(const struct nettle_cipher *cipher,
 		   const struct tstring *key,
@@ -460,6 +464,7 @@ test_cipher_stream(const struct nettle_cipher *cipher,
   free(ctx);
   free(data);
 }
+#endif
 
 void
 test_aead(const struct nettle_aead *aead,
@@ -478,13 +483,14 @@ test_aead(const struct nettle_aead *aead,
   ASSERT (cleartext->length == ciphertext->length);
   length = cleartext->length;
 
+  ASSERT (key->length == aead->key_size);
   ASSERT (digest->length <= aead->block_size);
 
   data = xalloc(length);
   
   /* encryption */
   memset(buffer, 0, aead->block_size);
-  aead->set_key(ctx, key->length, key->data);
+  aead->set_key(ctx, key->data);
 
   aead->set_iv(ctx, iv->length, iv->data);
 
diff --git a/twofish-meta.c b/twofish-meta.c
index 607a8bd82efd265bee586787bc3a4efcef2ec38f..31e4d0208af29e9faaba59067434c211697a528e 100644
--- a/twofish-meta.c
+++ b/twofish-meta.c
@@ -2,7 +2,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2002 Niels Möller
+ * Copyright (C) 2002, 2014 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
@@ -28,11 +28,20 @@
 
 #include "twofish.h"
 
-const struct nettle_cipher nettle_twofish128
-= _NETTLE_CIPHER(twofish, TWOFISH, 128);
+#define TWOFISH(bits) {					\
+  "twofish" #bits,					\
+  sizeof(struct twofish_ctx),				\
+  TWOFISH_BLOCK_SIZE,					\
+  TWOFISH ## bits ## _KEY_SIZE,				\
+  (nettle_set_key_func *) twofish ## bits ## _set_key,	\
+  (nettle_set_key_func *) twofish ## bits ## _set_key,	\
+  (nettle_crypt_func *) twofish_encrypt,		\
+  (nettle_crypt_func *) twofish_decrypt			\
+}
 
+const struct nettle_cipher nettle_twofish128
+= TWOFISH(128);
 const struct nettle_cipher nettle_twofish192
-= _NETTLE_CIPHER(twofish, TWOFISH, 192);
-
+= TWOFISH(192);
 const struct nettle_cipher nettle_twofish256
-= _NETTLE_CIPHER(twofish, TWOFISH, 256);
+= TWOFISH(256);
diff --git a/twofish.c b/twofish.c
index 86530911ce79fad40849e0001f78da2faf2afe79..adaf1cc898facf76d46f2f9f28bc65806a990a0c 100644
--- a/twofish.c
+++ b/twofish.c
@@ -10,7 +10,7 @@
  * Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
  *
  * Integrated with the nettle library,
- * Copyright (C) 2001 Niels Möller
+ * Copyright (C) 2001, 2014 Niels Möller
  */
 
 /* nettle, low-level cryptographics library
@@ -326,6 +326,22 @@ twofish_set_key(struct twofish_ctx *context,
 				    s[3] >> (i*8));
 }
 
+void
+twofish128_set_key(struct twofish_ctx *context, const uint8_t *key)
+{
+  twofish_set_key (context, TWOFISH128_KEY_SIZE, key);
+}
+void
+twofish192_set_key(struct twofish_ctx *context, const uint8_t *key)
+{
+  twofish_set_key (context, TWOFISH192_KEY_SIZE, key);
+}
+void
+twofish256_set_key(struct twofish_ctx *context, const uint8_t *key)
+{
+  twofish_set_key (context, TWOFISH256_KEY_SIZE, key);
+}
+
 /* Encrypt blocks of 16 bytes of data with the twofish algorithm.
  *
  * Before this function can be used, twofish_set_key() must be used in order to
diff --git a/twofish.h b/twofish.h
index 321ae936c9de38dbd33b531dfcf7e48f62628a8e..200b4e90d10ff8b2d32dc7b9e1dc63d78a9c0482 100644
--- a/twofish.h
+++ b/twofish.h
@@ -5,7 +5,7 @@
 
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2001 Niels Möller
+ * Copyright (C) 2001, 2014 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
@@ -40,6 +40,9 @@ extern "C" {
 
 /* Name mangling */
 #define twofish_set_key nettle_twofish_set_key
+#define twofish128_set_key nettle_twofish128_set_key
+#define twofish192_set_key nettle_twofish192_set_key
+#define twofish256_set_key nettle_twofish256_set_key
 #define twofish_encrypt nettle_twofish_encrypt
 #define twofish_decrypt nettle_twofish_decrypt
 
@@ -51,6 +54,9 @@ extern "C" {
 #define TWOFISH_MAX_KEY_SIZE 32
 
 #define TWOFISH_KEY_SIZE 32
+#define TWOFISH128_KEY_SIZE 16
+#define TWOFISH192_KEY_SIZE 24
+#define TWOFISH256_KEY_SIZE 32
 
 struct twofish_ctx
 {
@@ -61,6 +67,12 @@ struct twofish_ctx
 void
 twofish_set_key(struct twofish_ctx *ctx,
 		size_t length, const uint8_t *key);
+void
+twofish128_set_key(struct twofish_ctx *context, const uint8_t *key);
+void
+twofish192_set_key(struct twofish_ctx *context, const uint8_t *key);
+void
+twofish256_set_key(struct twofish_ctx *context, const uint8_t *key);
 
 void
 twofish_encrypt(const struct twofish_ctx *ctx,