Commit | Line | Data |
---|---|---|
a4c6c9ba MW |
1 | /* |
2 | * crypto-test.h: common test vector processing | |
3 | */ | |
4 | /* | |
5 | * This file is Free Software. It was originally written for secnet. | |
6 | * | |
22708ca2 | 7 | * Copyright 2017, 2019 Mark Wooding |
a4c6c9ba MW |
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 */ | |
3f8f9733 MW |
69 | struct { unsigned char *p; size_t sz; } bytes; /* buffer of bytes */ |
70 | struct { char *p; size_t sz; } str; /* text string */ | |
a4c6c9ba MW |
71 | #ifdef REG_MEMBERS |
72 | REG_MEMBERS /* your members here */ | |
73 | #endif | |
74 | }; | |
75 | ||
76 | struct reg { | |
77 | unsigned f; /* flags */ | |
78 | #define REGF_LIVE 1u /* input register has a value */ | |
79 | union regval v; /* register value */ | |
80 | }; | |
81 | ||
82 | struct regty { | |
83 | void (*init)(union regval *v); /* set up raw memory */ | |
84 | void (*parse)(union regval *v, char *p); /* parse text input as value */ | |
85 | void (*dump)(FILE *fp, const union regval *v); /* dump value as text */ | |
86 | int (*eq)(const union regval *v0, const union regval *v1); /* equal? */ | |
87 | void (*release)(union regval *v); /* release any resources */ | |
88 | }; | |
89 | ||
90 | struct regdef { | |
91 | const char *name; /* register name (for input files) */ | |
92 | unsigned i; /* register index */ | |
93 | const struct regty *ty; /* register type descriptor */ | |
94 | unsigned f; /* flags */ | |
95 | #define REGF_OPT 1u /* (input) register is optional */ | |
96 | }; | |
97 | #define REGLIST_END { 0 } | |
98 | ||
99 | struct test_state { | |
100 | struct reg *in, *out; /* vectors of registers */ | |
101 | unsigned nrout; /* number of output registers */ | |
102 | unsigned nreg; /* total number of registers */ | |
103 | size_t regsz; /* size of an individual register */ | |
104 | int win, lose; /* number of tests passed/failed */ | |
105 | }; | |
106 | ||
107 | struct test { | |
108 | const char *name; /* name of the test */ | |
109 | void (*run)(struct test_state *state, const struct test *test); | |
110 | /* test runner (`run_test') */ | |
111 | const struct regdef *regs; /* register definitions */ | |
112 | void (*fn)(struct reg *out, const struct reg *in, void *ctx); | |
113 | /* test function */ | |
114 | }; | |
115 | ||
116 | /* Utility functions. */ | |
117 | extern NORETURN(bail(const char *msg, ...)) | |
118 | FORMAT(printf, 1, 2); | |
119 | extern void parse_hex(uint8_t *b, size_t sz, char *p); | |
120 | extern void dump_hex(FILE *fp, const uint8_t *b, size_t sz); | |
121 | extern void trivial_regty_init(union regval *v); | |
122 | extern void trivial_regty_release(union regval *v); | |
123 | extern void allocate_bytes(union regval *v, size_t sz); | |
3f8f9733 | 124 | extern void allocate_string(union regval *v, size_t sz); |
a4c6c9ba MW |
125 | |
126 | /* Built-in register types. */ | |
127 | extern const struct regty | |
128 | regty_int, | |
129 | regty_uint, | |
3f8f9733 MW |
130 | regty_bytes, |
131 | regty_string; | |
a4c6c9ba MW |
132 | |
133 | /* Running tests. */ | |
134 | extern void check_test_output(struct test_state *state, | |
135 | const struct test *test); | |
136 | extern void run_test(struct test_state *state, const struct test *test); | |
137 | extern int run_test_suite(unsigned nrout, unsigned nreg, size_t regsz, | |
138 | const struct test *tests, FILE *fp); | |
139 | ||
140 | #endif |