--- /dev/null
+/* -*-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