libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

commit d991f7b26a01a034eb0fa865099343a060443e4d
parent e4ff1d8b63f51fee31629516a1b4ab41def0beed
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Thu, 16 Jul 2026 18:12:33 +0200

MD5/SHA unit tests: aligned, more tests, more test vectors

Diffstat:
Msrc/tests/unit/unit_md5.c | 113++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/tests/unit/unit_sha256.c | 218+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/tests/unit/unit_sha512_256.c | 300++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 594 insertions(+), 37 deletions(-)

diff --git a/src/tests/unit/unit_md5.c b/src/tests/unit/unit_md5.c @@ -653,9 +653,6 @@ main (int argc, { "abc (RFC 1321)", "616263", "900150983cd24fb0d6963f7d28e17f72" }, - { "a (RFC 1321)", - "61", - "0cc175b9c0f1b6a831c399e269772661" }, { "message digest (RFC 1321)", "6d65737361676520646967657374", "f96b697d7cb7938d525a2f31aaf161d0" }, @@ -683,6 +680,7 @@ main (int argc, uint8_t data[1024]; size_t data_len; const char *test_name; + unsigned int i; unsigned int passed = 0; unsigned int total = 0; unsigned int num_failed; @@ -753,6 +751,9 @@ main (int argc, mhd_MD5_update (&ctx, 1, data); + mhd_MD5_update (&ctx, + 0, /* Empty data - valid for unit-tests only */ + data); data[0] = 'c'; mhd_MD5_update (&ctx, 1, @@ -805,10 +806,26 @@ main (int argc, data); mhd_MD5_finish_reset (&ctx, digest); + if (mhd_MD5_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend error after first hash: %d.\n", + test_name, + mhd_MD5_get_err (&ctx)); + mhd_MD5_deinit (&ctx); + exit (99); + } + if (check_digest (digest, + mhd_MD5_DIGEST_SIZE, + "900150983cd24fb0d6963f7d28e17f72", + "Reset and reuse context: first hash")) + passed++; + /* Second hash on same context */ - data_len = hex2bin ("616263", + total++; + data_len = hex2bin ("61", data, - sizeof(data)); /* "abc" again */ + sizeof(data)); /* "a" */ mhd_MD5_update (&ctx, data_len, data); @@ -819,26 +836,104 @@ main (int argc, { if (check_digest (digest, mhd_MD5_DIGEST_SIZE, - "900150983cd24fb0d6963f7d28e17f72", - test_name)) + "0cc175b9c0f1b6a831c399e269772661", + "Reset and reuse context: second hash")) passed++; } else { - printf ("FAIL: %s - backend reported error\n", - test_name); + fprintf (stderr, + "FAIL: %s - backend error after second hash: %d.\n", + test_name, + mhd_MD5_get_err (&ctx)); + mhd_MD5_deinit (&ctx); exit (99); } } else { fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_MD5_get_err (&ctx)); + mhd_MD5_deinit (&ctx); + exit (99); + } + mhd_MD5_deinit (&ctx); + + /* + * Test finish_deinit functionality + */ + total++; + test_name = "Finish and deinitialise context"; + mhd_MD5_init (&ctx); + if (mhd_MD5_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_MD5_get_err (&ctx)); + mhd_MD5_deinit (&ctx); + exit (99); + } + data_len = hex2bin ("616263", + data, + sizeof(data)); /* "abc" */ + mhd_MD5_update (&ctx, + data_len, + data); + mhd_MD5_finish_deinit (&ctx, + digest); + if (mhd_MD5_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend error: %d.\n", + test_name, + mhd_MD5_get_err (&ctx)); + exit (99); + } + if (check_digest (digest, + mhd_MD5_DIGEST_SIZE, + "900150983cd24fb0d6963f7d28e17f72", + test_name)) + passed++; + + /* + * Test hashing of a long multi-block stream of data + */ + total++; + test_name = "One million repetitions of 'a'"; + mhd_MD5_init (&ctx); + if (mhd_MD5_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_MD5_get_err (&ctx)); + mhd_MD5_deinit (&ctx); + exit (99); + } + memset (data, 'a', 1000); + for (i = 0; i < 1000; ++i) + mhd_MD5_update (&ctx, + 1000, + data); + mhd_MD5_finish (&ctx, + digest); + if (mhd_MD5_has_err (&ctx)) + { + fprintf (stderr, "FAIL: %s - backend error: %d.\n", test_name, mhd_MD5_get_err (&ctx)); mhd_MD5_deinit (&ctx); exit (99); } + if (check_digest (digest, + mhd_MD5_DIGEST_SIZE, + "7707d6ae4e027c70eea2a935c2296f21", + test_name)) + passed++; mhd_MD5_deinit (&ctx); num_failed = total - passed; diff --git a/src/tests/unit/unit_sha256.c b/src/tests/unit/unit_sha256.c @@ -677,6 +677,8 @@ main (int argc, uint8_t digest[mhd_SHA256_DIGEST_SIZE]; uint8_t data[1024]; size_t data_len; + const char *test_name; + unsigned int i; unsigned int passed = 0; unsigned int total = 0; unsigned int num_failed; @@ -712,19 +714,227 @@ main (int argc, } else { - printf ("FAIL: %s - digest function failed due to backend error\n", - t->name); + fprintf (stderr, + "FAIL: %s - digest function failed due to backend error: " \ + "%d.\n", + t->name, + mhd_SHA256_get_err (&ctx)); + mhd_SHA256_deinit (&ctx); exit (99); } } else { - printf ("FAIL: %s - error in init\n", - t->name); + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + t->name, + mhd_SHA256_get_err (&ctx)); + mhd_SHA256_deinit (&ctx); + exit (99); + } + mhd_SHA256_deinit (&ctx); + } + + /* + * Test update functionality + */ + total++; + test_name = "Multi-update: a + b + c"; + mhd_SHA256_init (&ctx); + if (!mhd_SHA256_has_err (&ctx)) + { + data[0] = 'a'; + mhd_SHA256_update (&ctx, + 1, + data); + data[0] = 'b'; + mhd_SHA256_update (&ctx, + 1, + data); + mhd_SHA256_update (&ctx, + 0, /* Empty data - valid for unit-tests only */ + data); + data[0] = 'c'; + mhd_SHA256_update (&ctx, + 1, + data); + mhd_SHA256_finish (&ctx, + digest); + if (!mhd_SHA256_has_err (&ctx)) + { + if (check_digest (digest, + mhd_SHA256_DIGEST_SIZE, + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", + test_name)) + passed++; + } + else + { + fprintf (stderr, + "FAIL: %s - backend error: %d.\n", + test_name, + mhd_SHA256_get_err (&ctx)); + mhd_SHA256_deinit (&ctx); + exit (99); + } + } + else + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_SHA256_get_err (&ctx)); + mhd_SHA256_deinit (&ctx); + exit (99); + } + mhd_SHA256_deinit (&ctx); + + /* + * Tests finish_reset and reuse of context + */ + total++; + test_name = "Reset and reuse context"; + mhd_SHA256_init (&ctx); + if (!mhd_SHA256_has_err (&ctx)) + { + /* First hash */ + data_len = hex2bin ("616263", + data, + sizeof(data)); /* "abc" */ + mhd_SHA256_update (&ctx, + data_len, + data); + mhd_SHA256_finish_reset (&ctx, digest); + + if (mhd_SHA256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend error after first hash: %d.\n", + test_name, + mhd_SHA256_get_err (&ctx)); + mhd_SHA256_deinit (&ctx); + exit (99); + } + if (check_digest (digest, + mhd_SHA256_DIGEST_SIZE, + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", + "Reset and reuse context: first hash")) + passed++; + + /* Second hash on same context */ + total++; + data_len = hex2bin ("61", + data, + sizeof(data)); /* "a" */ + mhd_SHA256_update (&ctx, + data_len, + data); + mhd_SHA256_finish (&ctx, + digest); + + if (!mhd_SHA256_has_err (&ctx)) + { + if (check_digest (digest, + mhd_SHA256_DIGEST_SIZE, + "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + "Reset and reuse context: second hash")) + passed++; + } + else + { + fprintf (stderr, + "FAIL: %s - backend error after second hash: %d.\n", + test_name, + mhd_SHA256_get_err (&ctx)); + mhd_SHA256_deinit (&ctx); exit (99); } + } + else + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_SHA256_get_err (&ctx)); + mhd_SHA256_deinit (&ctx); + exit (99); + } + mhd_SHA256_deinit (&ctx); + + /* + * Test finish_deinit functionality + */ + total++; + test_name = "Finish and deinitialise context"; + mhd_SHA256_init (&ctx); + if (mhd_SHA256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_SHA256_get_err (&ctx)); mhd_SHA256_deinit (&ctx); + exit (99); } + data_len = hex2bin ("616263", + data, + sizeof(data)); /* "abc" */ + mhd_SHA256_update (&ctx, + data_len, + data); + mhd_SHA256_finish_deinit (&ctx, + digest); + if (mhd_SHA256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend error: %d.\n", + test_name, + mhd_SHA256_get_err (&ctx)); + exit (99); + } + if (check_digest (digest, + mhd_SHA256_DIGEST_SIZE, + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", + test_name)) + passed++; + + /* + * Test hashing of a long multi-block stream of data + */ + total++; + test_name = "One million repetitions of 'a'"; + mhd_SHA256_init (&ctx); + if (mhd_SHA256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_SHA256_get_err (&ctx)); + mhd_SHA256_deinit (&ctx); + exit (99); + } + memset (data, 'a', 1000); + for (i = 0; i < 1000; ++i) + mhd_SHA256_update (&ctx, + 1000, + data); + mhd_SHA256_finish (&ctx, + digest); + if (mhd_SHA256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend error: %d.\n", + test_name, + mhd_SHA256_get_err (&ctx)); + mhd_SHA256_deinit (&ctx); + exit (99); + } + if (check_digest (digest, + mhd_SHA256_DIGEST_SIZE, + "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", + test_name)) + passed++; + mhd_SHA256_deinit (&ctx); num_failed = total - passed; diff --git a/src/tests/unit/unit_sha512_256.c b/src/tests/unit/unit_sha512_256.c @@ -539,23 +539,31 @@ test1_str (void) unsigned int i; struct mhd_Sha512_256Ctx ctx; + mhd_SHA512_256_init (&ctx); for (i = 0; i < units1_num; i++) { uint8_t digest[mhd_SHA512_256_DIGEST_SIZE]; - mhd_SHA512_256_init (&ctx); if (0 != data_units1[i].str_l.len) mhd_SHA512_256_update (&ctx, data_units1[i].str_l.len, (const uint8_t *)data_units1[i].str_l.str); - mhd_SHA512_256_finish (&ctx, - digest); + mhd_SHA512_256_finish_reset (&ctx, + digest); + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "External hashing error: %d.\n", + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } num_failed += check_result (MHD_FUNC_, i, digest, data_units1[i].digest); - mhd_SHA512_256_deinit (&ctx); } + mhd_SHA512_256_deinit (&ctx); return num_failed; } @@ -567,22 +575,30 @@ test1_bin (void) unsigned int i; struct mhd_Sha512_256Ctx ctx; + mhd_SHA512_256_init (&ctx); for (i = 0; i < units2_num; i++) { uint8_t digest[mhd_SHA512_256_DIGEST_SIZE]; - mhd_SHA512_256_init (&ctx); mhd_SHA512_256_update (&ctx, data_units2[i].bin_l.len, data_units2[i].bin_l.bin); - mhd_SHA512_256_finish (&ctx, - digest); + mhd_SHA512_256_finish_reset (&ctx, + digest); + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "External hashing error: %d.\n", + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } num_failed += check_result (MHD_FUNC_, i, digest, data_units2[i].digest); - mhd_SHA512_256_deinit (&ctx); } + mhd_SHA512_256_deinit (&ctx); return num_failed; } @@ -595,12 +611,12 @@ test2_str (void) unsigned int i; struct mhd_Sha512_256Ctx ctx; + mhd_SHA512_256_init (&ctx); for (i = 0; i < units1_num; i++) { uint8_t digest[mhd_SHA512_256_DIGEST_SIZE]; size_t part_s = data_units1[i].str_l.len / 4; - mhd_SHA512_256_init (&ctx); if (0 != part_s) mhd_SHA512_256_update (&ctx, part_s, @@ -610,14 +626,22 @@ test2_str (void) data_units1[i].str_l.len - part_s, (const uint8_t *)data_units1[i].str_l.str + part_s ); - mhd_SHA512_256_finish (&ctx, - digest); + mhd_SHA512_256_finish_reset (&ctx, + digest); + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "External hashing error: %d.\n", + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } num_failed += check_result (MHD_FUNC_, i, digest, data_units1[i].digest); - mhd_SHA512_256_deinit (&ctx); } + mhd_SHA512_256_deinit (&ctx); return num_failed; } @@ -629,26 +653,34 @@ test2_bin (void) unsigned int i; struct mhd_Sha512_256Ctx ctx; + mhd_SHA512_256_init (&ctx); for (i = 0; i < units2_num; i++) { uint8_t digest[mhd_SHA512_256_DIGEST_SIZE]; size_t part_s = data_units2[i].bin_l.len * 2 / 3; - mhd_SHA512_256_init (&ctx); mhd_SHA512_256_update (&ctx, part_s, data_units2[i].bin_l.bin); mhd_SHA512_256_update (&ctx, data_units2[i].bin_l.len - part_s, data_units2[i].bin_l.bin + part_s); - mhd_SHA512_256_finish (&ctx, - digest); + mhd_SHA512_256_finish_reset (&ctx, + digest); + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "External hashing error: %d.\n", + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } num_failed += check_result (MHD_FUNC_, i, digest, data_units2[i].digest); - mhd_SHA512_256_deinit (&ctx); } + mhd_SHA512_256_deinit (&ctx); return num_failed; } @@ -678,6 +710,7 @@ test_unaligned (void) exit (99); } + mhd_SHA512_256_init (&ctx); for (offset = MAX_OFFSET; offset >= 1; --offset) { uint8_t *unaligned_digest; @@ -691,18 +724,27 @@ test_unaligned (void) memset (unaligned_digest, 0, mhd_SHA512_256_DIGEST_SIZE); - mhd_SHA512_256_init (&ctx); mhd_SHA512_256_update (&ctx, tdata->bin_l.len, unaligned_buf); - mhd_SHA512_256_finish (&ctx, - unaligned_digest); + mhd_SHA512_256_finish_reset (&ctx, + unaligned_digest); + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "External hashing error: %d.\n", + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + free (digest_buf); + free (buf); + exit (99); + } num_failed += check_result (MHD_FUNC_, MAX_OFFSET - offset, unaligned_digest, tdata->digest); - mhd_SHA512_256_deinit (&ctx); } + mhd_SHA512_256_deinit (&ctx); free (digest_buf); free (buf); return num_failed; @@ -754,6 +796,8 @@ main (int argc, uint8_t digest[mhd_SHA512_256_DIGEST_SIZE]; uint8_t data[1024]; size_t data_len; + const char *test_name; + unsigned int i; unsigned int passed = 0; unsigned int total = 0; unsigned int num_failed; @@ -789,20 +833,228 @@ main (int argc, } else { - printf ("FAIL: %s - digest function failed due to backend error\n", - t->name); + fprintf (stderr, + "FAIL: %s - digest function failed due to backend error: " \ + "%d.\n", + t->name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); exit (99); } } else { - printf ("FAIL: %s - error in init\n", - t->name); + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + t->name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); exit (99); } mhd_SHA512_256_deinit (&ctx); } + /* + * Test update functionality + */ + total++; + test_name = "Multi-update: a + b + c"; + mhd_SHA512_256_init (&ctx); + if (!mhd_SHA512_256_has_err (&ctx)) + { + data[0] = 'a'; + mhd_SHA512_256_update (&ctx, + 1, + data); + data[0] = 'b'; + mhd_SHA512_256_update (&ctx, + 1, + data); + mhd_SHA512_256_update (&ctx, + 0, /* Empty data - valid for unit-tests only */ + data); + data[0] = 'c'; + mhd_SHA512_256_update (&ctx, + 1, + data); + mhd_SHA512_256_finish (&ctx, + digest); + if (!mhd_SHA512_256_has_err (&ctx)) + { + if (check_digest (digest, + mhd_SHA512_256_DIGEST_SIZE, + "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23", + test_name)) + passed++; + } + else + { + fprintf (stderr, + "FAIL: %s - backend error: %d.\n", + test_name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } + } + else + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } + mhd_SHA512_256_deinit (&ctx); + + /* + * Tests finish_reset and reuse of context + */ + total++; + test_name = "Reset and reuse context"; + mhd_SHA512_256_init (&ctx); + if (!mhd_SHA512_256_has_err (&ctx)) + { + /* First hash */ + data_len = hex2bin ("616263", + data, + sizeof(data)); /* "abc" */ + mhd_SHA512_256_update (&ctx, + data_len, + data); + mhd_SHA512_256_finish_reset (&ctx, digest); + + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend error after first hash: %d.\n", + test_name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } + if (check_digest (digest, + mhd_SHA512_256_DIGEST_SIZE, + "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23", + "Reset and reuse context: first hash")) + passed++; + + /* Second hash on same context */ + total++; + data_len = hex2bin ("61", + data, + sizeof(data)); /* "a" */ + mhd_SHA512_256_update (&ctx, + data_len, + data); + mhd_SHA512_256_finish (&ctx, + digest); + + if (!mhd_SHA512_256_has_err (&ctx)) + { + if (check_digest (digest, + mhd_SHA512_256_DIGEST_SIZE, + "455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8", + "Reset and reuse context: second hash")) + passed++; + } + else + { + fprintf (stderr, + "FAIL: %s - backend error after second hash: %d.\n", + test_name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } + } + else + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } + mhd_SHA512_256_deinit (&ctx); + + /* + * Test finish_deinit functionality + */ + total++; + test_name = "Finish and deinitialise context"; + mhd_SHA512_256_init (&ctx); + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } + data_len = hex2bin ("616263", + data, + sizeof(data)); /* "abc" */ + mhd_SHA512_256_update (&ctx, + data_len, + data); + mhd_SHA512_256_finish_deinit (&ctx, + digest); + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend error: %d.\n", + test_name, + mhd_SHA512_256_get_err (&ctx)); + exit (99); + } + if (check_digest (digest, + mhd_SHA512_256_DIGEST_SIZE, + "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23", + test_name)) + passed++; + + /* + * Test hashing of a long multi-block stream of data + */ + total++; + test_name = "One million repetitions of 'a'"; + mhd_SHA512_256_init (&ctx); + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend initialisation error: %d.\n", + test_name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } + memset (data, 'a', 1000); + for (i = 0; i < 1000; ++i) + mhd_SHA512_256_update (&ctx, + 1000, + data); + mhd_SHA512_256_finish (&ctx, + digest); + if (mhd_SHA512_256_has_err (&ctx)) + { + fprintf (stderr, + "FAIL: %s - backend error: %d.\n", + test_name, + mhd_SHA512_256_get_err (&ctx)); + mhd_SHA512_256_deinit (&ctx); + exit (99); + } + if (check_digest (digest, + mhd_SHA512_256_DIGEST_SIZE, + "9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21", + test_name)) + passed++; + mhd_SHA512_256_deinit (&ctx); + num_failed = total - passed; num_failed += test1_str ();