diff options
-rw-r--r-- | src/regress/lib/libcrypto/aead/aeadtest.c | 235 |
1 files changed, 220 insertions, 15 deletions
diff --git a/src/regress/lib/libcrypto/aead/aeadtest.c b/src/regress/lib/libcrypto/aead/aeadtest.c index da2334329f..bd6192324b 100644 --- a/src/regress/lib/libcrypto/aead/aeadtest.c +++ b/src/regress/lib/libcrypto/aead/aeadtest.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: aeadtest.c,v 1.18 2022/07/30 16:12:40 jsing Exp $ */ | 1 | /* $OpenBSD: aeadtest.c,v 1.19 2022/07/30 16:17:22 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014, Google Inc. | 3 | * Copyright (c) 2014, Google Inc. |
4 | * | 4 | * |
@@ -84,31 +84,32 @@ hex_digit(char h) | |||
84 | } | 84 | } |
85 | 85 | ||
86 | static int | 86 | static int |
87 | aead_from_name(const EVP_AEAD **aead, const char *name) | 87 | aead_from_name(const EVP_AEAD **aead, const EVP_CIPHER **cipher, |
88 | const char *name) | ||
88 | { | 89 | { |
89 | *aead = NULL; | 90 | *aead = NULL; |
91 | *cipher = NULL; | ||
90 | 92 | ||
91 | if (strcmp(name, "aes-128-gcm") == 0) { | 93 | if (strcmp(name, "aes-128-gcm") == 0) { |
92 | *aead = EVP_aead_aes_128_gcm(); | 94 | *aead = EVP_aead_aes_128_gcm(); |
95 | *cipher = EVP_aes_128_gcm(); | ||
93 | } else if (strcmp(name, "aes-256-gcm") == 0) { | 96 | } else if (strcmp(name, "aes-256-gcm") == 0) { |
94 | *aead = EVP_aead_aes_256_gcm(); | 97 | *aead = EVP_aead_aes_256_gcm(); |
98 | *cipher = EVP_aes_256_gcm(); | ||
95 | } else if (strcmp(name, "chacha20-poly1305") == 0) { | 99 | } else if (strcmp(name, "chacha20-poly1305") == 0) { |
96 | *aead = EVP_aead_chacha20_poly1305(); | 100 | *aead = EVP_aead_chacha20_poly1305(); |
97 | } else if (strcmp(name, "xchacha20-poly1305") == 0) { | 101 | } else if (strcmp(name, "xchacha20-poly1305") == 0) { |
98 | *aead = EVP_aead_xchacha20_poly1305(); | 102 | *aead = EVP_aead_xchacha20_poly1305(); |
99 | } else { | 103 | } else { |
100 | fprintf(stderr, "Unknown AEAD: %s\n", name); | 104 | fprintf(stderr, "Unknown AEAD: %s\n", name); |
101 | return -1; | ||
102 | } | ||
103 | |||
104 | if (*aead == NULL) | ||
105 | return 0; | 105 | return 0; |
106 | } | ||
106 | 107 | ||
107 | return 1; | 108 | return 1; |
108 | } | 109 | } |
109 | 110 | ||
110 | static int | 111 | static int |
111 | run_test_case(const EVP_AEAD* aead, unsigned char bufs[NUM_TYPES][BUF_MAX], | 112 | run_aead_test(const EVP_AEAD *aead, unsigned char bufs[NUM_TYPES][BUF_MAX], |
112 | const unsigned int lengths[NUM_TYPES], unsigned int line_no) | 113 | const unsigned int lengths[NUM_TYPES], unsigned int line_no) |
113 | { | 114 | { |
114 | EVP_AEAD_CTX *ctx; | 115 | EVP_AEAD_CTX *ctx; |
@@ -182,13 +183,213 @@ run_test_case(const EVP_AEAD* aead, unsigned char bufs[NUM_TYPES][BUF_MAX], | |||
182 | return ret; | 183 | return ret; |
183 | } | 184 | } |
184 | 185 | ||
186 | static int | ||
187 | run_cipher_aead_encrypt_test(const EVP_CIPHER *cipher, | ||
188 | unsigned char bufs[NUM_TYPES][BUF_MAX], | ||
189 | const unsigned int lengths[NUM_TYPES], unsigned int line_no) | ||
190 | { | ||
191 | unsigned char out[BUF_MAX + EVP_AEAD_MAX_TAG_LENGTH]; | ||
192 | EVP_CIPHER_CTX *ctx; | ||
193 | size_t out_len; | ||
194 | int len; | ||
195 | int ret = 0; | ||
196 | |||
197 | if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { | ||
198 | fprintf(stderr, "FAIL: EVP_CIPHER_CTX_new\n"); | ||
199 | goto err; | ||
200 | } | ||
201 | |||
202 | if (!EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL)) { | ||
203 | fprintf(stderr, "FAIL: EVP_EncryptInit_ex with cipher\n"); | ||
204 | goto err; | ||
205 | } | ||
206 | |||
207 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, lengths[NONCE], NULL)) { | ||
208 | fprintf(stderr, "FAIL: EVP_CTRL_AEAD_SET_IVLEN\n"); | ||
209 | goto err; | ||
210 | } | ||
211 | |||
212 | if (!EVP_EncryptInit_ex(ctx, NULL, NULL, bufs[KEY], NULL)) { | ||
213 | fprintf(stderr, "FAIL: EVP_EncryptInit_ex with key\n"); | ||
214 | goto err; | ||
215 | } | ||
216 | if (!EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, bufs[NONCE])) { | ||
217 | fprintf(stderr, "FAIL: EVP_EncryptInit_ex with nonce\n"); | ||
218 | goto err; | ||
219 | } | ||
220 | |||
221 | if (!EVP_EncryptUpdate(ctx, NULL, &len, bufs[AD], lengths[AD])) { | ||
222 | fprintf(stderr, "FAIL: EVP_EncryptUpdate with AD\n"); | ||
223 | goto err; | ||
224 | } | ||
225 | if ((unsigned int)len != lengths[AD]) { | ||
226 | fprintf(stderr, "FAIL: EVP_EncryptUpdate with AD length = %u, " | ||
227 | "want %u\n", len, lengths[AD]); | ||
228 | goto err; | ||
229 | } | ||
230 | if (!EVP_EncryptUpdate(ctx, out, &len, bufs[IN], lengths[IN])) { | ||
231 | fprintf(stderr, "FAIL: EVP_EncryptUpdate with plaintext\n"); | ||
232 | goto err; | ||
233 | } | ||
234 | out_len = len; | ||
235 | if (!EVP_EncryptFinal_ex(ctx, out + out_len, &len)) { | ||
236 | fprintf(stderr, "FAIL: EVP_EncryptFinal_ex\n"); | ||
237 | goto err; | ||
238 | } | ||
239 | out_len += len; | ||
240 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, lengths[TAG], | ||
241 | out + out_len)) { | ||
242 | fprintf(stderr, "FAIL: EVP_EncryptInit_ex with cipher\n"); | ||
243 | goto err; | ||
244 | } | ||
245 | out_len += lengths[TAG]; | ||
246 | |||
247 | if (out_len != lengths[CT] + lengths[TAG]) { | ||
248 | fprintf(stderr, "Bad output length on line %u: %zu vs %u\n", | ||
249 | line_no, out_len, (unsigned)(lengths[CT] + lengths[TAG])); | ||
250 | goto err; | ||
251 | } | ||
252 | |||
253 | if (memcmp(out, bufs[CT], lengths[CT]) != 0) { | ||
254 | fprintf(stderr, "Bad output on line %u\n", line_no); | ||
255 | goto err; | ||
256 | } | ||
257 | |||
258 | if (memcmp(out + lengths[CT], bufs[TAG], lengths[TAG]) != 0) { | ||
259 | fprintf(stderr, "Bad tag on line %u\n", line_no); | ||
260 | goto err; | ||
261 | } | ||
262 | |||
263 | ret = 1; | ||
264 | |||
265 | err: | ||
266 | EVP_CIPHER_CTX_free(ctx); | ||
267 | |||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | static int | ||
272 | run_cipher_aead_decrypt_test(const EVP_CIPHER *cipher, int invalid, | ||
273 | unsigned char bufs[NUM_TYPES][BUF_MAX], | ||
274 | const unsigned int lengths[NUM_TYPES], unsigned int line_no) | ||
275 | { | ||
276 | unsigned char in[BUF_MAX], out[BUF_MAX + EVP_AEAD_MAX_TAG_LENGTH]; | ||
277 | EVP_CIPHER_CTX *ctx; | ||
278 | size_t out_len; | ||
279 | int len; | ||
280 | int ret = 0; | ||
281 | |||
282 | if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { | ||
283 | fprintf(stderr, "FAIL: EVP_CIPHER_CTX_new\n"); | ||
284 | goto err; | ||
285 | } | ||
286 | |||
287 | if (!EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL)) { | ||
288 | fprintf(stderr, "FAIL: EVP_DecryptInit_ex with cipher\n"); | ||
289 | goto err; | ||
290 | } | ||
291 | |||
292 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, lengths[NONCE], | ||
293 | NULL)) { | ||
294 | fprintf(stderr, "FAIL: EVP_CTRL_AEAD_SET_IVLEN\n"); | ||
295 | goto err; | ||
296 | } | ||
297 | |||
298 | memcpy(in, bufs[TAG], lengths[TAG]); | ||
299 | if (invalid && lengths[CT] == 0) | ||
300 | in[0] ^= 0x80; | ||
301 | |||
302 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, lengths[TAG], in)) { | ||
303 | fprintf(stderr, "FAIL: EVP_CTRL_AEAD_SET_TAG\n"); | ||
304 | goto err; | ||
305 | } | ||
306 | |||
307 | if (!EVP_DecryptInit_ex(ctx, NULL, NULL, bufs[KEY], NULL)) { | ||
308 | fprintf(stderr, "FAIL: EVP_DecryptInit_ex with key\n"); | ||
309 | goto err; | ||
310 | } | ||
311 | if (!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, bufs[NONCE])) { | ||
312 | fprintf(stderr, "FAIL: EVP_DecryptInit_ex with nonce\n"); | ||
313 | goto err; | ||
314 | } | ||
315 | |||
316 | if (!EVP_DecryptUpdate(ctx, NULL, &len, bufs[AD], lengths[AD])) { | ||
317 | fprintf(stderr, "FAIL: EVP_DecryptUpdate with AD\n"); | ||
318 | goto err; | ||
319 | } | ||
320 | if ((unsigned int)len != lengths[AD]) { | ||
321 | fprintf(stderr, "FAIL: EVP_EncryptUpdate with AD length = %u, " | ||
322 | "want %u\n", len, lengths[AD]); | ||
323 | goto err; | ||
324 | } | ||
325 | |||
326 | memcpy(in, bufs[CT], lengths[CT]); | ||
327 | if (invalid && lengths[CT] > 0) | ||
328 | in[0] ^= 0x80; | ||
329 | |||
330 | if (!EVP_DecryptUpdate(ctx, out, &len, in, lengths[CT])) { | ||
331 | fprintf(stderr, "FAIL: EVP_DecryptUpdate with ciphertext\n"); | ||
332 | goto err; | ||
333 | } | ||
334 | out_len = len; | ||
335 | |||
336 | if (invalid) { | ||
337 | if (EVP_DecryptFinal_ex(ctx, out + out_len, &len)) { | ||
338 | fprintf(stderr, "FAIL: EVP_DecryptFinal_ex succeeded " | ||
339 | "with invalid ciphertext on line %u\n", line_no); | ||
340 | goto err; | ||
341 | } | ||
342 | goto done; | ||
343 | } | ||
344 | |||
345 | if (!EVP_DecryptFinal_ex(ctx, out + out_len, &len)) { | ||
346 | fprintf(stderr, "FAIL: EVP_DecryptFinal_ex\n"); | ||
347 | goto err; | ||
348 | } | ||
349 | out_len += len; | ||
350 | |||
351 | if (out_len != lengths[IN]) { | ||
352 | fprintf(stderr, "Bad decrypt on line %u: %zu\n", | ||
353 | line_no, out_len); | ||
354 | goto err; | ||
355 | } | ||
356 | |||
357 | if (memcmp(out, bufs[IN], out_len) != 0) { | ||
358 | fprintf(stderr, "Plaintext mismatch on line %u\n", line_no); | ||
359 | goto err; | ||
360 | } | ||
361 | |||
362 | done: | ||
363 | ret = 1; | ||
364 | |||
365 | err: | ||
366 | EVP_CIPHER_CTX_free(ctx); | ||
367 | |||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | static int | ||
372 | run_cipher_aead_test(const EVP_CIPHER *cipher, | ||
373 | unsigned char bufs[NUM_TYPES][BUF_MAX], | ||
374 | const unsigned int lengths[NUM_TYPES], unsigned int line_no) | ||
375 | { | ||
376 | if (!run_cipher_aead_encrypt_test(cipher, bufs, lengths, line_no)) | ||
377 | return 0; | ||
378 | if (!run_cipher_aead_decrypt_test(cipher, 0, bufs, lengths, line_no)) | ||
379 | return 0; | ||
380 | if (!run_cipher_aead_decrypt_test(cipher, 1, bufs, lengths, line_no)) | ||
381 | return 0; | ||
382 | |||
383 | return 1; | ||
384 | } | ||
385 | |||
185 | int | 386 | int |
186 | main(int argc, char **argv) | 387 | main(int argc, char **argv) |
187 | { | 388 | { |
188 | FILE *f; | 389 | FILE *f; |
189 | const EVP_AEAD *aead = NULL; | 390 | const EVP_AEAD *aead = NULL; |
391 | const EVP_CIPHER *cipher = NULL; | ||
190 | unsigned int line_no = 0, num_tests = 0, j; | 392 | unsigned int line_no = 0, num_tests = 0, j; |
191 | |||
192 | unsigned char bufs[NUM_TYPES][BUF_MAX]; | 393 | unsigned char bufs[NUM_TYPES][BUF_MAX]; |
193 | unsigned int lengths[NUM_TYPES]; | 394 | unsigned int lengths[NUM_TYPES]; |
194 | 395 | ||
@@ -233,17 +434,21 @@ main(int argc, char **argv) | |||
233 | if (!any_values_set) | 434 | if (!any_values_set) |
234 | continue; | 435 | continue; |
235 | 436 | ||
236 | switch (aead_from_name(&aead, bufs[AEAD])) { | 437 | if (!aead_from_name(&aead, &cipher, bufs[AEAD])) { |
237 | case 0: | ||
238 | fprintf(stderr, "Skipping test...\n"); | ||
239 | continue; | ||
240 | case -1: | ||
241 | fprintf(stderr, "Aborting...\n"); | 438 | fprintf(stderr, "Aborting...\n"); |
242 | return 4; | 439 | return 4; |
243 | } | 440 | } |
244 | 441 | ||
245 | if (!run_test_case(aead, bufs, lengths, line_no)) | 442 | if (aead != NULL) { |
246 | return 4; | 443 | if (!run_aead_test(aead, bufs, lengths, |
444 | line_no)) | ||
445 | return 4; | ||
446 | } | ||
447 | if (cipher != NULL) { | ||
448 | if (!run_cipher_aead_test(cipher, bufs, lengths, | ||
449 | line_no)) | ||
450 | return 4; | ||
451 | } | ||
247 | 452 | ||
248 | for (j = 0; j < NUM_TYPES; j++) | 453 | for (j = 0; j < NUM_TYPES; j++) |
249 | lengths[j] = 0; | 454 | lengths[j] = 0; |