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/mlkem_tests_util.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/mlkem_tests_util.c')
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c | 214 |
1 files changed, 133 insertions, 81 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c b/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c index 6287849e3b..1bb2ed3a8b 100644 --- a/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c +++ b/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mlkem_tests_util.c,v 1.4 2024/12/20 15:47:26 tb Exp $ */ | 1 | /* $OpenBSD: mlkem_tests_util.c,v 1.5 2024/12/26 00:04:24 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2024 Google Inc. | 3 | * Copyright (c) 2024 Google Inc. |
4 | * Copyright (c) 2024 Bob Beck <beck@obtuse.com> | 4 | * Copyright (c) 2024 Bob Beck <beck@obtuse.com> |
@@ -45,13 +45,12 @@ hexdump(const uint8_t *buf, size_t len, const uint8_t *compare) | |||
45 | } | 45 | } |
46 | 46 | ||
47 | int | 47 | int |
48 | compare_data(const uint8_t *want, const uint8_t *got, size_t len, size_t line, | 48 | compare_data(const uint8_t *want, const uint8_t *got, size_t len, const char *msg) |
49 | const char *msg) | ||
50 | { | 49 | { |
51 | if (memcmp(want, got, len) == 0) | 50 | if (memcmp(want, got, len) == 0) |
52 | return 0; | 51 | return 0; |
53 | 52 | ||
54 | warnx("FAIL: #%zu - %s differs", line, msg); | 53 | warnx("FAIL: %s differs", msg); |
55 | fprintf(stderr, "want:\n"); | 54 | fprintf(stderr, "want:\n"); |
56 | hexdump(want, len, got); | 55 | hexdump(want, len, got); |
57 | fprintf(stderr, "got:\n"); | 56 | fprintf(stderr, "got:\n"); |
@@ -62,80 +61,15 @@ compare_data(const uint8_t *want, const uint8_t *got, size_t len, size_t line, | |||
62 | } | 61 | } |
63 | 62 | ||
64 | int | 63 | int |
65 | compare_length(size_t want, size_t got, size_t line, const char *msg) | 64 | mlkem768_encode_private_key(const void *private_key, uint8_t **out_buf, |
66 | { | 65 | size_t *out_len) |
67 | if (want == got) | ||
68 | return 1; | ||
69 | |||
70 | warnx("#%zu: %s: want %zu, got %zu", line, msg, want, got); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int | ||
75 | hex_get_nibble_cbs(CBS *cbs, uint8_t *out_nibble) | ||
76 | { | ||
77 | uint8_t c; | ||
78 | |||
79 | if (!CBS_get_u8(cbs, &c)) | ||
80 | return 0; | ||
81 | |||
82 | if (c >= '0' && c <= '9') { | ||
83 | *out_nibble = c - '0'; | ||
84 | return 1; | ||
85 | } | ||
86 | if (c >= 'a' && c <= 'f') { | ||
87 | *out_nibble = c - 'a' + 10; | ||
88 | return 1; | ||
89 | } | ||
90 | if (c >= 'A' && c <= 'F') { | ||
91 | *out_nibble = c - 'A' + 10; | ||
92 | return 1; | ||
93 | } | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | void | ||
99 | hex_decode_cbs(CBS *cbs, CBB *cbb, size_t line, const char *msg) | ||
100 | { | ||
101 | if (!CBB_init(cbb, 0)) | ||
102 | errx(1, "#%zu %s: %s CBB_init", line, msg, __func__); | ||
103 | |||
104 | while (CBS_len(cbs) > 0) { | ||
105 | uint8_t hi, lo; | ||
106 | |||
107 | if (!hex_get_nibble_cbs(cbs, &hi)) | ||
108 | errx(1, "#%zu %s: %s nibble", line, msg, __func__); | ||
109 | if (!hex_get_nibble_cbs(cbs, &lo)) | ||
110 | errx(1, "#%zu %s: %s nibble", line, msg, __func__); | ||
111 | |||
112 | if (!CBB_add_u8(cbb, hi << 4 | lo)) | ||
113 | errx(1, "#%zu %s: %s CBB_add_u8", line, msg, __func__); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | int | ||
118 | get_string_cbs(CBS *cbs_in, const char *str, size_t line, const char *msg) | ||
119 | { | ||
120 | CBS cbs; | ||
121 | size_t len = strlen(str); | ||
122 | |||
123 | if (!CBS_get_bytes(cbs_in, &cbs, len)) | ||
124 | errx(1, "#%zu %s: %s CBB_get_bytes", line, msg, __func__); | ||
125 | |||
126 | return CBS_mem_equal(&cbs, str, len); | ||
127 | } | ||
128 | |||
129 | int | ||
130 | mlkem768_encode_private_key(const struct MLKEM768_private_key *priv, | ||
131 | uint8_t **out_buf, size_t *out_len) | ||
132 | { | 66 | { |
133 | CBB cbb; | 67 | CBB cbb; |
134 | int ret = 0; | 68 | int ret = 0; |
135 | 69 | ||
136 | if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES)) | 70 | if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES)) |
137 | goto err; | 71 | goto err; |
138 | if (!MLKEM768_marshal_private_key(&cbb, priv)) | 72 | if (!MLKEM768_marshal_private_key(&cbb, private_key)) |
139 | goto err; | 73 | goto err; |
140 | if (!CBB_finish(&cbb, out_buf, out_len)) | 74 | if (!CBB_finish(&cbb, out_buf, out_len)) |
141 | goto err; | 75 | goto err; |
@@ -149,15 +83,15 @@ mlkem768_encode_private_key(const struct MLKEM768_private_key *priv, | |||
149 | } | 83 | } |
150 | 84 | ||
151 | int | 85 | int |
152 | mlkem768_encode_public_key(const struct MLKEM768_public_key *pub, | 86 | mlkem768_encode_public_key(const void *public_key, uint8_t **out_buf, |
153 | uint8_t **out_buf, size_t *out_len) | 87 | size_t *out_len) |
154 | { | 88 | { |
155 | CBB cbb; | 89 | CBB cbb; |
156 | int ret = 0; | 90 | int ret = 0; |
157 | 91 | ||
158 | if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES)) | 92 | if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES)) |
159 | goto err; | 93 | goto err; |
160 | if (!MLKEM768_marshal_public_key(&cbb, pub)) | 94 | if (!MLKEM768_marshal_public_key(&cbb, public_key)) |
161 | goto err; | 95 | goto err; |
162 | if (!CBB_finish(&cbb, out_buf, out_len)) | 96 | if (!CBB_finish(&cbb, out_buf, out_len)) |
163 | goto err; | 97 | goto err; |
@@ -171,15 +105,15 @@ mlkem768_encode_public_key(const struct MLKEM768_public_key *pub, | |||
171 | } | 105 | } |
172 | 106 | ||
173 | int | 107 | int |
174 | mlkem1024_encode_private_key(const struct MLKEM1024_private_key *priv, | 108 | mlkem1024_encode_private_key(const void *private_key, uint8_t **out_buf, |
175 | uint8_t **out_buf, size_t *out_len) | 109 | size_t *out_len) |
176 | { | 110 | { |
177 | CBB cbb; | 111 | CBB cbb; |
178 | int ret = 0; | 112 | int ret = 0; |
179 | 113 | ||
180 | if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES)) | 114 | if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES)) |
181 | goto err; | 115 | goto err; |
182 | if (!MLKEM1024_marshal_private_key(&cbb, priv)) | 116 | if (!MLKEM1024_marshal_private_key(&cbb, private_key)) |
183 | goto err; | 117 | goto err; |
184 | if (!CBB_finish(&cbb, out_buf, out_len)) | 118 | if (!CBB_finish(&cbb, out_buf, out_len)) |
185 | goto err; | 119 | goto err; |
@@ -193,15 +127,15 @@ mlkem1024_encode_private_key(const struct MLKEM1024_private_key *priv, | |||
193 | } | 127 | } |
194 | 128 | ||
195 | int | 129 | int |
196 | mlkem1024_encode_public_key(const struct MLKEM1024_public_key *pub, | 130 | mlkem1024_encode_public_key(const void *public_key, uint8_t **out_buf, |
197 | uint8_t **out_buf, size_t *out_len) | 131 | size_t *out_len) |
198 | { | 132 | { |
199 | CBB cbb; | 133 | CBB cbb; |
200 | int ret = 0; | 134 | int ret = 0; |
201 | 135 | ||
202 | if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES)) | 136 | if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES)) |
203 | goto err; | 137 | goto err; |
204 | if (!MLKEM1024_marshal_public_key(&cbb, pub)) | 138 | if (!MLKEM1024_marshal_public_key(&cbb, public_key)) |
205 | goto err; | 139 | goto err; |
206 | if (!CBB_finish(&cbb, out_buf, out_len)) | 140 | if (!CBB_finish(&cbb, out_buf, out_len)) |
207 | goto err; | 141 | goto err; |
@@ -213,3 +147,121 @@ mlkem1024_encode_public_key(const struct MLKEM1024_public_key *pub, | |||
213 | 147 | ||
214 | return ret; | 148 | return ret; |
215 | } | 149 | } |
150 | |||
151 | int | ||
152 | mlkem768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
153 | const uint8_t *ciphertext, size_t ciphertext_len, const void *private_key) | ||
154 | { | ||
155 | return MLKEM768_decap(out_shared_secret, ciphertext, ciphertext_len, | ||
156 | private_key); | ||
157 | } | ||
158 | |||
159 | void | ||
160 | mlkem768_encap(uint8_t *out_ciphertext, | ||
161 | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
162 | const void *public_key) | ||
163 | { | ||
164 | MLKEM768_encap(out_ciphertext, out_shared_secret, public_key); | ||
165 | } | ||
166 | |||
167 | void | ||
168 | mlkem768_encap_external_entropy(uint8_t *out_ciphertext, | ||
169 | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
170 | const void *public_key, const uint8_t entropy[MLKEM_ENCAP_ENTROPY]) | ||
171 | { | ||
172 | MLKEM768_encap_external_entropy(out_ciphertext, out_shared_secret, | ||
173 | public_key, entropy); | ||
174 | } | ||
175 | |||
176 | void | ||
177 | mlkem768_generate_key(uint8_t *out_encoded_public_key, | ||
178 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key) | ||
179 | { | ||
180 | MLKEM768_generate_key(out_encoded_public_key, optional_out_seed, | ||
181 | out_private_key); | ||
182 | } | ||
183 | |||
184 | void | ||
185 | mlkem768_generate_key_external_entropy(uint8_t *out_encoded_public_key, | ||
186 | void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES]) | ||
187 | { | ||
188 | MLKEM768_generate_key_external_entropy(out_encoded_public_key, | ||
189 | out_private_key, entropy); | ||
190 | } | ||
191 | |||
192 | int | ||
193 | mlkem768_parse_private_key(void *out_private_key, CBS *private_key_cbs) | ||
194 | { | ||
195 | return MLKEM768_parse_private_key(out_private_key, private_key_cbs); | ||
196 | } | ||
197 | |||
198 | int | ||
199 | mlkem768_parse_public_key(void *out_public_key, CBS *public_key_cbs) | ||
200 | { | ||
201 | return MLKEM768_parse_public_key(out_public_key, public_key_cbs); | ||
202 | } | ||
203 | |||
204 | void | ||
205 | mlkem768_public_from_private(void *out_public_key, const void *private_key) | ||
206 | { | ||
207 | MLKEM768_public_from_private(out_public_key, private_key); | ||
208 | } | ||
209 | |||
210 | int | ||
211 | mlkem1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
212 | const uint8_t *ciphertext, size_t ciphertext_len, const void *private_key) | ||
213 | { | ||
214 | return MLKEM1024_decap(out_shared_secret, ciphertext, ciphertext_len, | ||
215 | private_key); | ||
216 | } | ||
217 | |||
218 | void | ||
219 | mlkem1024_encap(uint8_t *out_ciphertext, | ||
220 | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
221 | const void *public_key) | ||
222 | { | ||
223 | MLKEM1024_encap(out_ciphertext, out_shared_secret, public_key); | ||
224 | } | ||
225 | |||
226 | void | ||
227 | mlkem1024_encap_external_entropy(uint8_t *out_ciphertext, | ||
228 | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
229 | const void *public_key, const uint8_t entropy[MLKEM_ENCAP_ENTROPY]) | ||
230 | { | ||
231 | MLKEM1024_encap_external_entropy(out_ciphertext, out_shared_secret, | ||
232 | public_key, entropy); | ||
233 | } | ||
234 | |||
235 | void | ||
236 | mlkem1024_generate_key(uint8_t *out_encoded_public_key, | ||
237 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key) | ||
238 | { | ||
239 | MLKEM1024_generate_key(out_encoded_public_key, optional_out_seed, | ||
240 | out_private_key); | ||
241 | } | ||
242 | |||
243 | void | ||
244 | mlkem1024_generate_key_external_entropy(uint8_t *out_encoded_public_key, | ||
245 | void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES]) | ||
246 | { | ||
247 | MLKEM1024_generate_key_external_entropy(out_encoded_public_key, | ||
248 | out_private_key, entropy); | ||
249 | } | ||
250 | |||
251 | int | ||
252 | mlkem1024_parse_private_key(void *out_private_key, CBS *private_key_cbs) | ||
253 | { | ||
254 | return MLKEM1024_parse_private_key(out_private_key, private_key_cbs); | ||
255 | } | ||
256 | |||
257 | void | ||
258 | mlkem1024_public_from_private(void *out_public_key, const void *private_key) | ||
259 | { | ||
260 | MLKEM1024_public_from_private(out_public_key, private_key); | ||
261 | } | ||
262 | |||
263 | int | ||
264 | mlkem1024_parse_public_key(void *out_public_key, CBS *public_key_cbs) | ||
265 | { | ||
266 | return MLKEM1024_parse_public_key(out_public_key, public_key_cbs); | ||
267 | } | ||