diff options
| author | jsing <> | 2022-07-30 16:17:22 +0000 |
|---|---|---|
| committer | jsing <> | 2022-07-30 16:17:22 +0000 |
| commit | 377a903974dc4444a6e5beb46ba1b3c94f7ebc54 (patch) | |
| tree | 3d3b6560703b77881c8294c81ade81e778e5f3b9 /src | |
| parent | 5908be8aa22b0be9b5c21ff7e37a72ad249eeab2 (diff) | |
| download | openbsd-377a903974dc4444a6e5beb46ba1b3c94f7ebc54.tar.gz openbsd-377a903974dc4444a6e5beb46ba1b3c94f7ebc54.tar.bz2 openbsd-377a903974dc4444a6e5beb46ba1b3c94f7ebc54.zip | |
Run AEAD tests against EVP_CIPHER implementations.
In addition to running AEAD tests against the EVP_AEAD implementation, also
run them against the EVP_CIPHER implementation where applicable.
This is a perfect example of why EVP_AEAD exists and why EVP_CIPHER is
completely unsuited for use with AEADs...
Diffstat (limited to 'src')
| -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; |
