From ffec6637e0297eb2cc97f8f7ffbb34af184b8f11 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Sat, 5 Oct 2013 20:52:11 +0200
Subject: [PATCH] Implemented EAX.

---
 ChangeLog                  |  15 ++++
 Makefile.in                |   5 +-
 eax.c                      | 152 +++++++++++++++++++++++++++++++++++++
 eax.h                      | 146 +++++++++++++++++++++++++++++++++++
 nettle-internal.c          |  55 ++++++++++++++
 nettle-internal.h          |  43 +++++++++++
 testsuite/.test-rules.make |   3 +
 testsuite/Makefile.in      |   3 +-
 testsuite/eax-test.c       |  88 +++++++++++++++++++++
 9 files changed, 506 insertions(+), 4 deletions(-)
 create mode 100644 eax.c
 create mode 100644 eax.h
 create mode 100644 testsuite/eax-test.c

diff --git a/ChangeLog b/ChangeLog
index 732d3979..863eeac2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
 2013-10-05  Niels Möller  <nisse@lysator.liu.se>
 
+	* Makefile.in (nettle_SOURCES): Added eax.c.
+	(HEADERS): Added eax.h.
+
+	* testsuite/Makefile.in (TS_NETTLE_SOURCES): Added eax-test.c.
+
+	* testsuite/eax-test.c: New file.
+
+	* nettle-internal.c (nettle_eax_aes128): New aead algorithm.
+	(eax_aes128_set_key, eax_aes128_set_nonce, eax_aes128_update)
+	(eax_aes128_encrypt, eax_aes128_decrypt, eax_aes128_digest): New
+	functions.
+
+	* eax.c: New file.
+	* eax.h: New file.
+
 	* aes.h: Fixed type in name mangling for new aes functions.
 
 2013-09-28  Niels Möller  <nisse@lysator.liu.se>
diff --git a/Makefile.in b/Makefile.in
index 253ccec3..13acde64 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -82,8 +82,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
 		 cast128.c cast128-meta.c \
 		 blowfish.c \
 		 cbc.c ctr.c gcm.c gcm-aes.c \
-		 des.c \
-		 des3.c des-compat.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 \
 		 pbkdf2.c pbkdf2-hmac-sha1.c pbkdf2-hmac-sha256.c \
@@ -151,7 +150,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
 HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \
 	  base16.h base64.h buffer.h camellia.h cast128.h \
 	  cbc.h ctr.h \
-	  des.h des-compat.h dsa.h ecc-curve.h ecc.h ecdsa.h \
+	  des.h des-compat.h dsa.h eax.h ecc-curve.h ecc.h ecdsa.h \
 	  gcm.h gosthash94.h hmac.h \
 	  knuth-lfib.h \
 	  macros.h \
diff --git a/eax.c b/eax.c
new file mode 100644
index 00000000..77a6cc38
--- /dev/null
+++ b/eax.c
@@ -0,0 +1,152 @@
+/* eax.c
+ *
+ * EAX mode, see http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Niels Möller
+ *
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "eax.h"
+
+#include "ctr.h"
+#include "memxor.h"
+
+static void
+omac_init (uint8_t *state, unsigned t)
+{
+  memset (state, 0, EAX_BLOCK_SIZE - 1);
+  state[EAX_BLOCK_SIZE - 1] = t;
+}
+
+static void
+omac_update (uint8_t *state, const struct eax_key *key,
+	     void *cipher, nettle_crypt_func *f,
+	     size_t length, const uint8_t *data)
+{
+  for (; length >= EAX_BLOCK_SIZE;
+       length -= EAX_BLOCK_SIZE, data += EAX_BLOCK_SIZE)
+    {
+      f (cipher, EAX_BLOCK_SIZE, state, state);
+      memxor (state, data, EAX_BLOCK_SIZE);
+    }
+  if (length > 0)
+    {
+      /* Allowed only for the last call */
+      f (cipher, EAX_BLOCK_SIZE, state, state);
+      memxor (state, data, length);
+      state[length] ^= 0x80;
+      /* XOR with (P ^ B), since the digest processing
+       * unconditionally XORs with B */
+      memxor (state, key->pad_partial, EAX_BLOCK_SIZE);
+    }
+}
+
+static void
+omac_final (uint8_t *state, const struct eax_key *key,
+	    void *cipher, nettle_crypt_func *f)
+{
+  memxor (state, key->pad_block, EAX_BLOCK_SIZE);
+  f (cipher, EAX_BLOCK_SIZE, state, state);
+}
+
+/* Allows r == a */
+static void
+gf2_double (uint8_t *r, const uint8_t *a)
+{
+  unsigned high = - (a[0] >> 7);
+  unsigned i;
+  /* Shift left */
+  for (i = 0; i < EAX_BLOCK_SIZE - 1; i++)
+    r[i] = (a[i] << 1) + (a[i+1] >> 7);
+
+  /* Wrap around for x^{128} = x^7 + x^2 + x + 1 */
+  r[EAX_BLOCK_SIZE - 1] = (a[EAX_BLOCK_SIZE - 1] << 1) ^ (high & 0x87);
+}
+
+void
+eax_set_key (struct eax_key *key, void *cipher, nettle_crypt_func *f)
+{
+  static const uint8_t zero_block[EAX_BLOCK_SIZE];
+  f (cipher, EAX_BLOCK_SIZE, key->pad_block, zero_block);
+  gf2_double (key->pad_block, key->pad_block);
+  gf2_double (key->pad_partial, key->pad_block);
+  memxor (key->pad_partial, key->pad_block, EAX_BLOCK_SIZE);
+}
+
+void
+eax_set_nonce (struct eax_ctx *eax, const struct eax_key *key,
+	       void *cipher, nettle_crypt_func *f,
+	       size_t nonce_length, const uint8_t *nonce)
+{
+  omac_init (eax->omac_nonce, 0);
+  omac_update (eax->omac_nonce, key, cipher, f, nonce_length, nonce);
+  omac_final (eax->omac_nonce, key, cipher, f);
+  memcpy (eax->ctr, eax->omac_nonce, EAX_BLOCK_SIZE);
+
+  omac_init (eax->omac_data, 1);
+  omac_init (eax->omac_message, 2);
+}
+
+void
+eax_update (struct eax_ctx *eax, const struct eax_key *key,
+	    void *cipher, nettle_crypt_func *f,
+	    size_t data_length, const uint8_t *data)
+{
+  omac_update (eax->omac_data, key, cipher, f, data_length, data);
+}
+
+void
+eax_encrypt (struct eax_ctx *eax, const struct eax_key *key,
+	     void *cipher, nettle_crypt_func *f,
+	     size_t length, uint8_t *dst, const uint8_t *src)
+{
+  ctr_crypt (cipher, f, EAX_BLOCK_SIZE, eax->ctr, length, dst, src);
+  omac_update (eax->omac_message, key, cipher, f, length, dst);
+}
+
+void
+eax_decrypt (struct eax_ctx *eax, const struct eax_key *key,
+	     void *cipher, nettle_crypt_func *f,
+	     size_t length, uint8_t *dst, const uint8_t *src)
+{
+  omac_update (eax->omac_message, key, cipher, f, length, src);
+  ctr_crypt (cipher, f, EAX_BLOCK_SIZE, eax->ctr, length, dst, src);
+}
+
+void
+eax_digest (struct eax_ctx *eax, const struct eax_key *key,
+	    void *cipher, nettle_crypt_func *f,
+	    size_t length, uint8_t *digest)
+{
+  assert (length > 0);
+  assert (length <= EAX_BLOCK_SIZE);
+  omac_final (eax->omac_data, key, cipher, f);
+  omac_final (eax->omac_message, key, cipher, f);
+
+  memxor (eax->omac_nonce, eax->omac_data, length);
+  memxor3 (digest, eax->omac_nonce, eax->omac_message, length);
+}
diff --git a/eax.h b/eax.h
new file mode 100644
index 00000000..58bb412d
--- /dev/null
+++ b/eax.h
@@ -0,0 +1,146 @@
+/* eax.h
+ *
+ * EAX mode, see http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Niels Möller
+ *
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#ifndef NETTLE_EAX_H_INCLUDED
+#define NETTLE_EAX_H_INCLUDED
+
+#include "aes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define eax_set_key nettle_eax_set_key
+#define eax_set_nonce nettle_eax_set_nonce
+#define eax_update nettle_eax_update
+#define eax_encrypt nettle_eax_encrypt
+#define eax_decrypt nettle_eax_decrypt
+#define eax_digest nettle_eax_digest
+
+#define eax_aes_set_key nettle_eax_aes_set_key
+#define eax_aes_set_nonce nettle_eax_aes_set_nonce
+#define eax_aes_update nettle_eax_aes_update
+#define eax_aes_encrypt nettle_eax_aes_encrypt
+#define eax_aes_decrypt nettle_eax_aes_decrypt
+#define eax_aes_digest nettle_eax_aes_digest
+
+/* Restricted to block ciphers with 128 bit block size. FIXME: Reflect
+   this in naming? */
+
+#define EAX_BLOCK_SIZE 16
+
+/* FIXME: Ensure nice alignment. See gcm.h, union gcm_block. */
+
+/* Values independent of message and nonce */
+struct eax_key
+{
+  uint8_t pad_block[EAX_BLOCK_SIZE];
+  uint8_t pad_partial[EAX_BLOCK_SIZE];
+};
+
+struct eax_ctx
+{
+  uint8_t omac_nonce[EAX_BLOCK_SIZE];
+  uint8_t omac_data[EAX_BLOCK_SIZE];
+  uint8_t omac_message[EAX_BLOCK_SIZE];
+  uint8_t ctr[EAX_BLOCK_SIZE];
+};
+
+void
+eax_set_key (struct eax_key *key, void *cipher, nettle_crypt_func *f);
+
+void
+eax_set_nonce (struct eax_ctx *eax, const struct eax_key *key,
+	       void *cipher, nettle_crypt_func *f,
+	       size_t nonce_length, const uint8_t *nonce);
+
+void
+eax_update (struct eax_ctx *eax, const struct eax_key *key,
+	    void *cipher, nettle_crypt_func *f,
+	    size_t data_length, const uint8_t *data);
+
+void
+eax_encrypt (struct eax_ctx *eax, const struct eax_key *key,
+	     void *cipher, nettle_crypt_func *f,
+	     size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+eax_decrypt (struct eax_ctx *eax, const struct eax_key *key,
+	     void *cipher, nettle_crypt_func *f,
+	     size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+eax_digest (struct eax_ctx *eax, const struct eax_key *key,
+	    void *cipher, nettle_crypt_func *f,
+	    size_t length, uint8_t *digest);
+
+/* Put the cipher last, to get cipher-independent offsets for the EAX
+ * state. */
+#define EAX_CTX(type) \
+  { struct eax_key key; struct eax_ctx eax; type cipher; }
+
+#define EAX_SET_KEY(ctx, set_key, encrypt, length, data)		\
+  do {									\
+    (set_key)(&(ctx)->cipher, (length), (data));			\
+    if (0) (encrypt) (&(ctx)->cipher, 0, (void *) 0, (void *) 0);	\
+    eax_set_key (&(ctx)->key, &(ctx)->cipher, (nettle_crypt_func *) encrypt); \
+  } while (0)
+
+#define EAX_SET_NONCE(ctx, encrypt, length, nonce) \
+  (0 ? (encrypt) (&(ctx)->cipher, 0, (void *) 0, (void *) 0)	\
+   : eax_set_nonce (&(ctx)->eax, &(ctx)->key,			\
+		    &(ctx)->cipher, (nettle_crypt_func *) (encrypt),	\
+		    (length), (nonce)))
+
+#define EAX_UPDATE(ctx, encrypt, length, data)				\
+  (0 ? (encrypt) (&(ctx)->cipher, 0, (void *) 0, (void *) 0)		\
+   : eax_update (&(ctx)->eax, &(ctx)->key,				\
+		 &(ctx)->cipher, (nettle_crypt_func *) (encrypt),	\
+		 (length), (data)))
+
+#define EAX_ENCRYPT(ctx, encrypt, length, dst, src)			\
+  (0 ? (encrypt) (&(ctx)->cipher, 0, (void *) 0, (void *) 0)		\
+   : eax_encrypt (&(ctx)->eax, &(ctx)->key,				\
+		 &(ctx)->cipher, (nettle_crypt_func *) (encrypt),	\
+		  (length), (dst), (src)))
+
+#define EAX_DECRYPT(ctx, encrypt, length, dst, src)			\
+  (0 ? (encrypt) (&(ctx)->cipher, 0, (void *) 0, (void *) 0)		\
+   : eax_decrypt (&(ctx)->eax, &(ctx)->key,				\
+		 &(ctx)->cipher, (nettle_crypt_func *) (encrypt),	\
+		  (length), (dst), (src)))
+
+#define EAX_DIGEST(ctx, encrypt, length, digest)			\
+  (0 ? (encrypt) (&(ctx)->cipher, 0, (void *) 0, (void *) 0)		\
+   : eax_digest (&(ctx)->eax, &(ctx)->key,				\
+		 &(ctx)->cipher, (nettle_crypt_func *) (encrypt),	\
+		 (length), (digest)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_EAX_H_INCLUDED */
diff --git a/nettle-internal.c b/nettle-internal.c
index 8308df69..e4e71761 100644
--- a/nettle-internal.c
+++ b/nettle-internal.c
@@ -34,6 +34,7 @@
 #include "nettle-internal.h"
 #include "blowfish.h"
 #include "des.h"
+#include "eax.h"
 #include "gcm.h"
 #include "salsa20.h"
 
@@ -122,3 +123,57 @@ const struct nettle_cipher nettle_unified_aes192
 
 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)
+{
+  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 */
+}
+
+void
+eax_aes128_set_nonce(struct eax_aes128_ctx *ctx,
+		     size_t length, const uint8_t *iv)
+{
+  EAX_SET_NONCE(ctx, aes128_encrypt, length, iv);
+}
+
+void
+eax_aes128_update(struct eax_aes128_ctx *ctx, size_t length, const uint8_t *data)
+{
+  EAX_UPDATE(ctx, aes128_encrypt, length, data);
+}
+
+void
+eax_aes128_encrypt(struct eax_aes128_ctx *ctx,
+		size_t length, uint8_t *dst, const uint8_t *src)
+{
+  EAX_ENCRYPT(ctx, aes128_encrypt, length, dst, src);
+}
+
+void
+eax_aes128_decrypt(struct eax_aes128_ctx *ctx,
+		size_t length, uint8_t *dst, const uint8_t *src)
+{
+  EAX_DECRYPT(ctx, aes128_encrypt, length, dst, src);
+}
+
+void
+eax_aes128_digest(struct eax_aes128_ctx *ctx,
+	       size_t length, uint8_t *digest)
+{
+  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);
diff --git a/nettle-internal.h b/nettle-internal.h
index 09881ce9..10689d45 100644
--- a/nettle-internal.h
+++ b/nettle-internal.h
@@ -29,6 +29,8 @@
 
 #include "nettle-meta.h"
 
+#include "eax.h"
+
 /* Temporary allocation, for systems that don't support alloca. Note
  * that the allocation requests should always be reasonably small, so
  * that they can fit on the stack. For non-alloca systems, we use a
@@ -115,6 +117,19 @@ struct nettle_aead
   (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_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,	\
+}
+
 extern const struct nettle_aead nettle_gcm_aes128;
 extern const struct nettle_aead nettle_gcm_aes192;
 extern const struct nettle_aead nettle_gcm_aes256;
@@ -131,4 +146,32 @@ extern const struct nettle_aead nettle_gcm_twofish128;
 extern const struct nettle_aead nettle_gcm_twofish192;
 extern const struct nettle_aead nettle_gcm_twofish256;
 
+/* Tentative interface. */
+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);
+
+void
+eax_aes128_set_nonce(struct eax_aes128_ctx *ctx,
+		     size_t length, const uint8_t *iv);
+
+void
+eax_aes128_update(struct eax_aes128_ctx *ctx,
+		  size_t length, const uint8_t *data);
+
+void
+eax_aes128_encrypt(struct eax_aes128_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+eax_aes128_decrypt(struct eax_aes128_ctx *ctx,
+		   size_t length, uint8_t *dst, const uint8_t *src);
+
+void
+eax_aes128_digest(struct eax_aes128_ctx *ctx, size_t length, uint8_t *digest);
+
+extern const struct nettle_aead nettle_eax_aes128;
+
 #endif /* NETTLE_INTERNAL_H_INCLUDED */
diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make
index 93ba9a81..5549fc09 100644
--- a/testsuite/.test-rules.make
+++ b/testsuite/.test-rules.make
@@ -103,6 +103,9 @@ ctr-test$(EXEEXT): ctr-test.$(OBJEXT)
 gcm-test$(EXEEXT): gcm-test.$(OBJEXT)
 	$(LINK) gcm-test.$(OBJEXT) $(TEST_OBJS) -o gcm-test$(EXEEXT)
 
+eax-test$(EXEEXT): eax-test.$(OBJEXT)
+	$(LINK) eax-test.$(OBJEXT) $(TEST_OBJS) -o eax-test$(EXEEXT)
+
 hmac-test$(EXEEXT): hmac-test.$(OBJEXT)
 	$(LINK) hmac-test.$(OBJEXT) $(TEST_OBJS) -o hmac-test$(EXEEXT)
 
diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in
index 44fcf486..0ad950db 100644
--- a/testsuite/Makefile.in
+++ b/testsuite/Makefile.in
@@ -25,7 +25,8 @@ TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \
 		    sha3-384-test.c sha3-512-test.c \
 		    serpent-test.c twofish-test.c \
 		    knuth-lfib-test.c \
-		    cbc-test.c ctr-test.c gcm-test.c hmac-test.c umac-test.c \
+		    cbc-test.c ctr-test.c gcm-test.c eax-test.c \
+		    hmac-test.c umac-test.c \
 		    meta-hash-test.c meta-cipher-test.c meta-armor-test.c \
 		    buffer-test.c yarrow-test.c pbkdf2-test.c
 
diff --git a/testsuite/eax-test.c b/testsuite/eax-test.c
new file mode 100644
index 00000000..72e588ea
--- /dev/null
+++ b/testsuite/eax-test.c
@@ -0,0 +1,88 @@
+#include "testutils.h"
+#include "nettle-internal.h"
+
+void
+test_main(void)
+{
+  /* From the EAX specification,
+     http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf */
+  test_aead(&nettle_eax_aes128,
+	    SHEX("233952DEE4D5ED5F9B9C6D6FF80FF478"),	/* key */
+	    SHEX("6BFB914FD07EAE6B"),			/* auth data */
+	    SHEX(""),					/* plaintext */
+	    SHEX(""),					/* ciphertext */
+	    SHEX("62EC67F9C3A4A407FCB2A8C49031A8B3"),	/* nonce */
+	    SHEX("E037830E8389F27B025A2D6527E79D01"));	/* tag */
+
+  test_aead(&nettle_eax_aes128,
+	    SHEX("91945D3F4DCBEE0BF45EF52255F095A4"),
+	    SHEX("FA3BFD4806EB53FA"),
+	    SHEX("F7FB"),
+	    SHEX("19DD"),
+	    SHEX("BECAF043B0A23D843194BA972C66DEBD"),
+	    SHEX("5C4C9331049D0BDAB0277408F67967E5"));
+  
+  test_aead(&nettle_eax_aes128,
+	    SHEX("01F74AD64077F2E704C0F60ADA3DD523"),
+	    SHEX("234A3463C1264AC6"),
+	    SHEX("1A47CB4933"),
+	    SHEX("D851D5BAE0"),
+	    SHEX("70C3DB4F0D26368400A10ED05D2BFF5E"),
+	    SHEX("3A59F238A23E39199DC9266626C40F80"));
+
+  test_aead(&nettle_eax_aes128,
+	    SHEX("D07CF6CBB7F313BDDE66B727AFD3C5E8"),
+	    SHEX("33CCE2EABFF5A79D"),
+	    SHEX("481C9E39B1"),
+	    SHEX("632A9D131A"),
+	    SHEX("8408DFFF3C1A2B1292DC199E46B7D617"),
+	    SHEX("D4C168A4225D8E1FF755939974A7BEDE"));
+
+  test_aead(&nettle_eax_aes128,
+	    SHEX("35B6D0580005BBC12B0587124557D2C2"),
+	    SHEX("AEB96EAEBE2970E9"),
+	    SHEX("40D0C07DA5E4"),
+	    SHEX("071DFE16C675"),
+	    SHEX("FDB6B06676EEDC5C61D74276E1F8E816"),
+	    SHEX("CB0677E536F73AFE6A14B74EE49844DD"));
+
+  test_aead(&nettle_eax_aes128,
+	    SHEX("BD8E6E11475E60B268784C38C62FEB22"),
+	    SHEX("D4482D1CA78DCE0F"),
+	    SHEX("4DE3B35C3FC039245BD1FB7D"),
+	    SHEX("835BB4F15D743E350E728414"),
+	    SHEX("6EAC5C93072D8E8513F750935E46DA1B"),
+	    SHEX("ABB8644FD6CCB86947C5E10590210A4F"));
+
+  test_aead(&nettle_eax_aes128,
+	    SHEX("7C77D6E813BED5AC98BAA417477A2E7D"),
+	    SHEX("65D2017990D62528"),
+	    SHEX("8B0A79306C9CE7ED99DAE4F87F8DD61636"),
+	    SHEX("02083E3979DA014812F59F11D52630DA30"),
+	    SHEX("1A8C98DCD73D38393B2BF1569DEEFC19"),
+	    SHEX("137327D10649B0AA6E1C181DB617D7F2"));
+  
+  test_aead(&nettle_eax_aes128,
+	    SHEX("5FFF20CAFAB119CA2FC73549E20F5B0D"),
+	    SHEX("54B9F04E6A09189A"),
+	    SHEX("1BDA122BCE8A8DBAF1877D962B8592DD2D56"),
+	    SHEX("2EC47B2C4954A489AFC7BA4897EDCDAE8CC3"),
+	    SHEX("DDE59B97D722156D4D9AFF2BC7559826"),
+	    SHEX("3B60450599BD02C96382902AEF7F832A"));
+  
+  test_aead(&nettle_eax_aes128,
+	    SHEX("A4A4782BCFFD3EC5E7EF6D8C34A56123"),
+	    SHEX("899A175897561D7E"),
+	    SHEX("6CF36720872B8513F6EAB1A8A44438D5EF11"),
+	    SHEX("0DE18FD0FDD91E7AF19F1D8EE8733938B1E8"),
+	    SHEX("B781FCF2F75FA5A8DE97A9CA48E522EC"),
+	    SHEX("E7F6D2231618102FDB7FE55FF1991700"));
+  
+  test_aead(&nettle_eax_aes128,
+	    SHEX("8395FCF1E95BEBD697BD010BC766AAC3"),
+	    SHEX("126735FCC320D25A"),
+	    SHEX("CA40D7446E545FFAED3BD12A740A659FFBBB3CEAB7"),
+	    SHEX("CB8920F87A6C75CFF39627B56E3ED197C552D295A7"),
+	    SHEX("22E7ADD93CFC6393C57EC0B3C17D6B44"),
+	    SHEX("CFC46AFC253B4652B1AF3795B124AB6E"));
+}
-- 
GitLab