summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2013-10-05 20:52:11 +0200
committerNiels Möller <nisse@lysator.liu.se>2013-10-05 20:52:11 +0200
commitffec6637e0297eb2cc97f8f7ffbb34af184b8f11 (patch)
tree60af841dcbe5f31ae9f566befdadff51caca7357
parent6438331a930470f997b8f94d73ef63985a9e4f87 (diff)
downloadnettle-ffec6637e0297eb2cc97f8f7ffbb34af184b8f11.tar.gz
Implemented EAX.
-rw-r--r--ChangeLog15
-rw-r--r--Makefile.in5
-rw-r--r--eax.c152
-rw-r--r--eax.h146
-rw-r--r--nettle-internal.c55
-rw-r--r--nettle-internal.h43
-rw-r--r--testsuite/.test-rules.make3
-rw-r--r--testsuite/Makefile.in3
-rw-r--r--testsuite/eax-test.c88
9 files changed, 506 insertions, 4 deletions
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"));
+}