symm/cmac.h, symm/cmac-def.h: Implement the CMAC (OMAC) message auth'n mode.
authorMark Wooding <mdw@distorted.org.uk>
Wed, 31 Oct 2018 12:05:48 +0000 (12:05 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 5 Sep 2019 00:36:05 +0000 (01:36 +0100)
Also introduce `utils/advmodes' containing toy implementations of
`fancy' blockcipher modes, which is useful as a reference and
playground.

26 files changed:
symm/Makefile.am
symm/cmac-def.h [new file with mode: 0644]
symm/cmac.h [new file with mode: 0644]
symm/t/blowfish
symm/t/cast128
symm/t/cast256.local [new file with mode: 0644]
symm/t/des
symm/t/des3
symm/t/desx
symm/t/idea
symm/t/mars.local [new file with mode: 0644]
symm/t/noekeon
symm/t/rc2
symm/t/rc5
symm/t/rijndael.local [new file with mode: 0644]
symm/t/rijndael192
symm/t/rijndael256
symm/t/safer
symm/t/safersk
symm/t/serpent.local [new file with mode: 0644]
symm/t/skipjack
symm/t/square
symm/t/tea
symm/t/twofish.local [new file with mode: 0644]
symm/t/xtea
utils/advmodes [new file with mode: 0755]

index 24a0afc..2af0945 100644 (file)
@@ -133,13 +133,14 @@ endif
 BLKCS                  += cast128 cast256
 libsymm_la_SOURCES     += cast-s.c cast-sk.c cast-base.h
 cast256.log: t/cast256
-EXTRA_DIST             += t/cast256.aes
+EXTRA_DIST             += t/cast256.aes t/cast256.local
 MAINTAINERCLEANFILES   += $(srcdir)/t/cast256
-t/cast256: t/cast256.aes
-       $(AM_V_GEN)$(srcdir)/aes-trans CAST256 \
-               <$(srcdir)/t/cast256.aes \
-               >$(srcdir)/t/cast256.new && \
-       mv $(srcdir)/t/cast256.new $(srcdir)/t/cast256
+t/cast256: t/cast256.aes t/cast256.local
+       $(AM_V_GEN)cd $(srcdir) && \
+               { ./aes-trans CAST256 <t/cast256.aes && \
+                 cat t/cast256.local; \
+               } >t/cast256.new && \
+               mv t/cast256.new t/cast256
 
 ## IBM's `DES' block cipher, by Feistel, Coppersmith, and others.
 BLKCS                  += des des3
@@ -175,13 +176,14 @@ $(precomp)/symm/mars-tab.c:
                mv $(precomp)/symm/mars-tab.c.new $(precomp)/symm/mars-tab.c
 endif
 mars.log: t/mars
-EXTRA_DIST             += t/mars.aes
+EXTRA_DIST             += t/mars.aes t/mars.local
 MAINTAINERCLEANFILES   += $(srcdir)/t/mars
-t/mars: t/mars.aes
-       $(AM_V_GEN)$(srcdir)/aes-trans Mars \
-               <$(srcdir)/t/mars.aes \
-               >$(srcdir)/t/mars.new && \
-       mv $(srcdir)/t/mars.new $(srcdir)/t/mars
+t/mars: t/mars.aes t/mars.local
+       $(AM_V_GEN)cd $(srcdir) && \
+               { ./aes-trans Mars <t/mars.aes && \
+                 cat t/mars.local; \
+               } >t/mars.new && \
+               mv t/mars.new t/mars
 
 ## Daemen, Peeters, Van Assche and Rijmen's `Noekeon'.
 BLKCS                  += noekeon
@@ -222,13 +224,14 @@ $(precomp)/symm/rijndael-tab.c:
                        $(precomp)/symm/rijndael-tab.c
 endif
 rijndael.log: t/rijndael
-EXTRA_DIST             += t/rijndael.aes
+EXTRA_DIST             += t/rijndael.aes t/rijndael.local
 MAINTAINERCLEANFILES   += $(srcdir)/t/rijndael
-t/rijndael: t/rijndael.aes
-       $(AM_V_GEN)$(srcdir)/aes-trans Rijndael \
-               <$(srcdir)/t/rijndael.aes \
-               >$(srcdir)/t/rijndael.new && \
-       mv $(srcdir)/t/rijndael.new $(srcdir)/t/rijndael
+t/rijndael: t/rijndael.aes t/rijndael.local
+       $(AM_V_GEN)cd $(srcdir) && \
+               { ./aes-trans Rijndael <t/rijndael.aes && \
+                 cat t/rijndael.local; \
+               } >t/rijndael.new && \
+               mv t/rijndael.new t/rijndael
 
 ## Massey's `SAFER' block ciphers.
 BLKCS                  += safer safersk
@@ -252,13 +255,14 @@ libsymm_la_SOURCES        += serpent-sbox.h
 check_PROGRAMS         += serpent-check
 TESTS                  += serpent-check
 serpent.log: t/serpent
-EXTRA_DIST             += t/serpent.aes
+EXTRA_DIST             += t/serpent.aes t/serpent.local
 MAINTAINERCLEANFILES   += $(srcdir)/t/serpent
-t/serpent: t/serpent.aes
-       $(AM_V_GEN)$(srcdir)/aes-trans Serpent -v rev=1 \
-               <$(srcdir)/t/serpent.aes \
-               >$(srcdir)/t/serpent.new && \
-       mv $(srcdir)/t/serpent.new $(srcdir)/t/serpent
+t/serpent: t/serpent.aes t/serpent.local
+       $(AM_V_GEN)cd $(srcdir) && \
+               { ./aes-trans Serpent -v rev=1 <t/serpent.aes && \
+                 cat t/serpent.local; \
+               } >t/serpent.new && \
+               mv t/serpent.new t/serpent
 
 ## The National Security Agency's `Skipjack' block cipher.  You don't want to
 ## use this.
@@ -297,13 +301,14 @@ $(precomp)/symm/twofish-tab.c:
                        $(precomp)/symm/twofish-tab.c
 endif
 twofish.log: t/twofish
-EXTRA_DIST             += t/twofish.aes
+EXTRA_DIST             += t/twofish.aes t/twofish.local
 MAINTAINERCLEANFILES   += $(srcdir)/t/twofish
-t/twofish: t/twofish.aes
-       $(AM_V_GEN)$(srcdir)/aes-trans Twofish \
-               <$(srcdir)/t/twofish.aes \
-               >$(srcdir)/t/twofish.new && \
-       mv $(srcdir)/t/twofish.new $(srcdir)/t/twofish
+t/twofish: t/twofish.aes t/twofish.local
+       $(AM_V_GEN)cd $(srcdir) && \
+               { ./aes-trans Twofish <t/twofish.aes && \
+                 cat t/twofish.local; \
+               } >t/twofish.new && \
+               mv t/twofish.new t/twofish
 
 ## The old NIST modes for DES.
 BLKCCIPHERMODES                += cbc cfb ecb ofb
@@ -311,6 +316,9 @@ BLKCCIPHERMODES             += cbc cfb ecb ofb
 ## Counter mode.
 BLKCCIPHERMODES                += counter
 
+## CMAC mode.
+BLKCMACMODES           += cmac
+
 ###--------------------------------------------------------------------------
 ### Hash functions.
 
diff --git a/symm/cmac-def.h b/symm/cmac-def.h
new file mode 100644 (file)
index 0000000..701d3b5
--- /dev/null
@@ -0,0 +1,406 @@
+/* -*-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.
+ */
+
+#ifndef CATACOMB_CMAC_DEF_H
+#define CATACOMB_CMAC_DEF_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <string.h>
+
+#include <mLib/bits.h>
+#include <mLib/sub.h>
+
+#ifndef CATACOMB_ARENA_H
+#  include "arena.h"
+#endif
+
+#ifndef CATACOMB_BLKC_H
+#  include "blkc.h"
+#endif
+
+#ifndef CATACOMB_GMAC_H
+#  include "gmac.h"
+#endif
+
+#ifndef CATACOMB_PARANOIA_H
+#  include "paranoia.h"
+#endif
+
+#ifndef CATACOMB_RSVR_H
+#  include "rsvr.h"
+#endif
+
+/*----- Low-level OMAC definitions ----------------------------------------*/
+
+/* --- @OMAC_BLOCK@ --- *
+ *
+ * Arguments:  @PRE@, @pre@ = prefixes for the underlying block cipher
+ *             @pre_ctx *k@ = pointer to expanded blockcipher key
+ *             @uint32 *a@ = accumulator state to update
+ *             @octet *p@ = pointer to input block to accumulate
+ *
+ * Use:                Update the state @a@ from the input block @p@.
+ */
+
+#define OMAC_BLOCK(PRE, pre, k, a, p) do {                             \
+  pre##_ctx *_k = (k); uint32 *_a = (a); const octet *_pp = (p);       \
+  BLKC_XLOAD(PRE, _a, _pp); pre##_eblk(_k, _a, _a);                    \
+} while (0)
+
+/* --- @OMAC_DEF@ --- *
+ *
+ * Arguments:  @PRE@, @pre@ = prefixes for the underlying block cipher
+ *
+ * Use:                Creates low-level implementation for the OMAC message-
+ *             authentication mode.
+ */
+
+#define OMAC_DEF(PRE, pre)                                             \
+                                                                       \
+/* Buffering policy for OMAC. */                                       \
+const rsvr_policy pre##_omacpolicy =                                   \
+  { RSVRF_FULL, PRE##_BLKSZ, PRE##_BLKSZ };                            \
+                                                                       \
+/* --- @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.                              \
+ */                                                                    \
+                                                                       \
+void pre##_omacmasks(pre##_ctx *k, uint32 *m0, uint32 *m1)             \
+{                                                                      \
+  uint32 t[PRE##_BLKSZ/4];                                             \
+                                                                       \
+  BLKC_ZERO(PRE, t); pre##_eblk(k, t, t);                              \
+  BLKC_BLSHIFT(PRE, IRRED, m0, t);                                     \
+  BLKC_BLSHIFT(PRE, IRRED, m1, m0);                                    \
+}                                                                      \
+                                                                       \
+/* --- @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@.      \
+ */                                                                    \
+                                                                       \
+void pre##_omacdone(pre##_ctx *k, const uint32 *m0, const uint32 *m1,  \
+                   uint32 *a, octet *p, unsigned n)                    \
+{                                                                      \
+  /* Do any necessary padding and apply the appropriate mask to the    \
+   * accumulator.                                                      \
+   */                                                                  \
+  if (n == PRE##_BLKSZ)                                                        \
+    BLKC_XMOVE(PRE, a, m0);                                            \
+  else {                                                               \
+    p[n] = 0x80; memset(p + n + 1, 0, PRE##_BLKSZ - n - 1);            \
+    BLKC_XMOVE(PRE, a, m1);                                            \
+  }                                                                    \
+                                                                       \
+  /* Fetch the buffer contents and cycle the block cipher one last     \
+   * time.                                                             \
+   */                                                                  \
+  BLKC_XLOAD(PRE, a, p);                                               \
+  pre##_eblk(k, a, a);                                                 \
+}
+
+/*----- Properly cooked CMAC ----------------------------------------------*/
+
+/* --- @CMAC_DEF@ --- *
+ *
+ * Arguments:  @PRE@, @pre@ = prefixes for the underlying block cipher
+ *
+ * Use:                Creates an implementation for the CMAC message-authentication
+ *             mode.
+ */
+
+#define CMAC_DEF(PRE, pre) CMAC_DEFX(PRE, pre, #pre, #pre)
+
+#define CMAC_DEFX(PRE, pre, name, fname)                               \
+                                                                       \
+OMAC_DEF(PRE, pre)                                                     \
+                                                                       \
+/* --- @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.                                         \
+ */                                                                    \
+                                                                       \
+void pre##_cmacsetkey(pre##_cmackey *key, const void *k, size_t ksz)   \
+{                                                                      \
+  pre##_init(&key->ctx, k, ksz);                                       \
+  pre##_omacmasks(&key->ctx, key->m0, key->m1);                                \
+}                                                                      \
+                                                                       \
+/* --- @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.              \
+ */                                                                    \
+                                                                       \
+void pre##_cmacinit(pre##_cmacctx *ctx, const pre##_cmackey *k)                \
+  { ctx->k = *k; ctx->off = 0; BLKC_ZERO(PRE, ctx->a); }               \
+                                                                       \
+/* --- @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.                                 \
+ */                                                                    \
+                                                                       \
+void pre##_cmachash(pre##_cmacctx *ctx, const void *p, size_t sz)      \
+{                                                                      \
+  rsvr_state st;                                                       \
+  const octet *q;                                                      \
+                                                                       \
+  rsvr_setup(&st, &pre##_omacpolicy, ctx->b, &ctx->off, p, sz);                \
+  RSVR_DO(&st) while ((q = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0)          \
+    OMAC_BLOCK(PRE, pre, &ctx->k.ctx, ctx->a, q);                      \
+}                                                                      \
+                                                                       \
+/* --- @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.  The     \
+ *             context is clobbered and can't be used for anything     \
+ *             useful any more.                                        \
+ */                                                                    \
+                                                                       \
+void pre##_cmacdone(pre##_cmacctx *ctx, void *t)                       \
+{                                                                      \
+  pre##_omacdone(&ctx->k.ctx, ctx->k.m0, ctx->k.m1,                    \
+                ctx->a, ctx->b, ctx->off);                             \
+  BLKC_STORE(PRE, t, ctx->a);                                          \
+}                                                                      \
+                                                                       \
+/* --- Generic MAC interface --- */                                    \
+                                                                       \
+static const gmac_ops gkops;                                           \
+static const ghash_ops gops;                                           \
+                                                                       \
+typedef struct gkctx {                                                 \
+  gmac m;                                                              \
+  pre##_cmackey k;                                                     \
+} gkctx;                                                               \
+                                                                       \
+typedef struct gctx {                                                  \
+  ghash h;                                                             \
+  pre##_cmacctx c;                                                     \
+  octet buf[PRE##_BLKSZ];                                              \
+} gctx;                                                                        \
+                                                                       \
+static ghash *gkinit(gmac *m)                                          \
+{                                                                      \
+  gkctx *gk = (gkctx *)m;                                              \
+  gctx *g = S_CREATE(gctx);                                            \
+  g->h.ops = &gops;                                                    \
+  pre##_cmacinit(&g->c, &gk->k);                                       \
+  return (&g->h);                                                      \
+}                                                                      \
+                                                                       \
+static gmac *gkey(const void *k, size_t sz)                            \
+{                                                                      \
+  gkctx *gk = S_CREATE(gkctx);                                         \
+  gk->m.ops = &gkops;                                                  \
+  pre##_cmacsetkey(&gk->k, k, sz);                                     \
+  return (&gk->m);                                                     \
+}                                                                      \
+                                                                       \
+static void ghhash(ghash *h, const void *p, size_t sz)                 \
+  { gctx *g = (gctx *)h; pre##_cmachash(&g->c, p, sz); }               \
+                                                                       \
+static octet *ghdone(ghash *h, void *buf)                              \
+{                                                                      \
+  gctx *g = (gctx *)h;                                                 \
+  if (!buf) buf = g->buf;                                              \
+  pre##_cmacdone(&g->c, buf);                                          \
+  return (buf);                                                                \
+}                                                                      \
+                                                                       \
+static ghash *ghcopy(ghash *h)                                         \
+{                                                                      \
+  gctx *g = (gctx *)h;                                                 \
+  gctx *gg = S_CREATE(gctx);                                           \
+  memcpy(gg, g, sizeof(gctx));                                         \
+  return (&gg->h);                                                     \
+}                                                                      \
+                                                                       \
+static void ghdestroy(ghash *h)                                                \
+  { gctx *g = (gctx *)h; BURN(*g); S_DESTROY(g); }                     \
+                                                                       \
+static void gkdestroy(gmac *m)                                         \
+  { gkctx *gk = (gkctx *)m; BURN(*gk); S_DESTROY(gk); }                        \
+                                                                       \
+static ghash *ghinit(void)                                             \
+{                                                                      \
+  assert(((void)"Attempt to instantiate an unkeyed MAC", 0));          \
+  return (0);                                                          \
+}                                                                      \
+                                                                       \
+const gcmac pre##_cmac =                                               \
+  { name "-cmac", PRE##_BLKSZ, pre##_keysz, gkey };                    \
+static const gmac_ops gkops = { &pre##_cmac, gkinit, gkdestroy };      \
+static const gchash gch = { name "-cmac", PRE##_BLKSZ, ghinit };       \
+static const ghash_ops gops =                                          \
+  { &gch, ghhash, ghdone, ghdestroy, ghcopy };                         \
+                                                                       \
+CMAC_TESTX(PRE, pre, name, fname)
+
+#define CMAC_TEST(PRE, pre) HMAC_TESTX(PRE, pre, #pre, #pre)
+
+/* --- @CMAC_TEST@ --- *
+ *
+ * Arguments:  @PRE@, @pre@ = prefixes for the underlying block cipher
+ *
+ * Use:                Standard test rig for CMAC functions.
+ */
+
+#ifdef TEST_RIG
+
+#include <stdio.h>
+
+#include <mLib/dstr.h>
+#include <mLib/quis.h>
+#include <mLib/testrig.h>
+
+#define CMAC_TESTX(PRE, pre, name, fname)                              \
+                                                                       \
+static int macverify(dstr *v)                                          \
+{                                                                      \
+  pre##_cmacctx cctx;                                                  \
+  pre##_cmackey ckey;                                                  \
+  int ok = 1;                                                          \
+  int i;                                                               \
+  octet *p;                                                            \
+  int szs[] = { 1, 7, 192, -1, 0 }, *ip;                               \
+  size_t csz;                                                          \
+  dstr d;                                                              \
+                                                                       \
+  dstr_create(&d);                                                     \
+  dstr_ensure(&d, PRE##_BLKSZ);                                                \
+  d.len = PRE##_BLKSZ;                                                 \
+                                                                       \
+  pre##_cmacsetkey(&ckey, v[0].buf, v[0].len);                         \
+                                                                       \
+  for (ip = szs; *ip; ip++) {                                          \
+    i = *ip;                                                           \
+    csz = v[1].len;                                                    \
+    if (i == -1)                                                       \
+      i = csz;                                                         \
+    if (i > csz)                                                       \
+      continue;                                                                \
+    p = (octet *)v[1].buf;                                             \
+    pre##_cmacinit(&cctx, &ckey);                                      \
+    while (csz) {                                                      \
+      if (i > csz)                                                     \
+       i = csz;                                                        \
+      pre##_cmachash(&cctx, p, i);                                     \
+      p += i;                                                          \
+      csz -= i;                                                                \
+    }                                                                  \
+    pre##_cmacdone(&cctx, d.buf);                                      \
+    if (memcmp(d.buf, v[2].buf, PRE##_BLKSZ) != 0) {                   \
+      printf("\nfail:\n\tstep = %i\n\tkey = ", *ip);                   \
+      type_hex.dump(&v[0], stdout);                                    \
+      fputs("\n\tinput = ", stdout);                                   \
+      type_hex.dump(&v[1], stdout);                                    \
+      fputs("\n\texpected = ", stdout);                                        \
+      type_hex.dump(&v[2], stdout);                                    \
+      fputs("\n\tcomputed = ", stdout);                                        \
+      type_hex.dump(&d, stdout);                                       \
+      putchar('\n');                                                   \
+      ok = 0;                                                          \
+    }                                                                  \
+  }                                                                    \
+                                                                       \
+  dstr_destroy(&d);                                                    \
+  return (ok);                                                         \
+}                                                                      \
+                                                                       \
+static test_chunk macdefs[] = {                                                \
+  { name "-cmac", macverify,                                           \
+    { &type_hex, &type_hex, &type_hex, 0 } },                          \
+  { 0, 0, { 0 } }                                                      \
+};                                                                     \
+                                                                       \
+int main(int argc, char *argv[])                                       \
+{                                                                      \
+  ego(argv[0]);                                                                \
+  test_run(argc, argv, macdefs, SRCDIR"/t/" fname);                    \
+  return (0);                                                          \
+}
+
+#else
+#  define CMAC_TESTX(PRE, pre, name, fname)
+#endif
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
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
index 449f967..6752016 100644 (file)
@@ -117,3 +117,54 @@ blowfish {
   f0e1d2c3b4a5968778695a4b3c2d1e0f0011223344556677
        fedcba9876543210        05044b62fa52d080;
 }
+
+blowfish-cmac {
+  60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa906
+    ""
+    233f464f6f4fed40;
+  0d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d
+    1f
+    f80086d1f74c3c25;
+  337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e
+    6057acc87638f508046733d9ff61cdbda3b3e9878731ebfe
+    88141768f1834980;
+  dd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450
+    727a9b542cde52ebfda19d0ccc520f215eb57b
+    8b2e3c8554c039c5;
+  b3a4f3ebbbb18ac6c95a97
+    ""
+    992c2d7bae553fa1;
+  a48030370c33d090c54215
+    ab
+    3ef759021e0bd2c2;
+  d6b3ad54efc9a38378c5b9
+    3bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac
+    7ef83257367f4dcf;
+  26afa3349829b94586306f
+    ed54154f8f28523c03d4de1600157846b710ee
+    595b0c57e4ecd664;
+  72807a2219
+    ""
+    c17ded27f35e843b;
+  bfb474fd71
+    d8
+    063d632b053cfb61;
+  91f24bb65d
+    1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbac
+    aefe8538008cd029;
+  a48b77dba1
+    89196d1ebba10b0467cb9fc2712a199e533fa9
+    296073d2f0263834;
+  156308cdec3f768281e040a9b9a222bd689aef66f5306c
+    ""
+    fc5dcde84c290e8e;
+  eb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb
+    0b
+    f0e70394d6b143c9;
+  ad7d95214ade49cb3b6f5fe8368131115c037ba323fe1d
+    c8151784873f0eb5b647da6794c18b5337685a96ed65b9ac
+    a9be9c5120820347;
+  a338527ef19b09c063c46f88de9fd41e72d7b97e23e6ea
+    bdff3bcd211499268878dbf30f1dad89d4b9b1
+    a54fb7e239aeec4c;
+}
index a456ea0..8f76328 100644 (file)
@@ -13,3 +13,54 @@ cast128 {
   0123456789abcdef
   7ac816d16e9b302e;
 }
+
+cast128-cmac {
+  60d7bcda163547d348b7551195
+    ""
+    e027f02068e914e0;
+  e77022907dd1dff7dac5c9941d
+    26
+    a28361e0bd2c591c;
+  d0c6eb14ad568f86edd1dc9268
+    eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0
+    4eeb71793dd20683;
+  a54364c76c160f11896c479484
+    6ecfa14a7130c9f137120634c9519848a877ff
+    f46b0adba4856f4f;
+  77bf79192a5b50
+    ""
+    79360635503a7f04;
+  ade5d9cd739a3d
+    1f
+    9a100ee7cd214433;
+  337f29549e6b0d
+    27a4ba234085406a6136512061f7080cc07df0591d8fa21f
+    81e6063cc8dd3e25;
+  2dd88374d8cde8
+    e160ad10997a21635c6d62c9269029df3e6057
+    077ce3be2b167375;
+  acc87638f508046733d9
+    ""
+    e0ac1c1c71776fcb;
+  ff61cdbda3b3e9878731
+    eb
+    de618ec3a0d64ca2;
+  fedd4705e505da1435dc
+    eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533
+    1b5ed15a16456292;
+  966f27043eb621b7f65b
+    000961040ef2f9b2fc5fa450727a9b542cde52
+    fe228a47df7c250d;
+  ebfda19d0ccc520f21
+    ""
+    e8d3cb82a354843c;
+  5eb57bb3a4f3ebbbb1
+    8a
+    c7fcbad7ee9257d3;
+  c6c95a97a48030370c
+    33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260
+    1d547d096465faf6;
+  5faee2b03fb648e27f
+    ff63102758fe2b69ac26afa3349829b9458630
+    10bd2c18c3337a4f;
+}
diff --git a/symm/t/cast256.local b/symm/t/cast256.local
new file mode 100644 (file)
index 0000000..cde1a90
--- /dev/null
@@ -0,0 +1,52 @@
+### Local tests for CAST256.
+
+cast256-cmac {
+  60d7bcda163547d348b7551195
+    ""
+    550f6aa2b500f5b19d32c63502e8448b;
+  e77022907dd1dff7dac5c9941d
+    26
+    198a435819e092069eaf3c5a455baf3c;
+  d0c6eb14ad568f86edd1dc9268
+    eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206
+    2e7ac3fd9be8475d5b81a6f5fd3392e9;
+  34c9519848a877ff77bf79192a
+    5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8
+    7bcad81a16a4c1d1cf5fc4f107d9e50c;
+  8374d8cde8e160ad10997a21
+    ""
+    50fdac1d477bd12e61df27c230eb0858;
+  635c6d62c9269029df3e6057
+    ac
+    8ac07980a2538da61bf9fdb8f9791197;
+  c87638f508046733d9ff61cd
+    bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6
+    4e9a7999789a6d1041fd26295aaa4942;
+  21b7f65b000961040ef2f9b2
+    fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5
+    ffbaaeeaf8f93c7c71c7708e21043c32;
+  4215abd6b3ad54ef
+    ""
+    d3fc1c69dbbe8a358f5f968f8e60047e;
+  c9a38378c5b93bf4
+    f2
+    d37b1e960767df9d502e6c942e90f39d;
+  aad2605faee2b03f
+    b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219
+    55f8a2b6e7bd774ff32cac26cee4f1ef;
+  bfb474fd71d891f2
+    4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9f
+    d33ece086863448e6714580ec9f8d267;
+  c2712a199e533fa9156308cdec3f768281
+    ""
+    9b818524f8ebef2f840938b85c30b9b8;
+  e040a9b9a222bd689aef66f5306ceb0c6b
+    08
+    44a2b05a0953086b802e5dfbccef8691;
+  ac8b0a22260c571b4a42bb8fdb233bfa6a
+    5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65
+    ffa9d762bb11005e32a5747de41738c2;
+  b9aca338527ef19b09c063c46f88de9fd4
+    1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d
+    4e21bb0835d28d84b50e6db35757d672;
+}
index 7b75304..61934c4 100644 (file)
@@ -60,3 +60,30 @@ des {
 
   0e329232ea6d0d73 8787878787878787 0000000000000000;
 }
+
+des-cmac {
+  bef260d7bcda1635
+    ""
+    38adff25bb9e255b;
+  47d348b7551195e7
+    70
+    a70403c9dc15813e;
+  22907dd1dff7dac5
+    c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed
+    5e05047524a92169;
+  810c9b689daaa906
+    0d2d4b6003062365b0a54364c76c160f11896c
+    d345f04671d2f856;
+  4794846ecfa14a
+    ""
+    d1f159eb76e2dcb3;
+  7130c9f1371206
+    34
+    1728ecf20653375b;
+  c9519848a877ff
+    77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4
+    6f19d2ec30d3057a;
+  ba234085406a61
+    36512061f7080cc07df0591d8fa21f2dd88374
+    2b5a2cec413de519;
+}
index f1adb1a..b441d69 100644 (file)
@@ -39,3 +39,83 @@ des3 {
   0123456789abcdeffedcba987654321089abcdef01234567
        0123456789abcde7 de0b7c06ae5e0ed5;
 }
+
+des3-cmac {
+  ## Examples from NIST.
+
+  0123456789abcdef23456789abcdef01
+    ""
+    79ce52a7f786a960;
+  0123456789abcdef23456789abcdef01
+    6bc1bee22e409f96e93d7e117393172a
+    cc18a0b79af2413b;
+  0123456789abcdef23456789abcdef01
+    6bc1bee22e409f96e93d7e117393172aae2d8a57
+    c06d377ecd101969;
+  0123456789abcdef23456789abcdef01
+    6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51
+    9cd33580f9b64dfb;
+
+  0123456789abcdef23456789abcdef01456789abcdef0123
+    ""
+    7db0d37df936c550;
+  0123456789abcdef23456789abcdef01456789abcdef0123
+    6bc1bee22e409f96e93d7e117393172a
+    30239cf1f52e6609;
+  0123456789abcdef23456789abcdef01456789abcdef0123
+    6bc1bee22e409f96e93d7e117393172aae2d8a57
+    6c9f3ee4923f6be2;
+  0123456789abcdef23456789abcdef01456789abcdef0123
+    6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51
+    99429bd0bf7904e5;
+
+  ## Locally generated tests.
+  60d7bcda163547d348b7551195e7
+    ""
+    97b9dfb874462432;
+  7022907dd1dff7dac5c9941d26d0
+    c6
+    f403026117612b0e;
+  eb14ad568f86edd1dc9268eeee53
+    3285a6ed810c9b689daaa9060d2d4b6003062365b0a54364
+    4e0fbacfa297003b;
+  c76c160f11896c4794846ecfa14a
+    7130c9f137120634c9519848a877ff77bf7919
+    19d5f833e07e2015;
+  2a5b50ade5d9cd73
+    ""
+    ed38c0855386e014;
+  9a3d1f337f29549e
+    6b
+    c86e5386ee0e7b04;
+  0d27a4ba23408540
+    6a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8
+    d5306ab188df59b5;
+  e160ad10997a2163
+    5c6d62c9269029df3e6057acc87638f5080467
+    b6fc8dee2287152c;
+  33d9ff61cdbda3b3e9878731ebfedd47
+    ""
+    349cd58ebc44cb39;
+  05e505da1435dceaa7b1cc49ae1d50c3
+    82
+    a8322086e22dbed8;
+  01a894476b3f102b752eb9529533966f
+    27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b54
+    35c70f6e2cbab396;
+  2cde52ebfda19d0ccc520f215eb57bb3
+    a4f3ebbbb18ac6c95a97a48030370c33d090c5
+    639e5e64b410da07;
+  4215abd6b3ad54efc9a38378c5b93bf4f2aad2605f
+    ""
+    41240c9c71435050;
+  aee2b03fb648e27fff63102758fe2b69ac26afa334
+    98
+    ab4c2c83747e8c5b;
+  29b94586306fed54154f8f28523c03d4de16001578
+    46b710ee72807a2219bfb474fd71d891f24bb65d1563259f
+    eff715a559241957;
+  9eb53b571ea629c54d57dd2d42f70800df9fcbaca4
+    8b77dba189196d1ebba10b0467cb9fc2712a19
+    2753a7135b48898f;
+}
index 0f64086..03af5fd 100644 (file)
@@ -20,3 +20,54 @@ desx {
   00451338957377 4e6f772069732074 3fa40e8a984d4815;
   0123456789abcdef 4e6f772069732074 3fa40e8a984d4815;
 }
+
+desx-cmac {
+  60d7bcda163547d348b7551195e770
+    ""
+    a63cd9292fdf838b;
+  22907dd1dff7dac5c9941d26d0c6eb
+    14
+    a750bb7618266464;
+  ad568f86edd1dc9268eeee533285a6
+    ed810c9b689daaa9060d2d4b6003062365b0a54364c76c16
+    46adc2fa0e79b3b1;
+  0f11896c4794846ecfa14a7130c9f1
+    37120634c9519848a877ff77bf79192a5b50ad
+    68ba5dd6b52f40fb;
+  e5d9cd739a3d1f33
+    ""
+    3480b2e14686a332;
+  7f29549e6b0d27a4
+    ba
+    9bbb98b5d49df72c;
+  234085406a613651
+    2061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10
+    f2c52f3919204c2b;
+  997a21635c6d62c9
+    269029df3e6057acc87638f508046733d9ff61
+    e5acddb871d45625;
+  cdbda3b3e9878731ebfedd4705e505da
+    ""
+    08febcce60b0e724;
+  1435dceaa7b1cc49ae1d50c38201a894
+    47
+    80bdb1521243c0b1;
+  6b3f102b752eb9529533966f27043eb6
+    21b7f65b000961040ef2f9b2fc5fa450727a9b542cde52eb
+    86e00e79a5a63fc9;
+  fda19d0ccc520f215eb57bb3a4f3ebbb
+    b18ac6c95a97a48030370c33d090c54215abd6
+    9b4ee9b29a9da89c;
+  b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648
+    ""
+    00413cee3fc9338f;
+  e27fff63102758fe2b69ac26afa3349829b94586306fed
+    54
+    f0bda4592cdc8ed1;
+  154f8f28523c03d4de1600157846b710ee72807a2219bf
+    b474fd71d891f24bb65d1563259f9eb53b571ea629c54d57
+    88158a6ce8f67fb2;
+  dd2d42f70800df9fcbaca48b77dba189196d1ebba10b04
+    67cb9fc2712a199e533fa9156308cdec3f7682
+    ebda61b856727ef6;
+}
index c0b928d..4853f84 100644 (file)
@@ -24,3 +24,18 @@ idea {
   729a27ed8f5c3e8baf16560d14c90b43 d53fabbf94ff8b5f 1d0cb2af1654820a;
   729a27ed8f5c3e8baf16560d14c90b43 df8c6fc637e3dad1 29358cc6c83828ae;
 }
+
+idea-cmac {
+  e4bef260d7bcda163547d348b7551195
+    ""
+    2a288096bbfd3366;
+  e77022907dd1dff7dac5c9941d26d0c6
+    eb
+    2f7fb9948ff504c6;
+  14ad568f86edd1dc9268eeee533285a6
+    ed810c9b689daaa9060d2d4b6003062365b0a54364c76c16
+    d077db9252901d26;
+  0f11896c4794846ecfa14a7130c9f137
+    120634c9519848a877ff77bf79192a5b50ade5
+    c17895f93dd73a8a;
+}
diff --git a/symm/t/mars.local b/symm/t/mars.local
new file mode 100644 (file)
index 0000000..941b70b
--- /dev/null
@@ -0,0 +1,52 @@
+### Local tests for Mars.
+
+mars-cmac {
+  60d7bcda163547d348b75511
+    ""
+    35a1192271ad4f717fe9e5ce36550ccc;
+  95e77022907dd1dff7dac5c9
+    94
+    79d05cda7236e8a9038a3e87d6dd590d;
+  1d26d0c6eb14ad568f86edd1
+    dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1
+    04093d618ec9a9f929abceba0ea5d6a5;
+  37120634c9519848a877ff77
+    bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8f
+    0436ec24f98dbf64019710d997ca79ad;
+  a21f2dd88374d8cde8e160ad10997a21635c6d62
+    ""
+    51be3cd07c56c6f821f8261bbf55fa38;
+  c9269029df3e6057acc87638f508046733d9ff61
+    cd
+    c29104d9daa7eb4abadd817b6890df83;
+  bda3b3e9878731ebfedd4705e505da1435dceaa7
+    b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b54
+    6b2daa274c101b703e7cca9de8608b13;
+  2cde52ebfda19d0ccc520f215eb57bb3a4f3ebbb
+    b18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e2
+    de39e39bd3108b76ec6c4c68a923ecfc;
+  7fff63102758fe2b
+    ""
+    db668c175219b873ce67bfee1bf797dc;
+  69ac26afa3349829
+    b9
+    d8e6cec8197a0d3b02b973e0b8821048;
+  4586306fed54154f
+    8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42
+    1fef4ac7afbf6a5b2e8c6eb271a6c73c;
+  f70800df9fcbaca4
+    8b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66
+    bdc7b92cd3b6b1f19165fa1452144363;
+  f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b
+    ""
+    baf27c811850b45c6165fa5f28c558ea;
+  6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65
+    b9
+    c838ff7ffa0b020de74cdf1bc6d9cb1b;
+  aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf3
+    0f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa92
+    3834f582405017c74df2a58f50896bbe;
+  1451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e61766
+    9c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb6
+    797407de4940048d366f408567a0b4ca;
+}
index 0764732..f1e7296 100644 (file)
@@ -8,3 +8,18 @@ noekeon {
   ba6933819299c71699a99f08f678178b
     52f88a7b283c1f7bdf7b6faa5011c7d8 5096f2bfc82ae6e2d9495515c277fa70;
 }
+
+noekeon-cmac {
+  e4bef260d7bcda163547d348b7551195
+    ""
+    2863ef2fdd68856576cdd771bfa6f2d5;
+  e77022907dd1dff7dac5c9941d26d0c6
+    eb
+    f8e7683bb1eaa6647a054678315b5eda;
+  14ad568f86edd1dc9268eeee533285a6
+    ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a8
+    0a792a2d00ebcf99531795f4b5014e2e;
+  77ff77bf79192a5b50ade5d9cd739a3d
+    1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10
+    c123e79e5caf935e4534444d32d814d3;
+}
index ed90d3f..642c5cb 100644 (file)
@@ -11,3 +11,54 @@ rc2 {
    88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e 129
    0000000000000000 5b78d3a43dfff1f1;
 }
+
+rc2-cmac {
+  60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268ee
+    ""
+    994f0987c07cbba3;
+  ee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a71
+    30
+    93e320d01033928d;
+  c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085
+    406a6136512061f7080cc07df0591d8fa21f2dd88374d8cd
+    ba4c9972985a3777;
+  e8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731eb
+    fedd4705e505da1435dceaa7b1cc49ae1d50c3
+    fb945bb5060a692c;
+  8201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa33498
+    ""
+    33d92d711438bf90;
+  29b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a
+    22
+    d387a2b3add24161;
+  260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22b
+    b02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2a
+    200579382f8fefd7;
+  ebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98
+    ef1f0446b42fb144d44b6d00f06dc188d472a7
+    72b14ddabaa01c99;
+  84e0c6f21195a3b9f4ae985511265febd11c16
+    ""
+    35d8b20b8aedd4c5;
+  4720eef9eb1c8dd0b00951f284649016ed0045
+    63
+    3c8051aab08b5e2a;
+  31854bc78bf43966eb0cfa9138ddc399084456
+    08fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126
+    d71ceb7b023f4a2a;
+  b807e6daa089c3f9099c5ffb824173d7634c04
+    226f30cbb7f0e4a973a8cd190107314717a774
+    7cb1fd4850d2b1cb;
+  56f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9b
+    ""
+    8db7f9520ec921d2;
+  c597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9c
+    e0
+    53c35ba18d421787;
+  21a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18c
+    bfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458
+    d6409d3b48a62658;
+  cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957
+    f4b03cf43e89957f9a3e8128f8743d16687b7b
+    9ffecd00a5ce33b6;
+}
index e7a02c9..2c58adf 100644 (file)
@@ -13,3 +13,54 @@ rc5 {
   dc49db1375a5584f6485b413b5f12baf 2f42b3b70369fc92 65c178b284d197cc;
   5269f149d41ba0152497574d7f153125 65c178b284d197cc eb44e415da319824;
 }
+
+rc5-cmac {
+  60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057
+    ""
+    daf5b15f8e1e563c;
+  acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed5415
+    4f
+    da179047660f232b;
+  8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a
+    96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b9
+    0bc5dfb1ac40f05c;
+  7e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a8744
+    98ad0abef8bc4fcb70e27e98ef1f0446b42fb1
+    ba244301c8380eac;
+  44d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff677
+    ""
+    4c21b877018c36b9;
+  8554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d1
+    7d
+    3806f9d4de532103;
+  4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c
+    3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac8
+    a23a44e7657e986c;
+  61a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cf
+    f206877de69146acc3ab6cf8556b7aa7769459
+    e4b7b2e862a7a773;
+  48d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee475
+    ""
+    f0b878ae4b245d7a;
+  8a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e
+    0c
+    6f07948d34c807ed;
+  536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1
+    a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551c
+    3b56f732d29bcda8;
+  a4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb2384
+    1da1ae8f4ae480cda98ad6cf2bacf6f9fd3f82
+    28c46ab756a75864;
+  1330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f1
+    ""
+    08523dfcb089cd8c;
+  6f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59c
+    c7
+    26a7e390109474a1;
+  83443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae648
+    25ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099
+    841195a80291401c;
+  f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8
+    e9002926ad0284c738f4cb0f58a1e34c8b15ad
+    029a65f6ecedeaec;
+}
diff --git a/symm/t/rijndael.local b/symm/t/rijndael.local
new file mode 100644 (file)
index 0000000..053a0d4
--- /dev/null
@@ -0,0 +1,94 @@
+### Local tests for Rijndael.
+
+rijndael-cmac {
+  ## NIST examples.
+
+  2b7e151628aed2a6abf7158809cf4f3c
+    ""
+    bb1d6929e95937287fa37d129b756746;
+  2b7e151628aed2a6abf7158809cf4f3c
+    6bc1bee22e409f96e93d7e117393172a
+    070a16b46b4d4144f79bdd9dd04a287c;
+  2b7e151628aed2a6abf7158809cf4f3c
+    6bc1bee22e409f96e93d7e117393172aae2d8a57
+    7d85449ea6ea19c823a7bf78837dfade;
+  2b7e151628aed2a6abf7158809cf4f3c
+    6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710
+    51f0bebf7e3b9d92fc49741779363cfe;
+
+  8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
+    ""
+    d17ddf46adaacde531cac483de7a9367;
+  8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
+    6bc1bee22e409f96e93d7e117393172a
+    9e99a7bf31e710900662f65e617c5184;
+  8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
+    6bc1bee22e409f96e93d7e117393172aae2d8a57
+    3d75c194ed96070444a9fa7ec740ecf8;
+  8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
+    6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710
+    a1d5df0eed790f794d77589659f39a11;
+
+  603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4
+    ""
+    028962f61b7bf89efc6b551f4667d983;
+  603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4
+    6bc1bee22e409f96e93d7e117393172a
+    28a7023f452e8f82bd4bf28d8c37c35c;
+  603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4
+    6bc1bee22e409f96e93d7e117393172aae2d8a57
+    156727dc0878944a023c1fe03bad6d93;
+  603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4
+    6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710
+    e1992190549f6ed5696a2c056c315410;
+
+  ## Locally generated tests.
+  60d7bcda163547d348b7551195e77022
+    ""
+    63f719651118fd4d45cb4feebc3150cb;
+  907dd1dff7dac5c9941d26d0c6eb14ad
+    56
+    bc9d9dfba6e312cfe8e6c500a1d805d3;
+  8f86edd1dc9268eeee533285a6ed810c
+    9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77
+    ba66e97ee7b233119abc32fa42be9401;
+  bf79192a5b50ade5d9cd739a3d1f337f
+    29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21
+    a51011f5c5d190016cf3e9db6fb32fbc;
+  635c6d62c9269029df3e6057acc87638f5080467
+    ""
+    9285e3dc234cbd47605641edd2052999;
+  33d9ff61cdbda3b3e9878731ebfedd4705e505da
+    14
+    edc6f130780024d1b8b18361790d949c;
+  35dceaa7b1cc49ae1d50c38201a894476b3f102b
+    752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3
+    ac7f798e3227ecb5e4d868c6f07ce3d0;
+  a4f3ebbbb18ac6c95a97a48030370c33d090c542
+    15abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829
+    9045fe42a3307e0d86fa17dbaa73196b;
+  b94586306fed54154f8f28523c03d4de1600157846b710ee72807a22
+    ""
+    b74dbdd96ca8714c2223ce172d7c5541;
+  19bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d
+    42
+    bcbf74240e12721322ac24676c8eeb16;
+  f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e
+    533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5c
+    1889506d1415435dbc580f7b05c1c2e4;
+  fb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc81517
+    84873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6
+    ccf79bcc9696a3887f23f791aa3fbafa;
+  eabdff3bcd211499268878db
+    ""
+    72c93457d9e50f9ce47227ce159722c7;
+  f30f1dad89d4b9b12012e471
+    3d
+    63c431d9cc49118b4af79b5dbf2efded;
+  f46795630e7952d22bb02d71
+    00b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da0
+    86b6a12fb898bf6a4cad2052a70864ad;
+  8da3aefc5f8584b7c5e61766
+    9c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb6
+    3a2d6cd3d65ba29059613d7e6b6e1278;
+}
index d7732ff..1ace8b1 100644 (file)
@@ -2882,3 +2882,54 @@ rijndael192 {
        df6e46c2dbf69f357bbe22bf604efca58a7352a18f41a7ad
        1d5fa8d85dc2428dabb69eb4c9cea7180f2fa554eadb9dc4;
 }
+
+rijndael192-cmac {
+  60d7bcda163547d348b7551195e77022
+    ""
+    60b69a71abf68553087a4635c8f3d6a6445330a424fcd5bc;
+  907dd1dff7dac5c9941d26d0c6eb14ad
+    56
+    a70f592cc5ea00d17b15fa9810fd694c21e9df121ef3b4b4;
+  8f86edd1dc9268eeee533285a6ed810c
+    9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba
+    872bf13b5f881a915c9342329f04911369c818c0ea171840;
+  234085406a6136512061f7080cc07df0
+    591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49
+    8b456186aa6c2a0d7595f606dc18e4934435f659d05d8994;
+  ae1d50c38201a894476b3f102b752eb952953396
+    ""
+    2d401a31a7641d7793074c1fd8f49be54d4b542aaefaa85b;
+  6f27043eb621b7f65b000961040ef2f9b2fc5fa4
+    50
+    f6433b85e1c5134170efabaf9787fbd7e65cb12ce129d440;
+  727a9b542cde52ebfda19d0ccc520f215eb57bb3
+    a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f
+    20c4e9333e614096c96a21d83ef6779616d99f93167fd455;
+  8f28523c03d4de1600157846b710ee72807a2219
+    bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f7682
+    a7ae91664738b763e5d45d556edd0b59923f159dc9cea08f;
+  81e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a
+    ""
+    558b741080d1a886fd8798f4100853f2004201a48be08907;
+  42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c
+    03
+    e115710b82135a9cbc43aefae273556dcfb62394c78417a6;
+  7ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9
+    aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b
+    22ac79b7ae3011dc8a14b3516edadac8de849d9599fefa6c;
+  663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef3
+    15d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e4
+    57c8bb706e09c6ac44146a999925abef54403c8e610efca4;
+  7479a684b5aefa69a4cd5214
+    ""
+    afde241e1a29decdd2f924776073a7108b90a02528d9db4a;
+  7ed12ca986981a874498ad0a
+    be
+    37beddab340f4b5245afc8b5a0fd78004ffcdbdd2f3a41e5;
+  f8bc4fcb70e27e98ef1f0446
+    b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc3990844
+    4d27aa546ff3594eeaf076a140cf3e38686d4d9b2d9f75b5;
+  5608fe95e81c2533e31c9c1a
+    9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e
+    3848a7fc35a38ec5c202692eb9cc03067f1e3a587996a2fe;
+}
index 732685f..5513fee 100644 (file)
@@ -2895,3 +2895,54 @@ rijndael256 {
     1188d6578860ceb90a80228c344c3d9e72e775cae5d41b0fd9ff9c60d0898fd0
     ec81f1cda5409281c7b4d5f698b6ca5d0ec79598571237a08a60a4a0724b739a;
 }
+
+rijndael256-cmac {
+  60d7bcda163547d348b7551195e77022
+    ""
+    a45b5e26bf4b809a89993f34d7b96a1518383ae7a57b51c1ac78cb29a1432a2a;
+  907dd1dff7dac5c9941d26d0c6eb14ad
+    56
+    768cdb787a4de07dc2c7ff3c1846d2fbcd1bcf867dbe9f25607cca4443ee25b9;
+  8f86edd1dc9268eeee533285a6ed810c
+    9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd883
+    00c1e6af11c6d84eda40876c32f4467f45a0f9cbf862545bf05487fd06713dad;
+  74d8cde8e160ad10997a21635c6d62c9
+    269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52
+    8f1442e79bfd604a4400d183e4509b454411b03d63dfbae7db2b03c998db8724;
+  ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6
+    ""
+    66129452d7b724416120de9f272b2d531a1cc0faaf945ab3160734ae639483f0;
+  c95a97a48030370c33d090c54215abd6b3ad54ef
+    c9
+    1576f9e568d9bcb014a679b7024aae490080ba401d8808cd9e2b7fe57f0eab66;
+  a38378c5b93bf4f2aad2605faee2b03fb648e27f
+    ff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2
+    e2ebc3f8e727de99c6fd46bef8e7df52599e0f8de53567bdfbfd2b52b907e7ff;
+  712a199e533fa9156308cdec3f768281e040a9b9
+    a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c4
+    afc6c9c54cbe70a0e7fa6146a5ed4ae9ce68a1d609af79708281be0c2715c8fe;
+  6f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad
+    ""
+    39733f351c3e4a5b686ff0a932407c4dc2f41bb387592881b3f92f915ece1cd0;
+  89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20
+    a8
+    b6caa7f9735ae9ea8083faa068dc284cd5d14332984ced7f46d3e93bddd7fac6;
+  f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f
+    1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abe
+    7fcf4a19556a8ba23df01de57087481a425410f3f092e4f801a681625b713935;
+  f8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784
+    e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c
+    6377ee34258253260374a4654c8bd727bdef4e5921e59a770a8a6178bc61620f;
+  5ffb824173d7634c04226f30
+    ""
+    4ad4651e26e46ac9b3890fc7adae23cbfcf808d96586a4c88a27c6a8533b51c3;
+  cbb7f0e4a973a8cd19010731
+    47
+    18566621f2c24c55bd880e8603461de80fcf01ceeda7bb7aedb4253204372e14;
+  17a77456f3ff669c732b58db
+    8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a4
+    16a524c850d351e451cd482587f4f622542283b085e16ba423c8c54085b08350;
+  58cb948bdd409b687fa3a682
+    7b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d
+    3e8977f205b75e6fae2105cbb8cdb26f3e8057957ce69b9e6be62362bd225924;
+}
index 15f75ee..8d869af 100644 (file)
@@ -11,3 +11,30 @@ safersk {
   0102030405060708 0102030405060708 60d04ad7c49b8ded;
   100f0e0d0c0b0a090807060504030201 0102030405060708 b260740f80d2445d;
 }
+
+safer-cmac {
+  bef260d7bcda163547d348b7551195e7
+    ""
+    b9f9da8b0465e894;
+  7022907dd1dff7dac5c9941d26d0c6eb
+    14
+    cf652451ff1ea9e1;
+  ad568f86edd1dc9268eeee533285a6ed
+    810c9b689daaa9060d2d4b6003062365b0a54364c76c160f
+    5056bba2984b1682;
+  11896c4794846ecfa14a7130c9f13712
+    0634c9519848a877ff77bf79192a5b50ade5d9
+    2c9685d013b7efff;
+  cd739a3d1f337f29
+    ""
+    b7c678291a02ea9e;
+  549e6b0d27a4ba23
+    40
+    0cb9e87774a1ef4a;
+  85406a6136512061
+    f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a
+    0a9d5c038c99f36d;
+  21635c6d62c92690
+    29df3e6057acc87638f508046733d9ff61cdbd
+    fe61dbd63946d430;
+}
index 8c42f58..83233e1 100644 (file)
@@ -1 +1,28 @@
-### No tests here.  See `safer' instead.
+### Only modes here.  See `safersk' for the blockcipher test vectors.
+
+safersk-cmac {
+  bef260d7bcda163547d348b7551195e7
+    ""
+    9ba8f2c1b6cfeb77;
+  7022907dd1dff7dac5c9941d26d0c6eb
+    14
+    37dcfeffa9f5744b;
+  ad568f86edd1dc9268eeee533285a6ed
+    810c9b689daaa9060d2d4b6003062365b0a54364c76c160f
+    05bf5b261fbd88de;
+  11896c4794846ecfa14a7130c9f13712
+    0634c9519848a877ff77bf79192a5b50ade5d9
+    0ee50cf1eb23cc77;
+  cd739a3d1f337f29
+    ""
+    975807086410e7e5;
+  549e6b0d27a4ba23
+    40
+    b5b26235e6a34f78;
+  85406a6136512061
+    f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a
+    b98cae59f10f22cd;
+  21635c6d62c92690
+    29df3e6057acc87638f508046733d9ff61cdbd
+    d85e3e89ce01118c;
+}
diff --git a/symm/t/serpent.local b/symm/t/serpent.local
new file mode 100644 (file)
index 0000000..60bc1a5
--- /dev/null
@@ -0,0 +1,52 @@
+### Local tests for Serpent.
+
+serpent-cmac {
+  60d7bcda163547d348b7551195
+    ""
+    837d499a07a2518f04835f42131f5831;
+  e77022907dd1dff7dac5c9941d
+    26
+    db320e0bfa3ebb37c57ea0c60576c393;
+  d0c6eb14ad568f86edd1dc9268
+    eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206
+    0c9a89126f4cad2192ffa4a7c0ca9d68;
+  34c9519848a877ff77bf79192a
+    5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8
+    324c00f44175151d1a2bf9342cf4ef93;
+  8374d8cde8e160ad10997a21
+    ""
+    829328f2a128fdc7c48a7714a5f66acf;
+  635c6d62c9269029df3e6057
+    ac
+    28d493c79ae17e3c1480c921bf4e6d2e;
+  c87638f508046733d9ff61cd
+    bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6
+    63c9c5f2dcd9e476c72dee514b84d6f9;
+  21b7f65b000961040ef2f9b2
+    fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5
+    ca4332a12b4981383e8548d4beacce63;
+  4215abd6b3ad54ef
+    ""
+    51a036a675d7fd48aea66b5fea454712;
+  c9a38378c5b93bf4
+    f2
+    5b8642963edfd3fc3537cf7a53ffdb72;
+  aad2605faee2b03f
+    b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219
+    40bbb9860714b5c28a127928704b04f2;
+  bfb474fd71d891f2
+    4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9f
+    b59d4d54d7846d564c8e65a6ae652a74;
+  c2712a199e533fa9156308cdec3f768281
+    ""
+    9af557733264840dca5e8260f160ffb4;
+  e040a9b9a222bd689aef66f5306ceb0c6b
+    08
+    ca7d2919e279fd3caf61e6ff35bb7803;
+  ac8b0a22260c571b4a42bb8fdb233bfa6a
+    5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65
+    33036f52f479780af315c2de95e9dc86;
+  b9aca338527ef19b09c063c46f88de9fd4
+    1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d
+    8ef0d030ddb7bd4c700e15efc563f5cf;
+}
index 63ac0cb..a43c250 100644 (file)
@@ -99,3 +99,18 @@ skipjack {
   06e3c0e541f4aae6fe93 40009f8a465a9feb 0e7aace421bc79d8;
   2ea09f1cc89e064f09bc 543208b05bfa3858 a95d87fad12c3593;
 }
+
+skipjack-cmac {
+  e4bef260d7bcda163547
+    ""
+    5a0fba9745b5a83e;
+  d348b7551195e7702290
+    7d
+    8610508eeee08d29;
+  d1dff7dac5c9941d26d0
+    c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689d
+    46b1504483d84dff;
+  aaa9060d2d4b60030623
+    65b0a54364c76c160f11896c4794846ecfa14a
+    cffcc55881902725;
+}
index 7b348e2..49cf085 100644 (file)
@@ -521,3 +521,42 @@ square {
   00000000000000000000000000000001
        0f1e2d3c4b5a69788796a5b4c3d2e1f0 69bd984641e0aa887bc23738f60070db;
 }
+
+square-cmac {
+  f260d7bc
+    ""
+    29984a33657f622352c1ee581eab804e;
+  da163547
+    d3
+    cdc5e3485007695cdeb53ce1e8cec39e;
+  48b75511
+    95e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003
+    7fdd1689e5a004d05b0bc92e3ecc8f16;
+  062365b0
+    a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd
+    95f37b226b5f157fb68c9b235085799a;
+  739a3d1f337f29549e6b0d27
+    ""
+    c48de9e2768ea55c731b65c22052aebd;
+  a4ba234085406a6136512061
+    f7
+    4710b0fec299631f0d53e9ce3b0a172b;
+  080cc07df0591d8fa21f2dd8
+    8374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47
+    88eeeecc2b156790ac07c7c4c7b6c431;
+  05e505da1435dceaa7b1cc49
+    ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a
+    ac18ee08b5e9a21581b33f73b63e9a41;
+  9b542cde52ebfda1
+    ""
+    d45f57812f3249ba56239bf41459682c;
+  9d0ccc520f215eb5
+    7b
+    12f4a147fd87d19814850cea849fab85;
+  b3a4f3ebbbb18ac6
+    c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b
+    950e0997bc4188db73c08df2e1e880a6;
+  69ac26afa3349829
+    b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d156325
+    a1fa99cf13347b5b803ccc6c2e183381;
+}
index 9eec55d..62516fa 100644 (file)
@@ -72,3 +72,54 @@ tea {
   c86c21d8c26dc291f662c8f2fe79b74b 0993d3b68c1d4a5d d33c2e41dd5da131;
   af4f4615c7c298639b9728251991419f 1e268f9e710313b5 a9478f8cf88b7e10;
 }
+
+tea-cmac {
+  60d7bcda163547d348b7551195
+    ""
+    c9d9c939fb01921a;
+  e77022907dd1dff7dac5c9941d
+    26
+    71bafd3a810cb7fe;
+  d0c6eb14ad568f86edd1dc9268
+    eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0
+    fa579abf1f086cd6;
+  a54364c76c160f11896c479484
+    6ecfa14a7130c9f137120634c9519848a877ff
+    de36e64b775dcb5c;
+  77bf79192a5b50
+    ""
+    7d4dff89fcd86251;
+  ade5d9cd739a3d
+    1f
+    8ebb09e514e0fff8;
+  337f29549e6b0d
+    27a4ba234085406a6136512061f7080cc07df0591d8fa21f
+    c079db9ba9f93c6d;
+  2dd88374d8cde8
+    e160ad10997a21635c6d62c9269029df3e6057
+    c57695c67af0e83c;
+  acc87638f508046733d9
+    ""
+    26c7bc682ced6dd4;
+  ff61cdbda3b3e9878731
+    eb
+    d26aadbc23507937;
+  fedd4705e505da1435dc
+    eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533
+    2b121397d4ba05e3;
+  966f27043eb621b7f65b
+    000961040ef2f9b2fc5fa450727a9b542cde52
+    06d48234005d0d34;
+  ebfda19d0ccc520f21
+    ""
+    ddc6b8ce28333159;
+  5eb57bb3a4f3ebbbb1
+    8a
+    e5a427c9e3c9b30d;
+  c6c95a97a48030370c
+    33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260
+    3994c72240c20e84;
+  5faee2b03fb648e27f
+    ff63102758fe2b69ac26afa3349829b9458630
+    ac308d1e150a1c6e;
+}
diff --git a/symm/t/twofish.local b/symm/t/twofish.local
new file mode 100644 (file)
index 0000000..5aa904a
--- /dev/null
@@ -0,0 +1,52 @@
+### Local tests for Twofish.
+
+twofish-cmac {
+  60d7bcda163547d348b7551195
+    ""
+    754e3b8b4c2532dd6d26b8d2f84c5052;
+  e77022907dd1dff7dac5c9941d
+    26
+    285e8d83398954587754b4811af4dab0;
+  d0c6eb14ad568f86edd1dc9268
+    eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206
+    8f5bfbfe9492043376e871ff2174ab5b;
+  34c9519848a877ff77bf79192a
+    5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8
+    1145ad608df01125e831efceb693c24b;
+  8374d8cde8e160ad10997a21
+    ""
+    1406392a843cc373790cd8696e89d1ea;
+  635c6d62c9269029df3e6057
+    ac
+    70ba3b7789c8bae0f1f51219e9730125;
+  c87638f508046733d9ff61cd
+    bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6
+    6fa25a24102c74af333d7d00e814c926;
+  21b7f65b000961040ef2f9b2
+    fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5
+    fa27b530c2b27564a3be2411d2eca2ff;
+  4215abd6b3ad54ef
+    ""
+    ed98c8e1a4135fa9bbde6733062c0be7;
+  c9a38378c5b93bf4
+    f2
+    ebc7a731525279b9f3432af13aa735d1;
+  aad2605faee2b03f
+    b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219
+    ad157b3ad3c9b514307a6075859baa83;
+  bfb474fd71d891f2
+    4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9f
+    2c6b7e9737106b483e1ca8497e995b5a;
+  c2712a199e533fa9156308cdec3f768281
+    ""
+    0b25455053592925387a5cab03aa3418;
+  e040a9b9a222bd689aef66f5306ceb0c6b
+    08
+    795defa6334cf18ed76ffa59a9ef6500;
+  ac8b0a22260c571b4a42bb8fdb233bfa6a
+    5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65
+    7a1639ba51eb2aeaf469d4980148378f;
+  b9aca338527ef19b09c063c46f88de9fd4
+    1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d
+    dabc6ab5c4f7051e8211bcafd27650f6;
+}
index be34740..a8f2738 100644 (file)
@@ -68,3 +68,54 @@ xtea {
   c86c21d8c26dc291f662c8f2fe79b74b 0993d3b68c1d4a5d 2b4195c3d67e3f99;
   af4f4615c7c298639b9728251991419f 1e268f9e710313b5 2536ccd8fdfe30e1;
 }
+
+xtea-cmac {
+  60d7bcda163547d348b7551195
+    ""
+    3fe52353f9b144ae;
+  e77022907dd1dff7dac5c9941d
+    26
+    809e38cc35e3a145;
+  d0c6eb14ad568f86edd1dc9268
+    eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0
+    9e781632642b42cd;
+  a54364c76c160f11896c479484
+    6ecfa14a7130c9f137120634c9519848a877ff
+    8d187ce6f32516ae;
+  77bf79192a5b50
+    ""
+    12bacc0346a97c7f;
+  ade5d9cd739a3d
+    1f
+    76efca6f4ea48f3a;
+  337f29549e6b0d
+    27a4ba234085406a6136512061f7080cc07df0591d8fa21f
+    390ba4bcc9d100f3;
+  2dd88374d8cde8
+    e160ad10997a21635c6d62c9269029df3e6057
+    666111e472d8cdfd;
+  acc87638f508046733d9
+    ""
+    2b1ff3b380aa5d5a;
+  ff61cdbda3b3e9878731
+    eb
+    85351b61c26c94cf;
+  fedd4705e505da1435dc
+    eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533
+    d8a892f0975b7e2c;
+  966f27043eb621b7f65b
+    000961040ef2f9b2fc5fa450727a9b542cde52
+    85b42005a520b9fc;
+  ebfda19d0ccc520f21
+    ""
+    cf0f227f8b2a8b46;
+  5eb57bb3a4f3ebbbb1
+    8a
+    a0cdc4acc3d77c92;
+  c6c95a97a48030370c
+    33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260
+    ac879bd822cf405d;
+  5faee2b03fb648e27f
+    ff63102758fe2b69ac26afa3349829b9458630
+    295b9c45cd0a8bab;
+}
diff --git a/utils/advmodes b/utils/advmodes
new file mode 100755 (executable)
index 0000000..96e5f5b
--- /dev/null
@@ -0,0 +1,310 @@
+#! /usr/bin/python
+
+from sys import argv
+from struct import pack
+from itertools import izip
+import catacomb as C
+
+R = C.FibRand(0)
+
+###--------------------------------------------------------------------------
+### Utilities.
+
+def combs(things, k):
+  ii = range(k)
+  n = len(things)
+  while True:
+    yield [things[i] for i in ii]
+    for j in xrange(k):
+      if j == k - 1: lim = n
+      else: lim = ii[j + 1]
+      i = ii[j] + 1
+      if i < lim:
+        ii[j] = i
+        break
+      ii[j] = j
+    else:
+      return
+
+POLYMAP = {}
+
+def poly(nbits):
+  try: return POLYMAP[nbits]
+  except KeyError: pass
+  base = C.GF(0).setbit(nbits).setbit(0)
+  for k in xrange(1, nbits, 2):
+    for cc in combs(range(1, nbits), k):
+      p = base + sum(C.GF(0).setbit(c) for c in cc)
+      if p.irreduciblep(): POLYMAP[nbits] = p; return p
+  raise ValueError, nbits
+
+def Z(n):
+  return C.ByteString.zero(n)
+
+def mul_blk_gf(m, x, p): return ((C.GF.loadb(m)*x)%p).storeb((p.nbits + 6)/8)
+
+def with_lastp(it):
+  it = iter(it)
+  try: j = next(it)
+  except StopIteration: raise ValueError, 'empty iter'
+  lastp = False
+  while not lastp:
+    i = j
+    try: j = next(it)
+    except StopIteration: lastp = True
+    yield i, lastp
+
+def safehex(x):
+  if len(x): return hex(x)
+  else: return '""'
+
+def keylens(ksz):
+  sel = []
+  if isinstance(ksz, C.KeySZSet): kk = ksz.set
+  elif isinstance(ksz, C.KeySZRange): kk = range(ksz.min, ksz.max, ksz.mod)
+  elif isinstance(ksz, C.KeySZAny): kk = range(64); sel = [0]
+  kk = list(kk); kk = kk[:]
+  n = len(kk)
+  while n and len(sel) < 4:
+    i = R.range(n)
+    n -= 1
+    kk[i], kk[n] = kk[n], kk[i]
+    sel.append(kk[n])
+  return sel
+
+def pad0star(m, w):
+  n = len(m)
+  if not n: r = w
+  else: r = (-len(m))%w
+  if r: m += Z(r)
+  return C.ByteString(m)
+
+def pad10star(m, w):
+  r = w - len(m)%w
+  if r: m += '\x80' + Z(r - 1)
+  return C.ByteString(m)
+
+def ntz(i):
+  j = 0
+  while (i&1) == 0: i >>= 1; j += 1
+  return j
+
+def blocks(x, w):
+  v, i, n = [], 0, len(x)
+  while n - i > w:
+    v.append(C.ByteString(x[i:i + w]))
+    i += w
+  return v, C.ByteString(x[i:])
+
+EMPTY = C.bytes('')
+
+def blocks0(x, w):
+  v, tl = blocks(x, w)
+  if len(tl) == w: v.append(tl); tl = EMPTY
+  return v, tl
+
+CUSTOM = {}
+
+###--------------------------------------------------------------------------
+### RC6.
+
+class RC6Cipher (type):
+  def __new__(cls, w, r):
+    name = 'rc6-%d/%d' % (w, r)
+    me = type(name, (RC6Base,), {})
+    me.name = name
+    me.r = r
+    me.w = w
+    me.blksz = w/2
+    me.keysz = C.KeySZRange(me.blksz, 1, 255, 1)
+    return me
+
+def rotw(w):
+  return w.bit_length() - 1
+
+def rol(w, x, n):
+  m0, m1 = C.MP(0).setbit(w - n) - 1, C.MP(0).setbit(n) - 1
+  return ((x&m0) << n) | (x >> (w - n))&m1
+
+def ror(w, x, n):
+  m0, m1 = C.MP(0).setbit(n) - 1, C.MP(0).setbit(w - n) - 1
+  return ((x&m0) << (w - n)) | (x >> n)&m1
+
+class RC6Base (object):
+
+  ## Magic constants.
+  P400 = C.MP(0xb7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfef324e7738926cfbe5f4bf8d8d8c31d763da06)
+  Q400 = C.MP(0x9e3779b97f4a7c15f39cc0605cedc8341082276bf3a27251f86c6a11d0c18e952767f0b153d27b7f0347045b5bf1827f0188)
+
+  def __init__(me, k):
+
+    ## Build the magic numbers.
+    P = me.P400 >> (400 - me.w)
+    if P%2 == 0: P += 1
+    Q = me.Q400 >> (400 - me.w)
+    if Q%2 == 0: Q += 1
+    M = C.MP(0).setbit(me.w) - 1
+
+    ## Convert the key into words.
+    wb = me.w/8
+    c = (len(k) + wb - 1)/wb
+    kb, ktl = blocks(k, me.w/8)
+    L = map(C.MP.loadl, kb + [ktl])
+    assert c == len(L)
+
+    ## Build the subkey table.
+    me.d = rotw(me.w)
+    n = 2*me.r + 4
+    S = [(P + i*Q)&M for i in xrange(n)]
+
+    ##for j in xrange(c):
+    ##  print 'L[%3d] = %s' % (j, hex(L[j]).upper()[2:].rjust(2*wb, '0'))
+    ##for i in xrange(n):
+    ##  print 'S[%3d] = %s' % (i, hex(S[i]).upper()[2:].rjust(2*wb, '0'))
+
+    i = j = 0
+    A = B = C.MP(0)
+
+    for s in xrange(3*max(c, n)):
+      A = S[i] = rol(me.w, S[i] + A + B, 3)
+      B = L[j] = rol(me.w, L[j] + A + B, (A + B)%(1 << me.d))
+      ##print 'S[%3d] = %s' % (i, hex(S[i]).upper()[2:].rjust(2*wb, '0'))
+      ##print 'L[%3d] = %s' % (j, hex(L[j]).upper()[2:].rjust(2*wb, '0'))
+      i = (i + 1)%n
+      j = (j + 1)%c
+
+    ## Done.
+    me.s = S
+
+  def encrypt(me, x):
+    M = C.MP(0).setbit(me.w) - 1
+    a, b, c, d = map(C.MP.loadl, blocks0(x, me.blksz/4)[0])
+    b = (b + me.s[0])&M
+    d = (d + me.s[1])&M
+    ##print 'B = %s' % (hex(b).upper()[2:].rjust(me.w/4, '0'))
+    ##print 'D = %s' % (hex(d).upper()[2:].rjust(me.w/4, '0'))
+    for i in xrange(2, 2*me.r + 2, 2):
+      t = rol(me.w, 2*b*b + b, me.d)
+      u = rol(me.w, 2*d*d + d, me.d)
+      a = (rol(me.w, a ^ t, u%(1 << me.d)) + me.s[i + 0])&M
+      c = (rol(me.w, c ^ u, t%(1 << me.d)) + me.s[i + 1])&M
+      ##print 'A = %s' % (hex(a).upper()[2:].rjust(me.w/4, '0'))
+      ##print 'C = %s' % (hex(c).upper()[2:].rjust(me.w/4, '0'))
+      a, b, c, d = b, c, d, a
+    a = (a + me.s[2*me.r + 2])&M
+    c = (c + me.s[2*me.r + 3])&M
+    ##print 'A = %s' % (hex(a).upper()[2:].rjust(me.w/4, '0'))
+    ##print 'C = %s' % (hex(c).upper()[2:].rjust(me.w/4, '0'))
+    return C.ByteString(a.storel(me.blksz/4) + b.storel(me.blksz/4) +
+                        c.storel(me.blksz/4) + d.storel(me.blksz/4))
+
+  def decrypt(me, x):
+    M = C.MP(0).setbit(me.w) - 1
+    a, b, c, d = map(C.MP.loadl, blocks0(x, me.blksz/4))
+    c = (c - me.s[2*me.r + 3])&M
+    a = (a - me.s[2*me.r + 2])&M
+    for i in xrange(2*me.r + 1, 1, -2):
+      a, b, c, d = d, a, b, c
+      u = rol(me.w, 2*d*d + d, me.d)
+      t = rol(me.w, 2*b*b + b, me.d)
+      c = ror(me.w, (c - me.s[i + 1])&M, t%(1 << me.d)) ^ u
+      a = ror(me.w, (a - me.s[i + 0])&M, u%(1 << me.d)) ^ t
+    a = (a + s[2*me.r + 2])&M
+    c = (c + s[2*me.r + 3])&M
+    return C.ByteString(a.storel(me.blksz/4) + b.storel(me.blksz/4) +
+                        c.storel(me.blksz/4) + d.storel(me.blksz/4))
+
+for (w, r) in [(8, 16), (16, 16), (24, 16), (32, 16),
+               (32, 20), (48, 16), (64, 16), (96, 16), (128, 16),
+               (192, 16), (256, 16), (400, 16)]:
+  CUSTOM['rc6-%d/%d' % (w, r)] = RC6Cipher(w, r)
+
+###--------------------------------------------------------------------------
+### OMAC (or CMAC).
+
+def omac_masks(E):
+  blksz = E.__class__.blksz
+  p = poly(8*blksz)
+  z = Z(blksz)
+  L = E.encrypt(z)
+  m0 = mul_blk_gf(L, 2, p)
+  m1 = mul_blk_gf(m0, 2, p)
+  return m0, m1
+
+def dump_omac(E):
+  blksz = E.__class__.blksz
+  m0, m1 = omac_masks(E)
+  print 'L = %s' % hex(E.encrypt(Z(blksz)))
+  print 'm0 = %s' % hex(m0)
+  print 'm1 = %s' % hex(m1)
+  for t in xrange(3):
+    print 'v%d = %s' % (t, hex(E.encrypt(C.MP(t).storeb(blksz))))
+    print 'z%d = %s' % (t, hex(omac(E, t, '')))
+
+def omac(E, t, m):
+  blksz = E.__class__.blksz
+  m0, m1 = omac_masks(E)
+  a = Z(blksz)
+  if t is not None: m = C.MP(t).storeb(blksz) + m
+  v, tl = blocks(m, blksz)
+  for x in v: a = E.encrypt(a ^ x)
+  r = blksz - len(tl)
+  if r == 0:
+    a = E.encrypt(a ^ tl ^ m0)
+  else:
+    pad = pad10star(tl, blksz)
+    a = E.encrypt(a ^ pad ^ m1)
+  return a
+
+def cmac(E, m):
+  if VERBOSE: dump_omac(E)
+  return omac(E, None, m),
+
+def cmacgen(bc):
+  return [(0,), (1,),
+          (3*bc.blksz,),
+          (3*bc.blksz - 5,)]
+
+###--------------------------------------------------------------------------
+### Main program.
+
+class struct (object):
+  def __init__(me, **kw):
+    me.__dict__.update(kw)
+
+binarg = struct(mk = R.block, parse = C.bytes, show = safehex)
+intarg = struct(mk = lambda x: x, parse = int, show = None)
+
+MODEMAP = { 'cmac': (cmacgen, [binarg], cmac) }
+
+mode = argv[1]
+bc = None
+for d in CUSTOM, C.gcprps:
+  try: bc = d[argv[2]]
+  except KeyError: pass
+  else: break
+if bc is None: raise KeyError, argv[2]
+if len(argv) == 3:
+  VERBOSE = False
+  gen, argty, func = MODEMAP[mode]
+  print '%s-%s {' % (bc.name, mode)
+  for ksz in keylens(bc.keysz):
+    for argvals in gen(bc):
+      k = R.block(ksz)
+      args = [t.mk(a) for t, a in izip(argty, argvals)]
+      rets = func(bc(k), *args)
+      print '  %s' % safehex(k)
+      for t, a in izip(argty, args):
+        if t.show: print '    %s' % t.show(a)
+      for r, lastp in with_lastp(rets):
+        print '    %s%s' % (safehex(r), lastp and ';' or '')
+  print '}'
+else:
+  VERBOSE = True
+  k = C.bytes(argv[3])
+  gen, argty, func = MODEMAP[mode]
+  args = [t.parse(a) for t, a in izip(argty, argv[4:])]
+  rets = func(bc(k), *args)
+  for r in rets: print hex(r)
+
+###----- That's all, folks --------------------------------------------------