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