diff options
author | tb <> | 2024-12-26 00:04:24 +0000 |
---|---|---|
committer | tb <> | 2024-12-26 00:04:24 +0000 |
commit | 31d1b04da9af806cdb66a2b49ed6490e67479eef (patch) | |
tree | f187d226245651988501e2fb8891081ff9eea9f2 /src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c | |
parent | fe8b80dbfd7a71d866da84cfdab5d2ce23feac28 (diff) | |
download | openbsd-31d1b04da9af806cdb66a2b49ed6490e67479eef.tar.gz openbsd-31d1b04da9af806cdb66a2b49ed6490e67479eef.tar.bz2 openbsd-31d1b04da9af806cdb66a2b49ed6490e67479eef.zip |
Overhaul ML-KEM regress once more
Implement a file parser that drives a state machine to extract the test data
from the .txt files and manages the parsed data. Comments and empty lines are
ignored. The code currently assumes that instruction lines are at the start
of the file (which isn't generally true) and only supports two line types for
now. This is good enough for all the ML-KEM tests but should be easy enough
to extend.
Once all data for a test case is parsed in the expected order, a test handler
is called which can retrieve the test data via a simple API and throw warnings
and errors with information on the test case line number, etc.
Merge the tests into three programs: one parsing the .txt files and running
the corresponding test cases, a unit test and the iteration tests. Deduplicate
the actual test code and let the caller pass in an object containing the
API functions, private keys and arrays that need to be different between the
768 version and the 1024 version. This way we don't have two sets of half a
dozen .c files differing only in 3 or 4 occurrences of 768 and 1024.
All this will also make it a lot easier to hook these tests into portable.
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c')
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c | 195 |
1 files changed, 0 insertions, 195 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c deleted file mode 100644 index 7d76a625b0..0000000000 --- a/src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c +++ /dev/null | |||
@@ -1,195 +0,0 @@ | |||
1 | /* $OpenBSD: mlkem1024_decap_tests.c,v 1.4 2024/12/20 00:32:15 tb Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2024 Google Inc. | ||
4 | * Copyright (c) 2024 Bob Beck <beck@obtuse.com> | ||
5 | * Copyright (c) 2024 Theo Buehler <tb@openbsd.org> | ||
6 | * | ||
7 | * Permission to use, copy, modify, and/or distribute this software for any | ||
8 | * purpose with or without fee is hereby granted, provided that the above | ||
9 | * copyright notice and this permission notice appear in all copies. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
14 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
16 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
17 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
18 | */ | ||
19 | |||
20 | #include <assert.h> | ||
21 | #include <err.h> | ||
22 | #include <stdint.h> | ||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | |||
26 | #include "bytestring.h" | ||
27 | #include "mlkem.h" | ||
28 | |||
29 | #include "mlkem_tests_util.h" | ||
30 | |||
31 | static int | ||
32 | MlkemDecapFileTest(CBB *ciphertext_cbb, CBB *shared_secret_cbb, | ||
33 | CBB *private_key_cbb, int should_fail, size_t line) | ||
34 | { | ||
35 | struct MLKEM1024_private_key priv; | ||
36 | uint8_t *ciphertext = NULL, *shared_secret = NULL, *private_key = NULL; | ||
37 | size_t ciphertext_len = 0, shared_secret_len = 0, private_key_len = 0; | ||
38 | uint8_t shared_secret_buf[MLKEM_SHARED_SECRET_BYTES]; | ||
39 | CBS private_key_cbs; | ||
40 | int failed = 1; | ||
41 | |||
42 | if (!CBB_finish(ciphertext_cbb, &ciphertext, &ciphertext_len)) | ||
43 | goto err; | ||
44 | if (!CBB_finish(shared_secret_cbb, &shared_secret, &shared_secret_len)) | ||
45 | goto err; | ||
46 | if (!CBB_finish(private_key_cbb, &private_key, &private_key_len)) | ||
47 | goto err; | ||
48 | |||
49 | CBS_init(&private_key_cbs, private_key, private_key_len); | ||
50 | |||
51 | if (!MLKEM1024_parse_private_key(&priv, &private_key_cbs)) { | ||
52 | if ((failed = !should_fail)) | ||
53 | warnx("#%zu: parse_private_key", line); | ||
54 | goto err; | ||
55 | } | ||
56 | if (!MLKEM1024_decap(shared_secret_buf, ciphertext, ciphertext_len, | ||
57 | &priv)) { | ||
58 | if ((failed = !should_fail)) | ||
59 | warnx("#%zu: decap", line); | ||
60 | goto err; | ||
61 | } | ||
62 | |||
63 | failed = compare_data(shared_secret, shared_secret_buf, | ||
64 | MLKEM_SHARED_SECRET_BYTES, line, "shared_secret"); | ||
65 | |||
66 | if (should_fail != failed) { | ||
67 | warnx("FAIL: #%zu: should_fail %d, failed %d", | ||
68 | line, should_fail, failed); | ||
69 | failed = 1; | ||
70 | } | ||
71 | |||
72 | err: | ||
73 | CBB_cleanup(ciphertext_cbb); | ||
74 | CBB_cleanup(shared_secret_cbb); | ||
75 | CBB_cleanup(private_key_cbb); | ||
76 | freezero(ciphertext, ciphertext_len); | ||
77 | freezero(shared_secret, shared_secret_len); | ||
78 | freezero(private_key, private_key_len); | ||
79 | |||
80 | return failed; | ||
81 | } | ||
82 | |||
83 | #define S_START 0 | ||
84 | #define S_COMMENT 1 | ||
85 | #define S_PRIVATE_KEY 2 | ||
86 | #define S_CIPHERTEXT 3 | ||
87 | #define S_RESULT 4 | ||
88 | #define S_SHARED_SECRET 5 | ||
89 | |||
90 | #define S2S(x) case x: return #x | ||
91 | |||
92 | static const char * | ||
93 | state2str(int state) | ||
94 | { | ||
95 | switch (state) { | ||
96 | S2S(S_START); | ||
97 | S2S(S_COMMENT); | ||
98 | S2S(S_PRIVATE_KEY); | ||
99 | S2S(S_CIPHERTEXT); | ||
100 | S2S(S_RESULT); | ||
101 | S2S(S_SHARED_SECRET); | ||
102 | default: | ||
103 | errx(1, "unknown state %d", state); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | int | ||
108 | main(int argc, char **argv) | ||
109 | { | ||
110 | CBB ciphertext = { 0 }, shared_secret = { 0 }, private_key = { 0 }; | ||
111 | int should_fail = 0; | ||
112 | const char *test; | ||
113 | size_t line = 0; | ||
114 | char *buf = NULL; | ||
115 | size_t buflen = 0; | ||
116 | ssize_t len; | ||
117 | FILE *fp; | ||
118 | int state; | ||
119 | int failed = 0; | ||
120 | |||
121 | if (argc < 2) | ||
122 | errx(1, "%s: missing test file", argv[0]); | ||
123 | |||
124 | test = argv[1]; | ||
125 | |||
126 | if ((fp = fopen(test, "r")) == NULL) | ||
127 | err(1, "can't open test file"); | ||
128 | |||
129 | state = S_COMMENT; | ||
130 | line = 0; | ||
131 | |||
132 | while ((len = getline(&buf, &buflen, fp)) != -1) { | ||
133 | const char *msg = state2str(state); | ||
134 | CBS cbs; | ||
135 | uint8_t u8; | ||
136 | |||
137 | line++; | ||
138 | CBS_init(&cbs, buf, len); | ||
139 | |||
140 | if (!CBS_get_last_u8(&cbs, &u8)) | ||
141 | errx(1, "#%zu %s: CBB_get_last_u8", line, msg); | ||
142 | assert(u8 == '\n'); | ||
143 | |||
144 | switch (state) { | ||
145 | case S_START: | ||
146 | state = S_COMMENT; | ||
147 | break; | ||
148 | case S_COMMENT: | ||
149 | if (!CBS_get_u8(&cbs, &u8)) | ||
150 | errx(1, "#%zu %s: CBB_get_u8", line, msg); | ||
151 | assert(u8 == '#'); | ||
152 | if (!CBS_skip(&cbs, CBS_len(&cbs))) | ||
153 | errx(1, "#%zu %s: CBB_skip", line, msg); | ||
154 | state = S_PRIVATE_KEY; | ||
155 | break; | ||
156 | case S_PRIVATE_KEY: | ||
157 | if (!get_string_cbs(&cbs, "private_key: ", line, msg)) | ||
158 | errx(1, "#%zu %s: get_string_cbs", line, msg); | ||
159 | hex_decode_cbs(&cbs, &private_key, line, msg); | ||
160 | state = S_CIPHERTEXT; | ||
161 | break; | ||
162 | case S_CIPHERTEXT: | ||
163 | if (!get_string_cbs(&cbs, "ciphertext: ", line, msg)) | ||
164 | errx(1, "#%zu %s: get_string_cbs", line, msg); | ||
165 | hex_decode_cbs(&cbs, &ciphertext, line, msg); | ||
166 | state = S_RESULT; | ||
167 | break; | ||
168 | case S_RESULT: | ||
169 | if (!get_string_cbs(&cbs, "result: ", line, msg)) | ||
170 | errx(1, "#%zu %s: get_string_cbs", line, msg); | ||
171 | should_fail = get_string_cbs(&cbs, "fail", line, msg); | ||
172 | state = S_SHARED_SECRET; | ||
173 | break; | ||
174 | case S_SHARED_SECRET: | ||
175 | if (!get_string_cbs(&cbs, "shared_secret: ", line, msg)) | ||
176 | errx(1, "#%zu %s: get_string_cbs", line, msg); | ||
177 | hex_decode_cbs(&cbs, &shared_secret, line, msg); | ||
178 | |||
179 | failed |= MlkemDecapFileTest(&ciphertext, &shared_secret, | ||
180 | &private_key, should_fail, line); | ||
181 | |||
182 | state = S_START; | ||
183 | break; | ||
184 | } | ||
185 | if (CBS_len(&cbs) > 0) | ||
186 | errx(1, "#%zu %s: CBS_len", line, msg); | ||
187 | } | ||
188 | free(buf); | ||
189 | |||
190 | if (ferror(fp)) | ||
191 | err(1, NULL); | ||
192 | fclose(fp); | ||
193 | |||
194 | return failed; | ||
195 | } | ||