libmicrohttpd2

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

unit_sha256.c (32078B)


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