chiark / gitweb /
@@@ 64-bit kludging
[secnet] / crypto-test.h
1 /*
2  * crypto-test.h: common test vector processing
3  */
4 /*
5  * This file is Free Software.  It was originally written for secnet.
6  *
7  * Copyright 2017, 2019 Mark Wooding
8  *
9  * You may redistribute secnet as a whole and/or modify it under the
10  * terms of the GNU General Public License as published by the Free
11  * Software Foundation; either version 3, or (at your option) any
12  * later version.
13  *
14  * You may redistribute this file and/or modify it under the terms of
15  * the GNU General Public License as published by the Free Software
16  * Foundation; either version 2, or (at your option) any later
17  * version.
18  *
19  * This software is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this software; if not, see
26  * https://www.gnu.org/licenses/gpl.html.
27  */
28
29 #ifndef crypto_test_h
30 #define crypto_test_h
31
32 /* Basic model.
33  *
34  * There is a collection of `registers', each of which can store a value.
35  * Some registers are designated as `input': their values are set while
36  * reading the test vector.  Other registers are designated as `output': the
37  * test function is expected to calculate their values, which are then
38  * compared against final values supplied by the test vector.  Any
39  * discrepancies are reported.
40  *
41  * While a test suite is running, there is a single vector of registers, and
42  * registers are identified by index, starting from zero.  The number of
43  * registers, `nreg', and a threshold `nrout', are defined by the test suite:
44  * registers with index less than `nrout' are for output; other registers up
45  * to, but not including, `nreg' are for input.  Finally, the test suite
46  * defines the size of a register.  The common test machinery treats
47  * registers as entirely opaque, acting on them only through their defined
48  * types.
49  *
50  * Each kind of test defines a register mapping, which assigns types and
51  * (textual) names to some subset of the registers.  A register can be marked
52  * optional; by default, the test vector parser will report an error if a
53  * defined register is not assigned a value.
54  *
55  * The register type is responsible for handling the register on behalf of
56  * the common code.  (Test functions can have built-in knowledge of which
57  * registers have which types, and can manipulate registers directly, of
58  * course.)
59  *
60  * Finally, each test defines a test runner, which is responsible for
61  * invoking the test function and checking that the output registers are
62  * correct.  There is a generic test runner, but some tests might benefit
63  * from special arrangements.
64  */
65
66 union regval {
67     long i;                             /* signed integer */
68     unsigned long u;                    /* unsigned integer */
69     struct { void *p; size_t sz; } bytes; /* buffer of bytes */
70 #ifdef REG_MEMBERS
71     REG_MEMBERS                         /* your members here */
72 #endif
73 };
74
75 struct reg {
76     unsigned f;                         /* flags */
77 #define REGF_LIVE 1u                    /*   input register has a value */
78     union regval v;                     /* register value */
79 };
80
81 struct regty {
82     void (*init)(union regval *v);      /* set up raw memory */
83     void (*parse)(union regval *v, char *p); /* parse text input as value */
84     void (*dump)(FILE *fp, const union regval *v); /* dump value as text */
85     int (*eq)(const union regval *v0, const union regval *v1); /* equal? */
86     void (*release)(union regval *v);   /* release any resources */
87 };
88
89 struct regdef {
90     const char *name;                   /* register name (for input files) */
91     unsigned i;                         /* register index */
92     const struct regty *ty;             /* register type descriptor */
93     unsigned f;                         /* flags */
94 #define REGF_OPT 1u                     /*   (input) register is optional */
95 };
96 #define REGLIST_END { 0 }
97
98 struct test_state {
99     struct reg *in, *out;               /* vectors of registers */
100     unsigned nrout;                     /* number of output registers */
101     unsigned nreg;                      /* total number of registers */
102     size_t regsz;                       /* size of an individual register */
103     int win, lose;                      /* number of tests passed/failed */
104 };
105
106 struct test {
107     const char *name;                   /* name of the test */
108     void (*run)(struct test_state *state, const struct test *test);
109                                         /* test runner (`run_test') */
110     const struct regdef *regs;          /* register definitions */
111     void (*fn)(struct reg *out, const struct reg *in, void *ctx);
112                                         /* test function */
113 };
114
115 /* Utility functions. */
116 extern NORETURN(bail(const char *msg, ...))
117     FORMAT(printf, 1, 2);
118 extern void parse_hex(uint8_t *b, size_t sz, char *p);
119 extern void dump_hex(FILE *fp, const uint8_t *b, size_t sz);
120 extern void trivial_regty_init(union regval *v);
121 extern void trivial_regty_release(union regval *v);
122 extern void allocate_bytes(union regval *v, size_t sz);
123
124 /* Built-in register types. */
125 extern const struct regty
126     regty_int,
127     regty_uint,
128     regty_bytes;
129
130 /* Running tests. */
131 extern void check_test_output(struct test_state *state,
132                               const struct test *test);
133 extern void run_test(struct test_state *state, const struct test *test);
134 extern int run_test_suite(unsigned nrout, unsigned nreg, size_t regsz,
135                           const struct test *tests, FILE *fp);
136
137 #endif