symm/eax.h, symm/eax-def.h: Implement the EAX authenticated encryption mode.
[catacomb] / symm / eax.h
diff --git a/symm/eax.h b/symm/eax.h
new file mode 100644 (file)
index 0000000..0018da6
--- /dev/null
@@ -0,0 +1,294 @@
+/* -*-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