symm/*-def.h: Overhaul encryption mode testing.
[catacomb] / symm / modes-test.h
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