From e57d2fe2e0385f219e1e4f7adc051ad6b98905c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Sun, 26 Jan 2014 21:35:40 +0100
Subject: [PATCH] New gcm-aes interface.

---
 ChangeLog                   |  29 ++++++++++
 Makefile.in                 |   3 +-
 examples/nettle-benchmark.c |  20 +++----
 gcm-aes128.c                |  74 ++++++++++++++++++++++++
 gcm-aes192.c                |  74 ++++++++++++++++++++++++
 gcm-aes256.c                |  74 ++++++++++++++++++++++++
 gcm.h                       | 111 +++++++++++++++++++++++++++++++++---
 nettle-internal.c           |  15 ++---
 nettle-internal.h           |  15 +----
 testsuite/gcm-test.c        |  50 ++++++++++++++--
 10 files changed, 420 insertions(+), 45 deletions(-)
 create mode 100644 gcm-aes128.c
 create mode 100644 gcm-aes192.c
 create mode 100644 gcm-aes256.c

diff --git a/ChangeLog b/ChangeLog
index 53348ae4..ee6afd1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2014-01-26  Niels Möller  <nisse@lysator.liu.se>
+
+	* nettle-internal.h (_NETTLE_AEAD_FIX): Renamed to...
+	(_NETTLE_AEAD): ... new name, and deleted old definition. Also use
+	_set_nonce instead of _set_iv.
+	* nettle-internal.c (nettle_gcm_aes128, nettle_gcm_aes192)
+	(nettle_gcm_aes256): Define in terms of new interface.
+	(nettle_eax_aes128): Updated for _NETTLE_AEAD changes.
+
+	* testsuite/gcm-test.c (test_gcm_hash): Likewise use struct
+	gcm_aes128_ctx.
+	(test_main): Added a testcase using the old interface based on
+	struct gcm_aes_ctx.
+
+	* examples/nettle-benchmark.c (time_gcm): Update to use new struct
+	gcm_aes128_ctx. Also use name "gcm-aes128" in output.
+
+	* gcm.h: New interface for gcm_aes128, gcm_aes192, gcm_aes256,
+	using the new AES interface.
+	(GCM_CTX): Reorder fields, putting the cipher context
+	last.
+
+	* Makefile.in (nettle_SOURCES): Added gcm-aes128.c, gcm-aes192.c,
+	and gcm-aes256.c.
+
+	* gcm-aes128.c: New file.
+	* gcm-aes192.c: New file
+	* gcm-aes256.c: New file.
+
 2014-01-25  Niels Möller  <nisse@lysator.liu.se>
 
 	* gcm.h (GCM_SET_KEY): Deleted length argument.
diff --git a/Makefile.in b/Makefile.in
index 878d6216..7292ea26 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -87,7 +87,8 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
 		 camellia256-meta.c \
 		 cast128.c cast128-meta.c \
 		 blowfish.c \
-		 cbc.c ctr.c gcm.c gcm-aes.c \
+		 cbc.c ctr.c gcm.c \
+		 gcm-aes.c gcm-aes128.c gcm-aes192.c gcm-aes256.c \
 		 des.c des3.c des-compat.c eax.c \
 		 hmac.c hmac-md5.c hmac-ripemd160.c hmac-sha1.c \
 		 hmac-sha224.c hmac-sha256.c hmac-sha384.c hmac-sha512.c \
diff --git a/examples/nettle-benchmark.c b/examples/nettle-benchmark.c
index c139e1a8..6de7dbcf 100644
--- a/examples/nettle-benchmark.c
+++ b/examples/nettle-benchmark.c
@@ -422,31 +422,31 @@ time_gcm(void)
   static uint8_t data[BENCH_BLOCK];
   struct bench_hash_info hinfo;
   struct bench_cipher_info cinfo;
-  struct gcm_aes_ctx ctx;
+  struct gcm_aes128_ctx ctx;
 
-  uint8_t key[16];
+  uint8_t key[AES128_KEY_SIZE];
   uint8_t iv[GCM_IV_SIZE];
 
-  gcm_aes_set_key(&ctx, sizeof(key), key);
-  gcm_aes_set_iv(&ctx, sizeof(iv), iv);
+  gcm_aes128_set_key(&ctx, sizeof(key), key);
+  gcm_aes128_set_iv(&ctx, sizeof(iv), iv);
 
   hinfo.ctx = &ctx;
-  hinfo.update = (nettle_hash_update_func *) gcm_aes_update;
+  hinfo.update = (nettle_hash_update_func *) gcm_aes128_update;
   hinfo.data = data;
   
-  display("gcm-aes", "update", GCM_BLOCK_SIZE,
+  display("gcm-aes128", "update", GCM_BLOCK_SIZE,
 	  time_function(bench_hash, &hinfo));
   
   cinfo.ctx = &ctx;
-  cinfo.crypt = (nettle_crypt_func *) gcm_aes_encrypt;
+  cinfo.crypt = (nettle_crypt_func *) gcm_aes128_encrypt;
   cinfo.data = data;
 
-  display("gcm-aes", "encrypt", GCM_BLOCK_SIZE,
+  display("gcm-aes128", "encrypt", GCM_BLOCK_SIZE,
 	  time_function(bench_cipher, &cinfo));
 
-  cinfo.crypt = (nettle_crypt_func *) gcm_aes_decrypt;
+  cinfo.crypt = (nettle_crypt_func *) gcm_aes128_decrypt;
 
-  display("gcm-aes", "decrypt", GCM_BLOCK_SIZE,
+  display("gcm-aes128", "decrypt", GCM_BLOCK_SIZE,
 	  time_function(bench_cipher, &cinfo));
 }
 
diff --git a/gcm-aes128.c b/gcm-aes128.c
new file mode 100644
index 00000000..4a2ec97c
--- /dev/null
+++ b/gcm-aes128.c
@@ -0,0 +1,74 @@
+/* gcm-aes128.c
+ *
+ * Galois counter mode using AES128 as the underlying cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011, 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
+ * 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 "gcm.h"
+
+void
+gcm_aes128_set_key(struct gcm_aes128_ctx *ctx, size_t length, const uint8_t *key)
+{
+  assert (length == AES128_KEY_SIZE);
+  GCM_SET_KEY(ctx, aes128_set_encrypt_key, aes128_encrypt, key);
+}
+
+void
+gcm_aes128_set_iv (struct gcm_aes128_ctx *ctx,
+		      size_t length, const uint8_t *iv)
+{
+  GCM_SET_IV (ctx, length, iv);
+}
+
+void
+gcm_aes128_update (struct gcm_aes128_ctx *ctx,
+		   size_t length, const uint8_t *data)
+{
+  GCM_UPDATE (ctx, length, data);
+}
+
+void
+gcm_aes128_encrypt(struct gcm_aes128_ctx *ctx,
+		size_t length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_ENCRYPT(ctx, aes128_encrypt, length, dst, src);
+}
+
+void
+gcm_aes128_decrypt(struct gcm_aes128_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_DECRYPT(ctx, aes128_encrypt, length, dst, src);
+}
+
+void
+gcm_aes128_digest(struct gcm_aes128_ctx *ctx,
+		  size_t length, uint8_t *digest)
+{
+  GCM_DIGEST(ctx, aes128_encrypt, length, digest);
+}
diff --git a/gcm-aes192.c b/gcm-aes192.c
new file mode 100644
index 00000000..3671829d
--- /dev/null
+++ b/gcm-aes192.c
@@ -0,0 +1,74 @@
+/* gcm-aes192.c
+ *
+ * Galois counter mode using AES192 as the underlying cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011, 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
+ * 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 "gcm.h"
+
+void
+gcm_aes192_set_key(struct gcm_aes192_ctx *ctx, size_t length, const uint8_t *key)
+{
+  assert (length == AES192_KEY_SIZE);
+  GCM_SET_KEY(ctx, aes192_set_encrypt_key, aes192_encrypt, key);
+}
+
+void
+gcm_aes192_set_iv (struct gcm_aes192_ctx *ctx,
+		      size_t length, const uint8_t *iv)
+{
+  GCM_SET_IV (ctx, length, iv);
+}
+
+void
+gcm_aes192_update (struct gcm_aes192_ctx *ctx,
+		   size_t length, const uint8_t *data)
+{
+  GCM_UPDATE (ctx, length, data);
+}
+
+void
+gcm_aes192_encrypt(struct gcm_aes192_ctx *ctx,
+		size_t length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_ENCRYPT(ctx, aes192_encrypt, length, dst, src);
+}
+
+void
+gcm_aes192_decrypt(struct gcm_aes192_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_DECRYPT(ctx, aes192_encrypt, length, dst, src);
+}
+
+void
+gcm_aes192_digest(struct gcm_aes192_ctx *ctx,
+		  size_t length, uint8_t *digest)
+{
+  GCM_DIGEST(ctx, aes192_encrypt, length, digest);
+}
diff --git a/gcm-aes256.c b/gcm-aes256.c
new file mode 100644
index 00000000..3fb6c680
--- /dev/null
+++ b/gcm-aes256.c
@@ -0,0 +1,74 @@
+/* gcm-aes256.c
+ *
+ * Galois counter mode using AES256 as the underlying cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011, 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
+ * 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 "gcm.h"
+
+void
+gcm_aes256_set_key(struct gcm_aes256_ctx *ctx, size_t length, const uint8_t *key)
+{
+  assert (length == AES256_KEY_SIZE);
+  GCM_SET_KEY(ctx, aes256_set_encrypt_key, aes256_encrypt, key);
+}
+
+void
+gcm_aes256_set_iv (struct gcm_aes256_ctx *ctx,
+		   size_t length, const uint8_t *iv)
+{
+  GCM_SET_IV (ctx, length, iv);
+}
+
+void
+gcm_aes256_update (struct gcm_aes256_ctx *ctx,
+		   size_t length, const uint8_t *data)
+{
+  GCM_UPDATE (ctx, length, data);
+}
+
+void
+gcm_aes256_encrypt(struct gcm_aes256_ctx *ctx,
+		size_t length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_ENCRYPT(ctx, aes256_encrypt, length, dst, src);
+}
+
+void
+gcm_aes256_decrypt(struct gcm_aes256_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_DECRYPT(ctx, aes256_encrypt, length, dst, src);
+}
+
+void
+gcm_aes256_digest(struct gcm_aes256_ctx *ctx,
+		  size_t length, uint8_t *digest)
+{
+  GCM_DIGEST(ctx, aes256_encrypt, length, digest);
+}
diff --git a/gcm.h b/gcm.h
index 10578107..f0548516 100644
--- a/gcm.h
+++ b/gcm.h
@@ -5,13 +5,10 @@
  *
  */
 
-/* NOTE: Tentative interface, subject to change. No effort will be
-   made to avoid incompatible changes. */
-
 /* nettle, low-level cryptographics library
  *
- * Copyright (C) 2011 Niels Möller
  * Copyright (C) 2011 Katholieke Universiteit Leuven
+ * Copyright (C) 2011, 2014 Niels Möller
  * 
  * Contributed by Nikos Mavrogiannopoulos
  *
@@ -48,6 +45,27 @@ extern "C" {
 #define gcm_decrypt nettle_gcm_decrypt
 #define gcm_digest nettle_gcm_digest
 
+#define gcm_aes128_set_key nettle_gcm_aes128_set_key
+#define gcm_aes128_set_iv nettle_gcm_aes128_set_iv
+#define gcm_aes128_update nettle_gcm_aes128_update
+#define gcm_aes128_encrypt nettle_gcm_aes128_encrypt
+#define gcm_aes128_decrypt nettle_gcm_aes128_decrypt
+#define gcm_aes128_digest nettle_gcm_aes128_digest
+
+#define gcm_aes192_set_key nettle_gcm_aes192_set_key
+#define gcm_aes192_set_iv nettle_gcm_aes192_set_iv
+#define gcm_aes192_update nettle_gcm_aes192_update
+#define gcm_aes192_encrypt nettle_gcm_aes192_encrypt
+#define gcm_aes192_decrypt nettle_gcm_aes192_decrypt
+#define gcm_aes192_digest nettle_gcm_aes192_digest
+
+#define gcm_aes256_set_key nettle_gcm_aes256_set_key
+#define gcm_aes256_set_iv nettle_gcm_aes256_set_iv
+#define gcm_aes256_update nettle_gcm_aes256_update
+#define gcm_aes256_encrypt nettle_gcm_aes256_encrypt
+#define gcm_aes256_decrypt nettle_gcm_aes256_decrypt
+#define gcm_aes256_digest nettle_gcm_aes256_digest
+
 #define gcm_aes_set_key nettle_gcm_aes_set_key
 #define gcm_aes_set_iv nettle_gcm_aes_set_iv
 #define gcm_aes_update nettle_gcm_aes_update
@@ -65,7 +83,7 @@ struct gcm_key
 {
   union nettle_block16 h[1 << GCM_TABLE_BITS];
 };
-  
+
 /* Per-message state, depending on the iv */
 struct gcm_ctx {
   /* Original counter block */
@@ -109,10 +127,9 @@ gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
 	   size_t length, uint8_t *digest);
 
 /* Convenience macrology (not sure how useful it is) */
-
-/* All-in-one context, with cipher, hash subkey, and message state. */
+/* All-in-one context, with hash subkey, message state, and cipher. */
 #define GCM_CTX(type) \
-{ type cipher; struct gcm_key key; struct gcm_ctx gcm; }
+  { struct gcm_key key; struct gcm_ctx gcm; type cipher; }
 
 /* NOTE: Avoid using NULL, as we don't include anything defining it. */
 #define GCM_SET_KEY(ctx, set_key, encrypt, key)			\
@@ -147,6 +164,84 @@ gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
 		  (nettle_crypt_func *) (encrypt),			\
 		  (length), (digest)))
 
+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);
+
+/* FIXME: Define _update and _set_iv as some kind of aliaes,
+   there's nothing aes-specific. */
+void
+gcm_aes128_update (struct gcm_aes128_ctx *ctx,
+		   size_t length, const uint8_t *data);
+void
+gcm_aes128_set_iv (struct gcm_aes128_ctx *ctx,
+		   size_t length, const uint8_t *iv);
+
+void
+gcm_aes128_encrypt(struct gcm_aes128_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_aes128_decrypt(struct gcm_aes128_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_aes128_digest(struct gcm_aes128_ctx *ctx,
+		  size_t length, uint8_t *digest);
+
+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);
+
+void
+gcm_aes192_update (struct gcm_aes192_ctx *ctx,
+		   size_t length, const uint8_t *data);
+void
+gcm_aes192_set_iv (struct gcm_aes192_ctx *ctx,
+		   size_t length, const uint8_t *iv);
+
+void
+gcm_aes192_encrypt(struct gcm_aes192_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_aes192_decrypt(struct gcm_aes192_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_aes192_digest(struct gcm_aes192_ctx *ctx,
+		  size_t length, uint8_t *digest);
+
+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);
+
+void
+gcm_aes256_update (struct gcm_aes256_ctx *ctx,
+		   size_t length, const uint8_t *data);
+void
+gcm_aes256_set_iv (struct gcm_aes256_ctx *ctx,
+		   size_t length, const uint8_t *iv);
+
+void
+gcm_aes256_encrypt(struct gcm_aes256_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_aes256_decrypt(struct gcm_aes256_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_aes256_digest(struct gcm_aes256_ctx *ctx,
+		  size_t length, uint8_t *digest);
+
+/* Old aes interface, for backwards compatibility */
 struct gcm_aes_ctx GCM_CTX(struct aes_ctx);
 
 void
diff --git a/nettle-internal.c b/nettle-internal.c
index e4e71761..40f2dd45 100644
--- a/nettle-internal.c
+++ b/nettle-internal.c
@@ -107,12 +107,16 @@ nettle_salsa20r12 = {
   (nettle_crypt_func *) salsa20r12_crypt
 };
 
+#define gcm_aes128_set_nonce gcm_aes128_set_iv
+#define gcm_aes192_set_nonce gcm_aes192_set_iv
+#define gcm_aes256_set_nonce gcm_aes256_set_iv
 const struct nettle_aead
-nettle_gcm_aes128 = _NETTLE_AEAD(gcm, GCM, aes, 128);
+nettle_gcm_aes128 = _NETTLE_AEAD(gcm, GCM, aes128, 128);
 const struct nettle_aead
-nettle_gcm_aes192 = _NETTLE_AEAD(gcm, GCM, aes, 192);
+nettle_gcm_aes192 = _NETTLE_AEAD(gcm, GCM, aes192, 192);
 const struct nettle_aead
-nettle_gcm_aes256 = _NETTLE_AEAD(gcm, GCM, aes, 256);
+nettle_gcm_aes256 = _NETTLE_AEAD(gcm, GCM, aes256, 256);
+
 
 /* Old, unified, interface */
 const struct nettle_cipher nettle_unified_aes128
@@ -172,8 +176,5 @@ eax_aes128_digest(struct eax_aes128_ctx *ctx,
   EAX_DIGEST(ctx, aes128_encrypt, length, digest);
 }
 
-/* FIXME: Rename to set_nonce, in struct nettle_aead. */
-#define eax_aes128_set_iv eax_aes128_set_nonce
-
 const struct nettle_aead
-nettle_eax_aes128 = _NETTLE_AEAD_FIX(eax, EAX, aes128, 128);
+nettle_eax_aes128 = _NETTLE_AEAD(eax, EAX, aes128, 128);
diff --git a/nettle-internal.h b/nettle-internal.h
index 19e242c9..b5a168e5 100644
--- a/nettle-internal.h
+++ b/nettle-internal.h
@@ -103,25 +103,12 @@ struct nettle_aead
 };
 
 #define _NETTLE_AEAD(type, TYPE, name, key_size) {	\
-  #type "-" #name #key_size,				\
-  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_iv,	\
-  (nettle_hash_update_func *) type##_##name##_update,	\
-  (nettle_crypt_func *) type##_##name##_encrypt,	\
-  (nettle_crypt_func *) type##_##name##_decrypt,	\
-  (nettle_hash_digest_func *) type##_##name##_digest,	\
-}
-
-#define _NETTLE_AEAD_FIX(type, TYPE, name, key_size) {	\
   #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_iv,	\
+  (nettle_set_key_func *) type##_##name##_set_nonce,	\
   (nettle_hash_update_func *) type##_##name##_update,	\
   (nettle_crypt_func *) type##_##name##_encrypt,	\
   (nettle_crypt_func *) type##_##name##_decrypt,	\
diff --git a/testsuite/gcm-test.c b/testsuite/gcm-test.c
index ce8d5933..5b7ed697 100644
--- a/testsuite/gcm-test.c
+++ b/testsuite/gcm-test.c
@@ -5,15 +5,15 @@
 static void
 test_gcm_hash (const struct tstring *msg, const struct tstring *ref)
 {
-  struct gcm_aes_ctx ctx;
+  struct gcm_aes128_ctx ctx;
   const uint8_t z16[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
   uint8_t digest[16];
 
   ASSERT (ref->length == sizeof(digest));
-  gcm_aes_set_key (&ctx, 16, z16);
-  gcm_aes_set_iv (&ctx, 16, z16);
-  gcm_aes_update (&ctx, msg->length, msg->data);
-  gcm_aes_digest (&ctx, sizeof(digest), digest);
+  gcm_aes128_set_key (&ctx, 16, z16);
+  gcm_aes128_set_iv (&ctx, 16, z16);
+  gcm_aes128_update (&ctx, msg->length, msg->data);
+  gcm_aes128_digest (&ctx, sizeof(digest), digest);
   if (!MEMEQ (ref->length, ref->data, digest))
     {
       fprintf (stderr, "gcm_hash failed, msg: %s\nOutput: ", msg->data);
@@ -25,6 +25,27 @@ 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)
+{
+  ASSERT (length == AES128_KEY_SIZE);
+  gcm_aes_set_key (ctx, length, key);
+}
+static const struct nettle_aead
+nettle_gcm_unified_aes128 = {
+  "gcm-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_hash_update_func *) gcm_aes_update,
+  (nettle_crypt_func *) gcm_aes_encrypt,
+  (nettle_crypt_func *) gcm_aes_decrypt,
+  (nettle_hash_digest_func *) gcm_aes_digest
+};
+    
+
 void
 test_main(void)
 {
@@ -117,6 +138,25 @@ test_main(void)
 		 "16aedbf5a0de6a57a637b39b"),
 	    SHEX("619cc5aefffe0bfa462af43c1699d050"));
 
+  /* Same test, but with old gcm_aes interface */
+  test_aead(&nettle_gcm_unified_aes128,
+	    SHEX("feffe9928665731c6d6a8f9467308308"),
+	    SHEX("feedfacedeadbeeffeedfacedeadbeef"
+		 "abaddad2"),
+	    SHEX("d9313225f88406e5a55909c5aff5269a"
+		 "86a7a9531534f7da2e4c303d8a318a72"
+		 "1c3c0c95956809532fcf0e2449a6b525"
+		 "b16aedf5aa0de657ba637b39"),
+	    SHEX("8ce24998625615b603a033aca13fb894"
+		 "be9112a5c3a211a8ba262a3cca7e2ca7"
+		 "01e4a9a4fba43c90ccdcb281d48c7c6f"
+		 "d62875d2aca417034c34aee5"),
+	    SHEX("9313225df88406e555909c5aff5269aa"
+		 "6a7a9538534f7da1e4c303d2a318a728"
+		 "c3c0c95156809539fcf0e2429a6b5254"
+		 "16aedbf5a0de6a57a637b39b"),
+	    SHEX("619cc5aefffe0bfa462af43c1699d050"));
+
   /* Test case 7 */
   test_aead(&nettle_gcm_aes192,
 	    SHEX("00000000000000000000000000000000"
-- 
GitLab