1 /* $OpenBSD: evp_test.c,v 1.20 2024/07/09 17:24:12 tb Exp $ */ 2 /* 3 * Copyright (c) 2017, 2022 Joel Sing <jsing@openbsd.org> 4 * Copyright (c) 2023, 2024 Theo Buehler <tb@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <assert.h> 20 #include <err.h> 21 #include <stdio.h> 22 #include <string.h> 23 24 #include <openssl/crypto.h> 25 #include <openssl/evp.h> 26 #include <openssl/kdf.h> 27 #include <openssl/objects.h> 28 #include <openssl/ossl_typ.h> 29 30 static int 31 evp_asn1_method_test(void) 32 { 33 const EVP_PKEY_ASN1_METHOD *method; 34 int count, pkey_id, i; 35 int failed = 1; 36 37 if ((count = EVP_PKEY_asn1_get_count()) < 1) { 38 fprintf(stderr, "FAIL: failed to get pkey asn1 method count\n"); 39 goto failure; 40 } 41 for (i = 0; i < count; i++) { 42 if ((method = EVP_PKEY_asn1_get0(i)) == NULL) { 43 fprintf(stderr, "FAIL: failed to get pkey %d\n", i); 44 goto failure; 45 } 46 } 47 48 if ((method = EVP_PKEY_asn1_find(NULL, EVP_PKEY_RSA)) == NULL) { 49 fprintf(stderr, "FAIL: failed to find RSA method\n"); 50 goto failure; 51 } 52 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) { 53 fprintf(stderr, "FAIL: failed to get RSA method info\n"); 54 goto failure; 55 } 56 if (pkey_id != EVP_PKEY_RSA) { 57 fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", 58 pkey_id, EVP_PKEY_RSA); 59 goto failure; 60 } 61 62 if ((method = EVP_PKEY_asn1_find(NULL, EVP_PKEY_RSA_PSS)) == NULL) { 63 fprintf(stderr, "FAIL: failed to find RSA-PSS method\n"); 64 goto failure; 65 } 66 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) { 67 fprintf(stderr, "FAIL: failed to get RSA-PSS method info\n"); 68 goto failure; 69 } 70 if (pkey_id != EVP_PKEY_RSA_PSS) { 71 fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", 72 pkey_id, EVP_PKEY_RSA_PSS); 73 goto failure; 74 } 75 76 if ((method = EVP_PKEY_asn1_find_str(NULL, "RSA", -1)) == NULL) { 77 fprintf(stderr, "FAIL: failed to find RSA method by str\n"); 78 goto failure; 79 } 80 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) { 81 fprintf(stderr, "FAIL: failed to get RSA method info\n"); 82 goto failure; 83 } 84 if (pkey_id != EVP_PKEY_RSA) { 85 fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", 86 pkey_id, EVP_PKEY_RSA); 87 goto failure; 88 } 89 90 if ((method = EVP_PKEY_asn1_find_str(NULL, "RSA-PSS", -1)) == NULL) { 91 fprintf(stderr, "FAIL: failed to find RSA-PSS method\n"); 92 goto failure; 93 } 94 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) { 95 fprintf(stderr, "FAIL: failed to get RSA-PSS method info\n"); 96 goto failure; 97 } 98 if (pkey_id != EVP_PKEY_RSA_PSS) { 99 fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", 100 pkey_id, EVP_PKEY_RSA_PSS); 101 goto failure; 102 } 103 104 failed = 0; 105 106 failure: 107 108 return failed; 109 } 110 111 /* EVP_PKEY_asn1_find() by hand. Allows cross-checking and finding duplicates. */ 112 static const EVP_PKEY_ASN1_METHOD * 113 evp_pkey_asn1_find(int nid, int skip_id) 114 { 115 const EVP_PKEY_ASN1_METHOD *ameth; 116 int count, i, pkey_id; 117 118 count = EVP_PKEY_asn1_get_count(); 119 for (i = 0; i < count; i++) { 120 if (i == skip_id) 121 continue; 122 if ((ameth = EVP_PKEY_asn1_get0(i)) == NULL) 123 return NULL; 124 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, 125 NULL, NULL, ameth)) 126 return NULL; 127 if (pkey_id == nid) 128 return ameth; 129 } 130 131 return NULL; 132 } 133 134 static int 135 evp_asn1_method_aliases_test(void) 136 { 137 const EVP_PKEY_ASN1_METHOD *ameth; 138 int id, base_id, flags; 139 const char *info, *pem_str; 140 int count, i; 141 int failed = 0; 142 143 if ((count = EVP_PKEY_asn1_get_count()) <= 0) { 144 fprintf(stderr, "FAIL: EVP_PKEY_asn1_get_count(): %d\n", count); 145 failed |= 1; 146 } 147 for (i = 0; i < count; i++) { 148 if ((ameth = EVP_PKEY_asn1_get0(i)) == NULL) { 149 fprintf(stderr, "FAIL: no ameth for index %d < %d\n", 150 i, count); 151 failed |= 1; 152 continue; 153 } 154 if (!EVP_PKEY_asn1_get0_info(&id, &base_id, &flags, 155 &info, &pem_str, ameth)) { 156 fprintf(stderr, "FAIL: no info for ameth %d\n", i); 157 failed |= 1; 158 continue; 159 } 160 161 /* 162 * The following are all true or all false for any ameth: 163 * 1. ASN1_PKEY_ALIAS is set 2. id != base_id 164 * 3. info == NULL 4. pem_str == NULL 165 */ 166 167 if ((flags & ASN1_PKEY_ALIAS) == 0) { 168 size_t pem_str_len; 169 170 if (id != base_id) { 171 fprintf(stderr, "FAIL: non-alias with " 172 "id %d != base_id %d\n", id, base_id); 173 failed |= 1; 174 continue; 175 } 176 if (info == NULL || strlen(info) == 0) { 177 fprintf(stderr, "FAIL: missing or empty info %d\n", id); 178 failed |= 1; 179 continue; 180 } 181 if (pem_str == NULL) { 182 fprintf(stderr, "FAIL: missing pem_str %d\n", id); 183 failed |= 1; 184 continue; 185 } 186 if ((pem_str_len = strlen(pem_str)) == 0) { 187 fprintf(stderr, "FAIL: empty pem_str %d\n", id); 188 failed |= 1; 189 continue; 190 } 191 192 if (evp_pkey_asn1_find(id, i) != NULL) { 193 fprintf(stderr, "FAIL: duplicate ameth %d\n", id); 194 failed |= 1; 195 continue; 196 } 197 198 if (ameth != EVP_PKEY_asn1_find(NULL, id)) { 199 fprintf(stderr, "FAIL: EVP_PKEY_asn1_find(%d) " 200 "returned different ameth\n", id); 201 failed |= 1; 202 continue; 203 } 204 if (ameth != EVP_PKEY_asn1_find_str(NULL, pem_str, -1)) { 205 fprintf(stderr, "FAIL: EVP_PKEY_asn1_find_str(%s) " 206 "returned different ameth\n", pem_str); 207 failed |= 1; 208 continue; 209 } 210 if (ameth != EVP_PKEY_asn1_find_str(NULL, 211 pem_str, pem_str_len)) { 212 fprintf(stderr, "FAIL: EVP_PKEY_asn1_find_str(%s, %zu) " 213 "returned different ameth\n", pem_str, pem_str_len); 214 failed |= 1; 215 continue; 216 } 217 if (EVP_PKEY_asn1_find_str(NULL, pem_str, 218 pem_str_len - 1) != NULL) { 219 fprintf(stderr, "FAIL: EVP_PKEY_asn1_find_str(%s, %zu) " 220 "returned an ameth\n", pem_str, pem_str_len - 1); 221 failed |= 1; 222 continue; 223 } 224 continue; 225 } 226 227 if (id == base_id) { 228 fprintf(stderr, "FAIL: alias with id %d == base_id %d\n", 229 id, base_id); 230 failed |= 1; 231 } 232 if (info != NULL) { 233 fprintf(stderr, "FAIL: alias %d with info %s\n", id, info); 234 failed |= 1; 235 } 236 if (pem_str != NULL) { 237 fprintf(stderr, "FAIL: alias %d with pem_str %s\n", 238 id, pem_str); 239 failed |= 1; 240 } 241 242 /* Check that ameth resolves to a non-alias. */ 243 if ((ameth = evp_pkey_asn1_find(base_id, -1)) == NULL) { 244 fprintf(stderr, "FAIL: no ameth with pkey_id %d\n", 245 base_id); 246 failed |= 1; 247 continue; 248 } 249 if (!EVP_PKEY_asn1_get0_info(NULL, NULL, &flags, NULL, NULL, ameth)) { 250 fprintf(stderr, "FAIL: no info for ameth with pkey_id %d\n", 251 base_id); 252 failed |= 1; 253 continue; 254 } 255 if ((flags & ASN1_PKEY_ALIAS) != 0) { 256 fprintf(stderr, "FAIL: ameth with pkey_id %d " 257 "resolves to another alias\n", base_id); 258 failed |= 1; 259 } 260 } 261 262 return failed; 263 } 264 265 static const struct evp_iv_len_test { 266 const EVP_CIPHER *(*cipher)(void); 267 int iv_len; 268 int setlen; 269 int expect; 270 } evp_iv_len_tests[] = { 271 { 272 .cipher = EVP_aes_128_ccm, 273 .iv_len = 7, 274 .setlen = 11, 275 .expect = 1, 276 }, 277 { 278 .cipher = EVP_aes_128_ccm, 279 .iv_len = 7, 280 .setlen = 6, 281 .expect = 0, 282 }, 283 { 284 .cipher = EVP_aes_128_ccm, 285 .iv_len = 7, 286 .setlen = 13, 287 .expect = 1, 288 }, 289 { 290 .cipher = EVP_aes_128_ccm, 291 .iv_len = 7, 292 .setlen = 14, 293 .expect = 0, 294 }, 295 296 { 297 .cipher = EVP_aes_192_ccm, 298 .iv_len = 7, 299 .setlen = 11, 300 .expect = 1, 301 }, 302 { 303 .cipher = EVP_aes_192_ccm, 304 .iv_len = 7, 305 .setlen = 6, 306 .expect = 0, 307 }, 308 { 309 .cipher = EVP_aes_192_ccm, 310 .iv_len = 7, 311 .setlen = 13, 312 .expect = 1, 313 }, 314 { 315 .cipher = EVP_aes_192_ccm, 316 .iv_len = 7, 317 .setlen = 14, 318 .expect = 0, 319 }, 320 321 { 322 .cipher = EVP_aes_256_ccm, 323 .iv_len = 7, 324 .setlen = 11, 325 .expect = 1, 326 }, 327 { 328 .cipher = EVP_aes_256_ccm, 329 .iv_len = 7, 330 .setlen = 6, 331 .expect = 0, 332 }, 333 { 334 .cipher = EVP_aes_256_ccm, 335 .iv_len = 7, 336 .setlen = 13, 337 .expect = 1, 338 }, 339 { 340 .cipher = EVP_aes_256_ccm, 341 .iv_len = 7, 342 .setlen = 14, 343 .expect = 0, 344 }, 345 346 { 347 .cipher = EVP_aes_128_gcm, 348 .iv_len = 12, 349 .setlen = 16, 350 .expect = 1, 351 }, 352 { 353 .cipher = EVP_aes_128_gcm, 354 .iv_len = 12, 355 .setlen = 0, 356 .expect = 0, 357 }, 358 { 359 .cipher = EVP_aes_128_gcm, 360 .iv_len = 12, 361 .setlen = 1, 362 .expect = 1, 363 }, 364 /* XXX - GCM IV length isn't capped... */ 365 { 366 .cipher = EVP_aes_128_gcm, 367 .iv_len = 12, 368 .setlen = 1024 * 1024, 369 .expect = 1, 370 }, 371 372 { 373 .cipher = EVP_aes_192_gcm, 374 .iv_len = 12, 375 .setlen = 16, 376 .expect = 1, 377 }, 378 { 379 .cipher = EVP_aes_192_gcm, 380 .iv_len = 12, 381 .setlen = 0, 382 .expect = 0, 383 }, 384 { 385 .cipher = EVP_aes_192_gcm, 386 .iv_len = 12, 387 .setlen = 1, 388 .expect = 1, 389 }, 390 /* XXX - GCM IV length isn't capped... */ 391 { 392 .cipher = EVP_aes_128_gcm, 393 .iv_len = 12, 394 .setlen = 1024 * 1024, 395 .expect = 1, 396 }, 397 398 { 399 .cipher = EVP_aes_256_gcm, 400 .iv_len = 12, 401 .setlen = 16, 402 .expect = 1, 403 }, 404 { 405 .cipher = EVP_aes_256_gcm, 406 .iv_len = 12, 407 .setlen = 0, 408 .expect = 0, 409 }, 410 { 411 .cipher = EVP_aes_256_gcm, 412 .iv_len = 12, 413 .setlen = 1, 414 .expect = 1, 415 }, 416 /* XXX - GCM IV length isn't capped... */ 417 { 418 .cipher = EVP_aes_128_gcm, 419 .iv_len = 12, 420 .setlen = 1024 * 1024, 421 .expect = 1, 422 }, 423 424 { 425 .cipher = EVP_aes_128_ecb, 426 .iv_len = 0, 427 .setlen = 11, 428 .expect = 0, 429 }, 430 431 { 432 .cipher = EVP_chacha20_poly1305, 433 .iv_len = 12, 434 .setlen = 11, 435 .expect = 1, 436 }, 437 { 438 .cipher = EVP_chacha20_poly1305, 439 .iv_len = 12, 440 .setlen = 12, 441 .expect = 1, 442 }, 443 { 444 .cipher = EVP_chacha20_poly1305, 445 .iv_len = 12, 446 .setlen = 13, 447 .expect = 0, 448 }, 449 { 450 .cipher = EVP_chacha20_poly1305, 451 .iv_len = 12, 452 .setlen = 1, 453 .expect = 1, 454 }, 455 { 456 .cipher = EVP_chacha20_poly1305, 457 .iv_len = 12, 458 .setlen = 0, 459 .expect = 0, 460 }, 461 }; 462 463 #define N_EVP_IV_LEN_TESTS \ 464 (sizeof(evp_iv_len_tests) / sizeof(evp_iv_len_tests[0])) 465 466 static int 467 evp_pkey_iv_len_testcase(const struct evp_iv_len_test *test) 468 { 469 const EVP_CIPHER *cipher = test->cipher(); 470 const char *name; 471 EVP_CIPHER_CTX *ctx; 472 int ret; 473 int failure = 1; 474 475 assert(cipher != NULL); 476 name = OBJ_nid2ln(EVP_CIPHER_nid(cipher)); 477 assert(name != NULL); 478 479 if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { 480 fprintf(stderr, "FAIL: %s: EVP_CIPHER_CTX_new()\n", name); 481 goto failure; 482 } 483 484 if ((ret = EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL)) <= 0) { 485 fprintf(stderr, "FAIL: %s: EVP_EncryptInit_ex:" 486 " want %d, got %d\n", name, 1, ret); 487 goto failure; 488 } 489 if ((ret = EVP_CIPHER_CTX_iv_length(ctx)) != test->iv_len) { 490 fprintf(stderr, "FAIL: %s EVP_CIPHER_CTX_iv_length (before set)" 491 " want %d, got %d\n", name, test->iv_len, ret); 492 goto failure; 493 } 494 if ((ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, 495 test->setlen, NULL)) != test->expect) { 496 fprintf(stderr, "FAIL: %s EVP_CIPHER_CTX_ctrl" 497 " want %d, got %d\n", name, test->expect, ret); 498 goto failure; 499 } 500 if (test->expect == 0) 501 goto done; 502 if ((ret = EVP_CIPHER_CTX_iv_length(ctx)) != test->setlen) { 503 fprintf(stderr, "FAIL: %s EVP_CIPHER_CTX_iv_length (after set)" 504 " want %d, got %d\n", name, test->setlen, ret); 505 goto failure; 506 } 507 508 done: 509 failure = 0; 510 511 failure: 512 EVP_CIPHER_CTX_free(ctx); 513 514 return failure; 515 } 516 517 static int 518 evp_pkey_iv_len_test(void) 519 { 520 size_t i; 521 int failure = 0; 522 523 for (i = 0; i < N_EVP_IV_LEN_TESTS; i++) 524 failure |= evp_pkey_iv_len_testcase(&evp_iv_len_tests[i]); 525 526 return failure; 527 } 528 529 struct do_all_arg { 530 const char *previous; 531 int failure; 532 }; 533 534 static void 535 evp_do_all_cb_common(const char *descr, const void *ptr, const char *from, 536 const char *to, struct do_all_arg *arg) 537 { 538 const char *previous = arg->previous; 539 540 assert(from != NULL); 541 arg->previous = from; 542 543 if (ptr == NULL && to == NULL) { 544 arg->failure |= 1; 545 fprintf(stderr, "FAIL: %s %s: method and alias both NULL\n", 546 descr, from); 547 } 548 if (ptr != NULL && to != NULL) { 549 arg->failure |= 1; 550 fprintf(stderr, "FAIL: %s %s has method and alias \"%s\"\n", 551 descr, from, to); 552 } 553 554 if (previous == NULL) 555 return; 556 557 if (strcmp(previous, from) >= 0) { 558 arg->failure |= 1; 559 fprintf(stderr, "FAIL: %ss %s and %s out of order\n", descr, 560 previous, from); 561 } 562 } 563 564 static void 565 evp_cipher_do_all_cb(const EVP_CIPHER *cipher, const char *from, const char *to, 566 void *arg) 567 { 568 evp_do_all_cb_common("cipher", cipher, from, to, arg); 569 } 570 571 static void 572 evp_md_do_all_cb(const EVP_MD *md, const char *from, const char *to, void *arg) 573 { 574 evp_do_all_cb_common("digest", md, from, to, arg); 575 } 576 577 static int 578 evp_do_all_test(void) 579 { 580 struct do_all_arg arg; 581 int failure = 0; 582 583 memset(&arg, 0, sizeof(arg)); 584 EVP_CIPHER_do_all(evp_cipher_do_all_cb, &arg); 585 failure |= arg.failure; 586 587 memset(&arg, 0, sizeof(arg)); 588 EVP_MD_do_all(evp_md_do_all_cb, &arg); 589 failure |= arg.failure; 590 591 return failure; 592 } 593 594 static void 595 evp_cipher_aliases_cb(const EVP_CIPHER *cipher, const char *from, const char *to, 596 void *arg) 597 { 598 struct do_all_arg *do_all = arg; 599 const EVP_CIPHER *from_cipher, *to_cipher; 600 601 if (to == NULL) 602 return; 603 604 from_cipher = EVP_get_cipherbyname(from); 605 to_cipher = EVP_get_cipherbyname(to); 606 607 if (from_cipher != NULL && from_cipher == to_cipher) 608 return; 609 610 fprintf(stderr, "FAIL: cipher mismatch from \"%s\" to \"%s\": " 611 "from: %p, to: %p\n", from, to, from_cipher, to_cipher); 612 do_all->failure |= 1; 613 } 614 615 static void 616 evp_digest_aliases_cb(const EVP_MD *digest, const char *from, const char *to, 617 void *arg) 618 { 619 struct do_all_arg *do_all = arg; 620 const EVP_MD *from_digest, *to_digest; 621 622 if (to == NULL) 623 return; 624 625 from_digest = EVP_get_digestbyname(from); 626 to_digest = EVP_get_digestbyname(to); 627 628 if (from_digest != NULL && from_digest == to_digest) 629 return; 630 631 fprintf(stderr, "FAIL: digest mismatch from \"%s\" to \"%s\": " 632 "from: %p, to: %p\n", from, to, from_digest, to_digest); 633 do_all->failure |= 1; 634 } 635 636 static int 637 evp_aliases_test(void) 638 { 639 struct do_all_arg arg; 640 int failure = 0; 641 642 memset(&arg, 0, sizeof(arg)); 643 EVP_CIPHER_do_all(evp_cipher_aliases_cb, &arg); 644 failure |= arg.failure; 645 646 memset(&arg, 0, sizeof(arg)); 647 EVP_MD_do_all(evp_digest_aliases_cb, &arg); 648 failure |= arg.failure; 649 650 return failure; 651 } 652 653 static void 654 obj_name_cb(const OBJ_NAME *obj_name, void *do_all_arg) 655 { 656 struct do_all_arg *arg = do_all_arg; 657 struct do_all_arg arg_copy = *arg; 658 const char *previous = arg->previous; 659 const char *descr = "OBJ_NAME unknown"; 660 661 assert(obj_name->name != NULL); 662 arg->previous = obj_name->name; 663 664 if (obj_name->type == OBJ_NAME_TYPE_CIPHER_METH) { 665 descr = "OBJ_NAME cipher"; 666 667 if (obj_name->alias == 0) { 668 const EVP_CIPHER *cipher; 669 670 if ((cipher = EVP_get_cipherbyname(obj_name->name)) != 671 (const EVP_CIPHER *)obj_name->data) { 672 arg->failure |= 1; 673 fprintf(stderr, "FAIL: %s by name %p != %p\n", 674 descr, cipher, obj_name->data); 675 } 676 677 evp_do_all_cb_common(descr, obj_name->data, 678 obj_name->name, NULL, &arg_copy); 679 } else if (obj_name->alias == OBJ_NAME_ALIAS) { 680 evp_cipher_aliases_cb(NULL, obj_name->name, 681 obj_name->data, &arg_copy); 682 } else { 683 fprintf(stderr, "FAIL %s %s: unexpected alias value %d\n", 684 descr, obj_name->name, obj_name->alias); 685 arg->failure |= 1; 686 } 687 } else if (obj_name->type == OBJ_NAME_TYPE_MD_METH) { 688 descr = "OBJ_NAME digest"; 689 690 if (obj_name->alias == 0) { 691 const EVP_MD *evp_md; 692 693 if ((evp_md = EVP_get_digestbyname(obj_name->name)) != 694 (const EVP_MD *)obj_name->data) { 695 arg->failure |= 1; 696 fprintf(stderr, "FAIL: %s by name %p != %p\n", 697 descr, evp_md, obj_name->data); 698 } 699 700 evp_do_all_cb_common(descr, obj_name->data, 701 obj_name->name, NULL, &arg_copy); 702 } else if (obj_name->alias == OBJ_NAME_ALIAS) { 703 evp_digest_aliases_cb(NULL, obj_name->name, 704 obj_name->data, &arg_copy); 705 } else { 706 fprintf(stderr, "FAIL: %s %s: unexpected alias value %d\n", 707 descr, obj_name->name, obj_name->alias); 708 arg->failure |= 1; 709 } 710 } else { 711 fprintf(stderr, "FAIL: unexpected OBJ_NAME type %d\n", 712 obj_name->type); 713 arg->failure |= 1; 714 } 715 716 if (previous != NULL && strcmp(previous, obj_name->name) >= 0) { 717 arg->failure |= 1; 718 fprintf(stderr, "FAIL: %ss %s and %s out of order\n", descr, 719 previous, obj_name->name); 720 } 721 722 arg->failure |= arg_copy.failure; 723 } 724 725 static int 726 obj_name_do_all_test(void) 727 { 728 struct do_all_arg arg; 729 int failure = 0; 730 731 memset(&arg, 0, sizeof(arg)); 732 OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, obj_name_cb, &arg); 733 failure |= arg.failure; 734 735 memset(&arg, 0, sizeof(arg)); 736 OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, obj_name_cb, &arg); 737 failure |= arg.failure; 738 739 return failure; 740 } 741 742 static int 743 evp_get_cipherbyname_test(void) 744 { 745 int failure = 0; 746 747 /* Should handle NULL gracefully */ 748 failure |= EVP_get_cipherbyname(NULL) != NULL; 749 750 return failure; 751 } 752 753 static int 754 evp_get_digestbyname_test(void) 755 { 756 int failure = 0; 757 758 /* Should handle NULL gracefully */ 759 failure |= EVP_get_digestbyname(NULL) != NULL; 760 761 return failure; 762 } 763 764 static void 765 hexdump(const unsigned char *buf, int len) 766 { 767 int i; 768 769 if (len <= 0) { 770 fprintf(stderr, "<negative length %d>\n", len); 771 return; 772 } 773 774 for (i = 1; i <= len; i++) 775 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); 776 777 fprintf(stderr, "\n"); 778 } 779 780 static int 781 kdf_compare_bytes(const char *label, const unsigned char *d1, int len1, 782 const unsigned char *d2, int len2) 783 { 784 if (len1 != len2) { 785 fprintf(stderr, "FAIL: %s - byte lengths differ " 786 "(%d != %d)\n", label, len1, len2); 787 fprintf(stderr, "Got:\n"); 788 hexdump(d1, len1); 789 fprintf(stderr, "Want:\n"); 790 hexdump(d2, len2); 791 return 0; 792 } 793 if (memcmp(d1, d2, len1) != 0) { 794 fprintf(stderr, "FAIL: %s - bytes differ\n", label); 795 fprintf(stderr, "Got:\n"); 796 hexdump(d1, len1); 797 fprintf(stderr, "Want:\n"); 798 hexdump(d2, len2); 799 return 0; 800 } 801 return 1; 802 } 803 804 static int 805 evp_kdf_tls1_prf_basic(void) 806 { 807 EVP_PKEY_CTX *pctx; 808 unsigned char got[16]; 809 size_t got_len = sizeof(got); 810 unsigned char want[16] = { 811 0x8e, 0x4d, 0x93, 0x25, 0x30, 0xd7, 0x65, 0xa0, 812 0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc, 813 }; 814 int failed = 1; 815 816 if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL)) == NULL) { 817 fprintf(stderr, "FAIL: EVP_PKEY_CTX_new_id\n"); 818 goto err; 819 } 820 821 if (EVP_PKEY_derive_init(pctx) <= 0) { 822 fprintf(stderr, "FAIL: EVP_PKEY_derive_init\n"); 823 goto err; 824 } 825 826 if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha256()) <= 0) { 827 fprintf(stderr, "FAIL: EVP_PKEY_CTX_set1_tls1_prf_md\n"); 828 goto err; 829 } 830 831 if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, "secret", 6) <= 0) { 832 fprintf(stderr, "FAIL: EVP_PKEY_CTX_set1_tls1_prf_secret\n"); 833 goto err; 834 } 835 836 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, "seed", 4) <= 0) { 837 fprintf(stderr, "FAIL: EVP_PKEY_CTX_set1_tls1_prf_seed\n"); 838 goto err; 839 } 840 841 if (EVP_PKEY_derive(pctx, got, &got_len) <= 0) { 842 fprintf(stderr, "FAIL: EVP_PKEY_derive\n"); 843 goto err; 844 } 845 846 if (!kdf_compare_bytes("kdf test", got, got_len, want, sizeof(want))) 847 goto err; 848 849 failed = 0; 850 851 err: 852 EVP_PKEY_CTX_free(pctx); 853 854 return failed; 855 } 856 857 #define TLS_PRF_OUT_LEN 128 858 859 static const struct tls_prf_test { 860 const unsigned char *desc; 861 const EVP_MD *(*md)(void); 862 const uint16_t cipher_value; 863 const unsigned char out[TLS_PRF_OUT_LEN]; 864 } tls_prf_tests[] = { 865 { 866 .desc = "MD5+SHA1", 867 .md = EVP_md5_sha1, 868 .cipher_value = 0x0033, 869 .out = { 870 0x03, 0xa1, 0xc1, 0x7d, 0x2c, 0xa5, 0x3d, 0xe8, 871 0x9d, 0x59, 0x5e, 0x30, 0xf5, 0x71, 0xbb, 0x96, 872 0xde, 0x5c, 0x8e, 0xdc, 0x25, 0x8a, 0x7c, 0x05, 873 0x9f, 0x7d, 0x35, 0x29, 0x45, 0xae, 0x56, 0xad, 874 0x9f, 0x57, 0x15, 0x5c, 0xdb, 0x83, 0x3a, 0xac, 875 0x19, 0xa8, 0x2b, 0x40, 0x72, 0x38, 0x1e, 0xed, 876 0xf3, 0x25, 0xde, 0x84, 0x84, 0xd8, 0xd1, 0xfc, 877 0x31, 0x85, 0x81, 0x12, 0x55, 0x4d, 0x12, 0xb5, 878 0xed, 0x78, 0x5e, 0xba, 0xc8, 0xec, 0x8d, 0x28, 879 0xa1, 0x21, 0x1e, 0x6e, 0x07, 0xf1, 0xfc, 0xf5, 880 0xbf, 0xe4, 0x8e, 0x8e, 0x97, 0x15, 0x93, 0x85, 881 0x75, 0xdd, 0x87, 0x09, 0xd0, 0x4e, 0xe5, 0xd5, 882 0x9e, 0x1f, 0xd6, 0x1c, 0x3b, 0xe9, 0xad, 0xba, 883 0xe0, 0x16, 0x56, 0x62, 0x90, 0xd6, 0x82, 0x84, 884 0xec, 0x8a, 0x22, 0xbe, 0xdc, 0x6a, 0x5e, 0x05, 885 0x12, 0x44, 0xec, 0x60, 0x61, 0xd1, 0x8a, 0x66, 886 }, 887 }, 888 { 889 .desc = "SHA256 (via TLSv1.2)", 890 .md = EVP_sha256, 891 .cipher_value = 0x0033, 892 .out = { 893 0x37, 0xa7, 0x06, 0x71, 0x6e, 0x19, 0x19, 0xda, 894 0x23, 0x8c, 0xcc, 0xb4, 0x2f, 0x31, 0x64, 0x9d, 895 0x05, 0x29, 0x1c, 0x33, 0x7e, 0x09, 0x1b, 0x0c, 896 0x0e, 0x23, 0xc1, 0xb0, 0x40, 0xcc, 0x31, 0xf7, 897 0x55, 0x66, 0x68, 0xd9, 0xa8, 0xae, 0x74, 0x75, 898 0xf3, 0x46, 0xe9, 0x3a, 0x54, 0x9d, 0xe0, 0x8b, 899 0x7e, 0x6c, 0x63, 0x1c, 0xfa, 0x2f, 0xfd, 0xc9, 900 0xd3, 0xf1, 0xd3, 0xfe, 0x7b, 0x9e, 0x14, 0x95, 901 0xb5, 0xd0, 0xad, 0x9b, 0xee, 0x78, 0x8c, 0x83, 902 0x18, 0x58, 0x7e, 0xa2, 0x23, 0xc1, 0x8b, 0x62, 903 0x94, 0x12, 0xcb, 0xb6, 0x60, 0x69, 0x32, 0xfe, 904 0x98, 0x0e, 0x93, 0xb0, 0x8e, 0x5c, 0xfb, 0x6e, 905 0xdb, 0x9a, 0xc2, 0x9f, 0x8c, 0x5c, 0x43, 0x19, 906 0xeb, 0x4a, 0x52, 0xad, 0x62, 0x2b, 0xdd, 0x9f, 907 0xa3, 0x74, 0xa6, 0x96, 0x61, 0x4d, 0x98, 0x40, 908 0x63, 0xa6, 0xd4, 0xbb, 0x17, 0x11, 0x75, 0xed, 909 }, 910 }, 911 { 912 .desc = "SHA384", 913 .md = EVP_sha384, 914 .cipher_value = 0x009d, 915 .out = { 916 0x00, 0x93, 0xc3, 0xfd, 0xa7, 0xbb, 0xdc, 0x5b, 917 0x13, 0x3a, 0xe6, 0x8b, 0x1b, 0xac, 0xf3, 0xfb, 918 0x3c, 0x9a, 0x78, 0xf6, 0x19, 0xf0, 0x13, 0x0f, 919 0x0d, 0x01, 0x9d, 0xdf, 0x0a, 0x28, 0x38, 0xce, 920 0x1a, 0x9b, 0x43, 0xbe, 0x56, 0x12, 0xa7, 0x16, 921 0x58, 0xe1, 0x8a, 0xe4, 0xc5, 0xbb, 0x10, 0x4c, 922 0x3a, 0xf3, 0x7f, 0xd3, 0xdb, 0xe4, 0xe0, 0x3d, 923 0xcc, 0x83, 0xca, 0xf0, 0xf9, 0x69, 0xcc, 0x70, 924 0x83, 0x32, 0xf6, 0xfc, 0x81, 0x80, 0x02, 0xe8, 925 0x31, 0x1e, 0x7c, 0x3b, 0x34, 0xf7, 0x34, 0xd1, 926 0xcf, 0x2a, 0xc4, 0x36, 0x2f, 0xe9, 0xaa, 0x7f, 927 0x6d, 0x1f, 0x5e, 0x0e, 0x39, 0x05, 0x15, 0xe1, 928 0xa2, 0x9a, 0x4d, 0x97, 0x8c, 0x62, 0x46, 0xf1, 929 0x87, 0x65, 0xd8, 0xe9, 0x14, 0x11, 0xa6, 0x48, 930 0xd7, 0x0e, 0x6e, 0x70, 0xad, 0xfb, 0x3f, 0x36, 931 0x05, 0x76, 0x4b, 0xe4, 0x28, 0x50, 0x4a, 0xf2, 932 }, 933 }, 934 }; 935 936 #define N_TLS_PRF_TESTS \ 937 (sizeof(tls_prf_tests) / sizeof(*tls_prf_tests)) 938 939 #define TLS_PRF_SEED1 "tls prf seed 1" 940 #define TLS_PRF_SEED2 "tls prf seed 2" 941 #define TLS_PRF_SEED3 "tls prf seed 3" 942 #define TLS_PRF_SEED4 "tls prf seed 4" 943 #define TLS_PRF_SEED5 "tls prf seed 5" 944 #define TLS_PRF_SECRET "tls prf secretz" 945 946 static int 947 do_tls_prf_evp_test(int test_no, const struct tls_prf_test *test) 948 { 949 EVP_PKEY_CTX *pkey_ctx = NULL; 950 unsigned char *out; 951 size_t len, out_len; 952 int failed = 1; 953 954 if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL)) == NULL) 955 errx(1, "EVP_PKEY_CTX_new_id"); 956 957 if ((out = malloc(TLS_PRF_OUT_LEN)) == NULL) 958 errx(1, "malloc"); 959 960 for (len = 1; len <= TLS_PRF_OUT_LEN; len++) { 961 if (EVP_PKEY_derive_init(pkey_ctx) <= 0) 962 errx(1, "EVP_PKEY_derive_init"); 963 964 if (EVP_PKEY_CTX_set_tls1_prf_md(pkey_ctx, test->md()) <= 0) 965 errx(1, "EVP_PKEY_CTX_set_tls1_prf_md"); 966 967 if (EVP_PKEY_CTX_set1_tls1_prf_secret(pkey_ctx, TLS_PRF_SECRET, 968 sizeof(TLS_PRF_SECRET)) <= 0) 969 errx(1, "EVP_PKEY_CTX_set1_tls1_prf_secret"); 970 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED1, 971 sizeof(TLS_PRF_SEED1)) <= 0) 972 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 1"); 973 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED2, 974 sizeof(TLS_PRF_SEED2)) <= 0) 975 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 2"); 976 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED3, 977 sizeof(TLS_PRF_SEED3)) <= 0) 978 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 3"); 979 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED4, 980 sizeof(TLS_PRF_SEED4)) <= 0) 981 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 4"); 982 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED5, 983 sizeof(TLS_PRF_SEED5)) <= 0) 984 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 5"); 985 986 out_len = len; 987 if (EVP_PKEY_derive(pkey_ctx, out, &out_len) <= 0) 988 errx(1, "EVP_PKEY_derive"); 989 990 if (out_len != len) { 991 fprintf(stderr, "FAIL: %s: length %zu != %zu\n", 992 __func__, out_len, len); 993 goto err; 994 } 995 996 if (memcmp(test->out, out, out_len) != 0) { 997 fprintf(stderr, "FAIL: tls_PRF output differs for " 998 "len %zu\n", len); 999 fprintf(stderr, "output:\n"); 1000 hexdump(out, out_len); 1001 fprintf(stderr, "test data:\n"); 1002 hexdump(test->out, len); 1003 goto err; 1004 } 1005 } 1006 1007 failed = 0; 1008 1009 err: 1010 EVP_PKEY_CTX_free(pkey_ctx); 1011 free(out); 1012 1013 return failed; 1014 } 1015 1016 static int 1017 evp_kdf_tls1_prf(void) 1018 { 1019 size_t i; 1020 int failed = 0; 1021 1022 for (i = 0; i < N_TLS_PRF_TESTS; i++) 1023 failed |= do_tls_prf_evp_test(i, &tls_prf_tests[i]); 1024 1025 return failed; 1026 } 1027 1028 int 1029 main(int argc, char **argv) 1030 { 1031 int failed = 0; 1032 1033 failed |= evp_asn1_method_test(); 1034 failed |= evp_asn1_method_aliases_test(); 1035 failed |= evp_pkey_iv_len_test(); 1036 failed |= evp_do_all_test(); 1037 failed |= evp_aliases_test(); 1038 failed |= obj_name_do_all_test(); 1039 failed |= evp_get_cipherbyname_test(); 1040 failed |= evp_get_digestbyname_test(); 1041 failed |= evp_kdf_tls1_prf_basic(); 1042 failed |= evp_kdf_tls1_prf(); 1043 1044 OPENSSL_cleanup(); 1045 1046 return failed; 1047 } 1048