symm/ocb1.h, symm/pmac1.h, ...: Implement PMAC1 and OCB1.
[catacomb] / symm / ocb1.h
diff --git a/symm/ocb1.h b/symm/ocb1.h
new file mode 100644 (file)
index 0000000..42cfb81
--- /dev/null
@@ -0,0 +1,345 @@
+/* -*-c-*-
+ *
+ * The OCB1 authenticated encryption mode
+ *
+ * (c) 2018 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 OCB1 -----------------------------------------------------*
+ *
+ * OCB was designed in 2001 by Phillip Rogaway, with Mihir Bellare and John
+ * Black, as a blockcipher-based authenticated encryption scheme which can
+ * operate on multiple message blocks in parallel and requires only a single
+ * blockcipher application per message block.  It refines Charanjit Jutla's
+ * earlier IAPM, which was the first such mode to be proven secure.  This
+ * version implements the `OCB.PMAC' mode described by Rogaway in 2002, which
+ * combines the original OCB with PMAC (Rogaway and Black, 2002) into a
+ * single authenticated-encryption with associated-data (AEAD) scheme.
+ *
+ * The patent situation on these efficient authenticated encryption schemes
+ * is fraught.  IBM hold two patents on Jutla's pioneering work on `IACBC'
+ * and `IAPM' which can apply (a third was filed at least six years too
+ * late), and Virgil Gligor and Pompiliu Donescu hold patents on their `XECB'
+ * and `XCBC' modes; these may or may not apply to OCB.  Rogaway himself
+ * holds US patents on various versions of OCB, but has issued free licences
+ * for free (`open source') software, and for all non-military use.  I think
+ * Catacomb's implementation of OCB falls within the scope of the former
+ * licence.
+ *
+ * Confusingly, Rogaway's 2004 paper `Efficient Instantiations of Tweakable
+ * Blockciphers and Refinements to Modes OCB and PMAC' named the new versions
+ * of those modes `OCB1' and `PMAC1'.  The 2011 paper by Krovetz and Rogaway,
+ * `The Software Performance of Authenticated-Encryption Modes' renamed the
+ * original 2001 version of OCB as `OCB1', and the 2004 version `OCB2', and
+ * introduced a new `OCB3'.  I've decided to follow and extend the 2011
+ * naming, so `OCB1' refers to the 2001 OCB; the 2004 version would be
+ * `OCB2'.
+ *
+ * The OCB specification is clear about how OCB applies to arbitrary block
+ * sizes.
+ *
+ * OCB1 is a fairly well-behaved AEAD mode.  It doesn't require
+ * precommentment to any lengths, and allows header data to be processed
+ * independently of any message.  On the other hand, it only accepts nonces
+ * the same size as the underlying blockcipher's block size, and it buffers
+ * up to a whole block's worth of data internally, which somewhat complicates
+ * streaming.
+ */
+
+#ifndef CATACOMB_OCB1_H
+#define CATACOMB_OCB1_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
+
+#ifndef CATACOMB_OCB_H
+#  include "ocb.h"
+#endif
+
+#ifndef CATACOMB_RSVR_H
+#  include "rsvr.h"
+#endif
+
+/*----- Macros ------------------------------------------------------------*/
+
+/* --- @OCB1_DECL@ --- *
+ *
+ * Arguments:  @PRE@, @pre@ = prefixes for the underlying block cipher
+ *
+ * Use:                Creates declarations for OCB1 message-authentication mode.
+ */
+
+#define OCB1_STRUCTS(PRE, pre, keyty, aadty)                           \
+                                                                       \
+typedef struct keyty {                                                 \
+  pre##_ctx ctx;                       /* Underlying cipher context */ \
+  uint32 lxinv[PRE##_BLKSZ/4];         /* Final-block mask */          \
+  uint32 lmask[OCB_NCALC][PRE##_BLKSZ/4]; /* Precalculated masks */    \
+} keyty;                                                               \
+                                                                       \
+typedef struct aadty {                                                 \
+  keyty k;                             /* Processed key material */    \
+  uint32 o[PRE##_BLKSZ/4];             /* Current offset */            \
+  uint32 a[PRE##_BLKSZ/4];             /* Accumulator state */         \
+  octet b[PRE##_BLKSZ];                        /* Input buffer */              \
+  unsigned long i;                     /* Block counter */             \
+  unsigned off;                                /* Offset into buffered data */ \
+} aadty;
+
+#define OCB1_DECL(PRE, pre)                                            \
+                                                                       \
+OCB1_STRUCTS(PRE, pre, pre##_ocb1key, pre##_ocb1aadctx)                        \
+                                                                       \
+typedef struct pre##_ocb1ctx {                                         \
+  /* This is the same as @pre_ocb1aadctx@ above, but the two are       \
+   * logically distinct and shouldn't be muddled up.                   \
+   */                                                                  \
+                                                                       \
+  pre##_ocb1key k;                     /* Processed key material */    \
+  uint32 o[PRE##_BLKSZ/4];             /* Current offset */            \
+  uint32 a[PRE##_BLKSZ/4];             /* Accumulator state */         \
+  octet b[PRE##_BLKSZ];                        /* Input buffer */              \
+  unsigned long i;                     /* Block counter */             \
+  unsigned off;                                /* Offset into buffered data */ \
+} pre##_ocb1ctx;                                                       \
+                                                                       \
+extern const rsvr_policy pre##_ocb1policy;                             \
+                                                                       \
+extern const octet pre##_ocb1noncesz[], pre##_ocb1tagsz[];             \
+                                                                       \
+/* --- @pre_ocb1setkey@ --- *                                          \
+ *                                                                     \
+ * Arguments:  @pre_ocb1key *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 OCB1 key block.                          \
+ */                                                                    \
+                                                                       \
+extern void pre##_ocb1setkey(pre##_ocb1key */*key*/,                   \
+                            const void */*k*/, size_t /*ksz*/);        \
+                                                                       \
+/* --- @pre_ocb1aadinit@ --- *                                         \
+ *                                                                     \
+ * Arguments:  @pre_ocb1aadctx *aad@ = pointer to AAD context          \
+ *             @const pre_ocb1key *key@ = pointer to key block         \
+ *                                                                     \
+ * Returns:    ---                                                     \
+ *                                                                     \
+ * Use:                Initializes an OCB1 AAD (`additional authenticated      \
+ *             data') context associated with a given key.  AAD        \
+ *             contexts can be copied and/or reused, saving time if    \
+ *             the AAD for 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 OCB1  \
+ *             operation context because the AAD on its own isn't much \
+ *             good.                                                   \
+ */                                                                    \
+                                                                       \
+extern void pre##_ocb1aadinit(pre##_ocb1aadctx */*aad*/,               \
+                             const pre##_ocb1key */*key*/);            \
+                                                                       \
+/* --- @pre_ocb1aadhash@ --- *                                         \
+ *                                                                     \
+ * Arguments:  @pre_ocb1aadctx *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##_ocb1aadhash(pre##_ocb1aadctx */*aad*/,               \
+                             const void */*p*/, size_t /*sz*/);        \
+                                                                       \
+/* --- @pre_ocb1aadtag@ --- *                                          \
+ *                                                                     \
+ * Arguments:  @const pre_ocb1aadctx *aad@ = pointer to context block  \
+ *             @uint32 *u@ = where to write the tag                    \
+ *                                                                     \
+ * Returns:    ---                                                     \
+ *                                                                     \
+ * Use:                Finishes processing AAD and produces a tag which can be \
+ *             mixed with an OCB1 checksum.  This function is exposed  \
+ *             for internal reasons and is not expected to be          \
+ *             generally useful.                                       \
+ */                                                                    \
+                                                                       \
+extern void pre##_ocb1aadtag(const pre##_ocb1aadctx */*aad*/,          \
+                            uint32 */*t*/);                            \
+                                                                       \
+/* --- @pre_ocb1init@ --- *                                            \
+ *                                                                     \
+ * Arguments:  @pre_ocb1ctx *ctx@ = pointer to OCB1 context            \
+ *             @const pre_ocb1key *key@ = pointer to key block         \
+ *             @const void *n@ = pointer to nonce                      \
+ *             @size_t nsz@ = size of nonce                            \
+ *                                                                     \
+ * Returns:    Zero on success, @-1@ if the nonce length is bad.       \
+ *                                                                     \
+ * Use:                Initialize an OCB1 operation context with a given key.  \
+ *                                                                     \
+ *             The original key needn't be kept around any more.       \
+ */                                                                    \
+                                                                       \
+extern int pre##_ocb1init(pre##_ocb1ctx */*ctx*/,                      \
+                         const pre##_ocb1key */*k*/,                   \
+                         const void */*n*/, size_t /*nsz*/);           \
+                                                                       \
+/* --- @pre_ocb1reinit@ --- *                                          \
+ *                                                                     \
+ * Arguments:  @pre_ocb1ctx *ctx@ = pointer to OCB1 context            \
+ *             @const void *n@ = pointer to nonce                      \
+ *             @size_t nsz@ = size of nonce                            \
+ *                                                                     \
+ * Returns:    Zero on success, @-1@ if the nonce length is bad.       \
+ *                                                                     \
+ * Use:                Reinitialize an OCB1 operation context, changing the    \
+ *             nonce.                                                  \
+ */                                                                    \
+                                                                       \
+extern int pre##_ocb1reinit(pre##_ocb1ctx */*ctx*/,                    \
+                           const void */*n*/, size_t /*nsz*/);         \
+                                                                       \
+/* --- @pre_ocb1encrypt@ --- *                                         \
+ *                                                                     \
+ * Arguments:  @pre_ocb1ctx *ctx@ = pointer to OCB1 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.                                    \
+ *                                                                     \
+ *             Note that OCB1 delays output if its input is not a      \
+ *             whole number of blocks.  This means that the output     \
+ *             might be smaller or larger the input by up to the block \
+ *             size.                                                   \
+ */                                                                    \
+                                                                       \
+extern int pre##_ocb1encrypt(pre##_ocb1ctx */*ctx*/,                   \
+                            const void */*src*/, size_t /*sz*/,        \
+                            buf */*dst*/);                             \
+                                                                       \
+/* --- @pre_ocb1decrypt@ --- *                                         \
+ *                                                                     \
+ * Arguments:  @pre_ocb1ctx *ctx@ = pointer to OCB1 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.                                    \
+ *                                                                     \
+ *             Note that OCB1 delays output if its input is not a      \
+ *             whole number of blocks.  This means that the output     \
+ *             might be smaller or larger the input by up to the block \
+ *             size.                                                   \
+ */                                                                    \
+                                                                       \
+extern int pre##_ocb1decrypt(pre##_ocb1ctx */*ctx*/,                   \
+                            const void */*src*/, size_t /*sz*/,        \
+                            buf */*dst*/);                             \
+                                                                       \
+/* --- @pre_ocb1encryptdone@ --- *                                     \
+ *                                                                     \
+ * Arguments:  @pre_ocb1ctx *ctx@ = pointer to an OCB1 context         \
+ *             @const pre_ocb1aadctx *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 OCB1 encryption operation.  The @aad@      \
+ *             pointer may be null if there is no additional           \
+ *             authenticated data.  OCB1 delays output, so this will   \
+ *             cause any remaining buffered plaintext to be encrypted  \
+ *             and written to @dst@.  Anyway, the function will fail   \
+ *             if the output buffer is broken.                         \
+ */                                                                    \
+                                                                       \
+extern int pre##_ocb1encryptdone(pre##_ocb1ctx */*ctx*/,               \
+                                const pre##_ocb1aadctx */*aad*/,       \
+                                buf */*dst*/,                          \
+                                void */*tag*/, size_t /*tsz*/);        \
+                                                                       \
+/* --- @pre_ocb1decryptdone@ --- *                                     \
+ *                                                                     \
+ * Arguments:  @pre_ocb1ctx *ctx@ = pointer to an OCB1 context         \
+ *             @const pre_ocb1aadctx *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 OCB1 decryption operation.  The @aad@      \
+ *             pointer may be null if there is no additional           \
+ *             authenticated data.  OCB1 delays output, so this will   \
+ *             cause any remaining buffered ciphertext to be decrypted \
+ *             and written to @dst@.  Anyway, the function will fail   \
+ *             if the output buffer is broken.                         \
+ */                                                                    \
+                                                                       \
+extern int pre##_ocb1decryptdone(pre##_ocb1ctx */*ctx*/,               \
+                                const pre##_ocb1aadctx */*aad*/,       \
+                                buf */*dst*/,                          \
+                                const void */*tag*/, size_t /*tsz*/);  \
+                                                                       \
+/* --- Generic AEAD interface --- */                                   \
+                                                                       \
+extern const gcaead pre##_ocb1;
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif