symm/*-def.h: Overhaul encryption mode testing.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 29 Oct 2018 22:48:49 +0000 (22:48 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 25 Nov 2018 11:38:04 +0000 (11:38 +0000)
Introduce a new source file (not part of the library proper) containing
the main code.  The old version only checked that the modes supported
round trips.  This is an improvement in several respects:

  * The per-mode code is now nearly trivial, and specific to the mode in
    question.

  * The new code checks that block-aligned (at least, in the case of ECB
    and CBC) or arbitrarily misaligned (in the case of CFB, OFB,
    counter, and MGF1, which are resumable) splits result in identical
    ciphertexts.

  * The new code can generate and/or check against regression-test
    data (in a binary format, because these can be big for non-resumable
    modes) to prevent cross-version interoperability bugs.  This data is
    generated automatically by `make distdir', and version controlled.

143 files changed:
symm/Makefile.am
symm/cbc-def.h
symm/cfb-def.h
symm/counter-def.h
symm/daftstory.h [deleted file]
symm/ecb-def.h
symm/mgf-def.h
symm/modes-test.c [new file with mode: 0644]
symm/modes-test.h [new file with mode: 0644]
symm/modes.am.in
symm/ofb-def.h
symm/t/modes/blowfish-cbc.regress [new file with mode: 0644]
symm/t/modes/blowfish-cfb.regress [new file with mode: 0644]
symm/t/modes/blowfish-counter.regress [new file with mode: 0644]
symm/t/modes/blowfish-ecb.regress [new file with mode: 0644]
symm/t/modes/blowfish-ofb.regress [new file with mode: 0644]
symm/t/modes/cast128-cbc.regress [new file with mode: 0644]
symm/t/modes/cast128-cfb.regress [new file with mode: 0644]
symm/t/modes/cast128-counter.regress [new file with mode: 0644]
symm/t/modes/cast128-ecb.regress [new file with mode: 0644]
symm/t/modes/cast128-ofb.regress [new file with mode: 0644]
symm/t/modes/cast256-cbc.regress [new file with mode: 0644]
symm/t/modes/cast256-cfb.regress [new file with mode: 0644]
symm/t/modes/cast256-counter.regress [new file with mode: 0644]
symm/t/modes/cast256-ecb.regress [new file with mode: 0644]
symm/t/modes/cast256-ofb.regress [new file with mode: 0644]
symm/t/modes/des-cbc.regress [new file with mode: 0644]
symm/t/modes/des-cfb.regress [new file with mode: 0644]
symm/t/modes/des-counter.regress [new file with mode: 0644]
symm/t/modes/des-ecb.regress [new file with mode: 0644]
symm/t/modes/des-ofb.regress [new file with mode: 0644]
symm/t/modes/des3-cbc.regress [new file with mode: 0644]
symm/t/modes/des3-cfb.regress [new file with mode: 0644]
symm/t/modes/des3-counter.regress [new file with mode: 0644]
symm/t/modes/des3-ecb.regress [new file with mode: 0644]
symm/t/modes/des3-ofb.regress [new file with mode: 0644]
symm/t/modes/desx-cbc.regress [new file with mode: 0644]
symm/t/modes/desx-cfb.regress [new file with mode: 0644]
symm/t/modes/desx-counter.regress [new file with mode: 0644]
symm/t/modes/desx-ecb.regress [new file with mode: 0644]
symm/t/modes/desx-ofb.regress [new file with mode: 0644]
symm/t/modes/has160-mgf.regress [new file with mode: 0644]
symm/t/modes/idea-cbc.regress [new file with mode: 0644]
symm/t/modes/idea-cfb.regress [new file with mode: 0644]
symm/t/modes/idea-counter.regress [new file with mode: 0644]
symm/t/modes/idea-ecb.regress [new file with mode: 0644]
symm/t/modes/idea-ofb.regress [new file with mode: 0644]
symm/t/modes/mars-cbc.regress [new file with mode: 0644]
symm/t/modes/mars-cfb.regress [new file with mode: 0644]
symm/t/modes/mars-counter.regress [new file with mode: 0644]
symm/t/modes/mars-ecb.regress [new file with mode: 0644]
symm/t/modes/mars-ofb.regress [new file with mode: 0644]
symm/t/modes/md2-mgf.regress [new file with mode: 0644]
symm/t/modes/md4-mgf.regress [new file with mode: 0644]
symm/t/modes/md5-mgf.regress [new file with mode: 0644]
symm/t/modes/noekeon-cbc.regress [new file with mode: 0644]
symm/t/modes/noekeon-cfb.regress [new file with mode: 0644]
symm/t/modes/noekeon-counter.regress [new file with mode: 0644]
symm/t/modes/noekeon-ecb.regress [new file with mode: 0644]
symm/t/modes/noekeon-ofb.regress [new file with mode: 0644]
symm/t/modes/rc2-cbc.regress [new file with mode: 0644]
symm/t/modes/rc2-cfb.regress [new file with mode: 0644]
symm/t/modes/rc2-counter.regress [new file with mode: 0644]
symm/t/modes/rc2-ecb.regress [new file with mode: 0644]
symm/t/modes/rc2-ofb.regress [new file with mode: 0644]
symm/t/modes/rc5-cbc.regress [new file with mode: 0644]
symm/t/modes/rc5-cfb.regress [new file with mode: 0644]
symm/t/modes/rc5-counter.regress [new file with mode: 0644]
symm/t/modes/rc5-ecb.regress [new file with mode: 0644]
symm/t/modes/rc5-ofb.regress [new file with mode: 0644]
symm/t/modes/rijndael-cbc.regress [new file with mode: 0644]
symm/t/modes/rijndael-cfb.regress [new file with mode: 0644]
symm/t/modes/rijndael-counter.regress [new file with mode: 0644]
symm/t/modes/rijndael-ecb.regress [new file with mode: 0644]
symm/t/modes/rijndael-ofb.regress [new file with mode: 0644]
symm/t/modes/rijndael192-cbc.regress [new file with mode: 0644]
symm/t/modes/rijndael192-cfb.regress [new file with mode: 0644]
symm/t/modes/rijndael192-counter.regress [new file with mode: 0644]
symm/t/modes/rijndael192-ecb.regress [new file with mode: 0644]
symm/t/modes/rijndael192-ofb.regress [new file with mode: 0644]
symm/t/modes/rijndael256-cbc.regress [new file with mode: 0644]
symm/t/modes/rijndael256-cfb.regress [new file with mode: 0644]
symm/t/modes/rijndael256-counter.regress [new file with mode: 0644]
symm/t/modes/rijndael256-ecb.regress [new file with mode: 0644]
symm/t/modes/rijndael256-ofb.regress [new file with mode: 0644]
symm/t/modes/rmd128-mgf.regress [new file with mode: 0644]
symm/t/modes/rmd160-mgf.regress [new file with mode: 0644]
symm/t/modes/rmd256-mgf.regress [new file with mode: 0644]
symm/t/modes/rmd320-mgf.regress [new file with mode: 0644]
symm/t/modes/safer-cbc.regress [new file with mode: 0644]
symm/t/modes/safer-cfb.regress [new file with mode: 0644]
symm/t/modes/safer-counter.regress [new file with mode: 0644]
symm/t/modes/safer-ecb.regress [new file with mode: 0644]
symm/t/modes/safer-ofb.regress [new file with mode: 0644]
symm/t/modes/safersk-cbc.regress [new file with mode: 0644]
symm/t/modes/safersk-cfb.regress [new file with mode: 0644]
symm/t/modes/safersk-counter.regress [new file with mode: 0644]
symm/t/modes/safersk-ecb.regress [new file with mode: 0644]
symm/t/modes/safersk-ofb.regress [new file with mode: 0644]
symm/t/modes/serpent-cbc.regress [new file with mode: 0644]
symm/t/modes/serpent-cfb.regress [new file with mode: 0644]
symm/t/modes/serpent-counter.regress [new file with mode: 0644]
symm/t/modes/serpent-ecb.regress [new file with mode: 0644]
symm/t/modes/serpent-ofb.regress [new file with mode: 0644]
symm/t/modes/sha-mgf.regress [new file with mode: 0644]
symm/t/modes/sha224-mgf.regress [new file with mode: 0644]
symm/t/modes/sha256-mgf.regress [new file with mode: 0644]
symm/t/modes/sha3-224-mgf.regress [new file with mode: 0644]
symm/t/modes/sha3-256-mgf.regress [new file with mode: 0644]
symm/t/modes/sha3-384-mgf.regress [new file with mode: 0644]
symm/t/modes/sha3-512-mgf.regress [new file with mode: 0644]
symm/t/modes/sha384-mgf.regress [new file with mode: 0644]
symm/t/modes/sha512-224-mgf.regress [new file with mode: 0644]
symm/t/modes/sha512-256-mgf.regress [new file with mode: 0644]
symm/t/modes/sha512-mgf.regress [new file with mode: 0644]
symm/t/modes/skipjack-cbc.regress [new file with mode: 0644]
symm/t/modes/skipjack-cfb.regress [new file with mode: 0644]
symm/t/modes/skipjack-counter.regress [new file with mode: 0644]
symm/t/modes/skipjack-ecb.regress [new file with mode: 0644]
symm/t/modes/skipjack-ofb.regress [new file with mode: 0644]
symm/t/modes/square-cbc.regress [new file with mode: 0644]
symm/t/modes/square-cfb.regress [new file with mode: 0644]
symm/t/modes/square-counter.regress [new file with mode: 0644]
symm/t/modes/square-ecb.regress [new file with mode: 0644]
symm/t/modes/square-ofb.regress [new file with mode: 0644]
symm/t/modes/tea-cbc.regress [new file with mode: 0644]
symm/t/modes/tea-cfb.regress [new file with mode: 0644]
symm/t/modes/tea-counter.regress [new file with mode: 0644]
symm/t/modes/tea-ecb.regress [new file with mode: 0644]
symm/t/modes/tea-ofb.regress [new file with mode: 0644]
symm/t/modes/tiger-mgf.regress [new file with mode: 0644]
symm/t/modes/twofish-cbc.regress [new file with mode: 0644]
symm/t/modes/twofish-cfb.regress [new file with mode: 0644]
symm/t/modes/twofish-counter.regress [new file with mode: 0644]
symm/t/modes/twofish-ecb.regress [new file with mode: 0644]
symm/t/modes/twofish-ofb.regress [new file with mode: 0644]
symm/t/modes/whirlpool-mgf.regress [new file with mode: 0644]
symm/t/modes/whirlpool256-mgf.regress [new file with mode: 0644]
symm/t/modes/xtea-cbc.regress [new file with mode: 0644]
symm/t/modes/xtea-cfb.regress [new file with mode: 0644]
symm/t/modes/xtea-counter.regress [new file with mode: 0644]
symm/t/modes/xtea-ecb.regress [new file with mode: 0644]
symm/t/modes/xtea-ofb.regress [new file with mode: 0644]

index 0e56319..3db9f3f 100644 (file)
@@ -32,6 +32,11 @@ nodist_libsymm_la_SOURCES =
 
 TEST_LIBS               = libsymm.la
 
+noinst_LTLIBRARIES     += libsymmtest.la
+libsymmtest_la_SOURCES  =
+libsymmtest_la_CFLAGS   = $(AM_CFLAGS) -DSRCDIR=\"$(srcdir)\"
+TEST_LIBS              += libsymmtest.la
+
 VPATH                  += $(srcdir)/modes
 
 ###--------------------------------------------------------------------------
@@ -592,6 +597,9 @@ MAINTAINERCLEANFILES        += $(GENMODES_H)
 pkginclude_HEADERS     += $(GENMODES_H)
 $(GENMODES_H): modes/gen-stamp
 
+## Additional test machinery.
+libsymmtest_la_SOURCES += modes-test.c modes-test.h
+
 ###--------------------------------------------------------------------------
 ### Autogenerated stub headers.
 
@@ -649,9 +657,13 @@ gmactab.c: gthingtab.c.in Makefile.am
 ## Run the test programs.
 TESTS                  += $(SYMM_TESTS)
 EXTRA_DIST             += $(SYMM_TEST_FILES)
+EXTRA_DIST             += $(REGRESSION_TEST_FILES)
 
-## A piece of sample text for round-trip testing encryption modes.
-EXTRA_DIST             += daftstory.h
+t/modes/%.regress:
+       $(MAKE) modes/$*.t && \
+               mkdir -p $(srcdir)/t/modes/ && \
+               modes/$*.t -o$(srcdir)/$@.new && \
+               mv $(srcdir)/$@.new $(srcdir)/$@
 
 ## Clean the debris from the `modes' subdirectory.
 CLEANFILES             += modes/*.to modes/*.t$(EXEEXT)
index 907a5db..3eab803 100644 (file)
@@ -444,9 +444,7 @@ CBC_TESTX(PRE, pre, name, fname)
 
 #ifdef TEST_RIG
 
-#include <stdio.h>
-
-#include "daftstory.h"
+#include "modes-test.h"
 
 /* --- @CBC_TEST@ --- *
  *
@@ -457,85 +455,28 @@ CBC_TESTX(PRE, pre, name, fname)
 
 #define CBC_TESTX(PRE, pre, name, fname)                               \
                                                                        \
-/* --- Initial plaintext for the test --- */                           \
-                                                                       \
-static const octet text[] = TEXT;                                      \
+static pre##_ctx key;                                                  \
+static pre##_cbcctx ctx;                                               \
                                                                        \
-/* --- Key and IV to use --- */                                                \
+static void pre##_cbc_test_setup(const octet *k, size_t ksz)           \
+  { pre##_init(&key, k, ksz); pre##_cbcsetkey(&ctx, &key); }           \
                                                                        \
-static const octet key[] = KEY;                                                \
-static const octet iv[] = IV;                                          \
+static void pre##_cbc_test_reset(const octet *iv)                      \
+  { pre##_cbcsetiv(&ctx, iv); }                                                \
                                                                        \
-/* --- Buffers for encryption and decryption output --- */             \
+static void pre##_cbc_test_enc(const octet *s, octet *d, size_t sz)    \
+  { pre##_cbcencrypt(&ctx, s, d, sz); }                                        \
                                                                        \
-static octet ct[sizeof(text)];                                         \
-static octet pt[sizeof(text)];                                         \
+static void pre##_cbc_test_dec(const octet *s, octet *d, size_t sz)    \
+  { pre##_cbcdecrypt(&ctx, s, d, sz); }                                        \
                                                                        \
-static void hexdump(const octet *p, size_t sz, size_t off)             \
+int main(int argc, char *argv[])                                       \
 {                                                                      \
-  const octet *q = p + sz;                                             \
-  for (sz = 0; p < q; p++, sz++) {                                     \
-    printf("%02x", *p);                                                        \
-    if ((off + sz + 1) % PRE##_BLKSZ == 0)                             \
-      putchar(':');                                                    \
-  }                                                                    \
-}                                                                      \
-                                                                       \
-int main(void)                                                         \
-{                                                                      \
-  size_t sz = 0, rest;                                                 \
-  pre##_cbcctx ctx;                                                    \
-  pre##_ctx k;                                                         \
-  int status = 0;                                                      \
-  int done = 0;                                                                \
-                                                                       \
-  size_t keysz = PRE##_KEYSZ ?                                         \
-    PRE##_KEYSZ : strlen((const char *)key);                           \
-                                                                       \
-  fputs(name "-cbc: ", stdout);                                                \
-                                                                       \
-  pre##_init(&k, key, keysz);                                          \
-  pre##_cbcsetkey(&ctx, &k);                                           \
-                                                                       \
-  while (sz <= sizeof(text)) {                                         \
-    rest = sizeof(text) - sz;                                          \
-    memcpy(ct, text, sizeof(text));                                    \
-    pre##_cbcsetiv(&ctx, iv);                                          \
-    pre##_cbcencrypt(&ctx, ct, ct, sz);                                        \
-    pre##_cbcencrypt(&ctx, ct + sz, ct + sz, rest);                    \
-    memcpy(pt, ct, sizeof(text));                                      \
-    pre##_cbcsetiv(&ctx, iv);                                          \
-    pre##_cbcdecrypt(&ctx, pt, pt, sz);                                        \
-    pre##_cbcdecrypt(&ctx, pt + sz, pt + sz, rest);                    \
-    if (memcmp(pt, text, sizeof(text)) == 0) {                         \
-      done++;                                                          \
-      if (sizeof(text) < 40 || done % 8 == 0)                          \
-       fputc('.', stdout);                                             \
-      if (done % 480 == 0)                                             \
-       fputs("\n\t", stdout);                                          \
-      fflush(stdout);                                                  \
-    } else {                                                           \
-      printf("\nError (sz = %lu)\n", (unsigned long)sz);               \
-      status = 1;                                                      \
-      printf("\tplaintext      = "); hexdump(text, sz, 0);             \
-       printf(", "); hexdump(text + sz, rest, sz);                     \
-       fputc('\n', stdout);                                            \
-      printf("\tciphertext     = "); hexdump(ct, sz, 0);               \
-       printf(", "); hexdump(ct + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      printf("\trecovered text = "); hexdump(pt, sz, 0);               \
-       printf(", "); hexdump(pt + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      fputc('\n', stdout);                                             \
-    }                                                                  \
-    if (sz < 63)                                                       \
-      sz++;                                                            \
-    else                                                               \
-      sz += 9;                                                         \
-  }                                                                    \
-                                                                       \
-  fputs(status ? " failed\n" : " ok\n", stdout);                       \
-  return (status);                                                     \
+  return test_encmode(fname "-cbc", PRE##_KEYSZ, PRE##_BLKSZ,          \
+                     1, TEMF_REFALIGN,                                 \
+                     pre##_cbc_test_setup, pre##_cbc_test_reset,       \
+                     pre##_cbc_test_enc, pre##_cbc_test_dec,           \
+                     argc, argv);                                      \
 }
 
 #else
index 78aa6d9..a76332d 100644 (file)
@@ -403,9 +403,7 @@ CFB_TESTX(PRE, pre, name, fname)
 
 #ifdef TEST_RIG
 
-#include <stdio.h>
-
-#include "daftstory.h"
+#include "modes-test.h"
 
 /* --- @CFB_TEST@ --- *
  *
@@ -416,85 +414,27 @@ CFB_TESTX(PRE, pre, name, fname)
 
 #define CFB_TESTX(PRE, pre, name, fname)                               \
                                                                        \
-/* --- Initial plaintext for the test --- */                           \
-                                                                       \
-static const octet text[] = TEXT;                                      \
+static pre##_ctx key;                                                  \
+static pre##_cfbctx ctx;                                               \
                                                                        \
-/* --- Key and IV to use --- */                                                \
+static void pre##_cfb_test_setup(const octet *k, size_t ksz)           \
+  { pre##_init(&key, k, ksz); pre##_cfbsetkey(&ctx, &key); }           \
                                                                        \
-static const octet key[] = KEY;                                                \
-static const octet iv[] = IV;                                          \
+static void pre##_cfb_test_reset(const octet *iv)                      \
+  { pre##_cfbsetiv(&ctx, iv); }                                                \
                                                                        \
-/* --- Buffers for encryption and decryption output --- */             \
+static void pre##_cfb_test_enc(const octet *s, octet *d, size_t sz)    \
+  { pre##_cfbencrypt(&ctx, s, d, sz); }                                        \
                                                                        \
-static octet ct[sizeof(text)];                                         \
-static octet pt[sizeof(text)];                                         \
+static void pre##_cfb_test_dec(const octet *s, octet *d, size_t sz)    \
+  { pre##_cfbdecrypt(&ctx, s, d, sz); }                                        \
                                                                        \
-static void hexdump(const octet *p, size_t sz, size_t off)             \
+int main(int argc, char *argv[])                                       \
 {                                                                      \
-  const octet *q = p + sz;                                             \
-  for (sz = 0; p < q; p++, sz++) {                                     \
-    printf("%02x", *p);                                                        \
-    if ((off + sz + 1) % PRE##_BLKSZ == 0)                             \
-      putchar(':');                                                    \
-  }                                                                    \
-}                                                                      \
-                                                                       \
-int main(void)                                                         \
-{                                                                      \
-  size_t sz = 0, rest;                                                 \
-  pre##_cfbctx ctx;                                                    \
-  int status = 0;                                                      \
-  int done = 0;                                                                \
-  pre##_ctx k;                                                         \
-                                                                       \
-  size_t keysz = PRE##_KEYSZ ?                                         \
-    PRE##_KEYSZ : strlen((const char *)key);                           \
-                                                                       \
-  fputs(name "-cfb: ", stdout);                                                \
-                                                                       \
-  pre##_init(&k, key, keysz);                                          \
-  pre##_cfbsetkey(&ctx, &k);                                           \
-                                                                       \
-  while (sz <= sizeof(text)) {                                         \
-    rest = sizeof(text) - sz;                                          \
-    memcpy(ct, text, sizeof(text));                                    \
-    pre##_cfbsetiv(&ctx, iv);                                          \
-    pre##_cfbencrypt(&ctx, ct, ct, sz);                                        \
-    pre##_cfbencrypt(&ctx, ct + sz, ct + sz, rest);                    \
-    memcpy(pt, ct, sizeof(text));                                      \
-    pre##_cfbsetiv(&ctx, iv);                                          \
-    pre##_cfbdecrypt(&ctx, pt, pt, rest);                              \
-    pre##_cfbdecrypt(&ctx, pt + rest, pt + rest, sz);                  \
-    if (memcmp(pt, text, sizeof(text)) == 0) {                         \
-      done++;                                                          \
-      if (sizeof(text) < 40 || done % 8 == 0)                          \
-       fputc('.', stdout);                                             \
-      if (done % 480 == 0)                                             \
-       fputs("\n\t", stdout);                                          \
-      fflush(stdout);                                                  \
-    } else {                                                           \
-      printf("\nError (sz = %lu)\n", (unsigned long)sz);               \
-      status = 1;                                                      \
-      printf("\tplaintext      = "); hexdump(text, sz, 0);             \
-       printf(", "); hexdump(text + sz, rest, sz);                     \
-       fputc('\n', stdout);                                            \
-      printf("\tciphertext     = "); hexdump(ct, sz, 0);               \
-       printf(", "); hexdump(ct + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      printf("\trecovered text = "); hexdump(pt, sz, 0);               \
-       printf(", "); hexdump(pt + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      fputc('\n', stdout);                                             \
-    }                                                                  \
-    if (sz < 63)                                                       \
-      sz++;                                                            \
-    else                                                               \
-      sz += 9;                                                         \
-  }                                                                    \
-                                                                       \
-  fputs(status ? " failed\n" : " ok\n", stdout);                       \
-  return (status);                                                     \
+  return test_encmode(fname "-cfb", PRE##_KEYSZ, PRE##_BLKSZ, 1, 0,    \
+                     pre##_cfb_test_setup, pre##_cfb_test_reset,       \
+                     pre##_cfb_test_enc, pre##_cfb_test_dec,           \
+                     argc, argv);                                      \
 }
 
 #else
index ad955db..2744430 100644 (file)
@@ -430,9 +430,7 @@ COUNTER_TESTX(PRE, pre, name, fname)
 
 #ifdef TEST_RIG
 
-#include <stdio.h>
-
-#include "daftstory.h"
+#include "modes-test.h"
 
 /* --- @COUNTER_TEST@ --- *
  *
@@ -443,85 +441,24 @@ COUNTER_TESTX(PRE, pre, name, fname)
 
 #define COUNTER_TESTX(PRE, pre, name, fname)                           \
                                                                        \
-/* --- Initial plaintext for the test --- */                           \
-                                                                       \
-static const octet text[] = TEXT;                                      \
-                                                                       \
-/* --- Key and IV to use --- */                                                \
+static pre##_ctx key;                                                  \
+static pre##_counterctx ctx;                                           \
                                                                        \
-static const octet key[] = KEY;                                                \
-static const octet iv[] = IV;                                          \
+static void pre##_counter_test_setup(const octet *k, size_t ksz)       \
+  { pre##_init(&key, k, ksz); pre##_countersetkey(&ctx, &key); }       \
                                                                        \
-/* --- Buffers for encryption and decryption output --- */             \
+static void pre##_counter_test_reset(const octet *iv)                  \
+  { pre##_countersetiv(&ctx, iv); }                                    \
                                                                        \
-static octet ct[sizeof(text)];                                         \
-static octet pt[sizeof(text)];                                         \
-                                                                       \
-static void hexdump(const octet *p, size_t sz, size_t off)             \
-{                                                                      \
-  const octet *q = p + sz;                                             \
-  for (sz = 0; p < q; p++, sz++) {                                     \
-    printf("%02x", *p);                                                        \
-    if ((off + sz + 1) % PRE##_BLKSZ == 0)                             \
-      putchar(':');                                                    \
-  }                                                                    \
-}                                                                      \
+static void pre##_counter_test_enc(const octet *s, octet *d, size_t sz)        \
+  { pre##_counterencrypt(&ctx, s, d, sz); }                            \
                                                                        \
-int main(void)                                                         \
+int main(int argc, char *argv[])                                       \
 {                                                                      \
-  size_t sz = 0, rest;                                                 \
-  pre##_counterctx ctx;                                                        \
-  int status = 0;                                                      \
-  int done = 0;                                                                \
-  pre##_ctx k;                                                         \
-                                                                       \
-  size_t keysz = PRE##_KEYSZ ?                                         \
-    PRE##_KEYSZ : strlen((const char *)key);                           \
-                                                                       \
-  fputs(name "-counter: ", stdout);                                    \
-                                                                       \
-  pre##_init(&k, key, keysz);                                          \
-  pre##_countersetkey(&ctx, &k);                                       \
-                                                                       \
-  while (sz <= sizeof(text)) {                                         \
-    rest = sizeof(text) - sz;                                          \
-    memcpy(ct, text, sizeof(text));                                    \
-    pre##_countersetiv(&ctx, iv);                                      \
-    pre##_counterencrypt(&ctx, ct, ct, sz);                            \
-    pre##_counterencrypt(&ctx, ct + sz, ct + sz, rest);                        \
-    memcpy(pt, ct, sizeof(text));                                      \
-    pre##_countersetiv(&ctx, iv);                                      \
-    pre##_counterencrypt(&ctx, pt, pt, rest);                          \
-    pre##_counterencrypt(&ctx, pt + rest, pt + rest, sz);              \
-    if (memcmp(pt, text, sizeof(text)) == 0) {                         \
-      done++;                                                          \
-      if (sizeof(text) < 40 || done % 8 == 0)                          \
-       fputc('.', stdout);                                             \
-      if (done % 480 == 0)                                             \
-       fputs("\n\t", stdout);                                          \
-      fflush(stdout);                                                  \
-    } else {                                                           \
-      printf("\nError (sz = %lu)\n", (unsigned long)sz);               \
-      status = 1;                                                      \
-      printf("\tplaintext      = "); hexdump(text, sz, 0);             \
-       printf(", "); hexdump(text + sz, rest, sz);                     \
-       fputc('\n', stdout);                                            \
-      printf("\tciphertext     = "); hexdump(ct, sz, 0);               \
-       printf(", "); hexdump(ct + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      printf("\trecovered text = "); hexdump(pt, sz, 0);               \
-       printf(", "); hexdump(pt + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      fputc('\n', stdout);                                             \
-    }                                                                  \
-    if (sz < 63)                                                       \
-      sz++;                                                            \
-    else                                                               \
-      sz += 9;                                                         \
-  }                                                                    \
-                                                                       \
-  fputs(status ? " failed\n" : " ok\n", stdout);                       \
-  return (status);                                                     \
+  return test_encmode(fname "-counter", PRE##_KEYSZ, PRE##_BLKSZ, 1, 0,        \
+                     pre##_counter_test_setup, pre##_counter_test_reset, \
+                     pre##_counter_test_enc, pre##_counter_test_enc,   \
+                     argc, argv);                                      \
 }
 
 #else
diff --git a/symm/daftstory.h b/symm/daftstory.h
deleted file mode 100644 (file)
index b4d6b58..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*-c-*-
- *
- * Daft story for use in test encryptions
- *
- * (c) 1999 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_DAFTSTORY_H
-#define CATACOMB_DAFTSTORY_H
-
-#ifdef __cplusplus
-  extern "C" {
-#endif
-
-/*----- Macros ------------------------------------------------------------*/
-
-/* --- Don't ask --- */
-
-#ifdef SMALL_TEST
-#  define TEXT "A small piece of text for testing encryption."
-#else
-#  define STORY "\
-Once upon a time there were a beautiful princess, a slightly nutty wizard,\n\
-and a watermelon.  Now, the watermelon had decided that it probably wasn't\n\
-going to get very far with the princess unless it did something pretty\n\
-drastic.  So it asked the wizard to turn it into a handsome prince.\n\
-\n\
-At least, this is the way that the wizard viewed the situation.  He might\n\
-have just hallucinated it all; those mushrooms had looked ever so nice.\n\
-\n\
-Back to the point.  The watermelon had expressed its desire not to be a\n\
-watermelon any more.  And the wizard was probably tripping something quite\n\
-powerful.  He hunted around a bit for his staff, and mumbled something\n\
-that film directors would think of as sounding appropriately arcane and\n\
-mystical (but was, in fact, just the ingredients list for an ancient\n\
-remedy for athlete's foot) and *pop*.  Cooked watermelon.  Yuk.\n\
-\n\
-Later in the year, the princess tripped over the hem of her dress, fell\n\
-down a spiral staircase, and died.  The king ordered dressmakers to attach\n\
-safety warnings to long dresses.\n\
-\n\
-And the wizard?         Who cares?\n\
-"
-#  define TEXT STORY STORY
-#endif
-
-#define KEY "Penguins rule OK, rhubarb cauliflower"
-#define IV "EdgewareCatacomb, parsley, sage, rosemary and thyme"
-
-/*----- That's all, folks -------------------------------------------------*/
-
-#ifdef __cplusplus
-  }
-#endif
-
-#endif
index 568ffa1..026343c 100644 (file)
@@ -368,9 +368,7 @@ ECB_TESTX(PRE, pre, name, fname)
 
 #ifdef TEST_RIG
 
-#include <stdio.h>
-
-#include "daftstory.h"
+#include "modes-test.h"
 
 /* --- @ECB_TEST@ --- *
  *
@@ -381,85 +379,28 @@ ECB_TESTX(PRE, pre, name, fname)
 
 #define ECB_TESTX(PRE, pre, name, fname)                               \
                                                                        \
-/* --- Initial plaintext for the test --- */                           \
-                                                                       \
-static const octet text[] = TEXT;                                      \
+static pre##_ctx key;                                                  \
+static pre##_ecbctx ctx;                                               \
                                                                        \
-/* --- Key and IV to use --- */                                                \
+static void pre##_ecb_test_setup(const octet *k, size_t ksz)           \
+  { pre##_init(&key, k, ksz); pre##_ecbsetkey(&ctx, &key); }           \
                                                                        \
-static const octet key[] = KEY;                                                \
-static const octet iv[] = IV;                                          \
+static void pre##_ecb_test_reset(const octet *iv)                      \
+  { ; }                                                                        \
                                                                        \
-/* --- Buffers for encryption and decryption output --- */             \
+static void pre##_ecb_test_enc(const octet *s, octet *d, size_t sz)    \
+  { pre##_ecbencrypt(&ctx, s, d, sz); }                                        \
                                                                        \
-static octet ct[sizeof(text)];                                         \
-static octet pt[sizeof(text)];                                         \
+static void pre##_ecb_test_dec(const octet *s, octet *d, size_t sz)    \
+  { pre##_ecbdecrypt(&ctx, s, d, sz); }                                        \
                                                                        \
-static void hexdump(const octet *p, size_t sz, size_t off)             \
+int main(int argc, char *argv[])                                       \
 {                                                                      \
-  const octet *q = p + sz;                                             \
-  for (sz = 0; p < q; p++, sz++) {                                     \
-    printf("%02x", *p);                                                        \
-    if ((off + sz + 1) % PRE##_BLKSZ == 0)                             \
-      putchar(':');                                                    \
-  }                                                                    \
-}                                                                      \
-                                                                       \
-int main(void)                                                         \
-{                                                                      \
-  size_t sz = 0, rest;                                                 \
-  pre##_ecbctx ctx;                                                    \
-  int status = 0;                                                      \
-  int done = 0;                                                                \
-                                                                       \
-  size_t keysz = PRE##_KEYSZ ?                                         \
-    PRE##_KEYSZ : strlen((const char *)key);                           \
-                                                                       \
-  fputs(name "-ecb: ", stdout);                                                \
-                                                                       \
-  pre##_ecbinit(&ctx, key, keysz, iv);                                 \
-                                                                       \
-  while (sz <= sizeof(text)) {                                         \
-    rest = sizeof(text) - sz;                                          \
-    if ((sz != 0 && sz < PRE##_BLKSZ) ||                               \
-       (rest != 0 && rest < PRE##_BLKSZ))                              \
-      goto next;                                                       \
-    memcpy(ct, text, sizeof(text));                                    \
-    pre##_ecbencrypt(&ctx, ct, ct, sz);                                        \
-    pre##_ecbencrypt(&ctx, ct + sz, ct + sz, rest);                    \
-    memcpy(pt, ct, sizeof(text));                                      \
-    pre##_ecbdecrypt(&ctx, pt, pt, sz);                                        \
-    pre##_ecbdecrypt(&ctx, pt + sz, pt + sz, rest);                    \
-    if (memcmp(pt, text, sizeof(text)) == 0) {                         \
-      done++;                                                          \
-      if (sizeof(text) < 40 || done % 8 == 0)                          \
-       fputc('.', stdout);                                             \
-      if (done % 480 == 0)                                             \
-       fputs("\n\t", stdout);                                          \
-      fflush(stdout);                                                  \
-    } else {                                                           \
-      printf("\nError (sz = %lu)\n", (unsigned long)sz);               \
-      status = 1;                                                      \
-      printf("\tplaintext      = "); hexdump(text, sz, 0);             \
-       printf(", "); hexdump(text + sz, rest, sz);                     \
-       fputc('\n', stdout);                                            \
-      printf("\tciphertext     = "); hexdump(ct, sz, 0);               \
-       printf(", "); hexdump(ct + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      printf("\trecovered text = "); hexdump(pt, sz, 0);               \
-       printf(", "); hexdump(pt + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      fputc('\n', stdout);                                             \
-    }                                                                  \
-  next:                                                                        \
-    if (sz < 63)                                                       \
-      sz++;                                                            \
-    else                                                               \
-      sz += 9;                                                         \
-  }                                                                    \
-                                                                       \
-  fputs(status ? " failed\n" : " ok\n", stdout);                       \
-  return (status);                                                     \
+  return test_encmode(fname "-ecb", PRE##_KEYSZ, PRE##_BLKSZ,          \
+                     PRE##_BLKSZ, TEMF_REFALIGN,                       \
+                     pre##_ecb_test_setup, pre##_ecb_test_reset,       \
+                     pre##_ecb_test_enc, pre##_ecb_test_dec,           \
+                     argc, argv);                                      \
 }
 
 #else
index 832cd07..aad09a4 100644 (file)
@@ -359,9 +359,7 @@ MGF_TESTX(PRE, pre, name, fname)
 
 #ifdef TEST_RIG
 
-#include <stdio.h>
-
-#include "daftstory.h"
+#include "modes-test.h"
 
 /* --- @MGF_TEST@ --- *
  *
@@ -372,81 +370,23 @@ MGF_TESTX(PRE, pre, name, fname)
 
 #define MGF_TESTX(PRE, pre, name, fname)                               \
                                                                        \
-/* --- Initial plaintext for the test --- */                           \
-                                                                       \
-static const octet text[] = TEXT;                                      \
-                                                                       \
-/* --- Key and IV to use --- */                                                \
+static pre##_mgfctx ctx;                                               \
                                                                        \
-static const octet key[] = KEY;                                                \
+static void pre##_mgf_test_setup(const octet *k, size_t ksz)           \
+  { pre##_mgfinit(&ctx, k, ksz); }                                     \
                                                                        \
-/* --- Buffers for encryption and decryption output --- */             \
+static void pre##_mgf_test_reset(const octet *iv)                      \
+  { pre##_mgfsetindex(&ctx, 0); }                                      \
                                                                        \
-static octet ct[sizeof(text)];                                         \
-static octet pt[sizeof(text)];                                         \
-                                                                       \
-static void hexdump(const octet *p, size_t sz)                         \
-{                                                                      \
-  const octet *q = p + sz;                                             \
-  for (sz = 0; p < q; p++, sz++) {                                     \
-    printf("%02x", *p);                                                        \
-    if ((sz + 1) % PRE##_HASHSZ == 0)                                  \
-      putchar(':');                                                    \
-  }                                                                    \
-}                                                                      \
+static void pre##_mgf_test_enc(const octet *s, octet *d, size_t sz)    \
+  { pre##_mgfencrypt(&ctx, s, d, sz); }                                        \
                                                                        \
-int main(void)                                                         \
+int main(int argc, char *argv[])                                       \
 {                                                                      \
-  size_t sz = 0, rest;                                                 \
-  pre##_mgfctx ctx;                                                    \
-  int status = 0;                                                      \
-  int done = 0;                                                                \
-                                                                       \
-  size_t keysz = strlen((const char *)key);                            \
-                                                                       \
-  fputs(name "-mgf: ", stdout);                                                \
-                                                                       \
-  pre##_mgfinit(&ctx, key, keysz);                                     \
-                                                                       \
-  while (sz <= sizeof(text)) {                                         \
-    rest = sizeof(text) - sz;                                          \
-    memcpy(ct, text, sizeof(text));                                    \
-    pre##_mgfsetindex(&ctx, 0);                                                \
-    pre##_mgfencrypt(&ctx, ct, ct, sz);                                        \
-    pre##_mgfencrypt(&ctx, ct + sz, ct + sz, rest);                    \
-    memcpy(pt, ct, sizeof(text));                                      \
-    pre##_mgfsetindex(&ctx, 0);                                                \
-    pre##_mgfencrypt(&ctx, pt, pt, rest);                              \
-    pre##_mgfencrypt(&ctx, pt + rest, pt + rest, sz);                  \
-    if (memcmp(pt, text, sizeof(text)) == 0) {                         \
-      done++;                                                          \
-      if (sizeof(text) < 40 || done % 8 == 0)                          \
-       fputc('.', stdout);                                             \
-      if (done % 480 == 0)                                             \
-       fputs("\n\t", stdout);                                          \
-      fflush(stdout);                                                  \
-    } else {                                                           \
-      printf("\nError (sz = %lu)\n", (unsigned long)sz);               \
-      status = 1;                                                      \
-      printf("\tplaintext      = "); hexdump(text, sz);                        \
-       printf(", "); hexdump(text + sz, rest);                         \
-       fputc('\n', stdout);                                            \
-      printf("\tciphertext     = "); hexdump(ct, sz);                  \
-       printf(", "); hexdump(ct + sz, rest);                           \
-       fputc('\n', stdout);                                            \
-      printf("\trecovered text = "); hexdump(pt, sz);                  \
-       printf(", "); hexdump(pt + sz, rest);                           \
-       fputc('\n', stdout);                                            \
-      fputc('\n', stdout);                                             \
-    }                                                                  \
-    if (sz < 63)                                                       \
-      sz++;                                                            \
-    else                                                               \
-      sz += 9;                                                         \
-  }                                                                    \
-                                                                       \
-  fputs(status ? " failed\n" : " ok\n", stdout);                       \
-  return (status);                                                     \
+  return test_encmode(fname "-mgf", 0, PRE##_HASHSZ, 1, 0,             \
+                     pre##_mgf_test_setup, pre##_mgf_test_reset,       \
+                     pre##_mgf_test_enc, pre##_mgf_test_enc,           \
+                     argc, argv);                                      \
 }
 
 #else
diff --git a/symm/modes-test.c b/symm/modes-test.c
new file mode 100644 (file)
index 0000000..bbda53b
--- /dev/null
@@ -0,0 +1,539 @@
+/* -*-c-*-
+ *
+ * Common code for testing encryption modes
+ *
+ * (c) 2018 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Catacomb is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb.  If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+
+#include <mLib/alloc.h>
+#include <mLib/bits.h>
+#include <mLib/dstr.h>
+#include <mLib/quis.h>
+#include <mLib/report.h>
+
+#include "modes-test.h"
+
+/*----- The reference data ------------------------------------------------*/
+
+#ifdef SMALL_TEST
+static const octet text[] = "A small piece of text for testing encryption.";
+#else
+#define STORY "\
+Once upon a time there were a beautiful princess, a slightly nutty wizard,\n\
+and a watermelon.  Now, the watermelon had decided that it probably wasn't\n\
+going to get very far with the princess unless it did something pretty\n\
+drastic.  So it asked the wizard to turn it into a handsome prince.\n\
+\n\
+At least, this is the way that the wizard viewed the situation.  He might\n\
+have just hallucinated it all; those mushrooms had looked ever so nice.\n\
+\n\
+Back to the point.  The watermelon had expressed its desire not to be a\n\
+watermelon any more.  And the wizard was probably tripping something quite\n\
+powerful.  He hunted around a bit for his staff, and mumbled something\n\
+that film directors would think of as sounding appropriately arcane and\n\
+mystical (but was, in fact, just the ingredients list for an ancient\n\
+remedy for athlete's foot) and *pop*.  Cooked watermelon.  Yuk.\n\
+\n\
+Later in the year, the princess tripped over the hem of her dress, fell\n\
+down a spiral staircase, and died.  The king ordered dressmakers to attach\n\
+safety warnings to long dresses.\n\
+\n\
+And the wizard?         Who cares?\n\
+"
+static const octet text[] = STORY STORY;
+#endif
+
+#define TEXTSZ (sizeof(text))
+
+static const octet key[] = "Penguins rule OK, rhubarb cauliflower",
+  iv[] = "EdgewareCatacomb, parsley, sage, rosemary and thyme";
+
+/*----- Static variables --------------------------------------------------*/
+
+/* Encryption buffers, for ciphertext, recovered plaintext, and consistency
+ * reference.
+ */
+static octet ct[TEXTSZ], pt[TEXTSZ], ref[TEXTSZ];
+
+/* A resizeable buffer for verifying regression data. */
+static octet *t = 0; size_t tsz = 0;
+
+/*----- Diagnostic utilities ----------------------------------------------*/
+
+/* Print the @sz@-byte buffer @p@, beginning at offset @off@ within some
+ * larger buffer, marking block boundaries every @blksz@ bytes.
+ */
+static void hexdump(const octet *p, size_t sz, size_t off, size_t blksz)
+{
+  const octet *q = p + sz;
+  for (sz = 0; p < q; p++, sz++) {
+    printf("%02x", *p);
+    if ((off + sz + 1)%blksz == 0) putchar(':');
+  }
+}
+
+/* Print the buffer @p@, labelling it as @what@, splitting it into three
+ * pieces of sizes @sz0@, @sz1@, and @sz2@ respectively.  Block boundaries
+ * every @blksz@ bytes are shown consistency, independent of the split
+ * positions.
+ */
+static void dump_split(const char *what, size_t blksz, const octet *p,
+                      size_t sz0, size_t sz1, size_t sz2)
+{
+  printf("\t%-16s = ", what);
+  hexdump(p, sz0, 0, blksz);
+  if (sz1) { printf(", "); hexdump(p + sz0, sz1, sz0, blksz); }
+  if (sz2) { printf(", "); hexdump(p + sz0 + sz1, sz2, sz0 + sz1, blksz); }
+  fputc('\n', stdout);
+}
+
+/*----- Regression-data utilities -----------------------------------------*/
+
+/* Regression modes.  We can @CHECK@ existing data, @RECORD@ new data, or
+ * @IGNORE@ the regression testing entirely.
+ */
+enum { IGNORE, RECORD, CHECK };
+
+/* Read or write regression data from/to @fp@ according to @rmode@.  The data
+ * item is described as @what@ in diagnostic messages, and consists of @sz@
+ * bytes beginning at @p@.
+ *
+ * If @rmode@ is @IGNORE@, then this function does nothing; if @rmode@ is
+ * @RECORD@, then it writes @p@ to the output file with some framing; and if
+ * @rmode@ is @CHECK@ then it checks that the next chunk of data from the
+ * file matches @p@.
+ *
+ * Returns zero if all is well or @-1@ on a mismatch; I/O errors are fatal.
+ *
+ * Framing is trivial and consists of a 4-byte big-endian non-inclusive
+ * length prepended to each buffer.  No padding is written to maintain
+ * alignment.
+ */
+static int regress_data(int rmode, FILE *fp, const char *what,
+                       const void *p, size_t sz)
+{
+  octet b[4];
+  size_t psz;
+
+  switch (rmode) {
+    case IGNORE:
+      return (0);
+    case RECORD:
+      STORE32(b, sz);
+      if (!fwrite(b, 4, 1, fp) || !fwrite(p, sz, 1, fp))
+       die(1, "failed to write %s: %s", what, strerror(errno));
+      return (0);
+    case CHECK:
+      if (!fread(b, 4, 1, fp))
+       die(1, "failed to read %s length: %s", what,
+           ferror(fp) ? strerror(errno) : "unexpected eof");
+      psz = LOAD32(b);
+      if (psz != sz)
+       die(1, "incorrect %s length (%lu /= %lu; sync failure?)",
+           what, (unsigned long)psz, (unsigned long)sz);
+      if (tsz < sz) { xfree(t); t = xmalloc(sz); tsz = sz; }
+      if (!fread(t, sz, 1, fp))
+       die(1, "failed to read %s: %s", what,
+           ferror(fp) ? strerror(errno) : "unexpected eof");
+      if (memcmp(p, t, sz) != 0) return (-1);
+      return (0);
+    default:
+      abort();
+  }
+}
+
+/* Read or write framing data from/to @fp@ according to @rmode@.  The framing
+ * item is describd as @what@ in diagnostic messages, and consists of @sz@
+ * bytes beginning at @p@.
+ *
+ * Framing data is used to verify that a recorded regression-data file is
+ * still appropriate for use.  A fatal error is reported on any kind of
+ * failure.
+ */
+static void regress_framing(int rmode, FILE *fp, const char *what,
+                           const void *p, size_t sz)
+{
+  if (regress_data(rmode, fp, what, p, sz))
+    die(1, "regression framing mismatch for %s (bug, or wrong file)", what);
+}
+
+/* Read or write crypto data from/to @fp@ according to @rmode@.  The data
+ * item is describd as @what@ in diagnostic messages, and consists of the
+ * bytes beginning at @p@.  For the purposes of diagnostics, this buffer has
+ * been notionally split into three pieces, with sizes @sz0@, @sz1@, and
+ * @sz2@, respectively.
+ *
+ * If al is well, return zero.  If the crypto data doesn't match the recorded
+ * regression data, then report the mismatch, showing the way in which the
+ * buffer is split, and return -1.  I/O errors are fatal.
+ */
+static int regress_crypto(int rmode, FILE *fp, const char *what, size_t blksz,
+                         const void *p, size_t sz0, size_t sz1, size_t sz2)
+{
+  int rc;
+
+  rc = regress_data(rmode, fp, what, p, sz0 + sz1 + sz2);
+  if (rc) {
+    printf("\nRegression mismatch (split = %lu/%lu/%lu)\n",
+          (unsigned long)sz0, (unsigned long)sz1, (unsigned long)sz2);
+    dump_split("plaintext", blksz, text, sz0, sz1, sz2);
+    dump_split("expected ct", blksz, t, sz0, sz1, sz2);
+    dump_split("computed ct", blksz, p, sz0, sz1, sz2);
+    fputc('\n', stdout);
+  }
+  return (rc);
+}
+
+/*----- Selecting fragment sizes ------------------------------------------*/
+
+/* Return codes from @step@. */
+enum { STEP, LIMIT, RESET };
+
+/* Update @*sz_inout@ the next largest suitable fragment size, up to a
+ * maximum of @max@.
+ *
+ * If the new size is still smaller than the maximum, then return @STEP@.  If
+ * the size is maximal, then return @LIMIT@.  If the size was previously
+ * maximal already, then return @RESET@.
+ *
+ * The sizes here are selected powers of two, and powers of two plus or minus
+ * 1, with the objective of testing how internal buffering is affected when
+ * the cursor is misaligned and realigned with block boundaries.
+ */
+static int step(size_t *sz_inout, size_t max)
+{
+  size_t i;
+
+  static size_t steps[] = {   1,   7,   8,   9,  15,  16,  17,
+                                 63,  64,  65, 255, 256, 257 };
+
+  if (*sz_inout == max) return (RESET);
+  for (i = 0; i < N(steps); i++)
+    if (steps[i] > *sz_inout) {
+      if (steps[i] < max) { *sz_inout = steps[i]; return (STEP); }
+      else break;
+    }
+  *sz_inout = max; return (LIMIT);
+}
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @test_encmode@ --- *
+ *
+ * Arguments:  @const char *name@ = name of the encryption scheme; used to
+ *                     find the regression-test filename
+ *             @size_t ksz@ = key size to use, or zero for `don't care'
+ *             @size_t blksz@ = block size
+ *             @size_t minsz@ = smallest acceptable buffer size, or 1
+ *             @unsigned f@ = various additional flags
+ *             @setupfn *setup@ = key-setup function
+ *             @resetfn *reset@ = state-reset function
+ *             @encfn *enc@ = encryption function
+ *             @decfn *dec@ = decryption function
+ *             @int argc@ = number of command-line arguments
+ *             @char *argv@ = pointer to command-line argument vector
+ *
+ * Returns:    Zero on success, nonzero to report failure.
+ *
+ * Use:                Tests an encryption mode which doesn't have any more formal
+ *             test vectors.
+ *
+ *             The @name@ is used firstly in diagnostic output and secondly
+ *             to form the default filename to use for regression-test data,
+ *             as `.../symm/t/modes/NAME.regress'.
+ *
+ *             The key size @ksz@ is simply passed on back to the @setup@
+ *             function, unless the caller passes in zero, in which case
+ *             @test_encmode@ chooses a key size for itself.
+ *
+ *             The block size @blksz@ is used in failure reports, to draw
+ *             attention to the block structure in the various buffers,
+ *             which may assist with diagnosis.  It's also used to determine
+ *             when to apply a consistency check: see below regarding the
+ *             @TEMF_REFALIGN@ flag.
+ *
+ *             The minimum buffer size @minsz@ expresses a limitation on the
+ *             provided @enc@ and @dec@ functions, that they don't work on
+ *             inputs smaller than @minsz@; accordingly, @test_encmode@ will
+ *             not test such small sizes.  This should be 1 if the mode has
+ *             no limitation.
+ *
+ *             The flags @f@ influence testing in various ways explained
+ *             below.
+ *
+ *             The caller-provided functions are assumed to act on some
+ *             global but hidden state,
+ *
+ *               * @setup@ is (currently, at least) called only once, with
+ *                 the key @k@ and its chosen size @ksz@.
+ *
+ *               * @reset@ is called at the start of each encryption or
+ *                 decryption operation, to program in the initialization
+ *                 vector to use.  Currently, the same IV is used in all of
+ *                 the tests, but this might not always be the case.
+ *
+ *               * @enc@ is called to encrypt a source buffer @s@ and write
+ *                 the ciphertext to a destination @d@; @sz@ is the common
+ *                 size of these buffers.
+ *
+ *               * @dec@ is called to decrypt a source buffer @s@ and write
+ *                 the recovered plaintext to a destination @d@; @sz@ is the
+ *                 common size of these buffers.
+ *
+ *             Finally, @int argc@ and @char *argv@ are the command-line
+ *             arguments provided to @main@; @test_encmode@ parses these and
+ *             alters its behaviour accordingly.
+ *
+ *             Currently, @test_encmode@'s tests are built around a single,
+ *             fairly large, fixed message.  In each test step, the message
+ *             is split into a number of fragments which are encrypted and
+ *             decrypted in turn.
+ *
+ *             The following tests are performed.
+ *
+ *               * The fundamental `round-trip' test, which verifies that
+ *                 the message can be encrypted and then decrypted
+ *                 successfully, if the same fragment boundaries are used in
+ *                 both cases.
+ *
+ *               * A `consistency' test.  Some modes, such as CFB, OFB, and
+ *                 counter, are `resumable': encryption operations are
+ *                 insensitive to the position of fragment boundaries, so a
+ *                 single message can be broken into fragments without
+ *                 affecting the result.  If @TEMF_REFALIGN@ is clear then
+ *                 the mode under test is verified to have this property.
+ *                 If @TEMF_REFALIGN' is set, a weaker property is verified:
+ *                 that encryption is insensitive to the position of
+ *                 /block-aligned/ fragment boundaries only.
+ *
+ *               * A `regression' test, which verifies that the code
+ *                 produces the same ciphertext as a previous version.  By
+ *                 setting command-line arguments appropriately, a test
+ *                 program can be told to record ciphertexts in a (binary)
+ *                 data file.  Usually, instead, the program will read the
+ *                 recorded ciphertexts back and verify that it produces the
+ *                 same data.  For resumable modes, it's only necessary to
+ *                 record single ciphertext, since all the other ciphertexts
+ *                 must be equal by consistency; otherwise all non-block-
+ *                 aligned splits are recorded separately.
+ */
+
+int test_encmode(const char *name,
+                size_t ksz, size_t blksz, size_t minsz, unsigned f,
+                setupfn *setup, resetfn *reset, encfn *enc, encfn *dec,
+                int argc, char *argv[])
+{
+  int ok = 1, refp = 0, i;
+  size_t sz0, sz1, sz2;
+  const char spinner[] = "/-\\|";
+  int rmode = CHECK, spin = isatty(STDOUT_FILENO) ? 0 : -1;
+  int regr;
+  const char *rname = 0, *p;
+  FILE *fp;
+  dstr d = DSTR_INIT;
+
+  ego(argv[0]);
+
+  /* Parse the command-line options. */
+  p = 0; i = 1;
+  for (;;) {
+
+    /* Read the next argument. */
+    if (!p || !*p) {
+      if (i >= argc) break;
+      p = argv[i++];
+      if (strcmp(p, "--") == 0) break;
+      if (p[0] != '-' || p[1] == 0) { i--; break; }
+      p++;
+    }
+
+    /* Interpret an option. */
+    switch (*p++) {
+      case 'h':
+       printf("%s test driver\n"
+              "Usage: %s [-i] [-o|-f FILENAME]\n", QUIS, QUIS);
+       exit(0);
+      case 'i':
+       rmode = IGNORE;
+       break;
+      case 'o':
+       if (!*p) {
+         if (i >= argc) die(1, "option `-o' expects an argument");
+         p = argv[i++];
+       }
+       rmode = RECORD; rname = p; p = 0;
+       break;
+      case 'f':
+       if (!*p) {
+         if (i >= argc) die(1, "option `-f' expects an argument");
+         p = argv[i++];
+       }
+       rmode = CHECK; rname = p; p = 0;
+       break;
+      default:
+       die(1, "option `-%c' unknown", p[-1]);
+    }
+  }
+
+  /* Check there's nothing else left. */
+  if (i < argc) die(1, "trailing junk on command line");
+
+  /* Open the regression-data file. */
+  if (rmode == IGNORE)
+    fp = 0;
+  else {
+    if (!rname) {
+      DRESET(&d); dstr_putf(&d, SRCDIR"/t/modes/%s.regress", name);
+      rname = xstrdup(d.buf);
+    }
+    fp = fopen(rname, rmode == RECORD ? "wb" : "rb");
+    if (!fp)
+      die(1, "failed to open `%s' for %s: %s", rname,
+         rmode == RECORD ? "writing" : "reading", strerror(errno));
+  }
+
+  /* Write a header describing the file, to trap misuse for the wrong mode,
+   * and changes in the text.
+   */
+  DRESET(&d);
+  dstr_putf(&d, "mode=%s, text=%lu", name, (unsigned long)TEXTSZ);
+  regress_framing(rmode, fp, "header", d.buf, d.len);
+
+  /* Start things up. */
+  printf("%s: ", name);
+  setup(key, ksz ? ksz: sizeof(key));
+
+  /* Work through various sizes of up to three fragments.  The middle
+   * fragment is the important one, since it can be misaligned or not at
+   * either end.
+   */
+  sz0 = sz1 = minsz;
+  for (;;) {
+
+    /* If output is to a terminal then display a spinner to keep humans
+     * amused.
+     */
+    if (spin >= 0) {
+      printf("\r%s: [%c]\b\b", name, spinner[spin]); fflush(stdout);
+      spin = (spin + 1)&3;
+    }
+
+    /* Prepare for the test. */
+    sz2 = TEXTSZ - sz1 - sz0;
+    ok = 1;
+
+    /* Encrypt the three fragments. */
+    reset(iv);
+    enc(text, ct, sz0);
+    if (sz1) {
+      memcpy(ct + sz0, text + sz0, sz1);
+      enc(ct + sz0, ct + sz0, sz1);
+    }
+    if (sz2)
+      enc(text + sz0 + sz1, ct + sz0 + sz1, sz2);
+
+    /* Try to check consistency.  We can't do this if (a) the mode is
+     * non-resumable and the fragments sizes are misaligned, or (b) this is
+     * our first pass through and we don't have a consistency reference yet.
+     *
+     * Also, decide whether to deploy the regression test, which we do if and
+     * only if we can't compare against the consistency reference.
+     */
+    regr = 0;
+    if ((f&TEMF_REFALIGN) && (sz0%blksz || sz1%blksz)) regr = 1;
+    else if (!refp) { memcpy(ref, ct, TEXTSZ); regr = 1; refp = 1; }
+    else if (memcmp(ref, ct, TEXTSZ) != 0) {
+      ok = 0;
+      printf("\nConsistency failure (split = %lu/%lu/%lu)\n",
+            (unsigned long)sz0, (unsigned long)sz1, (unsigned long)sz2);
+      dump_split("plaintext", blksz, text, sz0, sz1, sz2);
+      dump_split("reference", blksz, ref, sz0, sz1, sz2);
+      dump_split("ciphertext", blksz, ct, sz0, sz1, sz2);
+      fputc('\n', stdout);
+    }
+
+    /* If we need the regression test then do that.  Write a framing record
+     * to avoid confusion if the policy changes.
+     */
+    if (regr) {
+      DRESET(&d);
+      dstr_putf(&d, "split = %lu/%lu/%lu",
+               (unsigned long)sz0, (unsigned long)sz1, (unsigned long)sz2);
+      regress_framing(rmode, fp, "split", d.buf, d.len);
+      if (regress_crypto(rmode, fp, "regress", blksz, ct, sz0, sz1, sz2))
+       ok = 0;
+    }
+
+    /* Finally, decrypt and check that the round-trip works. */
+    reset(iv);
+    dec(ct, pt, sz0);
+    if (sz1) {
+      memcpy(pt + sz0, ct + sz0, sz1);
+      dec(pt + sz0, pt + sz0, sz1);
+    }
+    if (sz2)
+      dec(ct + sz0 + sz1, pt + sz0 + sz1, sz2);
+    if (memcmp(text, pt, TEXTSZ) != 0) {
+      ok = 0;
+      printf("\nRound-trip failure (split = %lu/%lu/%lu)\n",
+            (unsigned long)sz0, (unsigned long)sz1, (unsigned long)sz2);
+      dump_split("plaintext", blksz, text, sz0, sz1, sz2);
+      dump_split("ciphertext", blksz, ct, sz0, sz1, sz2);
+      dump_split("recovered", blksz, pt, sz0, sz1, sz2);
+      fputc('\n', stdout);
+    }
+
+    /* Update the fragment sizes. */
+    if (!sz1) break;
+    if (step(&sz1, TEXTSZ - sz0) == RESET) {
+      if (step(&sz0, TEXTSZ) == LIMIT) sz1 = 0;
+      else sz1 = minsz;
+    }
+  }
+
+  /* Close the regression data file. */
+  if (fp && (ferror(fp) || fclose(fp)))
+    die(1, "error closing `%s': %s", rname, strerror(errno));
+
+  /* Finish off the eyecandy spinner. */
+  if (spin >= 0) printf("\r%s: [%c] ", name, ok ? '*' : 'X');
+
+  /* Summarize the test result. */
+  if (ok) printf("ok\n");
+  else printf("failed\n");
+
+  /* And we're done. */
+  dstr_destroy(&d);
+  return (!ok);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/symm/modes-test.h b/symm/modes-test.h
new file mode 100644 (file)
index 0000000..a53341c
--- /dev/null
@@ -0,0 +1,165 @@
+/* -*-c-*-
+ *
+ * Common testing for encryption modes
+ *
+ * (c) 2018 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Catacomb is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb.  If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#ifndef CATACOMB_MODES_TEST_H
+#define CATACOMB_MODES_TEST_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <mLib/bits.h>
+
+/*----- Data structures ---------------------------------------------------*/
+
+/* Functions used by `test_encmode' below. */
+typedef void setupfn(const octet */*k*/, size_t /*ksz*/);
+typedef void resetfn(const octet */*iv*/);
+typedef void encfn(const octet */*s*/, octet */*d*/, size_t /*sz*/);
+
+/*----- Functions provided ------------------------------------------------*/
+
+#define TEMF_REFALIGN 1u               /* misalignment of pieces affects
+                                        * the encryption state
+                                        */
+
+/* --- @test_encmode@ --- *
+ *
+ * Arguments:  @const char *name@ = name of the encryption scheme; used to
+ *                     find the regression-test filename
+ *             @size_t ksz@ = key size to use, or zero for `don't care'
+ *             @size_t blksz@ = block size
+ *             @size_t minsz@ = smallest acceptable buffer size, or 1
+ *             @unsigned f@ = various additional flags
+ *             @setupfn *setup@ = key-setup function
+ *             @resetfn *reset@ = state-reset function
+ *             @encfn *enc@ = encryption function
+ *             @decfn *dec@ = decryption function
+ *             @int argc@ = number of command-line arguments
+ *             @char *argv@ = pointer to command-line argument vector
+ *
+ * Returns:    Zero on success, nonzero to report failure.
+ *
+ * Use:                Tests an encryption mode which doesn't have any more formal
+ *             test vectors.
+ *
+ *             The @name@ is used firstly in diagnostic output and secondly
+ *             to form the default filename to use for regression-test data,
+ *             as `.../symm/t/modes/NAME.regress'.
+ *
+ *             The key size @ksz@ is simply passed on back to the @setup@
+ *             function, unless the caller passes in zero, in which case
+ *             @test_encmode@ chooses a key size for itself.
+ *
+ *             The block size @blksz@ is used in failure reports, to draw
+ *             attention to the block structure in the various buffers,
+ *             which may assist with diagnosis.  It's also used to determine
+ *             when to apply a consistency check: see below regarding the
+ *             @TEMF_REFALIGN@ flag.
+ *
+ *             The minimum buffer size @minsz@ expresses a limitation on the
+ *             provided @enc@ and @dec@ functions, that they don't work on
+ *             inputs smaller than @minsz@; accordingly, @test_encmode@ will
+ *             not test such small sizes.  This should be 1 if the mode has
+ *             no limitation.
+ *
+ *             The flags @f@ influence testing in various ways explained
+ *             below.
+ *
+ *             The caller-provided functions are assumed to act on some
+ *             global but hidden state,
+ *
+ *               * @setup@ is (currently, at least) called only once, with
+ *                 the key @k@ and its chosen size @ksz@.
+ *
+ *               * @reset@ is called at the start of each encryption or
+ *                 decryption operation, to program in the initialization
+ *                 vector to use.  Currently, the same IV is used in all of
+ *                 the tests, but this might not always be the case.
+ *
+ *               * @enc@ is called to encrypt a source buffer @s@ and write
+ *                 the ciphertext to a destination @d@; @sz@ is the common
+ *                 size of these buffers.
+ *
+ *               * @dec@ is called to decrypt a source buffer @s@ and write
+ *                 the recovered plaintext to a destination @d@; @sz@ is the
+ *                 common size of these buffers.
+ *
+ *             Finally, @int argc@ and @char *argv@ are the command-line
+ *             arguments provided to @main@; @test_encmode@ parses these and
+ *             alters its behaviour accordingly.
+ *
+ *             Currently, @test_encmode@'s tests are built around a single,
+ *             fairly large, fixed message.  In each test step, the message
+ *             is split into a number of fragments which are encrypted and
+ *             decrypted in turn.
+ *
+ *             The following tests are performed.
+ *
+ *               * The fundamental `round-trip' test, which verifies that
+ *                 the message can be encrypted and then decrypted
+ *                 successfully, if the same fragment boundaries are used in
+ *                 both cases.
+ *
+ *               * A `consistency' test.  Some modes, such as CFB, OFB, and
+ *                 counter, are `resumable': encryption operations are
+ *                 insensitive to the position of fragment boundaries, so a
+ *                 single message can be broken into fragments without
+ *                 affecting the result.  If @TEMF_REFALIGN@ is clear then
+ *                 the mode under test is verified to have this property.
+ *                 If @TEMF_REFALIGN' is set, a weaker property is verified:
+ *                 that encryption is insensitive to the position of
+ *                 /block-aligned/ fragment boundaries only.
+ *
+ *               * A `regression' test, which verifies that the code
+ *                 produces the same ciphertext as a previous version.  By
+ *                 setting command-line arguments appropriately, a test
+ *                 program can be told to record ciphertexts in a (binary)
+ *                 data file.  Usually, instead, the program will read the
+ *                 recorded ciphertexts back and verify that it produces the
+ *                 same data.  For resumable modes, it's only necessary to
+ *                 record single ciphertext, since all the other ciphertexts
+ *                 must be equal by consistency; otherwise all non-block-
+ *                 aligned splits are recorded separately.
+ */
+
+extern int test_encmode(const char */*name*/,
+                       size_t /*ksz*/, size_t /*blksz*/,
+                       size_t /*minsz */, unsigned /*f*/,
+                       setupfn */*setup*/, resetfn */*reset*/,
+                       encfn */*enc*/, encfn */*dec*/,
+                       int /*argc*/, char */*argv*/[]);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
index 395d06f..8ce9f83 100644 (file)
@@ -75,3 +75,12 @@ SYMM_TEST_FILES += t/@{blkc:f}
 %repeat
 SYMM_TEST_FILES += t/@{hash:f}
 %end
+
+## Regression-test files.
+REGRESSION_TEST_FILES =
+%repeat
+REGRESSION_TEST_FILES += t/modes/@{blkc:f}-@{blkcciphermode}.regress
+%end
+%repeat
+REGRESSION_TEST_FILES += t/modes/@{hash:f}-@{hashciphermode}.regress
+%end
index e9eb503..87e750c 100644 (file)
@@ -442,9 +442,7 @@ OFB_TESTX(PRE, pre, name, name)
 
 #ifdef TEST_RIG
 
-#include <stdio.h>
-
-#include "daftstory.h"
+#include "modes-test.h"
 
 /* --- @OFB_TEST@ --- *
  *
@@ -455,85 +453,24 @@ OFB_TESTX(PRE, pre, name, name)
 
 #define OFB_TESTX(PRE, pre, name, fname)                                       \
                                                                        \
-/* --- Initial plaintext for the test --- */                           \
-                                                                       \
-static const octet text[] = TEXT;                                      \
-                                                                       \
-/* --- Key and IV to use --- */                                                \
+static pre##_ctx key;                                                  \
+static pre##_ofbctx ctx;                                               \
                                                                        \
-static const octet key[] = KEY;                                                \
-static const octet iv[] = IV;                                          \
+static void pre##_ofb_test_setup(const octet *k, size_t ksz)           \
+  { pre##_init(&key, k, ksz); pre##_ofbsetkey(&ctx, &key); }           \
                                                                        \
-/* --- Buffers for encryption and decryption output --- */             \
+static void pre##_ofb_test_reset(const octet *iv)                      \
+  { pre##_ofbsetiv(&ctx, iv); }                                                \
                                                                        \
-static octet ct[sizeof(text)];                                         \
-static octet pt[sizeof(text)];                                         \
-                                                                       \
-static void hexdump(const octet *p, size_t sz, size_t off)             \
-{                                                                      \
-  const octet *q = p + sz;                                             \
-  for (sz = 0; p < q; p++, sz++) {                                     \
-    printf("%02x", *p);                                                        \
-    if ((off + sz + 1) % PRE##_BLKSZ == 0)                             \
-      putchar(':');                                                    \
-  }                                                                    \
-}                                                                      \
+static void pre##_ofb_test_enc(const octet *s, octet *d, size_t sz)    \
+  { pre##_ofbencrypt(&ctx, s, d, sz); }                                        \
                                                                        \
-int main(void)                                                         \
+int main(int argc, char *argv[])                                       \
 {                                                                      \
-  size_t sz = 0, rest;                                                 \
-  pre##_ofbctx ctx;                                                    \
-  int status = 0;                                                      \
-  int done = 0;                                                                \
-  pre##_ctx k;                                                         \
-                                                                       \
-  size_t keysz = PRE##_KEYSZ ?                                         \
-    PRE##_KEYSZ : strlen((const char *)key);                           \
-                                                                       \
-  fputs(name "-ofb: ", stdout);                                                \
-                                                                       \
-  pre##_init(&k, key, keysz);                                          \
-  pre##_ofbsetkey(&ctx, &k);                                           \
-                                                                       \
-  while (sz <= sizeof(text)) {                                         \
-    rest = sizeof(text) - sz;                                          \
-    memcpy(ct, text, sizeof(text));                                    \
-    pre##_ofbsetiv(&ctx, iv);                                          \
-    pre##_ofbencrypt(&ctx, ct, ct, sz);                                        \
-    pre##_ofbencrypt(&ctx, ct + sz, ct + sz, rest);                    \
-    memcpy(pt, ct, sizeof(text));                                      \
-    pre##_ofbsetiv(&ctx, iv);                                          \
-    pre##_ofbencrypt(&ctx, pt, pt, rest);                              \
-    pre##_ofbencrypt(&ctx, pt + rest, pt + rest, sz);                  \
-    if (memcmp(pt, text, sizeof(text)) == 0) {                         \
-      done++;                                                          \
-      if (sizeof(text) < 40 || done % 8 == 0)                          \
-       fputc('.', stdout);                                             \
-      if (done % 480 == 0)                                             \
-       fputs("\n\t", stdout);                                          \
-      fflush(stdout);                                                  \
-    } else {                                                           \
-      printf("\nError (sz = %lu)\n", (unsigned long)sz);               \
-      status = 1;                                                      \
-      printf("\tplaintext      = "); hexdump(text, sz, 0);             \
-       printf(", "); hexdump(text + sz, rest, sz);                     \
-       fputc('\n', stdout);                                            \
-      printf("\tciphertext     = "); hexdump(ct, sz, 0);               \
-       printf(", "); hexdump(ct + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      printf("\trecovered text = "); hexdump(pt, sz, 0);               \
-       printf(", "); hexdump(pt + sz, rest, sz);                       \
-       fputc('\n', stdout);                                            \
-      fputc('\n', stdout);                                             \
-    }                                                                  \
-    if (sz < 63)                                                       \
-      sz++;                                                            \
-    else                                                               \
-      sz += 9;                                                         \
-  }                                                                    \
-                                                                       \
-  fputs(status ? " failed\n" : " ok\n", stdout);                       \
-  return (status);                                                     \
+  return test_encmode(fname "-ofb", PRE##_KEYSZ, PRE##_BLKSZ, 1, 0,    \
+                     pre##_ofb_test_setup, pre##_ofb_test_reset,       \
+                     pre##_ofb_test_enc, pre##_ofb_test_enc,           \
+                     argc, argv);                                      \
 }
 
 #else
diff --git a/symm/t/modes/blowfish-cbc.regress b/symm/t/modes/blowfish-cbc.regress
new file mode 100644 (file)
index 0000000..85c0c05
Binary files /dev/null and b/symm/t/modes/blowfish-cbc.regress differ
diff --git a/symm/t/modes/blowfish-cfb.regress b/symm/t/modes/blowfish-cfb.regress
new file mode 100644 (file)
index 0000000..204cba0
Binary files /dev/null and b/symm/t/modes/blowfish-cfb.regress differ
diff --git a/symm/t/modes/blowfish-counter.regress b/symm/t/modes/blowfish-counter.regress
new file mode 100644 (file)
index 0000000..41591ee
Binary files /dev/null and b/symm/t/modes/blowfish-counter.regress differ
diff --git a/symm/t/modes/blowfish-ecb.regress b/symm/t/modes/blowfish-ecb.regress
new file mode 100644 (file)
index 0000000..293b77d
Binary files /dev/null and b/symm/t/modes/blowfish-ecb.regress differ
diff --git a/symm/t/modes/blowfish-ofb.regress b/symm/t/modes/blowfish-ofb.regress
new file mode 100644 (file)
index 0000000..1b37899
Binary files /dev/null and b/symm/t/modes/blowfish-ofb.regress differ
diff --git a/symm/t/modes/cast128-cbc.regress b/symm/t/modes/cast128-cbc.regress
new file mode 100644 (file)
index 0000000..f0942ad
Binary files /dev/null and b/symm/t/modes/cast128-cbc.regress differ
diff --git a/symm/t/modes/cast128-cfb.regress b/symm/t/modes/cast128-cfb.regress
new file mode 100644 (file)
index 0000000..1c859eb
Binary files /dev/null and b/symm/t/modes/cast128-cfb.regress differ
diff --git a/symm/t/modes/cast128-counter.regress b/symm/t/modes/cast128-counter.regress
new file mode 100644 (file)
index 0000000..25cc116
Binary files /dev/null and b/symm/t/modes/cast128-counter.regress differ
diff --git a/symm/t/modes/cast128-ecb.regress b/symm/t/modes/cast128-ecb.regress
new file mode 100644 (file)
index 0000000..30dda77
Binary files /dev/null and b/symm/t/modes/cast128-ecb.regress differ
diff --git a/symm/t/modes/cast128-ofb.regress b/symm/t/modes/cast128-ofb.regress
new file mode 100644 (file)
index 0000000..c1b5ab8
Binary files /dev/null and b/symm/t/modes/cast128-ofb.regress differ
diff --git a/symm/t/modes/cast256-cbc.regress b/symm/t/modes/cast256-cbc.regress
new file mode 100644 (file)
index 0000000..c81b343
Binary files /dev/null and b/symm/t/modes/cast256-cbc.regress differ
diff --git a/symm/t/modes/cast256-cfb.regress b/symm/t/modes/cast256-cfb.regress
new file mode 100644 (file)
index 0000000..15cace7
Binary files /dev/null and b/symm/t/modes/cast256-cfb.regress differ
diff --git a/symm/t/modes/cast256-counter.regress b/symm/t/modes/cast256-counter.regress
new file mode 100644 (file)
index 0000000..d3e4947
Binary files /dev/null and b/symm/t/modes/cast256-counter.regress differ
diff --git a/symm/t/modes/cast256-ecb.regress b/symm/t/modes/cast256-ecb.regress
new file mode 100644 (file)
index 0000000..b80c11b
Binary files /dev/null and b/symm/t/modes/cast256-ecb.regress differ
diff --git a/symm/t/modes/cast256-ofb.regress b/symm/t/modes/cast256-ofb.regress
new file mode 100644 (file)
index 0000000..947bee3
Binary files /dev/null and b/symm/t/modes/cast256-ofb.regress differ
diff --git a/symm/t/modes/des-cbc.regress b/symm/t/modes/des-cbc.regress
new file mode 100644 (file)
index 0000000..c423fb2
Binary files /dev/null and b/symm/t/modes/des-cbc.regress differ
diff --git a/symm/t/modes/des-cfb.regress b/symm/t/modes/des-cfb.regress
new file mode 100644 (file)
index 0000000..918db62
Binary files /dev/null and b/symm/t/modes/des-cfb.regress differ
diff --git a/symm/t/modes/des-counter.regress b/symm/t/modes/des-counter.regress
new file mode 100644 (file)
index 0000000..47eefc1
Binary files /dev/null and b/symm/t/modes/des-counter.regress differ
diff --git a/symm/t/modes/des-ecb.regress b/symm/t/modes/des-ecb.regress
new file mode 100644 (file)
index 0000000..412681e
Binary files /dev/null and b/symm/t/modes/des-ecb.regress differ
diff --git a/symm/t/modes/des-ofb.regress b/symm/t/modes/des-ofb.regress
new file mode 100644 (file)
index 0000000..72ae042
Binary files /dev/null and b/symm/t/modes/des-ofb.regress differ
diff --git a/symm/t/modes/des3-cbc.regress b/symm/t/modes/des3-cbc.regress
new file mode 100644 (file)
index 0000000..012065a
Binary files /dev/null and b/symm/t/modes/des3-cbc.regress differ
diff --git a/symm/t/modes/des3-cfb.regress b/symm/t/modes/des3-cfb.regress
new file mode 100644 (file)
index 0000000..c225f47
Binary files /dev/null and b/symm/t/modes/des3-cfb.regress differ
diff --git a/symm/t/modes/des3-counter.regress b/symm/t/modes/des3-counter.regress
new file mode 100644 (file)
index 0000000..05a7e4d
Binary files /dev/null and b/symm/t/modes/des3-counter.regress differ
diff --git a/symm/t/modes/des3-ecb.regress b/symm/t/modes/des3-ecb.regress
new file mode 100644 (file)
index 0000000..47b26ce
Binary files /dev/null and b/symm/t/modes/des3-ecb.regress differ
diff --git a/symm/t/modes/des3-ofb.regress b/symm/t/modes/des3-ofb.regress
new file mode 100644 (file)
index 0000000..febfc6c
Binary files /dev/null and b/symm/t/modes/des3-ofb.regress differ
diff --git a/symm/t/modes/desx-cbc.regress b/symm/t/modes/desx-cbc.regress
new file mode 100644 (file)
index 0000000..253251d
Binary files /dev/null and b/symm/t/modes/desx-cbc.regress differ
diff --git a/symm/t/modes/desx-cfb.regress b/symm/t/modes/desx-cfb.regress
new file mode 100644 (file)
index 0000000..83d2aa0
Binary files /dev/null and b/symm/t/modes/desx-cfb.regress differ
diff --git a/symm/t/modes/desx-counter.regress b/symm/t/modes/desx-counter.regress
new file mode 100644 (file)
index 0000000..a017464
Binary files /dev/null and b/symm/t/modes/desx-counter.regress differ
diff --git a/symm/t/modes/desx-ecb.regress b/symm/t/modes/desx-ecb.regress
new file mode 100644 (file)
index 0000000..bd32a6e
Binary files /dev/null and b/symm/t/modes/desx-ecb.regress differ
diff --git a/symm/t/modes/desx-ofb.regress b/symm/t/modes/desx-ofb.regress
new file mode 100644 (file)
index 0000000..f6e1a8b
Binary files /dev/null and b/symm/t/modes/desx-ofb.regress differ
diff --git a/symm/t/modes/has160-mgf.regress b/symm/t/modes/has160-mgf.regress
new file mode 100644 (file)
index 0000000..516a475
Binary files /dev/null and b/symm/t/modes/has160-mgf.regress differ
diff --git a/symm/t/modes/idea-cbc.regress b/symm/t/modes/idea-cbc.regress
new file mode 100644 (file)
index 0000000..57230ed
Binary files /dev/null and b/symm/t/modes/idea-cbc.regress differ
diff --git a/symm/t/modes/idea-cfb.regress b/symm/t/modes/idea-cfb.regress
new file mode 100644 (file)
index 0000000..76f0995
Binary files /dev/null and b/symm/t/modes/idea-cfb.regress differ
diff --git a/symm/t/modes/idea-counter.regress b/symm/t/modes/idea-counter.regress
new file mode 100644 (file)
index 0000000..d825c4d
Binary files /dev/null and b/symm/t/modes/idea-counter.regress differ
diff --git a/symm/t/modes/idea-ecb.regress b/symm/t/modes/idea-ecb.regress
new file mode 100644 (file)
index 0000000..e573d52
Binary files /dev/null and b/symm/t/modes/idea-ecb.regress differ
diff --git a/symm/t/modes/idea-ofb.regress b/symm/t/modes/idea-ofb.regress
new file mode 100644 (file)
index 0000000..01fd5dc
Binary files /dev/null and b/symm/t/modes/idea-ofb.regress differ
diff --git a/symm/t/modes/mars-cbc.regress b/symm/t/modes/mars-cbc.regress
new file mode 100644 (file)
index 0000000..30d4d7e
Binary files /dev/null and b/symm/t/modes/mars-cbc.regress differ
diff --git a/symm/t/modes/mars-cfb.regress b/symm/t/modes/mars-cfb.regress
new file mode 100644 (file)
index 0000000..0874aaa
Binary files /dev/null and b/symm/t/modes/mars-cfb.regress differ
diff --git a/symm/t/modes/mars-counter.regress b/symm/t/modes/mars-counter.regress
new file mode 100644 (file)
index 0000000..145e943
Binary files /dev/null and b/symm/t/modes/mars-counter.regress differ
diff --git a/symm/t/modes/mars-ecb.regress b/symm/t/modes/mars-ecb.regress
new file mode 100644 (file)
index 0000000..d7f96df
Binary files /dev/null and b/symm/t/modes/mars-ecb.regress differ
diff --git a/symm/t/modes/mars-ofb.regress b/symm/t/modes/mars-ofb.regress
new file mode 100644 (file)
index 0000000..c29b704
Binary files /dev/null and b/symm/t/modes/mars-ofb.regress differ
diff --git a/symm/t/modes/md2-mgf.regress b/symm/t/modes/md2-mgf.regress
new file mode 100644 (file)
index 0000000..652a65e
Binary files /dev/null and b/symm/t/modes/md2-mgf.regress differ
diff --git a/symm/t/modes/md4-mgf.regress b/symm/t/modes/md4-mgf.regress
new file mode 100644 (file)
index 0000000..e138a74
Binary files /dev/null and b/symm/t/modes/md4-mgf.regress differ
diff --git a/symm/t/modes/md5-mgf.regress b/symm/t/modes/md5-mgf.regress
new file mode 100644 (file)
index 0000000..96bd16a
Binary files /dev/null and b/symm/t/modes/md5-mgf.regress differ
diff --git a/symm/t/modes/noekeon-cbc.regress b/symm/t/modes/noekeon-cbc.regress
new file mode 100644 (file)
index 0000000..5b3e218
Binary files /dev/null and b/symm/t/modes/noekeon-cbc.regress differ
diff --git a/symm/t/modes/noekeon-cfb.regress b/symm/t/modes/noekeon-cfb.regress
new file mode 100644 (file)
index 0000000..75ce901
Binary files /dev/null and b/symm/t/modes/noekeon-cfb.regress differ
diff --git a/symm/t/modes/noekeon-counter.regress b/symm/t/modes/noekeon-counter.regress
new file mode 100644 (file)
index 0000000..464ff7f
Binary files /dev/null and b/symm/t/modes/noekeon-counter.regress differ
diff --git a/symm/t/modes/noekeon-ecb.regress b/symm/t/modes/noekeon-ecb.regress
new file mode 100644 (file)
index 0000000..9a8efe4
Binary files /dev/null and b/symm/t/modes/noekeon-ecb.regress differ
diff --git a/symm/t/modes/noekeon-ofb.regress b/symm/t/modes/noekeon-ofb.regress
new file mode 100644 (file)
index 0000000..91cedd8
Binary files /dev/null and b/symm/t/modes/noekeon-ofb.regress differ
diff --git a/symm/t/modes/rc2-cbc.regress b/symm/t/modes/rc2-cbc.regress
new file mode 100644 (file)
index 0000000..8d49c5a
Binary files /dev/null and b/symm/t/modes/rc2-cbc.regress differ
diff --git a/symm/t/modes/rc2-cfb.regress b/symm/t/modes/rc2-cfb.regress
new file mode 100644 (file)
index 0000000..71ca172
Binary files /dev/null and b/symm/t/modes/rc2-cfb.regress differ
diff --git a/symm/t/modes/rc2-counter.regress b/symm/t/modes/rc2-counter.regress
new file mode 100644 (file)
index 0000000..f57e031
Binary files /dev/null and b/symm/t/modes/rc2-counter.regress differ
diff --git a/symm/t/modes/rc2-ecb.regress b/symm/t/modes/rc2-ecb.regress
new file mode 100644 (file)
index 0000000..07910a7
Binary files /dev/null and b/symm/t/modes/rc2-ecb.regress differ
diff --git a/symm/t/modes/rc2-ofb.regress b/symm/t/modes/rc2-ofb.regress
new file mode 100644 (file)
index 0000000..39c837f
Binary files /dev/null and b/symm/t/modes/rc2-ofb.regress differ
diff --git a/symm/t/modes/rc5-cbc.regress b/symm/t/modes/rc5-cbc.regress
new file mode 100644 (file)
index 0000000..0689ba4
Binary files /dev/null and b/symm/t/modes/rc5-cbc.regress differ
diff --git a/symm/t/modes/rc5-cfb.regress b/symm/t/modes/rc5-cfb.regress
new file mode 100644 (file)
index 0000000..5cd4011
Binary files /dev/null and b/symm/t/modes/rc5-cfb.regress differ
diff --git a/symm/t/modes/rc5-counter.regress b/symm/t/modes/rc5-counter.regress
new file mode 100644 (file)
index 0000000..5700843
Binary files /dev/null and b/symm/t/modes/rc5-counter.regress differ
diff --git a/symm/t/modes/rc5-ecb.regress b/symm/t/modes/rc5-ecb.regress
new file mode 100644 (file)
index 0000000..0ed3ee6
Binary files /dev/null and b/symm/t/modes/rc5-ecb.regress differ
diff --git a/symm/t/modes/rc5-ofb.regress b/symm/t/modes/rc5-ofb.regress
new file mode 100644 (file)
index 0000000..28103d7
Binary files /dev/null and b/symm/t/modes/rc5-ofb.regress differ
diff --git a/symm/t/modes/rijndael-cbc.regress b/symm/t/modes/rijndael-cbc.regress
new file mode 100644 (file)
index 0000000..2d44c16
Binary files /dev/null and b/symm/t/modes/rijndael-cbc.regress differ
diff --git a/symm/t/modes/rijndael-cfb.regress b/symm/t/modes/rijndael-cfb.regress
new file mode 100644 (file)
index 0000000..d0cb101
Binary files /dev/null and b/symm/t/modes/rijndael-cfb.regress differ
diff --git a/symm/t/modes/rijndael-counter.regress b/symm/t/modes/rijndael-counter.regress
new file mode 100644 (file)
index 0000000..49ae7af
Binary files /dev/null and b/symm/t/modes/rijndael-counter.regress differ
diff --git a/symm/t/modes/rijndael-ecb.regress b/symm/t/modes/rijndael-ecb.regress
new file mode 100644 (file)
index 0000000..2668a62
Binary files /dev/null and b/symm/t/modes/rijndael-ecb.regress differ
diff --git a/symm/t/modes/rijndael-ofb.regress b/symm/t/modes/rijndael-ofb.regress
new file mode 100644 (file)
index 0000000..6bc7d19
Binary files /dev/null and b/symm/t/modes/rijndael-ofb.regress differ
diff --git a/symm/t/modes/rijndael192-cbc.regress b/symm/t/modes/rijndael192-cbc.regress
new file mode 100644 (file)
index 0000000..99673d9
Binary files /dev/null and b/symm/t/modes/rijndael192-cbc.regress differ
diff --git a/symm/t/modes/rijndael192-cfb.regress b/symm/t/modes/rijndael192-cfb.regress
new file mode 100644 (file)
index 0000000..899550e
Binary files /dev/null and b/symm/t/modes/rijndael192-cfb.regress differ
diff --git a/symm/t/modes/rijndael192-counter.regress b/symm/t/modes/rijndael192-counter.regress
new file mode 100644 (file)
index 0000000..5b89d87
Binary files /dev/null and b/symm/t/modes/rijndael192-counter.regress differ
diff --git a/symm/t/modes/rijndael192-ecb.regress b/symm/t/modes/rijndael192-ecb.regress
new file mode 100644 (file)
index 0000000..3420f8a
Binary files /dev/null and b/symm/t/modes/rijndael192-ecb.regress differ
diff --git a/symm/t/modes/rijndael192-ofb.regress b/symm/t/modes/rijndael192-ofb.regress
new file mode 100644 (file)
index 0000000..6885dc2
Binary files /dev/null and b/symm/t/modes/rijndael192-ofb.regress differ
diff --git a/symm/t/modes/rijndael256-cbc.regress b/symm/t/modes/rijndael256-cbc.regress
new file mode 100644 (file)
index 0000000..d1f4f96
Binary files /dev/null and b/symm/t/modes/rijndael256-cbc.regress differ
diff --git a/symm/t/modes/rijndael256-cfb.regress b/symm/t/modes/rijndael256-cfb.regress
new file mode 100644 (file)
index 0000000..4e21cd6
Binary files /dev/null and b/symm/t/modes/rijndael256-cfb.regress differ
diff --git a/symm/t/modes/rijndael256-counter.regress b/symm/t/modes/rijndael256-counter.regress
new file mode 100644 (file)
index 0000000..a0eb2f3
Binary files /dev/null and b/symm/t/modes/rijndael256-counter.regress differ
diff --git a/symm/t/modes/rijndael256-ecb.regress b/symm/t/modes/rijndael256-ecb.regress
new file mode 100644 (file)
index 0000000..c82a4b2
Binary files /dev/null and b/symm/t/modes/rijndael256-ecb.regress differ
diff --git a/symm/t/modes/rijndael256-ofb.regress b/symm/t/modes/rijndael256-ofb.regress
new file mode 100644 (file)
index 0000000..45c4091
Binary files /dev/null and b/symm/t/modes/rijndael256-ofb.regress differ
diff --git a/symm/t/modes/rmd128-mgf.regress b/symm/t/modes/rmd128-mgf.regress
new file mode 100644 (file)
index 0000000..27b3f4c
Binary files /dev/null and b/symm/t/modes/rmd128-mgf.regress differ
diff --git a/symm/t/modes/rmd160-mgf.regress b/symm/t/modes/rmd160-mgf.regress
new file mode 100644 (file)
index 0000000..53d466f
Binary files /dev/null and b/symm/t/modes/rmd160-mgf.regress differ
diff --git a/symm/t/modes/rmd256-mgf.regress b/symm/t/modes/rmd256-mgf.regress
new file mode 100644 (file)
index 0000000..4a15390
Binary files /dev/null and b/symm/t/modes/rmd256-mgf.regress differ
diff --git a/symm/t/modes/rmd320-mgf.regress b/symm/t/modes/rmd320-mgf.regress
new file mode 100644 (file)
index 0000000..82b10f3
Binary files /dev/null and b/symm/t/modes/rmd320-mgf.regress differ
diff --git a/symm/t/modes/safer-cbc.regress b/symm/t/modes/safer-cbc.regress
new file mode 100644 (file)
index 0000000..a23aa49
Binary files /dev/null and b/symm/t/modes/safer-cbc.regress differ
diff --git a/symm/t/modes/safer-cfb.regress b/symm/t/modes/safer-cfb.regress
new file mode 100644 (file)
index 0000000..0c49a5c
Binary files /dev/null and b/symm/t/modes/safer-cfb.regress differ
diff --git a/symm/t/modes/safer-counter.regress b/symm/t/modes/safer-counter.regress
new file mode 100644 (file)
index 0000000..03ff097
Binary files /dev/null and b/symm/t/modes/safer-counter.regress differ
diff --git a/symm/t/modes/safer-ecb.regress b/symm/t/modes/safer-ecb.regress
new file mode 100644 (file)
index 0000000..882ff98
Binary files /dev/null and b/symm/t/modes/safer-ecb.regress differ
diff --git a/symm/t/modes/safer-ofb.regress b/symm/t/modes/safer-ofb.regress
new file mode 100644 (file)
index 0000000..b06625b
Binary files /dev/null and b/symm/t/modes/safer-ofb.regress differ
diff --git a/symm/t/modes/safersk-cbc.regress b/symm/t/modes/safersk-cbc.regress
new file mode 100644 (file)
index 0000000..9816c41
Binary files /dev/null and b/symm/t/modes/safersk-cbc.regress differ
diff --git a/symm/t/modes/safersk-cfb.regress b/symm/t/modes/safersk-cfb.regress
new file mode 100644 (file)
index 0000000..8db489f
Binary files /dev/null and b/symm/t/modes/safersk-cfb.regress differ
diff --git a/symm/t/modes/safersk-counter.regress b/symm/t/modes/safersk-counter.regress
new file mode 100644 (file)
index 0000000..a40cd29
Binary files /dev/null and b/symm/t/modes/safersk-counter.regress differ
diff --git a/symm/t/modes/safersk-ecb.regress b/symm/t/modes/safersk-ecb.regress
new file mode 100644 (file)
index 0000000..fcba346
Binary files /dev/null and b/symm/t/modes/safersk-ecb.regress differ
diff --git a/symm/t/modes/safersk-ofb.regress b/symm/t/modes/safersk-ofb.regress
new file mode 100644 (file)
index 0000000..36288cc
Binary files /dev/null and b/symm/t/modes/safersk-ofb.regress differ
diff --git a/symm/t/modes/serpent-cbc.regress b/symm/t/modes/serpent-cbc.regress
new file mode 100644 (file)
index 0000000..0f879de
Binary files /dev/null and b/symm/t/modes/serpent-cbc.regress differ
diff --git a/symm/t/modes/serpent-cfb.regress b/symm/t/modes/serpent-cfb.regress
new file mode 100644 (file)
index 0000000..0d27530
Binary files /dev/null and b/symm/t/modes/serpent-cfb.regress differ
diff --git a/symm/t/modes/serpent-counter.regress b/symm/t/modes/serpent-counter.regress
new file mode 100644 (file)
index 0000000..855d60a
Binary files /dev/null and b/symm/t/modes/serpent-counter.regress differ
diff --git a/symm/t/modes/serpent-ecb.regress b/symm/t/modes/serpent-ecb.regress
new file mode 100644 (file)
index 0000000..5306e95
Binary files /dev/null and b/symm/t/modes/serpent-ecb.regress differ
diff --git a/symm/t/modes/serpent-ofb.regress b/symm/t/modes/serpent-ofb.regress
new file mode 100644 (file)
index 0000000..3b5e6e7
Binary files /dev/null and b/symm/t/modes/serpent-ofb.regress differ
diff --git a/symm/t/modes/sha-mgf.regress b/symm/t/modes/sha-mgf.regress
new file mode 100644 (file)
index 0000000..797011a
Binary files /dev/null and b/symm/t/modes/sha-mgf.regress differ
diff --git a/symm/t/modes/sha224-mgf.regress b/symm/t/modes/sha224-mgf.regress
new file mode 100644 (file)
index 0000000..559e830
Binary files /dev/null and b/symm/t/modes/sha224-mgf.regress differ
diff --git a/symm/t/modes/sha256-mgf.regress b/symm/t/modes/sha256-mgf.regress
new file mode 100644 (file)
index 0000000..b6aa141
Binary files /dev/null and b/symm/t/modes/sha256-mgf.regress differ
diff --git a/symm/t/modes/sha3-224-mgf.regress b/symm/t/modes/sha3-224-mgf.regress
new file mode 100644 (file)
index 0000000..5bd9f01
Binary files /dev/null and b/symm/t/modes/sha3-224-mgf.regress differ
diff --git a/symm/t/modes/sha3-256-mgf.regress b/symm/t/modes/sha3-256-mgf.regress
new file mode 100644 (file)
index 0000000..0324143
Binary files /dev/null and b/symm/t/modes/sha3-256-mgf.regress differ
diff --git a/symm/t/modes/sha3-384-mgf.regress b/symm/t/modes/sha3-384-mgf.regress
new file mode 100644 (file)
index 0000000..dc86c05
Binary files /dev/null and b/symm/t/modes/sha3-384-mgf.regress differ
diff --git a/symm/t/modes/sha3-512-mgf.regress b/symm/t/modes/sha3-512-mgf.regress
new file mode 100644 (file)
index 0000000..e9b0fe0
Binary files /dev/null and b/symm/t/modes/sha3-512-mgf.regress differ
diff --git a/symm/t/modes/sha384-mgf.regress b/symm/t/modes/sha384-mgf.regress
new file mode 100644 (file)
index 0000000..bf688b2
Binary files /dev/null and b/symm/t/modes/sha384-mgf.regress differ
diff --git a/symm/t/modes/sha512-224-mgf.regress b/symm/t/modes/sha512-224-mgf.regress
new file mode 100644 (file)
index 0000000..ccd94ba
Binary files /dev/null and b/symm/t/modes/sha512-224-mgf.regress differ
diff --git a/symm/t/modes/sha512-256-mgf.regress b/symm/t/modes/sha512-256-mgf.regress
new file mode 100644 (file)
index 0000000..a01aa7a
Binary files /dev/null and b/symm/t/modes/sha512-256-mgf.regress differ
diff --git a/symm/t/modes/sha512-mgf.regress b/symm/t/modes/sha512-mgf.regress
new file mode 100644 (file)
index 0000000..3dae6fa
Binary files /dev/null and b/symm/t/modes/sha512-mgf.regress differ
diff --git a/symm/t/modes/skipjack-cbc.regress b/symm/t/modes/skipjack-cbc.regress
new file mode 100644 (file)
index 0000000..a1fad97
Binary files /dev/null and b/symm/t/modes/skipjack-cbc.regress differ
diff --git a/symm/t/modes/skipjack-cfb.regress b/symm/t/modes/skipjack-cfb.regress
new file mode 100644 (file)
index 0000000..3186986
Binary files /dev/null and b/symm/t/modes/skipjack-cfb.regress differ
diff --git a/symm/t/modes/skipjack-counter.regress b/symm/t/modes/skipjack-counter.regress
new file mode 100644 (file)
index 0000000..33a0ab1
Binary files /dev/null and b/symm/t/modes/skipjack-counter.regress differ
diff --git a/symm/t/modes/skipjack-ecb.regress b/symm/t/modes/skipjack-ecb.regress
new file mode 100644 (file)
index 0000000..6cbf31c
Binary files /dev/null and b/symm/t/modes/skipjack-ecb.regress differ
diff --git a/symm/t/modes/skipjack-ofb.regress b/symm/t/modes/skipjack-ofb.regress
new file mode 100644 (file)
index 0000000..2ff46ea
Binary files /dev/null and b/symm/t/modes/skipjack-ofb.regress differ
diff --git a/symm/t/modes/square-cbc.regress b/symm/t/modes/square-cbc.regress
new file mode 100644 (file)
index 0000000..40008aa
Binary files /dev/null and b/symm/t/modes/square-cbc.regress differ
diff --git a/symm/t/modes/square-cfb.regress b/symm/t/modes/square-cfb.regress
new file mode 100644 (file)
index 0000000..b8dda4e
Binary files /dev/null and b/symm/t/modes/square-cfb.regress differ
diff --git a/symm/t/modes/square-counter.regress b/symm/t/modes/square-counter.regress
new file mode 100644 (file)
index 0000000..39be028
Binary files /dev/null and b/symm/t/modes/square-counter.regress differ
diff --git a/symm/t/modes/square-ecb.regress b/symm/t/modes/square-ecb.regress
new file mode 100644 (file)
index 0000000..8aeff53
Binary files /dev/null and b/symm/t/modes/square-ecb.regress differ
diff --git a/symm/t/modes/square-ofb.regress b/symm/t/modes/square-ofb.regress
new file mode 100644 (file)
index 0000000..f718ed3
Binary files /dev/null and b/symm/t/modes/square-ofb.regress differ
diff --git a/symm/t/modes/tea-cbc.regress b/symm/t/modes/tea-cbc.regress
new file mode 100644 (file)
index 0000000..103aa1d
Binary files /dev/null and b/symm/t/modes/tea-cbc.regress differ
diff --git a/symm/t/modes/tea-cfb.regress b/symm/t/modes/tea-cfb.regress
new file mode 100644 (file)
index 0000000..78d0c7b
Binary files /dev/null and b/symm/t/modes/tea-cfb.regress differ
diff --git a/symm/t/modes/tea-counter.regress b/symm/t/modes/tea-counter.regress
new file mode 100644 (file)
index 0000000..d637d2d
Binary files /dev/null and b/symm/t/modes/tea-counter.regress differ
diff --git a/symm/t/modes/tea-ecb.regress b/symm/t/modes/tea-ecb.regress
new file mode 100644 (file)
index 0000000..8524c0c
Binary files /dev/null and b/symm/t/modes/tea-ecb.regress differ
diff --git a/symm/t/modes/tea-ofb.regress b/symm/t/modes/tea-ofb.regress
new file mode 100644 (file)
index 0000000..679611b
Binary files /dev/null and b/symm/t/modes/tea-ofb.regress differ
diff --git a/symm/t/modes/tiger-mgf.regress b/symm/t/modes/tiger-mgf.regress
new file mode 100644 (file)
index 0000000..497a490
Binary files /dev/null and b/symm/t/modes/tiger-mgf.regress differ
diff --git a/symm/t/modes/twofish-cbc.regress b/symm/t/modes/twofish-cbc.regress
new file mode 100644 (file)
index 0000000..bf01929
Binary files /dev/null and b/symm/t/modes/twofish-cbc.regress differ
diff --git a/symm/t/modes/twofish-cfb.regress b/symm/t/modes/twofish-cfb.regress
new file mode 100644 (file)
index 0000000..c3f9ea2
Binary files /dev/null and b/symm/t/modes/twofish-cfb.regress differ
diff --git a/symm/t/modes/twofish-counter.regress b/symm/t/modes/twofish-counter.regress
new file mode 100644 (file)
index 0000000..ad27602
Binary files /dev/null and b/symm/t/modes/twofish-counter.regress differ
diff --git a/symm/t/modes/twofish-ecb.regress b/symm/t/modes/twofish-ecb.regress
new file mode 100644 (file)
index 0000000..58e4f93
Binary files /dev/null and b/symm/t/modes/twofish-ecb.regress differ
diff --git a/symm/t/modes/twofish-ofb.regress b/symm/t/modes/twofish-ofb.regress
new file mode 100644 (file)
index 0000000..a11550a
Binary files /dev/null and b/symm/t/modes/twofish-ofb.regress differ
diff --git a/symm/t/modes/whirlpool-mgf.regress b/symm/t/modes/whirlpool-mgf.regress
new file mode 100644 (file)
index 0000000..0f48f39
Binary files /dev/null and b/symm/t/modes/whirlpool-mgf.regress differ
diff --git a/symm/t/modes/whirlpool256-mgf.regress b/symm/t/modes/whirlpool256-mgf.regress
new file mode 100644 (file)
index 0000000..5051954
Binary files /dev/null and b/symm/t/modes/whirlpool256-mgf.regress differ
diff --git a/symm/t/modes/xtea-cbc.regress b/symm/t/modes/xtea-cbc.regress
new file mode 100644 (file)
index 0000000..04f4ea2
Binary files /dev/null and b/symm/t/modes/xtea-cbc.regress differ
diff --git a/symm/t/modes/xtea-cfb.regress b/symm/t/modes/xtea-cfb.regress
new file mode 100644 (file)
index 0000000..3bde823
Binary files /dev/null and b/symm/t/modes/xtea-cfb.regress differ
diff --git a/symm/t/modes/xtea-counter.regress b/symm/t/modes/xtea-counter.regress
new file mode 100644 (file)
index 0000000..f56c42a
Binary files /dev/null and b/symm/t/modes/xtea-counter.regress differ
diff --git a/symm/t/modes/xtea-ecb.regress b/symm/t/modes/xtea-ecb.regress
new file mode 100644 (file)
index 0000000..cc252a6
Binary files /dev/null and b/symm/t/modes/xtea-ecb.regress differ
diff --git a/symm/t/modes/xtea-ofb.regress b/symm/t/modes/xtea-ofb.regress
new file mode 100644 (file)
index 0000000..ef53aff
Binary files /dev/null and b/symm/t/modes/xtea-ofb.regress differ