diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/regress/lib/libcrypto/sha/Makefile | 8 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/sha/sha_test.c | 286 |
2 files changed, 141 insertions, 153 deletions
diff --git a/src/regress/lib/libcrypto/sha/Makefile b/src/regress/lib/libcrypto/sha/Makefile index 6ec223116d..c6ab0398ba 100644 --- a/src/regress/lib/libcrypto/sha/Makefile +++ b/src/regress/lib/libcrypto/sha/Makefile | |||
| @@ -1,9 +1,15 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.5 2022/09/01 14:02:41 tb Exp $ | 1 | # $OpenBSD: Makefile,v 1.6 2025/05/22 03:35:40 joshua Exp $ |
| 2 | 2 | ||
| 3 | PROG = sha_test | 3 | PROG = sha_test |
| 4 | LDADD = -lcrypto | 4 | LDADD = -lcrypto |
| 5 | DPADD = ${LIBCRYPTO} | 5 | DPADD = ${LIBCRYPTO} |
| 6 | WARNINGS = Yes | 6 | WARNINGS = Yes |
| 7 | CFLAGS += -DLIBRESSL_INTERNAL -Werror | 7 | CFLAGS += -DLIBRESSL_INTERNAL -Werror |
| 8 | CFLAGS += -I${.CURDIR}/../test | ||
| 9 | SRCS += sha_test.c | ||
| 10 | SRCS += test.c | ||
| 11 | SRCS += test_util.c | ||
| 12 | |||
| 13 | .PATH: ${.CURDIR}/../test | ||
| 8 | 14 | ||
| 9 | .include <bsd.regress.mk> | 15 | .include <bsd.regress.mk> |
diff --git a/src/regress/lib/libcrypto/sha/sha_test.c b/src/regress/lib/libcrypto/sha/sha_test.c index 82a0c4cceb..904924c890 100644 --- a/src/regress/lib/libcrypto/sha/sha_test.c +++ b/src/regress/lib/libcrypto/sha/sha_test.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* $OpenBSD: sha_test.c,v 1.6 2023/07/19 15:11:42 joshua Exp $ */ | 1 | /* $OpenBSD: sha_test.c,v 1.7 2025/05/22 03:35:40 joshua Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2022, 2023 Joshua Sing <joshua@hypera.dev> | 3 | * Copyright (c) 2022, 2023, 2025 Joshua Sing <joshua@joshuasing.dev> |
| 4 | * | 4 | * |
| 5 | * Permission to use, copy, modify, and distribute this software for any | 5 | * Permission to use, copy, modify, and distribute this software for any |
| 6 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <stdint.h> | 21 | #include <stdint.h> |
| 22 | #include <string.h> | 22 | #include <string.h> |
| 23 | 23 | ||
| 24 | #include "test.h" | ||
| 25 | |||
| 24 | struct sha_test { | 26 | struct sha_test { |
| 25 | const int algorithm; | 27 | const int algorithm; |
| 26 | const uint8_t in[128]; | 28 | const uint8_t in[128]; |
| @@ -677,260 +679,240 @@ typedef unsigned char *(*sha_hash_func)(const unsigned char *, size_t, | |||
| 677 | unsigned char *); | 679 | unsigned char *); |
| 678 | 680 | ||
| 679 | static int | 681 | static int |
| 680 | sha_hash_from_algorithm(int algorithm, const char **out_label, | 682 | sha_hash_from_algorithm(int algorithm, sha_hash_func *out_func, |
| 681 | sha_hash_func *out_func, const EVP_MD **out_md, size_t *out_len) | 683 | const EVP_MD **out_md) |
| 682 | { | 684 | { |
| 683 | const char *label; | ||
| 684 | sha_hash_func sha_func; | 685 | sha_hash_func sha_func; |
| 685 | const EVP_MD *md; | 686 | const EVP_MD *md; |
| 686 | size_t len; | ||
| 687 | 687 | ||
| 688 | switch (algorithm) { | 688 | switch (algorithm) { |
| 689 | case NID_sha1: | 689 | case NID_sha1: |
| 690 | label = SN_sha1; | ||
| 691 | sha_func = SHA1; | 690 | sha_func = SHA1; |
| 692 | md = EVP_sha1(); | 691 | md = EVP_sha1(); |
| 693 | len = SHA_DIGEST_LENGTH; | ||
| 694 | break; | 692 | break; |
| 695 | case NID_sha224: | 693 | case NID_sha224: |
| 696 | label = SN_sha224; | ||
| 697 | sha_func = SHA224; | 694 | sha_func = SHA224; |
| 698 | md = EVP_sha224(); | 695 | md = EVP_sha224(); |
| 699 | len = SHA224_DIGEST_LENGTH; | ||
| 700 | break; | 696 | break; |
| 701 | case NID_sha256: | 697 | case NID_sha256: |
| 702 | label = SN_sha256; | ||
| 703 | sha_func = SHA256; | 698 | sha_func = SHA256; |
| 704 | md = EVP_sha256(); | 699 | md = EVP_sha256(); |
| 705 | len = SHA256_DIGEST_LENGTH; | ||
| 706 | break; | 700 | break; |
| 707 | case NID_sha384: | 701 | case NID_sha384: |
| 708 | label = SN_sha384; | ||
| 709 | sha_func = SHA384; | 702 | sha_func = SHA384; |
| 710 | md = EVP_sha384(); | 703 | md = EVP_sha384(); |
| 711 | len = SHA384_DIGEST_LENGTH; | ||
| 712 | break; | 704 | break; |
| 713 | case NID_sha512: | 705 | case NID_sha512: |
| 714 | label = SN_sha512; | ||
| 715 | sha_func = SHA512; | 706 | sha_func = SHA512; |
| 716 | md = EVP_sha512(); | 707 | md = EVP_sha512(); |
| 717 | len = SHA512_DIGEST_LENGTH; | ||
| 718 | break; | 708 | break; |
| 719 | case NID_sha3_224: | 709 | case NID_sha3_224: |
| 720 | label = SN_sha3_224; | ||
| 721 | sha_func = NULL; | 710 | sha_func = NULL; |
| 722 | md = EVP_sha3_224(); | 711 | md = EVP_sha3_224(); |
| 723 | len = 224 / 8; | ||
| 724 | break; | 712 | break; |
| 725 | case NID_sha3_256: | 713 | case NID_sha3_256: |
| 726 | label = SN_sha3_256; | ||
| 727 | sha_func = NULL; | 714 | sha_func = NULL; |
| 728 | md = EVP_sha3_256(); | 715 | md = EVP_sha3_256(); |
| 729 | len = 256 / 8; | ||
| 730 | break; | 716 | break; |
| 731 | case NID_sha3_384: | 717 | case NID_sha3_384: |
| 732 | label = SN_sha3_384; | ||
| 733 | sha_func = NULL; | 718 | sha_func = NULL; |
| 734 | md = EVP_sha3_384(); | 719 | md = EVP_sha3_384(); |
| 735 | len = 384 / 8; | ||
| 736 | break; | 720 | break; |
| 737 | case NID_sha3_512: | 721 | case NID_sha3_512: |
| 738 | label = SN_sha3_512; | ||
| 739 | sha_func = NULL; | 722 | sha_func = NULL; |
| 740 | md = EVP_sha3_512(); | 723 | md = EVP_sha3_512(); |
| 741 | len = 512 / 8; | ||
| 742 | break; | 724 | break; |
| 743 | default: | 725 | default: |
| 744 | fprintf(stderr, "FAIL: unknown algorithm (%d)\n", | ||
| 745 | algorithm); | ||
| 746 | return 0; | 726 | return 0; |
| 747 | } | 727 | } |
| 748 | 728 | ||
| 749 | if (out_label != NULL) | ||
| 750 | *out_label = label; | ||
| 751 | if (out_func != NULL) | 729 | if (out_func != NULL) |
| 752 | *out_func = sha_func; | 730 | *out_func = sha_func; |
| 753 | if (out_md != NULL) | 731 | if (out_md != NULL) |
| 754 | *out_md = md; | 732 | *out_md = md; |
| 755 | if (out_len != NULL) | ||
| 756 | *out_len = len; | ||
| 757 | 733 | ||
| 758 | return 1; | 734 | return 1; |
| 759 | } | 735 | } |
| 760 | 736 | ||
| 761 | static int | 737 | static void |
| 762 | sha_test(void) | 738 | test_sha_tv(struct test *t, const void *arg) |
| 763 | { | 739 | { |
| 740 | const struct sha_test *st = arg; | ||
| 764 | sha_hash_func sha_func; | 741 | sha_hash_func sha_func; |
| 765 | const struct sha_test *st; | ||
| 766 | EVP_MD_CTX *hash = NULL; | 742 | EVP_MD_CTX *hash = NULL; |
| 767 | const EVP_MD *md; | 743 | const EVP_MD *md; |
| 768 | uint8_t out[EVP_MAX_MD_SIZE]; | 744 | uint8_t out[EVP_MAX_MD_SIZE]; |
| 769 | size_t in_len, out_len; | 745 | size_t in_len, out_len; |
| 770 | size_t i; | ||
| 771 | const char *label; | ||
| 772 | int failed = 1; | ||
| 773 | 746 | ||
| 774 | if ((hash = EVP_MD_CTX_new()) == NULL) { | 747 | if ((hash = EVP_MD_CTX_new()) == NULL) { |
| 775 | fprintf(stderr, "FAIL: EVP_MD_CTX_new() failed\n"); | 748 | test_errorf(t, "EVP_MD_CTX_new()"); |
| 776 | goto failed; | 749 | goto fail; |
| 777 | } | 750 | } |
| 778 | 751 | ||
| 779 | for (i = 0; i < N_SHA_TESTS; i++) { | 752 | if (!sha_hash_from_algorithm(st->algorithm, &sha_func, &md)) |
| 780 | st = &sha_tests[i]; | 753 | goto fail; |
| 781 | if (!sha_hash_from_algorithm(st->algorithm, &label, &sha_func, | ||
| 782 | &md, &out_len)) | ||
| 783 | goto failed; | ||
| 784 | |||
| 785 | /* Digest */ | ||
| 786 | if (sha_func != NULL) { | ||
| 787 | memset(out, 0, sizeof(out)); | ||
| 788 | sha_func(st->in, st->in_len, out); | ||
| 789 | if (memcmp(st->out, out, out_len) != 0) { | ||
| 790 | fprintf(stderr, "FAIL (%s:%zu): mismatch\n", | ||
| 791 | label, i); | ||
| 792 | goto failed; | ||
| 793 | } | ||
| 794 | } | ||
| 795 | 754 | ||
| 796 | /* EVP single-shot digest */ | 755 | out_len = EVP_MD_size(md); |
| 797 | memset(out, 0, sizeof(out)); | ||
| 798 | if (!EVP_Digest(st->in, st->in_len, out, NULL, md, NULL)) { | ||
| 799 | fprintf(stderr, "FAIL (%s:%zu): EVP_Digest failed\n", | ||
| 800 | label, i); | ||
| 801 | goto failed; | ||
| 802 | } | ||
| 803 | 756 | ||
| 757 | /* Digest */ | ||
| 758 | if (sha_func != NULL) { | ||
| 759 | memset(out, 0, sizeof(out)); | ||
| 760 | sha_func(st->in, st->in_len, out); | ||
| 804 | if (memcmp(st->out, out, out_len) != 0) { | 761 | if (memcmp(st->out, out, out_len) != 0) { |
| 805 | fprintf(stderr, | 762 | test_errorf(t, "SHA: digest output mismatch"); |
| 806 | "FAIL (%s:%zu): EVP single-shot mismatch\n", | 763 | test_hexdiff(t, out, out_len, st->out); |
| 807 | label, i); | ||
| 808 | goto failed; | ||
| 809 | } | 764 | } |
| 765 | } | ||
| 810 | 766 | ||
| 811 | /* EVP digest */ | 767 | /* EVP single-shot digest */ |
| 812 | memset(out, 0, sizeof(out)); | 768 | memset(out, 0, sizeof(out)); |
| 813 | if (!EVP_DigestInit_ex(hash, md, NULL)) { | 769 | if (!EVP_Digest(st->in, st->in_len, out, NULL, md, NULL)) { |
| 814 | fprintf(stderr, | 770 | test_errorf(t, "EVP_Digest()"); |
| 815 | "FAIL (%s:%zu): EVP_DigestInit_ex failed\n", | 771 | goto fail; |
| 816 | label, i); | 772 | } |
| 817 | goto failed; | ||
| 818 | } | ||
| 819 | 773 | ||
| 820 | in_len = st->in_len / 2; | 774 | if (memcmp(st->out, out, out_len) != 0) { |
| 821 | if (!EVP_DigestUpdate(hash, st->in, in_len)) { | 775 | test_errorf(t, "EVP single-shot: output diget mismatch"); |
| 822 | fprintf(stderr, | 776 | test_hexdiff(t, out, out_len, st->out); |
| 823 | "FAIL (%s:%zu): EVP_DigestUpdate first half " | 777 | } |
| 824 | "failed\n", label, i); | ||
| 825 | goto failed; | ||
| 826 | } | ||
| 827 | 778 | ||
| 828 | if (!EVP_DigestUpdate(hash, st->in + in_len, | 779 | /* EVP digest */ |
| 829 | st->in_len - in_len)) { | 780 | memset(out, 0, sizeof(out)); |
| 830 | fprintf(stderr, | 781 | if (!EVP_DigestInit_ex(hash, md, NULL)) { |
| 831 | "FAIL (%s:%zu): EVP_DigestUpdate second half " | 782 | test_errorf(t, "EVP_DigestInit_ex() "); |
| 832 | "failed\n", label, i); | 783 | goto fail; |
| 833 | goto failed; | 784 | } |
| 834 | } | ||
| 835 | 785 | ||
| 836 | if (!EVP_DigestFinal_ex(hash, out, NULL)) { | 786 | in_len = st->in_len / 2; |
| 837 | fprintf(stderr, | 787 | if (!EVP_DigestUpdate(hash, st->in, in_len)) { |
| 838 | "FAIL (%s:%zu): EVP_DigestFinal_ex failed\n", | 788 | test_errorf(t, "EVP_DigestUpdate() first half"); |
| 839 | label, i); | 789 | goto fail; |
| 840 | goto failed; | 790 | } |
| 841 | } | ||
| 842 | 791 | ||
| 843 | if (memcmp(st->out, out, out_len) != 0) { | 792 | if (!EVP_DigestUpdate(hash, st->in + in_len, |
| 844 | fprintf(stderr, "FAIL (%s:%zu): EVP mismatch\n", | 793 | st->in_len - in_len)) { |
| 845 | label, i); | 794 | test_errorf(t, "EVP_DigestUpdate() second half"); |
| 846 | goto failed; | 795 | goto fail; |
| 847 | } | ||
| 848 | } | 796 | } |
| 849 | 797 | ||
| 850 | failed = 0; | 798 | if (!EVP_DigestFinal_ex(hash, out, NULL)) { |
| 799 | test_errorf(t, "EVP_DigestFinal_ex()"); | ||
| 800 | goto fail; | ||
| 801 | } | ||
| 851 | 802 | ||
| 852 | failed: | 803 | if (memcmp(st->out, out, out_len) != 0) { |
| 804 | test_errorf(t, "EVP: digest output mismatch"); | ||
| 805 | test_hexdiff(t, out, out_len, st->out); | ||
| 806 | } | ||
| 807 | |||
| 808 | |||
| 809 | fail: | ||
| 853 | EVP_MD_CTX_free(hash); | 810 | EVP_MD_CTX_free(hash); |
| 854 | return failed; | ||
| 855 | } | 811 | } |
| 856 | 812 | ||
| 857 | static int | 813 | static void |
| 858 | sha_repetition_test(void) | 814 | test_sha(struct test *t, const void *arg) |
| 859 | { | 815 | { |
| 860 | const struct sha_repetition_test *st; | 816 | const struct sha_test *st; |
| 817 | size_t i; | ||
| 818 | char *name; | ||
| 819 | |||
| 820 | for (i = 0; i < N_SHA_TESTS; i++) { | ||
| 821 | st = &sha_tests[i]; | ||
| 822 | if (asprintf(&name, "%s: '%s'", OBJ_nid2sn(st->algorithm), st->in) == -1) { | ||
| 823 | test_errorf(t, "create test name failed"); | ||
| 824 | return; | ||
| 825 | } | ||
| 826 | |||
| 827 | test_run(t, name, test_sha_tv, st); | ||
| 828 | free(name); | ||
| 829 | } | ||
| 830 | } | ||
| 831 | |||
| 832 | static void | ||
| 833 | test_sha_repetition_tv(struct test *t, const void *arg) | ||
| 834 | { | ||
| 835 | const struct sha_repetition_test *st = arg; | ||
| 861 | EVP_MD_CTX *hash = NULL; | 836 | EVP_MD_CTX *hash = NULL; |
| 862 | const EVP_MD *md; | 837 | const EVP_MD *md; |
| 863 | uint8_t buf[1024]; | 838 | uint8_t buf[1024]; |
| 864 | uint8_t out[EVP_MAX_MD_SIZE]; | 839 | uint8_t out[EVP_MAX_MD_SIZE]; |
| 865 | size_t out_len, part_len; | 840 | size_t out_len, part_len; |
| 866 | size_t i, j; | 841 | size_t i; |
| 867 | const char *label; | ||
| 868 | int failed = 1; | ||
| 869 | 842 | ||
| 870 | if ((hash = EVP_MD_CTX_new()) == NULL) { | 843 | if ((hash = EVP_MD_CTX_new()) == NULL) { |
| 871 | fprintf(stderr, "FAIL: EVP_MD_CTX_new() failed\n"); | 844 | test_errorf(t, "EVP_MD_CTX_new()"); |
| 872 | goto failed; | 845 | goto fail; |
| 873 | } | 846 | } |
| 874 | 847 | ||
| 875 | for (i = 0; i < N_SHA_REPETITION_TESTS; i++) { | 848 | if (!sha_hash_from_algorithm(st->algorithm, NULL, &md)) |
| 876 | st = &sha_repetition_tests[i]; | 849 | goto fail; |
| 877 | if (!sha_hash_from_algorithm(st->algorithm, &label, NULL, &md, | ||
| 878 | &out_len)) | ||
| 879 | goto failed; | ||
| 880 | |||
| 881 | /* EVP digest */ | ||
| 882 | if (!EVP_DigestInit_ex(hash, md, NULL)) { | ||
| 883 | fprintf(stderr, | ||
| 884 | "FAIL (%s:%zu): EVP_DigestInit_ex failed\n", | ||
| 885 | label, i); | ||
| 886 | goto failed; | ||
| 887 | } | ||
| 888 | 850 | ||
| 889 | memset(buf, st->in, sizeof(buf)); | 851 | out_len = EVP_MD_size(md); |
| 890 | 852 | ||
| 891 | for (j = 0; j < st->in_repetitions;) { | 853 | /* EVP digest */ |
| 892 | part_len = arc4random_uniform(sizeof(buf)); | 854 | if (!EVP_DigestInit_ex(hash, md, NULL)) { |
| 893 | if (part_len > st->in_repetitions - j) | 855 | test_errorf(t, "EVP_DigestInit_ex()"); |
| 894 | part_len = st->in_repetitions - j; | 856 | goto fail; |
| 857 | } | ||
| 895 | 858 | ||
| 896 | if (!EVP_DigestUpdate(hash, buf, part_len)) { | 859 | memset(buf, st->in, sizeof(buf)); |
| 897 | fprintf(stderr, | ||
| 898 | "FAIL (%s:%zu): EVP_DigestUpdate failed\n", | ||
| 899 | label, i); | ||
| 900 | goto failed; | ||
| 901 | } | ||
| 902 | 860 | ||
| 903 | j += part_len; | 861 | for (i = 0; i < st->in_repetitions;) { |
| 904 | } | 862 | part_len = arc4random_uniform(sizeof(buf)); |
| 863 | if (part_len > st->in_repetitions - i) | ||
| 864 | part_len = st->in_repetitions - i; | ||
| 905 | 865 | ||
| 906 | if (!EVP_DigestFinal_ex(hash, out, NULL)) { | 866 | if (!EVP_DigestUpdate(hash, buf, part_len)) { |
| 907 | fprintf(stderr, | 867 | test_errorf(t, "EVP_DigestUpdate()"); |
| 908 | "FAIL (%s:%zu): EVP_DigestFinal_ex failed\n", | 868 | goto fail; |
| 909 | label, i); | ||
| 910 | goto failed; | ||
| 911 | } | 869 | } |
| 912 | 870 | ||
| 913 | if (memcmp(st->out, out, out_len) != 0) { | 871 | i += part_len; |
| 914 | fprintf(stderr, "FAIL (%s:%zu): EVP mismatch\n", | 872 | } |
| 915 | label, i); | 873 | |
| 916 | goto failed; | 874 | if (!EVP_DigestFinal_ex(hash, out, NULL)) { |
| 917 | } | 875 | test_errorf(t, "EVP_DigestFinal_ex()"); |
| 876 | goto fail; | ||
| 918 | } | 877 | } |
| 919 | 878 | ||
| 920 | failed = 0; | 879 | if (memcmp(st->out, out, out_len) != 0) { |
| 880 | test_errorf(t, "EVP: digest output mismatch"); | ||
| 881 | test_hexdiff(t, out, out_len, st->out); | ||
| 882 | goto fail; | ||
| 883 | } | ||
| 921 | 884 | ||
| 922 | failed: | 885 | fail: |
| 923 | EVP_MD_CTX_free(hash); | 886 | EVP_MD_CTX_free(hash); |
| 924 | return failed; | 887 | } |
| 888 | |||
| 889 | static void | ||
| 890 | test_sha_repetition(struct test *t, const void *arg) | ||
| 891 | { | ||
| 892 | const struct sha_repetition_test *st; | ||
| 893 | size_t i; | ||
| 894 | char *name; | ||
| 895 | |||
| 896 | for (i = 0; i < N_SHA_REPETITION_TESTS; i++) { | ||
| 897 | st = &sha_repetition_tests[i]; | ||
| 898 | if (asprintf(&name, "%s: '%hhu' x %zu", OBJ_nid2sn(st->algorithm), | ||
| 899 | st->in, st->in_repetitions) == -1) { | ||
| 900 | test_errorf(t, "create test name failed"); | ||
| 901 | return; | ||
| 902 | } | ||
| 903 | |||
| 904 | test_run(t, name, test_sha_repetition_tv, st); | ||
| 905 | free(name); | ||
| 906 | } | ||
| 925 | } | 907 | } |
| 926 | 908 | ||
| 927 | int | 909 | int |
| 928 | main(int argc, char **argv) | 910 | main(int argc, char **argv) |
| 929 | { | 911 | { |
| 930 | int failed = 0; | 912 | struct test *t = test_init(); |
| 931 | 913 | ||
| 932 | failed |= sha_test(); | 914 | test_run(t, "sha", test_sha, NULL); |
| 933 | failed |= sha_repetition_test(); | 915 | test_run(t, "sha repetition", test_sha_repetition, NULL); |
| 934 | 916 | ||
| 935 | return failed; | 917 | return test_result(t); |
| 936 | } | 918 | } |
