symm/cmac.h, symm/cmac-def.h: Implement the CMAC (OMAC) message auth'n mode.
[catacomb] / symm / cmac.h
diff --git a/symm/cmac.h b/symm/cmac.h
new file mode 100644 (file)
index 0000000..95b047e
--- /dev/null
@@ -0,0 +1,210 @@
+/* -*-c-*-
+ *
+ * The CMAC message-authentication code
+ *
+ * (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 CMAC -----------------------------------------------------*
+ *
+ * CMAC was designed in 2003 by Tetsu Iwata and Kaoru Kurosawa as a reliable
+ * general purpose message-authentication code based on CBC-MAC.  CBC-MAC's
+ * deficiencies have been well known since at least 2000 when Bellare,
+ * Kilian, and Rogaway proved its security on constant-length messages.
+ * Black and Rogaway in 2000 described a number of three-key constructions
+ * for extending CBC-MAC's domain securely to arbitrary strings, culminating
+ * in a mode they named `XCBC', which uses a blockcipher key and two XOR
+ * masks.  Iwata and Kurosawa's original proposal, named `OMAC', refined XCBC
+ * by deriving the masks from the key, producing a `one-key MAC'.  Bellare,
+ * Rogaway, and Wagner slightly simplified the way the masks were derived
+ * when they used OMAC as a part of their EAX authenticated-encryption mode,
+ * and this change was adopted by NIST when they standardized OMAC, under the
+ * name `CMAC', in SP800-38B.
+ *
+ * NIST specify CMAC only for 64- and 128-bit blockciphers.  This
+ * implementation extends it to other lengths in the obvious way.
+ */
+
+#ifndef CATACOMB_CMAC_H
+#define CATACOMB_CMAC_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stddef.h>
+
+#include <mLib/bits.h>
+
+#ifndef CATACOMB_GMAC_H
+#  include "gmac.h"
+#endif
+
+#ifndef CATACOMB_RSVR_H
+#  include "rsvr.h"
+#endif
+
+/*----- Low-level OMAC declarations ---------------------------------------*/
+
+/* --- @OMAC_DECL@ --- *
+ *
+ * Arguments:  @PRE@, @pre@ = prefixes for the underlying block cipher
+ *
+ * Use:                Defines low-level implementation for the OMAC message-
+ *             authentication mode.
+ */
+
+#define OMAC_DECL(PRE, pre)                                            \
+                                                                       \
+/* Buffering policy for OMAC. */                                       \
+extern const rsvr_policy pre##_omacpolicy;                             \
+                                                                       \
+/* --- @pre_omacmasks@ --- *                                           \
+ *                                                                     \
+ * Arguments:  @pre_ctx *k@ = pointer to expanded blockcipher key      \
+ *             @uint32 *m0, *m1@ = buffers to store the masks          \
+ *                                                                     \
+ * Returns:    ---                                                     \
+ *                                                                     \
+ * Use:                Initialize the OMAC masks.  The mask buffers are        \
+ *             @PRE_BLKSZ/4@ words long.  The mmask @m0@ is applied to \
+ *             messages which are a whole number of blocks long; @m1@  \
+ *             is applied to messages with an incomplete final block,  \
+ *             following the 10* padding.                              \
+ */                                                                    \
+                                                                       \
+extern void pre##_omacmasks(pre##_ctx */*k*/,                          \
+                           uint32 */*m0*/, uint32 */*m1*/);            \
+                                                                       \
+/* --- @pre_omacdone@ --- *                                            \
+ *                                                                     \
+ * Arguments:  @pre_ctx *k@ = pointer to expanded blockcipher key      \
+ *             @const uint32 *m0, *m1@ = masks                         \
+ *             @uint32 *a@ = accumulator state to update               \
+ *             @octet *p@ = pointer to input buffer (clobbered)        \
+ *             @unsigned n@ = size of input buffer (no more than       \
+ *                     @PRE_BLKSZ@)                                    \
+ *                                                                     \
+ * Returns:    ---                                                     \
+ *                                                                     \
+ * Use:                Update and finalize the OMAC hash state with the last   \
+ *             few bytes of input.  The final tag is left in @a@.      \
+ */                                                                    \
+                                                                       \
+extern void pre##_omacdone(pre##_ctx */*k*/,                           \
+                          const uint32 */*m0*/, const uint32 */*m1*/,  \
+                          uint32 */*a*/, octet */*p*/, unsigned /*n*/);
+
+/*----- Macros ------------------------------------------------------------*/
+
+/* --- @CMAC_DECL@ --- *
+ *
+ * Arguments:  @PRE@, @pre@ = prefixes for the underlying block cipher
+ *
+ * Use:                Creates declarations for CMAC message-authentication mode.
+ */
+
+#define CMAC_DECL(PRE, pre)                                            \
+                                                                       \
+OMAC_DECL(PRE, pre)                                                    \
+                                                                       \
+typedef struct pre##_cmackey {                                         \
+  pre##_ctx ctx;                       /* Underlying cipher context */ \
+  uint32 m0[PRE##_BLKSZ/4], m1[PRE##_BLKSZ/4]; /* Final block masks */ \
+} pre##_cmackey;                                                       \
+                                                                       \
+typedef struct pre##_cmacctx {                                         \
+  pre##_cmackey k;                     /* Processed key material */    \
+  uint32 a[PRE##_BLKSZ/4];             /* Chaining state */            \
+  octet b[PRE##_BLKSZ];                        /* Input buffer */              \
+  unsigned off;                                /* Offset into buffered data */ \
+} pre##_cmacctx;                                                       \
+                                                                       \
+/* --- @pre_cmacsetkey@ --- *                                          \
+ *                                                                     \
+ * Arguments:  @pre_cmackey *key@ = pointer to CMAC key block          \
+ *             @ocnst void *k@ = pointer to key material               \
+ *             @size_t ksz@ = size of key material                     \
+ *                                                                     \
+ * Returns:    ---                                                     \
+ *                                                                     \
+ * Use:                Initializes a CMAC key.  This can be used for several   \
+ *             MAC operations.                                         \
+ */                                                                    \
+                                                                       \
+extern void pre##_cmacsetkey(pre##_cmackey */*key*/,                   \
+                            const void */*k*/, size_t /*ksz*/);        \
+                                                                       \
+/* --- @pre##_cmacinit@ --- *                                          \
+ *                                                                     \
+ * Arguments:  @pre_cmacctx *ctx@ = pointer to context block           \
+ *             @pre_cmackey *k@ = key block                            \
+ *                                                                     \
+ * Returns:    ---                                                     \
+ *                                                                     \
+ * Use:                Initializes a CMAC context ready to process a message.  \
+ *             It's not necessary to keep the key around.              \
+ */                                                                    \
+                                                                       \
+extern void pre##_cmacinit(pre##_cmacctx */*ctx*/,                     \
+                          const pre##_cmackey */*k*/);                 \
+                                                                       \
+/* --- @pre_cmachash@ --- *                                            \
+ *                                                                     \
+ * Arguments:  @pre_cmacctx *ctx@ = pointer to CMAC context block      \
+ *             @ocnst void *p@ = pointer to message buffer             \
+ *             @size_t sz@ = size of message buffer                    \
+ *                                                                     \
+ * Returns:    ---                                                     \
+ *                                                                     \
+ * Use:                Hashes some input data.                                 \
+ */                                                                    \
+                                                                       \
+extern void pre##_cmachash(pre##_cmacctx */*ctx*/,                     \
+                          const void */*p*/, size_t /*sz*/);           \
+                                                                       \
+/* --- @pre_cmacdone@ --- *                                            \
+ *                                                                     \
+ * Arguments:  @pre_cmacctx *ctx@ = pointer to CMAC context block      \
+ *             @void *t@ = where to write the tag                      \
+ *                                                                     \
+ * Returns:    ---                                                     \
+ *                                                                     \
+ * Use:                Finishes a MAC operation and produces the tag.          \
+ */                                                                    \
+                                                                       \
+extern void pre##_cmacdone(pre##_cmacctx */*ctx*/, void */*t*/);       \
+                                                                       \
+/* --- Generic MAC interface --- */                                    \
+                                                                       \
+extern const gcmac pre##_cmac;
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif