libmicrohttpd2

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

unit_sha256.c (26325B)


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