--- /dev/null
+/* -*-c-*-
+ *
+ * The EAX authenticated-encryption mode
+ *
+ * (c) 2017 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * Catacomb 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Notes on EAX ------------------------------------------------------*
+ *
+ * The name doesn't appear to be short for anything convincing. EAX was
+ * designed in 2004 by Mihir Bellare, Phillip Rogaway, and David Wagner, as a
+ * response to CCM's deficiencies, which Rogaway and Wagner had complained
+ * about the previous year. Like CCM, it's a patent-free authenticated
+ * encryption scheme based on counter mode and CBC-MAC, and needs two
+ * blockcipher applications per message block, but it's much more refined
+ * than CCM. The EAX specification is clear about how the mode applies to
+ * arbitrary block sizes, and I've not had to make any decisions on how to
+ * extend it myself.
+ *
+ * EAX allows arbitrarily sized nonces, and doesn't require precommitment to
+ * any lengths, and allows header data to be processed independently of any
+ * message. It's basically about as good as a rate-1/2 scheme is going to
+ * be.
+ */
+
+#ifndef CATACOMB_EAX_H
+#define CATACOMB_EAX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stddef.h>
+
+#include <mLib/bits.h>
+#include <mLib/buf.h>
+
+#ifndef CATACOMB_GAEAD_H
+# include "gaead.h"
+#endif
+
+/*----- Macros ------------------------------------------------------------*/
+
+/* --- @EAX_DECL@ --- *
+ *
+ * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher
+ *
+ * Use: Creates declarations for EAX authenticated-encryption mode.
+ */
+
+#define EAX_DECL(PRE, pre) \
+ \
+typedef struct pre##_eaxkey { \
+ pre##_ctx ctx; /* Block cipher key */ \
+ uint32 m0[PRE##_BLKSZ/4], m1[PRE##_BLKSZ/4]; /* Final OMAC masks */ \
+ uint32 v0[PRE##_BLKSZ/4], /* OMAC tweak accumulators */ \
+ v1[PRE##_BLKSZ/4], v2[PRE##_BLKSZ/4]; \
+ uint32 z0[PRE##_BLKSZ/4], /* Empty-message tag values */ \
+ z1[PRE##_BLKSZ/4], z2[PRE##_BLKSZ/4]; \
+} pre##_eaxkey; \
+ \
+typedef struct pre##_eaxaadctx { \
+ pre##_eaxkey k; /* Underlying key */ \
+ uint32 a[PRE##_BLKSZ/4]; /* OMAC accumulator */ \
+ octet b[PRE##_BLKSZ]; /* Input buffer */ \
+ unsigned off; /* Length of stuff in buffer */ \
+} pre##_eaxaadctx; \
+ \
+typedef struct pre##_eaxctx { \
+ /* The buffer is split into two portions. The first N octets hold a \
+ * chunk of ciphertext, which will be fed into the OMAC calculation; \
+ * the remaining BLKSZ - N octets hold E_K(C), which is the XOR mask \
+ * to apply to the plaintext or ciphertext. \
+ */ \
+ pre##_eaxkey k; /* Underlying key */ \
+ uint32 c[PRE##_BLKSZ/4]; /* Current counter value */ \
+ uint32 c0[PRE##_BLKSZ/4]; /* Initial counter */ \
+ uint32 a[PRE##_BLKSZ]; /* OMAC accumulator */ \
+ octet b[PRE##_BLKSZ]; /* Ciphertext/mask buffer */ \
+ unsigned off; /* Crossover point in buffer */ \
+} pre##_eaxctx; \
+ \
+extern const octet pre##_eaxnoncesz[], pre##_eaxtagsz[]; \
+ \
+/* --- @pre_eaxsetkey@ --- * \
+ * \
+ * Arguments: @pre_eaxkey *key@ = pointer to key block to fill in \
+ * @const void *k@ = pointer to key material \
+ * @size_t ksz@ = size of key material \
+ * \
+ * Returns: --- \
+ * \
+ * Use: Initializes an EAX key block. \
+ */ \
+ \
+extern void pre##_eaxsetkey(pre##_eaxkey */*key*/, \
+ const void */*k*/, size_t /*ksz*/); \
+ \
+/* --- @pre_eaxaadinit@ --- * \
+ * \
+ * Arguments: @pre_eaxaadctx *aad@ = pointer to AAD context \
+ * @const pre_eaxkey *key@ = pointer to key block \
+ * \
+ * Returns: --- \
+ * \
+ * Use: Initializes an EAX AAD (`additional authenticated \
+ * data') context associated with a given key. AAD \
+ * contexts can be copied and/or reused, saving time if \
+ * the AAD for a number of messages has a common prefix. \
+ * \
+ * The @key@ doesn't need to be kept around, though \
+ * usually there'll at least be another copy in some EAX \
+ * operation context because the AAD on its own isn't much \
+ * good. \
+ */ \
+ \
+extern void pre##_eaxaadinit(pre##_eaxaadctx */*aad*/, \
+ const pre##_eaxkey */*key*/); \
+ \
+/* --- @pre_eaxaadhash@ --- * \
+ * \
+ * Arguments: @pre_eaxaadctx *aad@ = pointer to AAD context \
+ * @const void *p@ = pointer to AAD material \
+ * @size_t sz@ = length of AAD material \
+ * \
+ * Returns: --- \
+ * \
+ * Use: Feeds AAD into the context. \
+ */ \
+ \
+extern void pre##_eaxaadhash(pre##_eaxaadctx */*aad*/, \
+ const void */*p*/, size_t /*sz*/); \
+ \
+/* --- @pre_eaxinit@ --- * \
+ * \
+ * Arguments: @pre_eaxctx *ctx@ = pointer to EAX context \
+ * @const pre_eaxkey *key@ = pointer to key block \
+ * @const void *n@ = pointer to nonce \
+ * @size_t nsz@ = size of nonce \
+ * \
+ * Returns: --- \
+ * \
+ * Use: Initialize an EAX operation context with a given key. \
+ * \
+ * The original key needn't be kept around any more. \
+ */ \
+ \
+extern void pre##_eaxinit(pre##_eaxctx */*ctx*/, \
+ const pre##_eaxkey */*k*/, \
+ const void */*n*/, size_t /*nsz*/); \
+ \
+/* --- @pre_eaxreinit@ --- * \
+ * \
+ * Arguments: @pre_eaxctx *ctx@ = pointer to EAX context \
+ * @const void *n@ = pointer to nonce \
+ * @size_t nsz@ = size of nonce \
+ * \
+ * Returns: --- \
+ * \
+ * Use: Reinitialize an EAX operation context, changing the \
+ * nonce. \
+ */ \
+ \
+extern void pre##_eaxreinit(pre##_eaxctx */*ctx*/, \
+ const void */*n*/, size_t /*nsz*/); \
+ \
+/* --- @pre_eaxencrypt@ --- * \
+ * \
+ * Arguments: @pre_eaxctx *ctx@ = pointer to EAX operation context \
+ * @const void *src@ = pointer to plaintext message chunk \
+ * @size_t sz@ = size of the plaintext \
+ * @buf *dst@ = a buffer to write the ciphertext to \
+ * \
+ * Returns: Zero on success; @-1@ on failure. \
+ * \
+ * Use: Encrypts a chunk of a plaintext message, writing a \
+ * chunk of ciphertext to the output buffer and updating \
+ * the operation state. \
+ * \
+ * For EAX, we always write a ciphertext chunk the same \
+ * size as the plaintext. The messing about with @buf@ \
+ * objects makes the interface consistent with other AEAD \
+ * schemes which can't do this. \
+ */ \
+ \
+extern int pre##_eaxencrypt(pre##_eaxctx */*ctx*/, \
+ const void */*src*/, size_t /*sz*/, \
+ buf */*dst*/); \
+ \
+/* --- @pre_eaxdecrypt@ --- * \
+ * \
+ * Arguments: @pre_eaxctx *ctx@ = pointer to EAX operation context \
+ * @const void *src@ = pointer to ciphertext message chunk \
+ * @size_t sz@ = size of the ciphertext \
+ * @buf *dst@ = a buffer to write the plaintext to \
+ * \
+ * Returns: Zero on success; @-1@ on failure. \
+ * \
+ * Use: Decrypts a chunk of a ciphertext message, writing a \
+ * chunk of plaintext to the output buffer and updating \
+ * the operation state. \
+ * \
+ * For EAX, we always write a plaintext chunk the same \
+ * size as the ciphertext. The messing about with @buf@ \
+ * objects makes the interface consistent with other AEAD \
+ * schemes which can't do this. \
+ */ \
+ \
+extern int pre##_eaxdecrypt(pre##_eaxctx */*ctx*/, \
+ const void */*src*/, size_t /*sz*/, \
+ buf */*dst*/); \
+ \
+/* --- @pre_eaxencryptdone@ --- * \
+ * \
+ * Arguments: @pre_eaxctx *ctx@ = pointer to an EAX context \
+ * @const pre_eaxaadctx *aad@ = pointer to AAD context, or \
+ * null \
+ * @buf *dst@ = buffer for remaining ciphertext \
+ * @void *tag@ = where to write the tag \
+ * @size_t tsz@ = length of tag to store \
+ * \
+ * Returns: Zero on success; @-1@ on failure. \
+ * \
+ * Use: Completes an EAX encryption operation. The @aad@ \
+ * pointer may be null if there is no additional \
+ * authenticated data. EAX doesn't buffer ciphertext, but \
+ * the output buffer is provided anyway for consistency \
+ * with other AEAD schemes which don't have this property; \
+ * the function will fail if the output buffer is broken. \
+ */ \
+ \
+extern int pre##_eaxencryptdone(pre##_eaxctx */*ctx*/, \
+ const pre##_eaxaadctx */*aad*/, \
+ buf */*dst*/, \
+ void */*tag*/, size_t /*tsz*/); \
+ \
+/* --- @pre_eaxdecryptdone@ --- * \
+ * \
+ * Arguments: @pre_eaxctx *ctx@ = pointer to an EAX context \
+ * @const pre_eaxaadctx *aad@ = pointer to AAD context, or \
+ * null \
+ * @buf *dst@ = buffer for remaining plaintext \
+ * @const void *tag@ = tag to verify \
+ * @size_t tsz@ = length of tag \
+ * \
+ * Returns: @+1@ for complete success; @0@ if tag verification \
+ * failed; @-1@ for other kinds of errors. \
+ * \
+ * Use: Completes an EAX decryption operation. The @aad@ \
+ * pointer may be null if there is no additional \
+ * authenticated data. EAX doesn't buffer plaintext, but \
+ * the output buffer is provided anyway for consistency \
+ * with other AEAD schemes which don't have this property; \
+ * the function will fail if the output buffer is broken. \
+ */ \
+ \
+extern int pre##_eaxdecryptdone(pre##_eaxctx */*ctx*/, \
+ const pre##_eaxaadctx */*aad*/, \
+ buf */*dst*/, \
+ const void */*tag*/, size_t /*tsz*/); \
+ \
+/* --- Generic AEAD interface --- */ \
+ \
+extern const gcaead pre##_eax;
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif