libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

test_md5.c (18540B)


      1 /*
      2   This file is part of libmicrohttpd
      3   Copyright (C) 2019-2023 Evgeny Grin (Karlson2k)
      4 
      5   This test tool is free software; you can redistribute it and/or
      6   modify it under the terms of the GNU General Public License as
      7   published by the Free Software Foundation; either version 2, or
      8   (at your option) any later version.
      9 
     10   This test tool is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   Lesser General Public License for more details.
     14 
     15   You should have received a copy of the GNU Lesser General Public
     16   License along with this library; if not, write to the Free Software
     17   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     18 */
     19 
     20 /**
     21  * @file microhttpd/test_md5.h
     22  * @brief  Unit tests for md5 functions
     23  * @author Karlson2k (Evgeny Grin)
     24  */
     25 
     26 #include "mhd_options.h"
     27 #include "mhd_md5_wrap.h"
     28 #include "test_helpers.h"
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 
     32 #if defined(MHD_MD5_TLSLIB) && defined(MHD_HTTPS_REQUIRE_GCRYPT)
     33 #define NEED_GCRYP_INIT 1
     34 #include <gcrypt.h>
     35 #endif /* MHD_MD5_TLSLIB && MHD_HTTPS_REQUIRE_GCRYPT */
     36 
     37 static int verbose = 0; /* verbose level (0-1)*/
     38 
     39 
     40 struct str_with_len
     41 {
     42   const char *const str;
     43   const size_t len;
     44 };
     45 
     46 #define D_STR_W_LEN(s) {(s), (sizeof((s)) / sizeof(char)) - 1}
     47 
     48 struct data_unit1
     49 {
     50   const struct str_with_len str_l;
     51   const uint8_t digest[MD5_DIGEST_SIZE];
     52 };
     53 
     54 static const struct data_unit1 data_units1[] = {
     55   {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."),
     56    {0x1c, 0x68, 0xc2, 0xe5, 0x1f, 0x63, 0xc9, 0x5f, 0x17, 0xab, 0x1f, 0x20,
     57     0x8b, 0x86, 0x39, 0x57}},
     58   {D_STR_W_LEN ("Simple string."),
     59    {0xf1, 0x2b, 0x7c, 0xad, 0xa0, 0x41, 0xfe, 0xde, 0x4e, 0x68, 0x16, 0x63,
     60     0xb4, 0x60, 0x5d, 0x78}},
     61   {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"),
     62    {0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c,
     63     0xca, 0x67, 0xe1, 0x3b}},
     64   {D_STR_W_LEN ("zyxwvutsrqponMLKJIHGFEDCBA"),
     65    {0x05, 0x61, 0x3a, 0x6b, 0xde, 0x75, 0x3a, 0x45, 0x91, 0xa8, 0x81, 0xb0,
     66     0xa7, 0xe2, 0xe2, 0x0e}},
     67   {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA" \
     68                 "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"),
     69    {0xaf, 0xab, 0xc7, 0xe9, 0xe7, 0x17, 0xbe, 0xd6, 0xc0, 0x0f, 0x78, 0x8c,
     70     0xde, 0xdd, 0x11, 0xd1}},
     71   {D_STR_W_LEN ("/long/long/long/long/long/long/long/long/long/long/long" \
     72                 "/long/long/long/long/long/long/long/long/long/long/long" \
     73                 "/long/long/long/long/long/long/long/long/long/long/long" \
     74                 "/long/long/long/long/long/long/long/long/long/long/long" \
     75                 "/long/long/long/long/long/long/long/long/long/long/long" \
     76                 "/long/long/long/long/long/long/long/long/long/long/long" \
     77                 "/long/long/long/long/path?with%20some=parameters"),
     78    {0x7e, 0xe6, 0xdb, 0xe2, 0x76, 0x49, 0x1a, 0xd8, 0xaf, 0xf3, 0x52, 0x2d,
     79     0xd8, 0xfc, 0x89, 0x1e}},
     80   {D_STR_W_LEN (""),
     81    {0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98,
     82     0xec, 0xf8, 0x42, 0x7e}},
     83   {D_STR_W_LEN ("a"),
     84    {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2,
     85     0x69, 0x77, 0x26, 0x61}},
     86   {D_STR_W_LEN ("abc"),
     87    {0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
     88     0x28, 0xe1, 0x7f, 0x72}},
     89   {D_STR_W_LEN ("message digest"),
     90    {0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, 0x52, 0x5a, 0x2f, 0x31,
     91     0xaa, 0xf1, 0x61, 0xd0}},
     92   {D_STR_W_LEN ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" \
     93                 "0123456789"),
     94    {0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, 0xa5, 0x61, 0x1c, 0x2c,
     95     0x9f, 0x41, 0x9d, 0x9f}},
     96   {D_STR_W_LEN ("12345678901234567890123456789012345678901234567890" \
     97                 "123456789012345678901234567890"),
     98    {0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, 0xac, 0x49, 0xda, 0x2e,
     99     0x21, 0x07, 0xb6, 0x7a}}
    100 };
    101 
    102 static const size_t units1_num = sizeof(data_units1) / sizeof(data_units1[0]);
    103 
    104 struct bin_with_len
    105 {
    106   const uint8_t bin[512];
    107   const size_t len;
    108 };
    109 
    110 struct data_unit2
    111 {
    112   const struct bin_with_len bin_l;
    113   const uint8_t digest[MD5_DIGEST_SIZE];
    114 };
    115 
    116 static const struct data_unit2 data_units2[] = {
    117   { { {97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
    118        112, 113, 114, 115, 116,
    119        117, 118, 119, 120, 121, 122}, 26}, /* a..z ASCII sequence */
    120     {0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c,
    121      0xca, 0x67, 0xe1, 0x3b}},
    122   { { {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
    123        65, 65, 65, 65, 65, 65,
    124        65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
    125        65, 65, 65, 65, 65, 65,
    126        65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
    127        65, 65, 65, 65, 65, 65}, 72 },/* 'A' x 72 times */
    128     {0x24, 0xa5, 0xef, 0x36, 0x82, 0x80, 0x3a, 0x06, 0x2f, 0xea, 0xad, 0xad,
    129      0x76, 0xda, 0xbd, 0xa8}},
    130   { { {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
    131        37, 38, 39, 40, 41, 42,
    132        43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
    133        61, 62, 63, 64, 65, 66, 67,
    134        68, 69, 70, 71, 72, 73}, 55}, /* 19..73 sequence */
    135     {0x6d, 0x2e, 0x6e, 0xde, 0x5d, 0x64, 0x6a, 0x17, 0xf1, 0x09, 0x2c, 0xac,
    136      0x19, 0x10, 0xe3, 0xd6}},
    137   { { {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
    138        26, 27, 28, 29, 30, 31,
    139        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
    140        50, 51, 52, 53, 54, 55, 56,
    141        57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69}, 63}, /* 7..69 sequence */
    142     {0x88, 0x13, 0x48, 0x47, 0x73, 0xaa, 0x92, 0xf2, 0xc9, 0xdd, 0x69, 0xb3,
    143      0xac, 0xf4, 0xba, 0x6e}},
    144   { { {38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
    145        56, 57, 58, 59, 60, 61,
    146        62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    147        80, 81, 82, 83, 84, 85, 86,
    148        87, 88, 89, 90, 91, 92}, 55}, /* 38..92 sequence */
    149     {0x80, 0xf0, 0x05, 0x7e, 0xa2, 0xf7, 0xc8, 0x43, 0x12, 0xd3, 0xb1, 0x61,
    150      0xab, 0x52, 0x3b, 0xaf}},
    151   { { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    152        21, 22, 23, 24, 25, 26, 27,
    153        28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
    154        46, 47, 48, 49, 50, 51, 52,
    155        53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    156        71, 72},
    157       72},/* 1..72 sequence */
    158     {0xc3, 0x28, 0xc5, 0xad, 0xc9, 0x26, 0xa9, 0x99, 0x95, 0x4a, 0x5e, 0x25,
    159      0x50, 0x34, 0x51, 0x73}},
    160   { { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    161        21, 22, 23, 24, 25, 26,
    162        27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
    163        45, 46, 47, 48, 49, 50, 51,
    164        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
    165        70, 71, 72, 73, 74, 75, 76,
    166        77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
    167        95, 96, 97, 98, 99, 100,
    168        101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
    169        115, 116, 117, 118, 119, 120,
    170        121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
    171        135, 136, 137, 138, 139, 140,
    172        141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
    173        155, 156, 157, 158, 159, 160,
    174        161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
    175        175, 176, 177, 178, 179, 180,
    176        181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
    177        195, 196, 197, 198, 199, 200,
    178        201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
    179        215, 216, 217, 218, 219, 220,
    180        221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,
    181        235, 236, 237, 238, 239, 240,
    182        241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
    183        255}, 256},                                                                        /* 0..255 sequence */
    184     {0xe2, 0xc8, 0x65, 0xdb, 0x41, 0x62, 0xbe, 0xd9, 0x63, 0xbf, 0xaa, 0x9e,
    185      0xf6, 0xac, 0x18, 0xf0}},
    186   { { {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
    187        185, 184, 183, 182, 181, 180,
    188        179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166,
    189        165, 164, 163, 162, 161, 160,
    190        159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146,
    191        145, 144, 143, 142, 141, 140,
    192        139}, 61},  /* 199..139 sequence */
    193     {0xbb, 0x3f, 0xdb, 0x4a, 0x96, 0x03, 0x36, 0x37, 0x38, 0x78, 0x5e, 0x44,
    194      0xbf, 0x3a, 0x85, 0x51}},
    195   { { {255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242,
    196        241, 240, 239, 238, 237, 236,
    197        235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222,
    198        221, 220, 219, 218, 217, 216,
    199        215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202,
    200        201, 200, 199, 198, 197, 196,
    201        195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182,
    202        181, 180, 179, 178, 177, 176,
    203        175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162,
    204        161, 160, 159, 158, 157, 156,
    205        155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142,
    206        141, 140, 139, 138, 137, 136,
    207        135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122,
    208        121, 120, 119, 118, 117, 116,
    209        115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102,
    210        101, 100, 99, 98, 97, 96, 95,
    211        94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77,
    212        76, 75, 74, 73, 72, 71, 70,
    213        69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52,
    214        51, 50, 49, 48, 47, 46, 45,
    215        44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27,
    216        26, 25, 24, 23, 22, 21, 20,
    217        19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 255},  /* 255..1 sequence */
    218     {0x52, 0x21, 0xa5, 0x83, 0x4f, 0x38, 0x7c, 0x73, 0xba, 0x18, 0x22, 0xb1,
    219      0xf9, 0x7e, 0xae, 0x8b}},
    220   { { {41, 35, 190, 132, 225, 108, 214, 174, 82, 144, 73, 241, 241, 187, 233,
    221        235, 179, 166, 219, 60, 135,
    222        12, 62, 153, 36, 94, 13, 28, 6, 183, 71, 222, 179, 18, 77, 200, 67, 187,
    223        139, 166, 31, 3, 90, 125, 9,
    224        56, 37, 31, 93, 212, 203, 252, 150, 245, 69, 59, 19, 13, 137, 10, 28,
    225        219, 174, 50, 32, 154, 80, 238,
    226        64, 120, 54, 253, 18, 73, 50, 246, 158, 125, 73, 220, 173, 79, 20, 242,
    227        68, 64, 102, 208, 107, 196,
    228        48, 183, 50, 59, 161, 34, 246, 34, 145, 157, 225, 139, 31, 218, 176, 202,
    229        153, 2, 185, 114, 157, 73,
    230        44, 128, 126, 197, 153, 213, 233, 128, 178, 234, 201, 204, 83, 191, 103,
    231        214, 191, 20, 214, 126, 45,
    232        220, 142, 102, 131, 239, 87, 73, 97, 255, 105, 143, 97, 205, 209, 30,
    233        157, 156, 22, 114, 114, 230,
    234        29, 240, 132, 79, 74, 119, 2, 215, 232, 57, 44, 83, 203, 201, 18, 30, 51,
    235        116, 158, 12, 244, 213,
    236        212, 159, 212, 164, 89, 126, 53, 207, 50, 34, 244, 204, 207, 211, 144,
    237        45, 72, 211, 143, 117, 230,
    238        217, 29, 42, 229, 192, 247, 43, 120, 129, 135, 68, 14, 95, 80, 0, 212,
    239        97, 141, 190, 123, 5, 21, 7,
    240        59, 51, 130, 31, 24, 112, 146, 218, 100, 84, 206, 177, 133, 62, 105, 21,
    241        248, 70, 106, 4, 150, 115,
    242        14, 217, 22, 47, 103, 104, 212, 247, 74, 74, 208, 87, 104}, 255},  /* pseudo-random data */
    243     {0x55, 0x61, 0x2c, 0xeb, 0x29, 0xee, 0xa8, 0xb2, 0xf6, 0x10, 0x7b, 0xc1,
    244      0x5b, 0x0f, 0x01, 0x95}}
    245 };
    246 
    247 static const size_t units2_num = sizeof(data_units2) / sizeof(data_units2[0]);
    248 
    249 
    250 /*
    251  *  Helper functions
    252  */
    253 
    254 /**
    255  * Print bin as hex
    256  *
    257  * @param bin binary data
    258  * @param len number of bytes in bin
    259  * @param hex pointer to len*2+1 bytes buffer
    260  */
    261 static void
    262 bin2hex (const uint8_t *bin,
    263          size_t len,
    264          char *hex)
    265 {
    266   while (len-- > 0)
    267   {
    268     unsigned int b1, b2;
    269     b1 = (*bin >> 4) & 0xf;
    270     *hex++ = (char) ((b1 > 9) ? (b1 + 'A' - 10) : (b1 + '0'));
    271     b2 = *bin++ & 0xf;
    272     *hex++ = (char) ((b2 > 9) ? (b2 + 'A' - 10) : (b2 + '0'));
    273   }
    274   *hex = 0;
    275 }
    276 
    277 
    278 static int
    279 check_result (const char *test_name,
    280               unsigned int check_num,
    281               const uint8_t calculated[MD5_DIGEST_SIZE],
    282               const uint8_t expected[MD5_DIGEST_SIZE])
    283 {
    284   int failed = memcmp (calculated, expected, MD5_DIGEST_SIZE);
    285   check_num++; /* Print 1-based numbers */
    286   if (failed)
    287   {
    288     char calc_str[MD5_DIGEST_STRING_SIZE];
    289     char expc_str[MD5_DIGEST_STRING_SIZE];
    290     bin2hex (calculated, MD5_DIGEST_SIZE, calc_str);
    291     bin2hex (expected, MD5_DIGEST_SIZE, expc_str);
    292     fprintf (stderr,
    293              "FAILED: %s check %u: calculated digest %s, expected digest %s.\n",
    294              test_name, check_num, calc_str, expc_str);
    295     fflush (stderr);
    296   }
    297   else if (verbose)
    298   {
    299     char calc_str[MD5_DIGEST_STRING_SIZE];
    300     bin2hex (calculated, MD5_DIGEST_SIZE, calc_str);
    301     printf ("PASSED: %s check %u: calculated digest %s "
    302             "matches expected digest.\n",
    303             test_name, check_num, calc_str);
    304     fflush (stdout);
    305   }
    306   return failed ? 1 : 0;
    307 }
    308 
    309 
    310 /*
    311  *  Tests
    312  */
    313 
    314 /* Calculated MD5 as one pass for whole data */
    315 static int
    316 test1_str (void)
    317 {
    318   unsigned int i;
    319   int num_failed = 0;
    320   struct Md5CtxWr ctx;
    321 
    322   MHD_MD5_init_one_time (&ctx);
    323 
    324   for (i = 0; i < units1_num; i++)
    325   {
    326     uint8_t digest[MD5_DIGEST_SIZE];
    327 
    328     MHD_MD5_update (&ctx, (const uint8_t *) data_units1[i].str_l.str,
    329                     data_units1[i].str_l.len);
    330     MHD_MD5_finish_reset (&ctx, digest);
    331 #ifdef MHD_MD5_HAS_EXT_ERROR
    332     if (0 != ctx.ext_error)
    333     {
    334       fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
    335       exit (99);
    336     }
    337 #endif
    338     num_failed += check_result (MHD_FUNC_, i, digest,
    339                                 data_units1[i].digest);
    340   }
    341   MHD_MD5_deinit (&ctx);
    342   return num_failed;
    343 }
    344 
    345 
    346 static int
    347 test1_bin (void)
    348 {
    349   unsigned int i;
    350   int num_failed = 0;
    351   struct Md5CtxWr ctx;
    352 
    353   MHD_MD5_init_one_time (&ctx);
    354 
    355   for (i = 0; i < units2_num; i++)
    356   {
    357     uint8_t digest[MD5_DIGEST_SIZE];
    358 
    359     MHD_MD5_update (&ctx, data_units2[i].bin_l.bin, data_units2[i].bin_l.len);
    360     MHD_MD5_finish_reset (&ctx, digest);
    361 #ifdef MHD_MD5_HAS_EXT_ERROR
    362     if (0 != ctx.ext_error)
    363     {
    364       fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
    365       exit (99);
    366     }
    367 #endif
    368     num_failed += check_result (MHD_FUNC_, i, digest,
    369                                 data_units2[i].digest);
    370   }
    371   MHD_MD5_deinit (&ctx);
    372   return num_failed;
    373 }
    374 
    375 
    376 /* Calculated MD5 as two iterations for whole data */
    377 static int
    378 test2_str (void)
    379 {
    380   unsigned int i;
    381   int num_failed = 0;
    382   struct Md5CtxWr ctx;
    383 
    384   MHD_MD5_init_one_time (&ctx);
    385 
    386   for (i = 0; i < units1_num; i++)
    387   {
    388     uint8_t digest[MD5_DIGEST_SIZE];
    389     size_t part_s = data_units1[i].str_l.len / 4;
    390 
    391     MHD_MD5_update (&ctx, (const uint8_t *) "", 0);
    392     MHD_MD5_update (&ctx, (const uint8_t *) data_units1[i].str_l.str, part_s);
    393     MHD_MD5_update (&ctx, (const uint8_t *) "", 0);
    394     MHD_MD5_update (&ctx, (const uint8_t *) data_units1[i].str_l.str + part_s,
    395                     data_units1[i].str_l.len - part_s);
    396     MHD_MD5_update (&ctx, (const uint8_t *) "", 0);
    397     MHD_MD5_finish_reset (&ctx, digest);
    398 #ifdef MHD_MD5_HAS_EXT_ERROR
    399     if (0 != ctx.ext_error)
    400     {
    401       fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
    402       exit (99);
    403     }
    404 #endif
    405     num_failed += check_result (MHD_FUNC_, i, digest,
    406                                 data_units1[i].digest);
    407   }
    408   MHD_MD5_deinit (&ctx);
    409   return num_failed;
    410 }
    411 
    412 
    413 static int
    414 test2_bin (void)
    415 {
    416   unsigned int i;
    417   int num_failed = 0;
    418   struct Md5CtxWr ctx;
    419 
    420   MHD_MD5_init_one_time (&ctx);
    421 
    422   for (i = 0; i < units2_num; i++)
    423   {
    424     uint8_t digest[MD5_DIGEST_SIZE];
    425     size_t part_s = data_units2[i].bin_l.len * 2 / 3;
    426 
    427     MHD_MD5_update (&ctx, data_units2[i].bin_l.bin, part_s);
    428     MHD_MD5_update (&ctx, (const uint8_t *) "", 0);
    429     MHD_MD5_update (&ctx, data_units2[i].bin_l.bin + part_s,
    430                     data_units2[i].bin_l.len - part_s);
    431     MHD_MD5_finish_reset (&ctx, digest);
    432 #ifdef MHD_MD5_HAS_EXT_ERROR
    433     if (0 != ctx.ext_error)
    434     {
    435       fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
    436       exit (99);
    437     }
    438 #endif
    439     num_failed += check_result (MHD_FUNC_, i, digest,
    440                                 data_units2[i].digest);
    441   }
    442   MHD_MD5_deinit (&ctx);
    443   return num_failed;
    444 }
    445 
    446 
    447 /* Use data set number 7 as it has the longest sequence */
    448 #define DATA_POS 6
    449 #define MAX_OFFSET 31
    450 
    451 static int
    452 test_unaligned (void)
    453 {
    454   int num_failed = 0;
    455   unsigned int offset;
    456   uint8_t *buf;
    457   uint8_t *digest_buf;
    458   struct Md5CtxWr ctx;
    459 
    460   const struct data_unit2 *const tdata = data_units2 + DATA_POS;
    461 
    462   buf = malloc (tdata->bin_l.len + MAX_OFFSET);
    463   digest_buf = malloc (MD5_DIGEST_SIZE + MAX_OFFSET);
    464   if ((NULL == buf) || (NULL == digest_buf))
    465     exit (99);
    466 
    467   MHD_MD5_init_one_time (&ctx);
    468 
    469   for (offset = MAX_OFFSET; offset >= 1; --offset)
    470   {
    471     uint8_t *unaligned_digest;
    472     uint8_t *unaligned_buf;
    473 
    474     unaligned_buf = buf + offset;
    475     memcpy (unaligned_buf, tdata->bin_l.bin, tdata->bin_l.len);
    476     unaligned_digest = digest_buf + MAX_OFFSET - offset;
    477     memset (unaligned_digest, 0, MD5_DIGEST_SIZE);
    478 
    479     MHD_MD5_update (&ctx, unaligned_buf, tdata->bin_l.len);
    480     MHD_MD5_finish_reset (&ctx, unaligned_digest);
    481 #ifdef MHD_MD5_HAS_EXT_ERROR
    482     if (0 != ctx.ext_error)
    483     {
    484       fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
    485       exit (99);
    486     }
    487 #endif
    488     num_failed += check_result (MHD_FUNC_, MAX_OFFSET - offset,
    489                                 unaligned_digest, tdata->digest);
    490   }
    491   MHD_MD5_deinit (&ctx);
    492   free (digest_buf);
    493   free (buf);
    494   return num_failed;
    495 }
    496 
    497 
    498 int
    499 main (int argc, char *argv[])
    500 {
    501   int num_failed = 0;
    502   (void) has_in_name; /* Mute compiler warning. */
    503   if (has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose"))
    504     verbose = 1;
    505 
    506 #ifdef NEED_GCRYP_INIT
    507   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
    508 #ifdef GCRYCTL_INITIALIZATION_FINISHED
    509   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
    510 #endif /* GCRYCTL_INITIALIZATION_FINISHED */
    511 #endif /* NEED_GCRYP_INIT */
    512 
    513   num_failed += test1_str ();
    514   num_failed += test1_bin ();
    515 
    516   num_failed += test2_str ();
    517   num_failed += test2_bin ();
    518 
    519   num_failed += test_unaligned ();
    520 
    521   return num_failed ? 1 : 0;
    522 }