| 1 | /* -*-c-*- |
| 2 | * |
| 3 | * Common testing for encryption modes |
| 4 | * |
| 5 | * (c) 2018 Straylight/Edgeware |
| 6 | */ |
| 7 | |
| 8 | /*----- Licensing notice --------------------------------------------------* |
| 9 | * |
| 10 | * This file is part of Catacomb. |
| 11 | * |
| 12 | * Catacomb is free software: you can redistribute it and/or modify it |
| 13 | * under the terms of the GNU Library General Public License as published |
| 14 | * by the Free Software Foundation; either version 2 of the License, or |
| 15 | * (at your option) any later version. |
| 16 | * |
| 17 | * Catacomb is distributed in the hope that it will be useful, but |
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 20 | * Library General Public License for more details. |
| 21 | * |
| 22 | * You should have received a copy of the GNU Library General Public |
| 23 | * License along with Catacomb. If not, write to the Free Software |
| 24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
| 25 | * USA. |
| 26 | */ |
| 27 | |
| 28 | #ifndef CATACOMB_MODES_TEST_H |
| 29 | #define CATACOMB_MODES_TEST_H |
| 30 | |
| 31 | #ifdef __cplusplus |
| 32 | extern "C" { |
| 33 | #endif |
| 34 | |
| 35 | /*----- Header files ------------------------------------------------------*/ |
| 36 | |
| 37 | #include <mLib/bits.h> |
| 38 | |
| 39 | /*----- Data structures ---------------------------------------------------*/ |
| 40 | |
| 41 | /* Functions used by `test_encmode' below. */ |
| 42 | typedef void setupfn(const octet */*k*/, size_t /*ksz*/); |
| 43 | typedef void resetfn(const octet */*iv*/); |
| 44 | typedef void encfn(const octet */*s*/, octet */*d*/, size_t /*sz*/); |
| 45 | |
| 46 | /*----- Functions provided ------------------------------------------------*/ |
| 47 | |
| 48 | #define TEMF_REFALIGN 1u /* misalignment of pieces affects |
| 49 | * the encryption state |
| 50 | */ |
| 51 | |
| 52 | /* --- @test_encmode@ --- * |
| 53 | * |
| 54 | * Arguments: @const char *name@ = name of the encryption scheme; used to |
| 55 | * find the regression-test filename |
| 56 | * @size_t ksz@ = key size to use, or zero for `don't care' |
| 57 | * @size_t blksz@ = block size |
| 58 | * @size_t minsz@ = smallest acceptable buffer size, or 1 |
| 59 | * @unsigned f@ = various additional flags |
| 60 | * @setupfn *setup@ = key-setup function |
| 61 | * @resetfn *reset@ = state-reset function |
| 62 | * @encfn *enc@ = encryption function |
| 63 | * @decfn *dec@ = decryption function |
| 64 | * @int argc@ = number of command-line arguments |
| 65 | * @char *argv@ = pointer to command-line argument vector |
| 66 | * |
| 67 | * Returns: Zero on success, nonzero to report failure. |
| 68 | * |
| 69 | * Use: Tests an encryption mode which doesn't have any more formal |
| 70 | * test vectors. |
| 71 | * |
| 72 | * The @name@ is used firstly in diagnostic output and secondly |
| 73 | * to form the default filename to use for regression-test data, |
| 74 | * as `.../symm/t/modes/NAME.regress'. |
| 75 | * |
| 76 | * The key size @ksz@ is simply passed on back to the @setup@ |
| 77 | * function, unless the caller passes in zero, in which case |
| 78 | * @test_encmode@ chooses a key size for itself. |
| 79 | * |
| 80 | * The block size @blksz@ is used in failure reports, to draw |
| 81 | * attention to the block structure in the various buffers, |
| 82 | * which may assist with diagnosis. It's also used to determine |
| 83 | * when to apply a consistency check: see below regarding the |
| 84 | * @TEMF_REFALIGN@ flag. |
| 85 | * |
| 86 | * The minimum buffer size @minsz@ expresses a limitation on the |
| 87 | * provided @enc@ and @dec@ functions, that they don't work on |
| 88 | * inputs smaller than @minsz@; accordingly, @test_encmode@ will |
| 89 | * not test such small sizes. This should be 1 if the mode has |
| 90 | * no limitation. |
| 91 | * |
| 92 | * The flags @f@ influence testing in various ways explained |
| 93 | * below. |
| 94 | * |
| 95 | * The caller-provided functions are assumed to act on some |
| 96 | * global but hidden state, |
| 97 | * |
| 98 | * * @setup@ is (currently, at least) called only once, with |
| 99 | * the key @k@ and its chosen size @ksz@. |
| 100 | * |
| 101 | * * @reset@ is called at the start of each encryption or |
| 102 | * decryption operation, to program in the initialization |
| 103 | * vector to use. Currently, the same IV is used in all of |
| 104 | * the tests, but this might not always be the case. |
| 105 | * |
| 106 | * * @enc@ is called to encrypt a source buffer @s@ and write |
| 107 | * the ciphertext to a destination @d@; @sz@ is the common |
| 108 | * size of these buffers. @d@ might be null, to discard |
| 109 | * output; @s@ might be null, to process all-zero input. |
| 110 | * |
| 111 | * * @dec@ is called to decrypt a source buffer @s@ and write |
| 112 | * the recovered plaintext to a destination @d@; @sz@ is the |
| 113 | * common size of these buffers. |
| 114 | * |
| 115 | * Finally, @int argc@ and @char *argv@ are the command-line |
| 116 | * arguments provided to @main@; @test_encmode@ parses these and |
| 117 | * alters its behaviour accordingly. |
| 118 | * |
| 119 | * Currently, @test_encmode@'s tests are built around a single, |
| 120 | * fairly large, fixed message. In each test step, the message |
| 121 | * is split into a number of fragments which are encrypted and |
| 122 | * decrypted in turn. |
| 123 | * |
| 124 | * The following tests are performed. |
| 125 | * |
| 126 | * * The fundamental `round-trip' test, which verifies that |
| 127 | * the message can be encrypted and then decrypted |
| 128 | * successfully, if the same fragment boundaries are used in |
| 129 | * both cases. |
| 130 | * |
| 131 | * * A `consistency' test. Some modes, such as CFB, OFB, and |
| 132 | * counter, are `resumable': encryption operations are |
| 133 | * insensitive to the position of fragment boundaries, so a |
| 134 | * single message can be broken into fragments without |
| 135 | * affecting the result. If @TEMF_REFALIGN@ is clear then |
| 136 | * the mode under test is verified to have this property. |
| 137 | * If @TEMF_REFALIGN' is set, a weaker property is verified: |
| 138 | * that encryption is insensitive to the position of |
| 139 | * /block-aligned/ fragment boundaries only. |
| 140 | * |
| 141 | * * A `regression' test, which verifies that the code |
| 142 | * produces the same ciphertext as a previous version. By |
| 143 | * setting command-line arguments appropriately, a test |
| 144 | * program can be told to record ciphertexts in a (binary) |
| 145 | * data file. Usually, instead, the program will read the |
| 146 | * recorded ciphertexts back and verify that it produces the |
| 147 | * same data. For resumable modes, it's only necessary to |
| 148 | * record single ciphertext, since all the other ciphertexts |
| 149 | * must be equal by consistency; otherwise all non-block- |
| 150 | * aligned splits are recorded separately. |
| 151 | */ |
| 152 | |
| 153 | extern int test_encmode(const char */*name*/, |
| 154 | size_t /*ksz*/, size_t /*blksz*/, |
| 155 | size_t /*minsz */, unsigned /*f*/, |
| 156 | setupfn */*setup*/, resetfn */*reset*/, |
| 157 | encfn */*enc*/, encfn */*dec*/, |
| 158 | int /*argc*/, char */*argv*/[]); |
| 159 | |
| 160 | /*----- That's all, folks -------------------------------------------------*/ |
| 161 | |
| 162 | #ifdef __cplusplus |
| 163 | } |
| 164 | #endif |
| 165 | |
| 166 | #endif |