libmicrohttpd2

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

unit_sha256.c (27123B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 
      3 /*
      4   This file is part of GNU libmicrohttpd.
      5   Copyright (C) 2025 Christian Grothoff
      6 
      7   GNU libmicrohttpd is free software; you can redistribute it and/or
      8   modify it under the terms of the GNU Lesser General Public
      9   License as published by the Free Software Foundation; either
     10   version 2.1 of the License, or (at your option) any later version.
     11 
     12   GNU libmicrohttpd is distributed in the hope that it will be useful,
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15   Lesser General Public License for more details.
     16 
     17   Alternatively, you can redistribute GNU libmicrohttpd and/or
     18   modify it under the terms of the GNU General Public License as
     19   published by the Free Software Foundation; either version 2 of
     20   the License, or (at your option) any later version, together
     21   with the eCos exception, as follows:
     22 
     23     As a special exception, if other files instantiate templates or
     24     use macros or inline functions from this file, or you compile this
     25     file and link it with other works to produce a work based on this
     26     file, this file does not by itself cause the resulting work to be
     27     covered by the GNU General Public License. However the source code
     28     for this file must still be made available in accordance with
     29     section (3) of the GNU General Public License v2.
     30 
     31     This exception does not invalidate any other reasons why a work
     32     based on this file might be covered by the GNU General Public
     33     License.
     34 
     35   You should have received copies of the GNU Lesser General Public
     36   License and the GNU General Public License along with this library;
     37   if not, see <https://www.gnu.org/licenses/>.
     38 */
     39 
     40 /**
     41  * @file src/test/unit/unit_sha256.c
     42  * @brief  The tests for SHA-256
     43  * @author Karlson2k (Evgeny Grin)
     44  * @author Christian Grothoff
     45  */
     46 #include <stdio.h>
     47 #include <stdlib.h>
     48 #include <string.h>
     49 #include <stdint.h>
     50 
     51 #include "mhd_sys_options.h"
     52 
     53 #if MHD_SHA256_EXTR_OPENSSL
     54 #include "../mhd2/sha256_ext_openssl.c"
     55 #elif MHD_SHA256_EXTR_GNUTLS
     56 #include "../mhd2/sha256_ext_gnutls.c"
     57 #elif MHD_SHA256_EXTR_MBEDTLS
     58 #include "../mhd2/sha256_ext_mbedtls.c"
     59 #else
     60 #include "../mhd2/sha256_int.c"
     61 #endif
     62 
     63 #include "../mhd2/mhd_sha256.h"
     64 
     65 #define SHA256_DIGEST_STRING_SIZE (mhd_SHA256_DIGEST_SIZE * 2 + 1)
     66 
     67 /**
     68  * Verbose output?
     69  */
     70 static int verbose;
     71 
     72 
     73 /**
     74  * Check whether one of strings in array is equal to @a param.
     75  * String @a argv[0] is ignored.
     76  * @param argc number of strings in @a argv, as passed to main function
     77  * @param argv array of strings, as passed to main function
     78  * @param param parameter to look for.
     79  * @return zero if @a argv is NULL, @a param is NULL or empty string,
     80  *         @a argc is less then 2 or @a param is not found in @a argv,
     81  *         non-zero if one of strings in @a argv is equal to @a param.
     82  */
     83 static int
     84 has_param (int argc, char *const argv[], const char *param)
     85 {
     86   int i;
     87   if (! argv || ! param || ! param[0])
     88     return 0;
     89 
     90   for (i = 1; i < argc; i++)
     91   {
     92     if (argv[i] && (strcmp (argv[i], param) == 0) )
     93       return ! 0;
     94   }
     95 
     96   return 0;
     97 }
     98 
     99 
    100 /* Helper function to convert hex string to binary */
    101 static size_t
    102 hex2bin (const char *hex,
    103          uint8_t *bin,
    104          size_t max_len)
    105 {
    106   size_t len = strlen (hex) / 2;
    107   if (len > max_len)
    108     len = max_len;
    109 
    110   for (size_t i = 0; i < len; i++)
    111   {
    112     sscanf (hex + 2 * i, "%2hhx", &bin[i]);
    113   }
    114   return len;
    115 }
    116 
    117 
    118 /* Helper function to compare digest with expected hex string */
    119 static int
    120 check_digest (const uint8_t *digest,
    121               size_t digest_len,
    122               const char *expected_hex,
    123               const char *test_name)
    124 {
    125   uint8_t expected[64];
    126   size_t expected_len = hex2bin (expected_hex, expected, sizeof(expected));
    127 
    128   if (expected_len != digest_len)
    129   {
    130     printf ("FAIL: %s - length mismatch\n", test_name);
    131     return 0;
    132   }
    133 
    134   if (memcmp (digest, expected, digest_len) != 0)
    135   {
    136     printf ("FAIL: %s\n", test_name);
    137     printf ("  Expected: %s\n", expected_hex);
    138     printf ("  Got:      ");
    139     for (size_t i = 0; i < digest_len; i++)
    140     {
    141       printf ("%02x", digest[i]);
    142     }
    143     printf ("\n");
    144     return 0;
    145   }
    146   if (verbose)
    147     printf ("PASS: %s\n",
    148             test_name);
    149   return 1;
    150 }
    151 
    152 
    153 struct str_with_len
    154 {
    155   const char *const str;
    156   const size_t len;
    157 };
    158 
    159 #define D_STR_W_LEN(s) {(s), (sizeof((s)) / sizeof(char)) - 1}
    160 
    161 struct data_unit1
    162 {
    163   const struct str_with_len str_l;
    164   const uint8_t digest[mhd_SHA256_DIGEST_SIZE];
    165 };
    166 
    167 static const struct data_unit1 data_units1[] = {
    168   {D_STR_W_LEN ("abc"),
    169    {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
    170     0x5d, 0xae, 0x22, 0x23,
    171     0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
    172     0xf2, 0x00, 0x15, 0xad}},
    173   {D_STR_W_LEN ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
    174    {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93,
    175     0x0c, 0x3e, 0x60, 0x39,
    176     0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4,
    177     0x19, 0xdb, 0x06, 0xc1}},
    178   {D_STR_W_LEN (""),
    179    {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
    180     0x99, 0x6f, 0xb9, 0x24,
    181     0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
    182     0x78, 0x52, 0xb8, 0x55}},
    183   {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."),
    184    {0x2f, 0xad, 0x7a, 0xff, 0x7d, 0xfe, 0xcd, 0x78, 0xe4, 0xa6, 0xf3, 0x85,
    185     0x97, 0x9d, 0xdc, 0x39,
    186     0x55, 0x24, 0x35, 0x4a, 0x00, 0x6f, 0x42, 0x72, 0x41, 0xc1, 0x52, 0xa7,
    187     0x01, 0x0b, 0x2c, 0x41}},
    188   {D_STR_W_LEN ("Simple string."),
    189    {0x01, 0x73, 0x17, 0xc4, 0x0a, 0x9a, 0x0e, 0x81, 0xb3, 0xa4, 0xb1, 0x8e,
    190     0xe9, 0xd6, 0xc2, 0xdf,
    191     0xfa, 0x7d, 0x53, 0x4e, 0xa1, 0xda, 0xb2, 0x5a, 0x75, 0xbb, 0x2c, 0x30,
    192     0x2f, 0x5f, 0x7a, 0xf4}},
    193   {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"),
    194    {0x71, 0xc4, 0x80, 0xdf, 0x93, 0xd6, 0xae, 0x2f, 0x1e, 0xfa, 0xd1, 0x44,
    195     0x7c, 0x66, 0xc9, 0x52,
    196     0x5e, 0x31, 0x62, 0x18, 0xcf, 0x51, 0xfc, 0x8d, 0x9e, 0xd8, 0x32, 0xf2,
    197     0xda, 0xf1, 0x8b, 0x73}},
    198   {D_STR_W_LEN ("zyxwvutsrqponMLKJIHGFEDCBA"),
    199    {0xce, 0x7d, 0xde, 0xb6, 0x1f, 0x7c, 0x1d, 0x83, 0x7c, 0x60, 0xd8, 0x36,
    200     0x73, 0x82, 0xac, 0x92,
    201     0xca, 0x37, 0xfd, 0x72, 0x8b, 0x0c, 0xd1, 0x6c, 0x55, 0xd5, 0x88, 0x98,
    202     0x24, 0xfa, 0x16, 0xf2}},
    203   {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA" \
    204                 "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"),
    205    {0x27, 0xd1, 0xe8, 0xbc, 0x6a, 0x79, 0x16, 0x83, 0x61, 0x73, 0xa9, 0xa8,
    206     0x9b, 0xaf, 0xaf, 0xcf,
    207     0x47, 0x4d, 0x09, 0xef, 0x6d, 0x50, 0x35, 0x12, 0x25, 0x72, 0xd8, 0x68,
    208     0xdc, 0x1f, 0xd2, 0xf4}},
    209   {D_STR_W_LEN ("/long/long/long/long/long/long/long/long/long/long/long" \
    210                 "/long/long/long/long/long/long/long/long/long/long/long" \
    211                 "/long/long/long/long/long/long/long/long/long/long/long" \
    212                 "/long/long/long/long/long/long/long/long/long/long/long" \
    213                 "/long/long/long/long/long/long/long/long/long/long/long" \
    214                 "/long/long/long/long/long/long/long/long/long/long/long" \
    215                 "/long/long/long/long/path?with%20some=parameters"),
    216    {0x73, 0x85, 0xc5, 0xb9, 0x8f, 0xaf, 0x7d, 0x5e, 0xad, 0xd8, 0x0b, 0x8e,
    217     0x12, 0xdb, 0x28, 0x60, 0xc7, 0xc7, 0x55, 0x05, 0x2f, 0x7c, 0x6f, 0xfa,
    218     0xd1, 0xe3, 0xe1, 0x7b, 0x04, 0xd4, 0xb0, 0x21}}
    219 };
    220 
    221 static const size_t units1_num = sizeof(data_units1) / sizeof(data_units1[0]);
    222 
    223 struct bin_with_len
    224 {
    225   const uint8_t bin[512];
    226   const size_t len;
    227 };
    228 
    229 struct data_unit2
    230 {
    231   const struct bin_with_len bin_l;
    232   const uint8_t digest[mhd_SHA256_DIGEST_SIZE];
    233 };
    234 
    235 /* Size must be less than 512 bytes! */
    236 static const struct data_unit2 data_units2[] = {
    237   { { {97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
    238        112, 113, 114, 115, 116,
    239        117, 118, 119, 120, 121, 122}, 26}, /* a..z ASCII sequence */
    240     {0x71, 0xc4, 0x80, 0xdf, 0x93, 0xd6, 0xae, 0x2f, 0x1e, 0xfa, 0xd1, 0x44,
    241      0x7c, 0x66, 0xc9, 0x52,
    242      0x5e, 0x31, 0x62, 0x18, 0xcf, 0x51, 0xfc, 0x8d, 0x9e, 0xd8, 0x32, 0xf2,
    243      0xda, 0xf1, 0x8b, 0x73}},
    244   { { {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
    245        65, 65, 65, 65, 65, 65,
    246        65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
    247        65, 65, 65, 65, 65, 65,
    248        65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
    249        65, 65, 65, 65, 65, 65}, 72 },/* 'A' x 72 times */
    250     {0x6a, 0x6d, 0x69, 0x1a, 0xc9, 0xba, 0x70, 0x95, 0x50, 0x46, 0x75, 0x7c,
    251      0xd6, 0x85, 0xb6, 0x25,
    252      0x77, 0x73, 0xff, 0x3a, 0xd9, 0x3f, 0x43, 0xd4, 0xd4, 0x81, 0x2c, 0x5b,
    253      0x10, 0x6f, 0x4b, 0x5b}},
    254   { { {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
    255        37, 38, 39, 40, 41, 42,
    256        43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
    257        61, 62, 63, 64, 65, 66, 67,
    258        68, 69, 70, 71, 72, 73}, 55}, /* 19..73 sequence */
    259     {0x06, 0xe4, 0xb3, 0x9e, 0xf1, 0xfb, 0x6c, 0xcf, 0xd7, 0x3f, 0x50, 0x9e,
    260      0xf4, 0x16, 0x17, 0xd4,
    261      0x63, 0x7c, 0x39, 0x1e, 0xa8, 0x0f, 0xa9, 0x88, 0x03, 0x44, 0x98, 0x0e,
    262      0x95, 0x81, 0xf0, 0x2a}},
    263   { { {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
    264        26, 27, 28, 29, 30, 31,
    265        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
    266        50, 51, 52, 53, 54, 55, 56,
    267        57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69}, 63}, /* 7..69 sequence */
    268     {0x4a, 0xd3, 0xc6, 0x87, 0x1f, 0xd1, 0xc5, 0xe2, 0x3e, 0x52, 0xdc, 0x22,
    269      0xd1, 0x10, 0xd2, 0x05,
    270      0x15, 0x23, 0xcd, 0x15, 0xac, 0x24, 0x88, 0x26, 0x02, 0x00, 0x70, 0x78,
    271      0x9f, 0x17, 0xf8, 0xd9}},
    272   { { {38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
    273        56, 57, 58, 59, 60, 61,
    274        62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    275        80, 81, 82, 83, 84, 85, 86,
    276        87, 88, 89, 90, 91, 92}, 55}, /* 38..92 sequence */
    277     {0xe6, 0x03, 0x0f, 0xc9, 0x0d, 0xca, 0x0c, 0x26, 0x41, 0xcf, 0x43, 0x27,
    278      0xec, 0xd6, 0x28, 0x2a,
    279      0x98, 0x24, 0x55, 0xd3, 0x5a, 0xed, 0x8b, 0x32, 0x19, 0x78, 0xeb, 0x83,
    280      0x1d, 0x19, 0x92, 0x79}},
    281   { { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    282        21, 22, 23, 24, 25, 26, 27,
    283        28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
    284        46, 47, 48, 49, 50, 51, 52,
    285        53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    286        71, 72},
    287       72},/* 1..72 sequence */
    288     {0x87, 0xa2, 0xfa, 0x2e, 0xec, 0x53, 0x05, 0x3c, 0xb1, 0xee, 0x07, 0xd7,
    289      0x59, 0x70, 0xf6, 0x50,
    290      0xcd, 0x9d, 0xc5, 0x8b, 0xdc, 0xb8, 0x65, 0x30, 0x4f, 0x70, 0x82, 0x9e,
    291      0xbd, 0xe2, 0x7d, 0xac}},
    292   { { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    293        21, 22, 23, 24, 25, 26,
    294        27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
    295        45, 46, 47, 48, 49, 50, 51,
    296        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
    297        70, 71, 72, 73, 74, 75, 76,
    298        77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
    299        95, 96, 97, 98, 99, 100,
    300        101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
    301        115, 116, 117, 118, 119, 120,
    302        121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
    303        135, 136, 137, 138, 139, 140,
    304        141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
    305        155, 156, 157, 158, 159, 160,
    306        161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
    307        175, 176, 177, 178, 179, 180,
    308        181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
    309        195, 196, 197, 198, 199, 200,
    310        201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
    311        215, 216, 217, 218, 219, 220,
    312        221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,
    313        235, 236, 237, 238, 239, 240,
    314        241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
    315        255}, 256},                                                                        /* 0..255 sequence */
    316     {0x40, 0xaf, 0xf2, 0xe9, 0xd2, 0xd8, 0x92, 0x2e, 0x47, 0xaf, 0xd4, 0x64,
    317      0x8e, 0x69, 0x67, 0x49,
    318      0x71, 0x58, 0x78, 0x5f, 0xbd, 0x1d, 0xa8, 0x70, 0xe7, 0x11, 0x02, 0x66,
    319      0xbf, 0x94, 0x48, 0x80}},
    320   { { {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
    321        185, 184, 183, 182, 181, 180,
    322        179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166,
    323        165, 164, 163, 162, 161, 160,
    324        159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146,
    325        145, 144, 143, 142, 141, 140,
    326        139}, 61},  /* 199..139 sequence */
    327     {0x85, 0xf8, 0xa2, 0x83, 0xd6, 0x3c, 0x76, 0x8e, 0xea, 0x8f, 0x1c, 0x57,
    328      0x2d, 0x85, 0xb6, 0xff,
    329      0xd8, 0x33, 0x57, 0x62, 0x1d, 0x37, 0xae, 0x0e, 0xfc, 0x22, 0xd3, 0xd5,
    330      0x8f, 0x53, 0x21, 0xb7}},
    331   { { {255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242,
    332        241, 240, 239, 238, 237, 236,
    333        235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222,
    334        221, 220, 219, 218, 217, 216,
    335        215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202,
    336        201, 200, 199, 198, 197, 196,
    337        195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182,
    338        181, 180, 179, 178, 177, 176,
    339        175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162,
    340        161, 160, 159, 158, 157, 156,
    341        155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142,
    342        141, 140, 139, 138, 137, 136,
    343        135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122,
    344        121, 120, 119, 118, 117, 116,
    345        115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102,
    346        101, 100, 99, 98, 97, 96, 95,
    347        94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77,
    348        76, 75, 74, 73, 72, 71, 70,
    349        69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52,
    350        51, 50, 49, 48, 47, 46, 45,
    351        44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27,
    352        26, 25, 24, 23, 22, 21, 20,
    353        19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 255},  /* 255..1 sequence */
    354     {0x61, 0x86, 0x96, 0xab, 0x3e, 0xaa, 0x0e, 0x64, 0xb2, 0xf7, 0x2d, 0x75,
    355      0x47, 0x5a, 0x14, 0x97,
    356      0xa3, 0x3d, 0x59, 0xa4, 0x08, 0xd9, 0x9e, 0x73, 0xf2, 0x78, 0x00, 0x5b,
    357      0x4b, 0x55, 0xca, 0x43}},
    358   { { {41, 35, 190, 132, 225, 108, 214, 174, 82, 144, 73, 241, 241, 187, 233,
    359        235, 179, 166, 219, 60, 135,
    360        12, 62, 153, 36, 94, 13, 28, 6, 183, 71, 222, 179, 18, 77, 200, 67, 187,
    361        139, 166, 31, 3, 90, 125, 9,
    362        56, 37, 31, 93, 212, 203, 252, 150, 245, 69, 59, 19, 13, 137, 10, 28,
    363        219, 174, 50, 32, 154, 80, 238,
    364        64, 120, 54, 253, 18, 73, 50, 246, 158, 125, 73, 220, 173, 79, 20, 242,
    365        68, 64, 102, 208, 107, 196,
    366        48, 183, 50, 59, 161, 34, 246, 34, 145, 157, 225, 139, 31, 218, 176, 202,
    367        153, 2, 185, 114, 157, 73,
    368        44, 128, 126, 197, 153, 213, 233, 128, 178, 234, 201, 204, 83, 191, 103,
    369        214, 191, 20, 214, 126, 45,
    370        220, 142, 102, 131, 239, 87, 73, 97, 255, 105, 143, 97, 205, 209, 30,
    371        157, 156, 22, 114, 114, 230,
    372        29, 240, 132, 79, 74, 119, 2, 215, 232, 57, 44, 83, 203, 201, 18, 30, 51,
    373        116, 158, 12, 244, 213,
    374        212, 159, 212, 164, 89, 126, 53, 207, 50, 34, 244, 204, 207, 211, 144,
    375        45, 72, 211, 143, 117, 230,
    376        217, 29, 42, 229, 192, 247, 43, 120, 129, 135, 68, 14, 95, 80, 0, 212,
    377        97, 141, 190, 123, 5, 21, 7,
    378        59, 51, 130, 31, 24, 112, 146, 218, 100, 84, 206, 177, 133, 62, 105, 21,
    379        248, 70, 106, 4, 150, 115,
    380        14, 217, 22, 47, 103, 104, 212, 247, 74, 74, 208, 87, 104}, 255},  /* pseudo-random data */
    381     {0x08, 0x7f, 0x86, 0xac, 0xe2, 0x2e, 0x28, 0x56, 0x74, 0x53, 0x4f, 0xc0,
    382      0xfb, 0xb8, 0x79, 0x57,
    383      0xc5, 0xc8, 0xd1, 0xb7, 0x47, 0xb7, 0xd9, 0xea, 0x97, 0xa8, 0x67, 0xe9,
    384      0x26, 0x93, 0xee, 0xa3}}
    385 };
    386 
    387 static const size_t units2_num = sizeof(data_units2) / sizeof(data_units2[0]);
    388 
    389 
    390 /*
    391  *  Helper functions
    392  */
    393 
    394 /**
    395  * Print bin as hex
    396  *
    397  * @param bin binary data
    398  * @param len number of bytes in bin
    399  * @param hex pointer to len*2+1 bytes buffer
    400  */
    401 static void
    402 bin2hex (const uint8_t *bin,
    403          size_t len,
    404          char *hex)
    405 {
    406   while (len-- > 0)
    407   {
    408     unsigned int b1, b2;
    409     b1 = (*bin >> 4) & 0xf;
    410     *hex++ = (char) ((b1 > 9) ? (b1 + 'A' - 10) : (b1 + '0'));
    411     b2 = *bin++ & 0xf;
    412     *hex++ = (char) ((b2 > 9) ? (b2 + 'A' - 10) : (b2 + '0'));
    413   }
    414   *hex = 0;
    415 }
    416 
    417 
    418 static int
    419 check_result (const char *test_name,
    420               unsigned int check_num,
    421               const uint8_t calculated[mhd_SHA256_DIGEST_SIZE],
    422               const uint8_t expected[mhd_SHA256_DIGEST_SIZE])
    423 {
    424   int failed = memcmp (calculated, expected, mhd_SHA256_DIGEST_SIZE);
    425   check_num++; /* Print 1-based numbers */
    426   if (failed)
    427   {
    428     char calc_str[SHA256_DIGEST_STRING_SIZE];
    429     char expc_str[SHA256_DIGEST_STRING_SIZE];
    430     bin2hex (calculated, mhd_SHA256_DIGEST_SIZE, calc_str);
    431     bin2hex (expected, mhd_SHA256_DIGEST_SIZE, expc_str);
    432     fprintf (stderr,
    433              "FAILED: %s check %u: calculated digest %s, expected digest %s.\n",
    434              test_name, check_num, calc_str, expc_str);
    435     fflush (stderr);
    436   }
    437   else if (verbose)
    438   {
    439     char calc_str[SHA256_DIGEST_STRING_SIZE];
    440     bin2hex (calculated, mhd_SHA256_DIGEST_SIZE, calc_str);
    441     printf ("PASSED: %s check %u: calculated digest %s "
    442             "matches expected digest.\n",
    443             test_name, check_num, calc_str);
    444     fflush (stdout);
    445   }
    446   return failed ? 1 : 0;
    447 }
    448 
    449 
    450 /*
    451  *  Tests
    452  */
    453 
    454 /* Calculated SHA-256 as one pass for whole data */
    455 static int
    456 test1_str (void)
    457 {
    458   int num_failed = 0;
    459   unsigned int i;
    460   struct mhd_Sha256Ctx ctx;
    461 
    462   mhd_SHA256_init_one_time (&ctx);
    463   for (i = 0; i < units1_num; i++)
    464   {
    465     uint8_t digest[mhd_SHA256_DIGEST_SIZE];
    466 
    467     mhd_SHA256_update (&ctx,
    468                        data_units1[i].str_l.len,
    469                        (const uint8_t *) data_units1[i].str_l.str);
    470     mhd_SHA256_finish_reset (&ctx,
    471                              digest);
    472 #ifdef MHD_SHA256_HAS_EXT_ERROR
    473     if (0 != ctx.ext_error)
    474     {
    475       fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
    476       exit (99);
    477     }
    478 #endif /* MHD_SHA256_HAS_EXT_ERROR */
    479     num_failed += check_result (MHD_FUNC_, i, digest,
    480                                 data_units1[i].digest);
    481   }
    482   mhd_SHA256_deinit (&ctx);
    483   return num_failed;
    484 }
    485 
    486 
    487 static int
    488 test1_bin (void)
    489 {
    490   int num_failed = 0;
    491   unsigned int i;
    492   struct mhd_Sha256Ctx ctx;
    493 
    494   mhd_SHA256_init_one_time (&ctx);
    495   for (i = 0; i < units2_num; i++)
    496   {
    497     uint8_t digest[mhd_SHA256_DIGEST_SIZE];
    498 
    499     mhd_SHA256_update (&ctx,
    500                        data_units2[i].bin_l.len,
    501                        data_units2[i].bin_l.bin);
    502     mhd_SHA256_finish_reset (&ctx, digest);
    503 #ifdef MHD_SHA256_HAS_EXT_ERROR
    504     if (0 != ctx.ext_error)
    505     {
    506       fprintf (stderr,
    507                "External hashing error: %d.\n",
    508                ctx.ext_error);
    509       exit (99);
    510     }
    511 #endif /* MHD_SHA256_HAS_EXT_ERROR */
    512     num_failed += check_result (MHD_FUNC_, i, digest,
    513                                 data_units2[i].digest);
    514   }
    515   mhd_SHA256_deinit (&ctx);
    516   return num_failed;
    517 }
    518 
    519 
    520 /* Calculated SHA-256 as two iterations for whole data */
    521 static int
    522 test2_str (void)
    523 {
    524   int num_failed = 0;
    525   unsigned int i;
    526   struct mhd_Sha256Ctx ctx;
    527 
    528   mhd_SHA256_init_one_time (&ctx);
    529   for (i = 0; i < units1_num; i++)
    530   {
    531     uint8_t digest[mhd_SHA256_DIGEST_SIZE];
    532     size_t part_s = data_units1[i].str_l.len / 4;
    533 
    534     mhd_SHA256_update (&ctx,
    535                        0,
    536                        (const uint8_t *) "");
    537     mhd_SHA256_update (&ctx,
    538                        part_s,
    539                        (const uint8_t *) data_units1[i].str_l.str);
    540     mhd_SHA256_update (&ctx,
    541                        0,
    542                        (const uint8_t *) "");
    543     mhd_SHA256_update (&ctx,
    544                        data_units1[i].str_l.len - part_s,
    545                        (const uint8_t *) data_units1[i].str_l.str + part_s);
    546     mhd_SHA256_update (&ctx,
    547                        0,
    548                        (const uint8_t *) "");
    549     mhd_SHA256_finish_reset (&ctx, digest);
    550 #ifdef MHD_SHA256_HAS_EXT_ERROR
    551     if (0 != ctx.ext_error)
    552     {
    553       fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
    554       exit (99);
    555     }
    556 #endif /* MHD_SHA256_HAS_EXT_ERROR */
    557     num_failed += check_result (MHD_FUNC_, i, digest,
    558                                 data_units1[i].digest);
    559   }
    560   mhd_SHA256_deinit (&ctx);
    561   return num_failed;
    562 }
    563 
    564 
    565 static int
    566 test2_bin (void)
    567 {
    568   int num_failed = 0;
    569   unsigned int i;
    570   struct mhd_Sha256Ctx ctx;
    571 
    572   mhd_SHA256_init_one_time (&ctx);
    573   for (i = 0; i < units2_num; i++)
    574   {
    575     uint8_t digest[mhd_SHA256_DIGEST_SIZE];
    576     size_t part_s = data_units2[i].bin_l.len * 2 / 3;
    577 
    578     mhd_SHA256_update (&ctx,
    579                        part_s,
    580                        data_units2[i].bin_l.bin);
    581     mhd_SHA256_update (&ctx,
    582                        0,
    583                        (const uint8_t *) "");
    584     mhd_SHA256_update (&ctx,
    585                        data_units2[i].bin_l.len - part_s,
    586                        data_units2[i].bin_l.bin + part_s);
    587     mhd_SHA256_finish_reset (&ctx,
    588                              digest);
    589 #ifdef MHD_SHA256_HAS_EXT_ERROR
    590     if (0 != ctx.ext_error)
    591     {
    592       fprintf (stderr,
    593                "External hashing error: %d.\n",
    594                ctx.ext_error);
    595       exit (99);
    596     }
    597 #endif /* MHD_SHA256_HAS_EXT_ERROR */
    598     num_failed += check_result (MHD_FUNC_, i, digest,
    599                                 data_units2[i].digest);
    600   }
    601   mhd_SHA256_deinit (&ctx);
    602   return num_failed;
    603 }
    604 
    605 
    606 /* Use data set number 7 as it has the longest sequence */
    607 #define DATA_POS 6
    608 #define MAX_OFFSET 31
    609 
    610 static int
    611 test_unaligned (void)
    612 {
    613   int num_failed = 0;
    614   unsigned int offset;
    615   uint8_t *buf;
    616   uint8_t *digest_buf;
    617   struct mhd_Sha256Ctx ctx;
    618 
    619   const struct data_unit2 *const tdata = data_units2 + DATA_POS;
    620 
    621   mhd_SHA256_init_one_time (&ctx);
    622   buf = malloc (tdata->bin_l.len + MAX_OFFSET);
    623   digest_buf = malloc (mhd_SHA256_DIGEST_SIZE + MAX_OFFSET);
    624   if ((NULL == buf) || (NULL == digest_buf))
    625     exit (99);
    626 
    627   for (offset = MAX_OFFSET; offset >= 1; --offset)
    628   {
    629     uint8_t *unaligned_digest;
    630     uint8_t *unaligned_buf;
    631 
    632     unaligned_buf = buf + offset;
    633     memcpy (unaligned_buf, tdata->bin_l.bin, tdata->bin_l.len);
    634     unaligned_digest = digest_buf + MAX_OFFSET - offset;
    635     memset (unaligned_digest, 0, mhd_SHA256_DIGEST_SIZE);
    636 
    637     mhd_SHA256_update (&ctx,
    638                        tdata->bin_l.len,
    639                        unaligned_buf);
    640     mhd_SHA256_finish_reset (&ctx,
    641                              unaligned_digest);
    642 #ifdef MHD_SHA256_HAS_EXT_ERROR
    643     if (0 != ctx.ext_error)
    644     {
    645       fprintf (stderr,
    646                "External hashing error: %d.\n",
    647                ctx.ext_error);
    648       exit (99);
    649     }
    650 #endif /* MHD_SHA256_HAS_EXT_ERROR */
    651     num_failed += check_result (MHD_FUNC_, MAX_OFFSET - offset,
    652                                 unaligned_digest, tdata->digest);
    653   }
    654   free (digest_buf);
    655   free (buf);
    656   mhd_SHA256_deinit (&ctx);
    657   return num_failed;
    658 }
    659 
    660 
    661 int
    662 main (int argc,
    663       char **argv)
    664 {
    665   struct Test
    666   {
    667     const char *name;
    668     const char *input;
    669     const char *digest;
    670   } tests[] = {
    671     {
    672       "Empty string (https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/shs/shabytetestvectors.zip)",
    673       "",
    674       "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    675     },
    676     {
    677       "d3 (https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/shs/shabytetestvectors.zip)",
    678       "d3",
    679       "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1"
    680     },
    681     {
    682       "11af (https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/shs/shabytetestvectors.zip)",
    683       "11af",
    684       "5ca7133fa735326081558ac312c620eeca9970d1e70a4b95533d956f072d1f98"
    685     },
    686     {
    687       "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq (https://di-mgt.com.au/sha_testvectors.html)",
    688       "6162636462636465636465666465666765666768666768696768696a68696a6b696a6b6c6a6b6c6d6b6c6d6e6c6d6e6f6d6e6f706e6f7071",
    689       "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
    690     },
    691     {
    692       "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu (https://di-mgt.com.au/sha_testvectors.html)",
    693       "61626364656667686263646566676869636465666768696a6465666768696a6b65666768696a6b6c666768696a6b6c6d6768696a6b6c6d6e68696a6b6c6d6e6f696a6b6c6d6e6f706a6b6c6d6e6f70716b6c6d6e6f7071726c6d6e6f707172736d6e6f70717273746e6f707172737475",
    694       "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1"
    695     },
    696     { "message digest",
    697       "6d65737361676520646967657374",
    698       "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650" },
    699     { "One byte 0x00",
    700       "00",
    701       "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d" },
    702     { "Two bytes 0x00 0x00",
    703       "0000",
    704       "96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7" },
    705     { NULL, NULL, NULL }
    706   };
    707   struct mhd_Sha256Ctx ctx;
    708   uint8_t digest[mhd_SHA256_DIGEST_SIZE];
    709   uint8_t data[1024];
    710   size_t data_len;
    711   int passed = 0;
    712   int total = 0;
    713   int num_failed;
    714 
    715   if (has_param (argc, argv, "-v") ||
    716       has_param (argc, argv, "--verbose"))
    717     verbose = 1;
    718 
    719 
    720   while (NULL != tests[total].name)
    721   {
    722     const struct Test *t = &tests[total];
    723 
    724     mhd_SHA256_init_one_time (&ctx);
    725     if (! mhd_SHA256_has_err (&ctx))
    726     {
    727       data_len = hex2bin (t->input,
    728                           data,
    729                           sizeof(data));
    730       if (0 != data_len)
    731         mhd_SHA256_update (&ctx,
    732                            data_len,
    733                            data);
    734       mhd_SHA256_finish_deinit (&ctx,
    735                                 digest);
    736       if (! mhd_SHA256_has_err (&ctx))
    737       {
    738         if (check_digest (digest,
    739                           mhd_SHA256_DIGEST_SIZE,
    740                           t->digest,
    741                           t->name))
    742           passed++;
    743       }
    744       else
    745       {
    746         printf ("FAIL: %s - error in finish\n",
    747                 t->name);
    748       }
    749     }
    750     else
    751     {
    752       printf ("FAIL: %s - error in init\n",
    753               t->name);
    754     }
    755     total++;
    756   }
    757 
    758   num_failed = total - passed;
    759 
    760   num_failed += test1_str ();
    761   num_failed += test1_bin ();
    762 
    763   num_failed += test2_str ();
    764   num_failed += test2_bin ();
    765 
    766   num_failed += test_unaligned ();
    767 
    768 
    769   if ((0 != num_failed) || verbose)
    770     fprintf (stderr,
    771              "Result: %d tests failed\n",
    772              num_failed);
    773 
    774   return (0 == num_failed) ? 0 : 1;
    775 }