libmicrohttpd2

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

unit_sha512_256.c (43833B)


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