aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-09-09 19:34:20 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-09-11 18:42:17 +0300
commit6cf8c2f33fd1534687044ec52cb18e86865d7f78 (patch)
tree5951d785583b94eafb8b7656d6febada3b9004a2
parent898550e1aeb894d3f285a21f91d652a7db1feb11 (diff)
downloadlibmicrohttpd-6cf8c2f33fd1534687044ec52cb18e86865d7f78.tar.gz
libmicrohttpd-6cf8c2f33fd1534687044ec52cb18e86865d7f78.zip
Implemented SHA-512/256 hashing support
The full implementation, with support hashing of more than 2 EiB (exbibytes), as described by specification. Includes additional code path for more compact code.
-rw-r--r--configure.ac30
-rw-r--r--src/include/microhttpd.h11
-rw-r--r--src/microhttpd/Makefile.am13
-rw-r--r--src/microhttpd/sha512_256.c591
-rw-r--r--src/microhttpd/sha512_256.h138
-rw-r--r--src/microhttpd/test_sha512_256.c588
6 files changed, 1370 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 64631425..b8de0798 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3082,6 +3082,34 @@ AS_VAR_IF([[enable_cookie]],[["yes"]],
3082AM_CONDITIONAL([ENABLE_COOKIE], [[test "x$enable_cookie" = "xyes"]]) 3082AM_CONDITIONAL([ENABLE_COOKIE], [[test "x$enable_cookie" = "xyes"]])
3083AC_MSG_RESULT([[$enable_cookie]]) 3083AC_MSG_RESULT([[$enable_cookie]])
3084 3084
3085# optional: SHA-512/256 support for Digest Auth. Enabled by default.
3086AC_ARG_ENABLE([[sha512-256]],
3087 [AS_HELP_STRING([[--disable-sha512-256]],[disable SHA-512/256 support for Digest Authentication])
3088 ],
3089 [
3090 AS_VAR_IF([[enable_sha512_256]],[["yes"]],
3091 [
3092 AS_VAR_IF([enable_dauth],["yes"],[],
3093 [
3094 AC_MSG_WARN([The parameter --enable-sha512-256 is ignored as Digest Authentication is disabled])
3095 enable_sha512_256='no'
3096 ]
3097 )
3098 ],[[enable_sha512_256='no']]
3099 )
3100 ], [[enable_sha512_256="${enable_dauth}"]]
3101)
3102AC_MSG_CHECKING([[whether to support SHA-512/256]])
3103AS_VAR_IF([[enable_sha512_256]],[["yes"]],
3104 [
3105 AC_DEFINE([[SHA512_256_SUPPORT]],[[1]],
3106 [Define to 1 if libmicrohttpd is compiled with SHA-512/256 support.])
3107 ]
3108)
3109AM_CONDITIONAL([ENABLE_SHA512_256], [[test "x${enable_sha512_256}" = "xyes"]])
3110AC_MSG_RESULT([[${enable_sha512_256}]])
3111
3112
3085AC_CACHE_CHECK([[for calloc()]], [[mhd_cv_have_func_calloc]], 3113AC_CACHE_CHECK([[for calloc()]], [[mhd_cv_have_func_calloc]],
3086 [ 3114 [
3087 AC_LINK_IFELSE([AC_LANG_PROGRAM([[ 3115 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@@ -3962,6 +3990,7 @@ AC_MSG_NOTICE([GNU libmicrohttpd ${PACKAGE_VERSION} Configuration Summary:
3962 Messages: ${enable_messages} 3990 Messages: ${enable_messages}
3963 Basic auth.: ${enable_bauth} 3991 Basic auth.: ${enable_bauth}
3964 Digest auth.: ${enable_dauth} 3992 Digest auth.: ${enable_dauth}
3993 SHA-512/256: ${enable_sha512_256}
3965 HTTP "Upgrade": ${enable_httpupgrade} 3994 HTTP "Upgrade": ${enable_httpupgrade}
3966 Cookie parsing: ${enable_cookie} 3995 Cookie parsing: ${enable_cookie}
3967 Postproc: ${enable_postprocessor} 3996 Postproc: ${enable_postprocessor}
@@ -3982,6 +4011,7 @@ AS_IF([test "x$enable_https" = "xyes"],
3982 4011
3983AS_IF([test "x$enable_bauth" != "xyes" || \ 4012AS_IF([test "x$enable_bauth" != "xyes" || \
3984 test "x$enable_dauth" != "xyes" || \ 4013 test "x$enable_dauth" != "xyes" || \
4014 test "x${enable_sha512_256}" != "xyes" || \
3985 test "x$enable_httpupgrade" != "xyes" || \ 4015 test "x$enable_httpupgrade" != "xyes" || \
3986 test "x$enable_cookie" != "xyes" || \ 4016 test "x$enable_cookie" != "xyes" || \
3987 test "x$enable_postprocessor" != "xyes"], 4017 test "x$enable_postprocessor" != "xyes"],
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 95c2bb4f..31d4c648 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -96,7 +96,7 @@ extern "C"
96 * they are parsed as decimal numbers. 96 * they are parsed as decimal numbers.
97 * Example: 0x01093001 = 1.9.30-1. 97 * Example: 0x01093001 = 1.9.30-1.
98 */ 98 */
99#define MHD_VERSION 0x00097537 99#define MHD_VERSION 0x00097538
100 100
101/* If generic headers don't work on your platform, include headers 101/* If generic headers don't work on your platform, include headers
102 which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t', 102 which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t',
@@ -4429,6 +4429,15 @@ MHD_destroy_post_processor (struct MHD_PostProcessor *pp);
4429#define MHD_SHA256_DIGEST_SIZE 32 4429#define MHD_SHA256_DIGEST_SIZE 32
4430 4430
4431/** 4431/**
4432 * Length of the binary output of the SHA-512/256 hash function.
4433 * The value is the same as the #MHD_SHA256_DIGEST_SIZE.
4434 * @sa #MHD_digest_get_hash_size()
4435 * @note Available since #MHD_VERSION 0x00097538
4436 * @ingroup authentication
4437 */
4438#define MHD_SHA512_256_DIGEST_SIZE 32
4439
4440/**
4432 * Base type of hash calculation. 4441 * Base type of hash calculation.
4433 * Used as part of #MHD_DigestAuthAlgo3 values. 4442 * Used as part of #MHD_DigestAuthAlgo3 values.
4434 * 4443 *
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index fbc545eb..b400d8e6 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -171,6 +171,10 @@ libmicrohttpd_la_SOURCES += \
171 mhd_bithelpers.h mhd_byteorder.h mhd_align.h \ 171 mhd_bithelpers.h mhd_byteorder.h mhd_align.h \
172 md5.c md5.h \ 172 md5.c md5.h \
173 sha256.c sha256.h 173 sha256.c sha256.h
174if ENABLE_SHA512_256
175libmicrohttpd_la_SOURCES += \
176 sha512_256.c sha512_256.h
177endif
174endif 178endif
175 179
176if ENABLE_BAUTH 180if ENABLE_BAUTH
@@ -215,6 +219,11 @@ check_PROGRAMS = \
215 test_options \ 219 test_options \
216 test_set_panic 220 test_set_panic
217 221
222if ENABLE_SHA512_256
223check_PROGRAMS += \
224 test_sha512_256
225endif
226
218if HAVE_POSIX_THREADS 227if HAVE_POSIX_THREADS
219if ENABLE_UPGRADE 228if ENABLE_UPGRADE
220if USE_POSIX_THREADS 229if USE_POSIX_THREADS
@@ -448,6 +457,10 @@ test_sha256_SOURCES = \
448 test_sha256.c test_helpers.h \ 457 test_sha256.c test_helpers.h \
449 sha256.c sha256.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h 458 sha256.c sha256.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
450 459
460test_sha512_256_SOURCES = \
461 test_sha512_256.c test_helpers.h \
462 sha512_256.c sha512_256.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
463
451test_sha1_SOURCES = \ 464test_sha1_SOURCES = \
452 test_sha1.c test_helpers.h \ 465 test_sha1.c test_helpers.h \
453 sha1.c sha1.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h 466 sha1.c sha1.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
diff --git a/src/microhttpd/sha512_256.c b/src/microhttpd/sha512_256.c
new file mode 100644
index 00000000..54389c6b
--- /dev/null
+++ b/src/microhttpd/sha512_256.c
@@ -0,0 +1,591 @@
1/*
2 This file is part of GNU libmicrohttpd
3 Copyright (C) 2022 Karlson2k (Evgeny Grin)
4
5 GNU libmicrohttpd is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library.
17 If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file microhttpd/sha512_256.c
22 * @brief Calculation of SHA-512/256 digest as defined in FIPS PUB 180-4 (2015)
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#include "sha512_256.h"
27
28#include <string.h>
29#ifdef HAVE_MEMORY_H
30#include <memory.h>
31#endif /* HAVE_MEMORY_H */
32#include "mhd_bithelpers.h"
33#include "mhd_assert.h"
34
35/**
36 * Initialise structure for SHA-512/256 calculation.
37 *
38 * @param ctx the calculation context
39 */
40void
41MHD_SHA512_256_init (struct Sha512_256Ctx *ctx)
42{
43 /* Initial hash values, see FIPS PUB 180-4 clause 5.3.6.2 */
44 /* Values generated by "IV Generation Function" as described in
45 * clause 5.3.6 */
46 ctx->H[0] = UINT64_C (0x22312194FC2BF72C);
47 ctx->H[1] = UINT64_C (0x9F555FA3C84C64C2);
48 ctx->H[2] = UINT64_C (0x2393B86B6F53B151);
49 ctx->H[3] = UINT64_C (0x963877195940EABD);
50 ctx->H[4] = UINT64_C (0x96283EE2A88EFFE3);
51 ctx->H[5] = UINT64_C (0xBE5E1E2553863992);
52 ctx->H[6] = UINT64_C (0x2B0199FC2C85B8AA);
53 ctx->H[7] = UINT64_C (0x0EB72DDC81C52CA2);
54
55 /* Initialise number of bytes and high part of number of bits. */
56 ctx->count = 0;
57 ctx->count_bits_hi = 0;
58}
59
60
61/**
62 * Base of SHA-512/256 transformation.
63 * Gets full 64 bytes block of data and updates hash values;
64 * @param H hash values
65 * @param data the data buffer with SHA512_256_BLOCK_SIZE bytes block
66 */
67static void
68sha512_256_transform (uint64_t H[SHA512_256_HASH_SIZE_WORDS],
69 const void *data)
70{
71 /* Working variables,
72 see FIPS PUB 180-4 clause 6.7, 6.4. */
73 uint64_t a = H[0];
74 uint64_t b = H[1];
75 uint64_t c = H[2];
76 uint64_t d = H[3];
77 uint64_t e = H[4];
78 uint64_t f = H[5];
79 uint64_t g = H[6];
80 uint64_t h = H[7];
81
82 /* Data buffer, used as a cyclic buffer.
83 See FIPS PUB 180-4 clause 5.2.2, 6.7, 6.4. */
84 uint64_t W[16];
85
86#ifndef _MHD_GET_64BIT_BE_ALLOW_UNALIGNED
87 if (0 != (((uintptr_t) data) % _MHD_UINT64_ALIGN))
88 { /* The input data is unaligned */
89 /* Copy the unaligned input data to the aligned buffer */
90 memcpy (W, data, sizeof(W));
91 /* The W[] buffer itself will be used as the source of the data,
92 * but the data will be reloaded in correct bytes order on
93 * the next steps */
94 data = (uint8_t *) W;
95 }
96#endif /* _MHD_GET_64BIT_BE_ALLOW_UNALIGNED */
97
98 /* 'Ch' and 'Maj' macro functions are defined with
99 widely-used optimisation.
100 See FIPS PUB 180-4 formulae 4.8, 4.9. */
101#define Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) )
102#define Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
103 /* Unoptimized (original) versions: */
104/* #define Ch(x,y,z) ( ( (x) & (y) ) ^ ( ~(x) & (z) ) ) */
105/* #define Maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */
106
107 /* Four 'Sigma' macro functions.
108 See FIPS PUB 180-4 formulae 4.10, 4.11, 4.12, 4.13. */
109#define SIG0(x) \
110 ( _MHD_ROTR64 ((x), 28) ^ _MHD_ROTR64 ((x), 34) ^ _MHD_ROTR64 ((x), 39) )
111#define SIG1(x) \
112 ( _MHD_ROTR64 ((x), 14) ^ _MHD_ROTR64 ((x), 18) ^ _MHD_ROTR64 ((x), 41) )
113#define sig0(x) \
114 ( _MHD_ROTR64 ((x), 1) ^ _MHD_ROTR64 ((x), 8) ^ ((x) >> 7) )
115#define sig1(x) \
116 ( _MHD_ROTR64 ((x), 19) ^ _MHD_ROTR64 ((x), 61) ^ ((x) >> 6) )
117
118 /* One step of SHA-512/256 computation,
119 see FIPS PUB 180-4 clause 6.4.2 step 3.
120 * Note: this macro updates working variables in-place, without rotation.
121 * Note: instead of reassigning all working variables on each step,
122 variables are rotated for each step:
123 SHA2STEP64(a, b, c, d, e, f, g, h, K[0], data[0]);
124 SHA2STEP64(h, a, b, c, d, e, f, g, K[1], data[1]);
125 so current 'vD' will be used as 'vE' on next step,
126 current 'vH' will be used as 'vA' on next step.
127 * Note: the first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in
128 FIPS PUB 180-4 clause 6.4.2 step 3.
129 the second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in
130 FIPS PUB 180-4 clause 6.4.2 step 3.
131 * Note: 'wt' must be used exactly one time in this macro as it change other
132 data as well every time when used. */
133#define SHA2STEP64(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \
134 (vD) += ((vH) += SIG1 ((vE)) + Ch ((vE),(vF),(vG)) + (kt) + (wt)); \
135 (vH) += SIG0 ((vA)) + Maj ((vA),(vB),(vC)); } while (0)
136
137 /* Get value of W(t) from input data buffer for 0 <= t <= 15,
138 See FIPS PUB 180-4 clause 6.2.
139 Input data must be read in big-endian bytes order,
140 see FIPS PUB 180-4 clause 3.1.2. */
141#define GET_W_FROM_DATA(buf,t) \
142 _MHD_GET_64BIT_BE (((const uint64_t*) (buf)) + (t))
143
144 /* 'W' generation and assignment for 16 <= t <= 79.
145 See FIPS PUB 180-4 clause 6.4.2.
146 As only last 16 'W' are used in calculations, it is possible to
147 use 16 elements array of W as a cyclic buffer.
148 * Note: ((t-16) & 15) have same value as (t & 15) */
149#define Wgen(w,t) ( (w)[(t - 16) & 15] + sig1 ((w)[((t) - 2) & 15]) \
150 + (w)[((t) - 7) & 15] + sig0 ((w)[((t) - 15) & 15]) )
151
152#ifndef MHD_FAVOR_SMALL_CODE
153 /* During first 16 steps, before making any calculations on each step,
154 the W element is read from the input data buffer as big-endian value and
155 stored in the array of W elements. */
156 /* Note: instead of using K constants as array, all K values are specified
157 individually for each step, see FIPS PUB 180-4 clause 4.2.3 for
158 K values. */
159 /* Note: instead of reassigning all working variables on each step,
160 variables are rotated for each step:
161 SHA2STEP64(a, b, c, d, e, f, g, h, K[0], data[0]);
162 SHA2STEP64(h, a, b, c, d, e, f, g, K[1], data[1]);
163 so current 'vD' will be used as 'vE' on next step,
164 current 'vH' will be used as 'vA' on next step. */
165 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x428a2f98d728ae22), \
166 W[0] = GET_W_FROM_DATA (data, 0));
167 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x7137449123ef65cd), \
168 W[1] = GET_W_FROM_DATA (data, 1));
169 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0xb5c0fbcfec4d3b2f), \
170 W[2] = GET_W_FROM_DATA (data, 2));
171 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0xe9b5dba58189dbbc), \
172 W[3] = GET_W_FROM_DATA (data, 3));
173 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x3956c25bf348b538), \
174 W[4] = GET_W_FROM_DATA (data, 4));
175 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x59f111f1b605d019), \
176 W[5] = GET_W_FROM_DATA (data, 5));
177 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x923f82a4af194f9b), \
178 W[6] = GET_W_FROM_DATA (data, 6));
179 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0xab1c5ed5da6d8118), \
180 W[7] = GET_W_FROM_DATA (data, 7));
181 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0xd807aa98a3030242), \
182 W[8] = GET_W_FROM_DATA (data, 8));
183 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x12835b0145706fbe), \
184 W[9] = GET_W_FROM_DATA (data, 9));
185 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x243185be4ee4b28c), \
186 W[10] = GET_W_FROM_DATA (data, 10));
187 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x550c7dc3d5ffb4e2), \
188 W[11] = GET_W_FROM_DATA (data, 11));
189 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x72be5d74f27b896f), \
190 W[12] = GET_W_FROM_DATA (data, 12));
191 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x80deb1fe3b1696b1), \
192 W[13] = GET_W_FROM_DATA (data, 13));
193 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x9bdc06a725c71235), \
194 W[14] = GET_W_FROM_DATA (data, 14));
195 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0xc19bf174cf692694), \
196 W[15] = GET_W_FROM_DATA (data, 15));
197
198 /* During last 64 steps, before making any calculations on each step,
199 current W element is generated from other W elements of the cyclic buffer
200 and the generated value is stored back in the cyclic buffer. */
201 /* Note: instead of using K constants as array, all K values are specified
202 individually for each step, see FIPS PUB 180-4 clause 4.2.3 for
203 K values. */
204 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0xe49b69c19ef14ad2), \
205 W[16 & 15] = Wgen (W,16));
206 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0xefbe4786384f25e3), \
207 W[17 & 15] = Wgen (W,17));
208 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x0fc19dc68b8cd5b5), \
209 W[18 & 15] = Wgen (W,18));
210 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x240ca1cc77ac9c65), \
211 W[19 & 15] = Wgen (W,19));
212 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x2de92c6f592b0275), \
213 W[20 & 15] = Wgen (W,20));
214 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x4a7484aa6ea6e483), \
215 W[21 & 15] = Wgen (W,21));
216 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x5cb0a9dcbd41fbd4), \
217 W[22 & 15] = Wgen (W,22));
218 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x76f988da831153b5), \
219 W[23 & 15] = Wgen (W,23));
220 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x983e5152ee66dfab), \
221 W[24 & 15] = Wgen (W,24));
222 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0xa831c66d2db43210), \
223 W[25 & 15] = Wgen (W,25));
224 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0xb00327c898fb213f), \
225 W[26 & 15] = Wgen (W,26));
226 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0xbf597fc7beef0ee4), \
227 W[27 & 15] = Wgen (W,27));
228 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0xc6e00bf33da88fc2), \
229 W[28 & 15] = Wgen (W,28));
230 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0xd5a79147930aa725), \
231 W[29 & 15] = Wgen (W,29));
232 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x06ca6351e003826f), \
233 W[30 & 15] = Wgen (W,30));
234 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x142929670a0e6e70), \
235 W[31 & 15] = Wgen (W,31));
236 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x27b70a8546d22ffc), \
237 W[32 & 15] = Wgen (W,32));
238 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x2e1b21385c26c926), \
239 W[33 & 15] = Wgen (W,33));
240 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x4d2c6dfc5ac42aed), \
241 W[34 & 15] = Wgen (W,34));
242 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x53380d139d95b3df), \
243 W[35 & 15] = Wgen (W,35));
244 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x650a73548baf63de), \
245 W[36 & 15] = Wgen (W,36));
246 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x766a0abb3c77b2a8), \
247 W[37 & 15] = Wgen (W,37));
248 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x81c2c92e47edaee6), \
249 W[38 & 15] = Wgen (W,38));
250 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x92722c851482353b), \
251 W[39 & 15] = Wgen (W,39));
252 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0xa2bfe8a14cf10364), \
253 W[40 & 15] = Wgen (W,40));
254 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0xa81a664bbc423001), \
255 W[41 & 15] = Wgen (W,41));
256 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0xc24b8b70d0f89791), \
257 W[42 & 15] = Wgen (W,42));
258 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0xc76c51a30654be30), \
259 W[43 & 15] = Wgen (W,43));
260 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0xd192e819d6ef5218), \
261 W[44 & 15] = Wgen (W,44));
262 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0xd69906245565a910), \
263 W[45 & 15] = Wgen (W,45));
264 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0xf40e35855771202a), \
265 W[46 & 15] = Wgen (W,46));
266 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x106aa07032bbd1b8), \
267 W[47 & 15] = Wgen (W,47));
268 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x19a4c116b8d2d0c8), \
269 W[48 & 15] = Wgen (W,48));
270 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x1e376c085141ab53), \
271 W[49 & 15] = Wgen (W,49));
272 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x2748774cdf8eeb99), \
273 W[50 & 15] = Wgen (W,50));
274 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x34b0bcb5e19b48a8), \
275 W[51 & 15] = Wgen (W,51));
276 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x391c0cb3c5c95a63), \
277 W[52 & 15] = Wgen (W,52));
278 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x4ed8aa4ae3418acb), \
279 W[53 & 15] = Wgen (W,53));
280 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x5b9cca4f7763e373), \
281 W[54 & 15] = Wgen (W,54));
282 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x682e6ff3d6b2b8a3), \
283 W[55 & 15] = Wgen (W,55));
284 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x748f82ee5defb2fc), \
285 W[56 & 15] = Wgen (W,56));
286 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x78a5636f43172f60), \
287 W[57 & 15] = Wgen (W,57));
288 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x84c87814a1f0ab72), \
289 W[58 & 15] = Wgen (W,58));
290 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x8cc702081a6439ec), \
291 W[59 & 15] = Wgen (W,59));
292 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x90befffa23631e28), \
293 W[60 & 15] = Wgen (W,60));
294 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0xa4506cebde82bde9), \
295 W[61 & 15] = Wgen (W,61));
296 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0xbef9a3f7b2c67915), \
297 W[62 & 15] = Wgen (W,62));
298 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0xc67178f2e372532b), \
299 W[63 & 15] = Wgen (W,63));
300 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0xca273eceea26619c), \
301 W[64 & 15] = Wgen (W,64));
302 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0xd186b8c721c0c207), \
303 W[65 & 15] = Wgen (W,65));
304 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0xeada7dd6cde0eb1e), \
305 W[66 & 15] = Wgen (W,66));
306 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0xf57d4f7fee6ed178), \
307 W[67 & 15] = Wgen (W,67));
308 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x06f067aa72176fba), \
309 W[68 & 15] = Wgen (W,68));
310 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x0a637dc5a2c898a6), \
311 W[69 & 15] = Wgen (W,69));
312 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x113f9804bef90dae), \
313 W[70 & 15] = Wgen (W,70));
314 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x1b710b35131c471b), \
315 W[71 & 15] = Wgen (W,71));
316 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x28db77f523047d84), \
317 W[72 & 15] = Wgen (W,72));
318 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x32caab7b40c72493), \
319 W[73 & 15] = Wgen (W,73));
320 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x3c9ebe0a15c9bebc), \
321 W[74 & 15] = Wgen (W,74));
322 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x431d67c49c100d4c), \
323 W[75 & 15] = Wgen (W,75));
324 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x4cc5d4becb3e42b6), \
325 W[76 & 15] = Wgen (W,76));
326 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x597f299cfc657e2a), \
327 W[77 & 15] = Wgen (W,77));
328 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x5fcb6fab3ad6faec), \
329 W[78 & 15] = Wgen (W,78));
330 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x6c44198c4a475817), \
331 W[79 & 15] = Wgen (W,79));
332#else /* MHD_FAVOR_SMALL_CODE */
333 if (1)
334 {
335 unsigned int t;
336 /* K constants array.
337 See FIPS PUB 180-4 clause 4.2.3 for K values. */
338 static const uint64_t K[80] =
339 { UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd),
340 UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc),
341 UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019),
342 UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118),
343 UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe),
344 UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2),
345 UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1),
346 UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694),
347 UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3),
348 UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65),
349 UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483),
350 UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5),
351 UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210),
352 UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4),
353 UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725),
354 UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70),
355 UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926),
356 UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df),
357 UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8),
358 UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b),
359 UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001),
360 UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30),
361 UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910),
362 UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8),
363 UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53),
364 UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8),
365 UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb),
366 UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3),
367 UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60),
368 UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec),
369 UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9),
370 UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b),
371 UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207),
372 UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178),
373 UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6),
374 UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b),
375 UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493),
376 UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c),
377 UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a),
378 UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817)};
379
380 /* One step of SHA-512/256 computation with working variables rotation,
381 see FIPS PUB 180-4 clause 6.4.2 step 3.
382 * Note: this version of macro reassign all working variable on
383 each step. */
384#define SHA2STEP64RV(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \
385 uint64_t tmp_h_ = (vH); \
386 SHA2STEP64((vA),(vB),(vC),(vD),(vE),(vF),(vG),tmp_h_,(kt),(wt)); \
387 (vH) = (vG); \
388 (vG) = (vF); \
389 (vF) = (vE); \
390 (vE) = (vD); \
391 (vD) = (vC); \
392 (vC) = (vB); \
393 (vB) = (vA); \
394 (vA) = tmp_h_; } while (0)
395
396 /* During first 16 steps, before making any calculations on each step,
397 the W element is read from the input data buffer as big-endian value and
398 stored in the array of W elements. */
399 for (t = 0; t < 16; ++t)
400 {
401 SHA2STEP64RV (a, b, c, d, e, f, g, h, K[t], \
402 W[t] = GET_W_FROM_DATA (data, t));
403 }
404 /* During last 64 steps, before making any calculations on each step,
405 current W element is generated from other W elements of the cyclic buffer
406 and the generated value is stored back in the cyclic buffer. */
407 for (t = 16; t < 80; ++t)
408 {
409 SHA2STEP64RV (a, b, c, d, e, f, g, h, K[t], \
410 W[t & 15] = Wgen (W,t));
411 }
412 }
413#endif /* MHD_FAVOR_SMALL_CODE */
414
415 /* Compute and store the intermediate hash.
416 See FIPS PUB 180-4 clause 6.4.2 step 4. */
417 H[0] += a;
418 H[1] += b;
419 H[2] += c;
420 H[3] += d;
421 H[4] += e;
422 H[5] += f;
423 H[6] += g;
424 H[7] += h;
425}
426
427
428/**
429 * Process portion of bytes.
430 *
431 * @param ctx the calculation context
432 * @param data bytes to add to hash
433 * @param length number of bytes in @a data
434 */
435void
436MHD_SHA512_256_update (struct Sha512_256Ctx *ctx,
437 const uint8_t *data,
438 size_t length)
439{
440 unsigned int bytes_have; /**< Number of bytes in the context buffer */
441 uint64_t count_hi; /**< The high part to be moved to another variable */
442
443 mhd_assert ((data != NULL) || (length == 0));
444
445 if (0 == length)
446 return; /* Do nothing */
447
448 /* Note: (count & (SHA512_256_BLOCK_SIZE-1))
449 equals (count % SHA512_256_BLOCK_SIZE) for this block size. */
450 bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1));
451 ctx->count += length;
452 count_hi = ctx->count >> 61;
453 if (0 != count_hi)
454 {
455 ctx->count_bits_hi += count_hi;
456 ctx->count &= UINT64_C (0x1FFFFFFFFFFFFFFF);
457 }
458
459 if (0 != bytes_have)
460 {
461 unsigned int bytes_left = SHA512_256_BLOCK_SIZE - bytes_have;
462 if (length >= bytes_left)
463 { /* Combine new data with data in the buffer and
464 process the full block. */
465 memcpy (((uint8_t *) ctx->buffer) + bytes_have,
466 data,
467 bytes_left);
468 data += bytes_left;
469 length -= bytes_left;
470 sha512_256_transform (ctx->H, ctx->buffer);
471 bytes_have = 0;
472 }
473 }
474
475 while (SHA512_256_BLOCK_SIZE <= length)
476 { /* Process any full blocks of new data directly,
477 without copying to the buffer. */
478 sha512_256_transform (ctx->H, data);
479 data += SHA512_256_BLOCK_SIZE;
480 length -= SHA512_256_BLOCK_SIZE;
481 }
482
483 if (0 != length)
484 { /* Copy incomplete block of new data (if any)
485 to the buffer. */
486 memcpy (((uint8_t *) ctx->buffer) + bytes_have, data, length);
487 }
488}
489
490
491/**
492 * Size of "length" insertion in bits.
493 * See FIPS PUB 180-4 clause 5.1.2.
494 */
495#define SHA512_256_SIZE_OF_LEN_ADD_BITS 128
496
497/**
498 * Size of "length" insertion in bytes.
499 */
500#define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8)
501
502/**
503 * Finalise SHA-512/256 calculation, return digest.
504 *
505 * @param ctx the calculation context
506 * @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes
507 */
508void
509MHD_SHA512_256_finish (struct Sha512_256Ctx *ctx,
510 uint8_t digest[SHA512_256_DIGEST_SIZE])
511{
512 uint64_t num_bits; /**< Number of processed bits */
513 unsigned int bytes_have; /**< Number of bytes in the context buffer */
514
515 /* Memorise the number of processed bits.
516 The padding and other data added here during the postprocessing must
517 not change the amount of hashed data. */
518 num_bits = ctx->count << 3;
519
520 /* Note: (count & (SHA512_256_BLOCK_SIZE-1))
521 equals (count % SHA512_256_BLOCK_SIZE) for this block size. */
522 bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1));
523
524 /* Input data must be padded with bit "1" and then the length of data in bits
525 must be added as the final bytes of the last block.
526 See FIPS PUB 180-4 clause 5.1.2. */
527 /* Data is always processed in form of bytes (not by individual bits),
528 therefore position of the first padding bit in byte is always
529 predefined (0x80). */
530 /* Buffer always have space for one byte at least (as full buffers are
531 processed immediately). */
532 ((uint8_t *) ctx->buffer)[bytes_have++] = 0x80;
533
534 if (SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD)
535 { /* No space in the current block to put the total length of message.
536 Pad the current block with zeros and process it. */
537 if (bytes_have < SHA512_256_BLOCK_SIZE)
538 memset (((uint8_t *) ctx->buffer) + bytes_have, 0,
539 SHA512_256_BLOCK_SIZE - bytes_have);
540 /* Process the full block. */
541 sha512_256_transform (ctx->H, ctx->buffer);
542 /* Start the new block. */
543 bytes_have = 0;
544 }
545
546 /* Pad the rest of the buffer with zeros. */
547 memset (((uint8_t *) ctx->buffer) + bytes_have, 0,
548 SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have);
549 /* Put high part of number of bits in processed message and then lower
550 part of number of bits as big-endian values.
551 See FIPS PUB 180-4 clause 5.1.2. */
552 /* Note: the target location is predefined and buffer is always aligned */
553 _MHD_PUT_64BIT_BE (ctx->buffer + SHA512_256_BLOCK_SIZE_WORDS - 2,
554 ctx->count_bits_hi);
555 _MHD_PUT_64BIT_BE (ctx->buffer + SHA512_256_BLOCK_SIZE_WORDS - 1,
556 num_bits);
557 /* Process the full final block. */
558 sha512_256_transform (ctx->H, ctx->buffer);
559
560 /* Put in BE mode the leftmost part of the hash as the final digest.
561 See FIPS PUB 180-4 clause 6.7. */
562#ifndef _MHD_PUT_64BIT_BE_UNALIGNED
563 if (0 != ((uintptr_t) digest) % _MHD_UINT64_ALIGN)
564 { /* The destination is unaligned */
565 uint64_t alig_dgst[SHA512_256_DIGEST_SIZE_WORDS];
566 _MHD_PUT_64BIT_BE (alig_dgst + 0, ctx->H[0]);
567 _MHD_PUT_64BIT_BE (alig_dgst + 1, ctx->H[1]);
568 _MHD_PUT_64BIT_BE (alig_dgst + 2, ctx->H[2]);
569 _MHD_PUT_64BIT_BE (alig_dgst + 3, ctx->H[3]);
570 /* Copy result to the unaligned destination address */
571 memcpy (digest, alig_dgst, SHA512_256_DIGEST_SIZE);
572 }
573 else /* Combined with the next 'if' */
574#endif /* ! _MHD_PUT_64BIT_BE_UNALIGNED */
575 if (1)
576 {
577 /* Use cast to (void*) here to mute compiler alignment warnings.
578 * Compilers are not smart enough to see that alignment has been checked. */
579 _MHD_PUT_64BIT_BE ((void *) (digest + 0 * SHA512_256_BYTES_IN_WORD), \
580 ctx->H[0]);
581 _MHD_PUT_64BIT_BE ((void *) (digest + 1 * SHA512_256_BYTES_IN_WORD), \
582 ctx->H[1]);
583 _MHD_PUT_64BIT_BE ((void *) (digest + 2 * SHA512_256_BYTES_IN_WORD), \
584 ctx->H[2]);
585 _MHD_PUT_64BIT_BE ((void *) (digest + 3 * SHA512_256_BYTES_IN_WORD), \
586 ctx->H[3]);
587 }
588
589 /* Erase potentially sensitive data. */
590 memset (ctx, 0, sizeof(struct Sha512_256Ctx));
591}
diff --git a/src/microhttpd/sha512_256.h b/src/microhttpd/sha512_256.h
new file mode 100644
index 00000000..43359dc7
--- /dev/null
+++ b/src/microhttpd/sha512_256.h
@@ -0,0 +1,138 @@
1/*
2 This file is part of GNU libmicrohttpd
3 Copyright (C) 2022 Karlson2k (Evgeny Grin)
4
5 GNU libmicrohttpd is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library.
17 If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file microhttpd/sha512_256.h
22 * @brief Calculation of SHA-512/256 digest
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#ifndef MHD_SHA512_256_H
27#define MHD_SHA512_256_H 1
28
29#include "mhd_options.h"
30#include <stdint.h>
31#ifdef HAVE_STDDEF_H
32#include <stddef.h> /* for size_t */
33#endif /* HAVE_STDDEF_H */
34
35
36/**
37 * Number of bits in single SHA-512/256 word.
38 */
39#define SHA512_256_WORD_SIZE_BITS 64
40
41/**
42 * Number of bytes in single SHA-512/256 word.
43 */
44#define SHA512_256_BYTES_IN_WORD (SHA512_256_WORD_SIZE_BITS / 8)
45
46/**
47 * Hash is kept internally as 8 64-bit words.
48 * This is intermediate hash size, used during computing the final digest.
49 */
50#define SHA512_256_HASH_SIZE_WORDS 8
51
52/**
53 * Size of SHA-512/256 resulting digest in bytes.
54 * This is the final digest size, not intermediate hash.
55 */
56#define SHA512_256_DIGEST_SIZE_WORDS (SHA512_256_HASH_SIZE_WORDS / 2)
57
58/**
59 * Size of SHA-512/256 resulting digest in bytes
60 * This is the final digest size, not intermediate hash.
61 */
62#define SHA512_256_DIGEST_SIZE \
63 (SHA512_256_DIGEST_SIZE_WORDS * SHA512_256_BYTES_IN_WORD)
64
65/**
66 * Size of SHA-512/256 digest string in chars including termination NUL.
67 */
68#define SHA512_256_DIGEST_STRING_SIZE ((SHA512_256_DIGEST_SIZE) * 2 + 1)
69
70/**
71 * Size of single processing block in bits.
72 * This is the final digest size, not intermediate hash.
73 */
74#define SHA512_256_BLOCK_SIZE_BITS 1024
75
76/**
77 * Size of single processing block in bytes.
78 */
79#define SHA512_256_BLOCK_SIZE (SHA512_256_BLOCK_SIZE_BITS / 8)
80
81/**
82 * Size of single processing block in words.
83 */
84#define SHA512_256_BLOCK_SIZE_WORDS \
85 (SHA512_256_BLOCK_SIZE_BITS / SHA512_256_WORD_SIZE_BITS)
86
87
88/**
89 * SHA-512/256 calculation context
90 */
91struct Sha512_256Ctx
92{
93 uint64_t H[SHA512_256_HASH_SIZE_WORDS]; /**< Intermediate hash value */
94 uint64_t buffer[SHA512_256_BLOCK_SIZE_WORDS]; /**< SHA512_256 input data buffer */
95 /**
96 * The number of bytes, lower part
97 */
98 uint64_t count;
99 /**
100 * The number of bits, high part.
101 * Unlike lower part, this counts the number of bits, not bytes.
102 */
103 uint64_t count_bits_hi;
104};
105
106/**
107 * Initialise structure for SHA-512/256 calculation.
108 *
109 * @param ctx the calculation context
110 */
111void
112MHD_SHA512_256_init (struct Sha512_256Ctx *ctx);
113
114
115/**
116 * Process portion of bytes.
117 *
118 * @param ctx the calculation context
119 * @param data bytes to add to hash
120 * @param length number of bytes in @a data
121 */
122void
123MHD_SHA512_256_update (struct Sha512_256Ctx *ctx,
124 const uint8_t *data,
125 size_t length);
126
127
128/**
129 * Finalise SHA-512/256 calculation, return digest.
130 *
131 * @param ctx the calculation context
132 * @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes
133 */
134void
135MHD_SHA512_256_finish (struct Sha512_256Ctx *ctx,
136 uint8_t digest[SHA512_256_DIGEST_SIZE]);
137
138#endif /* MHD_SHA512_256_H */
diff --git a/src/microhttpd/test_sha512_256.c b/src/microhttpd/test_sha512_256.c
new file mode 100644
index 00000000..85c3a0ee
--- /dev/null
+++ b/src/microhttpd/test_sha512_256.c
@@ -0,0 +1,588 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2019-2022 Karlson2k (Evgeny Grin)
4
5 This test tool is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2, or
8 (at your option) any later version.
9
10 This test tool is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20/**
21 * @file microhttpd/test_sha512_256.h
22 * @brief Unit tests for SHA-512/256 functions
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#include "mhd_options.h"
27#include "sha512_256.h"
28#include "test_helpers.h"
29#include <stdio.h>
30#include <stdlib.h>
31
32static int verbose = 0; /* verbose level (0-1)*/
33
34
35struct str_with_len
36{
37 const char *const str;
38 const size_t len;
39};
40
41#define D_STR_W_LEN(s) {(s), (sizeof((s)) / sizeof(char)) - 1}
42
43struct data_unit1
44{
45 const struct str_with_len str_l;
46 const uint8_t digest[SHA512_256_DIGEST_SIZE];
47};
48
49static const struct data_unit1 data_units1[] = {
50 {D_STR_W_LEN ("abc"),
51 {0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9, 0x9B, 0x2E, 0x29, 0xB7,
52 0x6B, 0x4C, 0x7D, 0xAB, 0xE4, 0xC2, 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46,
53 0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23}},
54 {D_STR_W_LEN ("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" \
55 "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
56 {0x39, 0x28, 0xE1, 0x84, 0xFB, 0x86, 0x90, 0xF8, 0x40, 0xDA, 0x39, 0x88,
57 0x12, 0x1D, 0x31, 0xBE, 0x65, 0xCB, 0x9D, 0x3E, 0xF8, 0x3E, 0xE6, 0x14,
58 0x6F, 0xEA, 0xC8, 0x61, 0xE1, 0x9B, 0x56, 0x3A}},
59 {D_STR_W_LEN (""), /* The empty zero-size input */
60 {0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28, 0xab, 0x87, 0xc3, 0x62,
61 0x2c, 0x51, 0x14, 0x06, 0x9b, 0xdd, 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74,
62 0x98, 0xd0, 0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a}},
63 {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."),
64 {0xc8, 0x7c, 0x5a, 0x55, 0x27, 0x77, 0x1b, 0xe7, 0x69, 0x3c, 0x50, 0x79,
65 0x32, 0xad, 0x7c, 0x79, 0xe9, 0x60, 0xa0, 0x18, 0xb7, 0x78, 0x2b, 0x6f,
66 0xa9, 0x7b, 0xa3, 0xa0, 0xb5, 0x18, 0x17, 0xa5}},
67 {D_STR_W_LEN ("Simple string."),
68 {0xde, 0xcb, 0x3c, 0x81, 0x65, 0x4b, 0xa0, 0xf5, 0xf0, 0x45, 0x6b, 0x7e,
69 0x61, 0xf5, 0x0d, 0xf5, 0x38, 0xa4, 0xfc, 0xb1, 0x8a, 0x95, 0xff, 0x59,
70 0xbc, 0x04, 0x82, 0xcf, 0x23, 0xb2, 0x32, 0x56}},
71 {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"),
72 {0xfc, 0x31, 0x89, 0x44, 0x3f, 0x9c, 0x26, 0x8f, 0x62, 0x6a, 0xea, 0x08,
73 0xa7, 0x56, 0xab, 0xe7, 0xb7, 0x26, 0xb0, 0x5f, 0x70, 0x1c, 0xb0, 0x82,
74 0x22, 0x31, 0x2c, 0xcf, 0xd6, 0x71, 0x0a, 0x26, }},
75 {D_STR_W_LEN ("zyxwvutsrqponMLKJIHGFEDCBA"),
76 {0xd2, 0x6d, 0x24, 0x81, 0xa4, 0xf9, 0x0a, 0x72, 0xd2, 0x7f, 0xc1, 0xac,
77 0xac, 0xe1, 0xc0, 0x6b, 0x39, 0x94, 0xac, 0x73, 0x50, 0x2e, 0x27, 0x97,
78 0xa3, 0x65, 0x37, 0x4e, 0xbb, 0x5c, 0x27, 0xe9}},
79 {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA" \
80 "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"),
81 {0xad, 0xe9, 0x5d, 0x55, 0x3b, 0x9e, 0x45, 0x69, 0xdb, 0x53, 0xa4, 0x04,
82 0x92, 0xe7, 0x87, 0x94, 0xff, 0xc9, 0x98, 0x5f, 0x93, 0x03, 0x86, 0x45,
83 0xe1, 0x97, 0x17, 0x72, 0x7c, 0xbc, 0x31, 0x15}},
84};
85
86static const size_t units1_num = sizeof(data_units1) / sizeof(data_units1[0]);
87
88struct bin_with_len
89{
90 const uint8_t bin[512];
91 const size_t len;
92};
93
94struct data_unit2
95{
96 const struct bin_with_len bin_l;
97 const uint8_t digest[SHA512_256_DIGEST_SIZE];
98};
99
100/* Size must be less than 512 bytes! */
101static const struct data_unit2 data_units2[] = {
102 { { {97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
103 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122}, 26}, /* a..z ASCII sequence */
104 {0xfc, 0x31, 0x89, 0x44, 0x3f, 0x9c, 0x26, 0x8f, 0x62, 0x6a, 0xea, 0x08,
105 0xa7, 0x56, 0xab, 0xe7, 0xb7, 0x26, 0xb0, 0x5f, 0x70, 0x1c, 0xb0, 0x82,
106 0x22, 0x31, 0x2c, 0xcf, 0xd6, 0x71, 0x0a, 0x26}},
107 { { {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
108 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
109 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
110 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65},
111 72 }, /* 'A' x 72 times */
112 {0x36, 0x5d, 0x41, 0x0e, 0x55, 0xd1, 0xfd, 0xe6, 0xc3, 0xb8, 0x68, 0xcc,
113 0xed, 0xeb, 0xcd, 0x0d, 0x2e, 0x34, 0xb2, 0x5c, 0xdf, 0xe7, 0x79, 0xe2,
114 0xe9, 0x65, 0x07, 0x33, 0x78, 0x0d, 0x01, 0x89}},
115 { { {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
116 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
117 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
118 73}, 55}, /* 19..73 sequence */
119 {0xb9, 0xe5, 0x74, 0x11, 0xbf, 0xa2, 0x0e, 0x98, 0xbe, 0x08, 0x69, 0x2e,
120 0x17, 0x9e, 0xc3, 0xfe, 0x61, 0xe3, 0x7a, 0x80, 0x2e, 0x25, 0x8c, 0xf3,
121 0x76, 0xda, 0x9f, 0x5f, 0xcd, 0x87, 0x48, 0x0d}},
122 { { {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
123 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
124 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
125 62, 63, 64, 65, 66, 67, 68, 69}, 63}, /* 7..69 sequence */
126 {0x80, 0x15, 0x83, 0xed, 0x7d, 0xef, 0x9f, 0xdf, 0xfb, 0x83, 0x1f, 0xc5,
127 0x8b, 0x50, 0x37, 0x81, 0x00, 0xc3, 0x4f, 0xfd, 0xfe, 0xc2, 0x9b, 0xaf,
128 0xfe, 0x15, 0x66, 0xe5, 0x08, 0x42, 0x5e, 0xae}},
129 { { {38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
130 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
131 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
132 92}, 55}, /* 38..92 sequence */
133 {0x76, 0x2f, 0x27, 0x4d, 0xfa, 0xd5, 0xa9, 0x21, 0x4e, 0xe9, 0x56, 0x22,
134 0x54, 0x38, 0x71, 0x3e, 0xef, 0x14, 0xa9, 0x22, 0x37, 0xf3, 0xb0, 0x50,
135 0x3d, 0x95, 0x40, 0xb7, 0x08, 0x64, 0xa9, 0xfd}},
136 { { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
137 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
138 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
139 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72}, 72}, /* 1..72 sequence */
140 {0x3f, 0x5c, 0xd3, 0xec, 0x40, 0xc4, 0xb9, 0x78, 0x35, 0x57, 0xc6, 0x4f,
141 0x3e, 0x46, 0x82, 0xdc, 0xd4, 0x46, 0x11, 0xd0, 0xb3, 0x0a, 0xbb, 0x89,
142 0xf1, 0x1d, 0x34, 0xb5, 0xf9, 0xd5, 0x10, 0x35}},
143 { { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
144 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
145 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
146 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
147 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
148 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
149 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
150 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
151 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
152 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
153 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
154 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
155 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
156 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
157 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,
158 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248,
159 249, 250, 251, 252, 253, 254, 255}, 256}, /* 0..255 sequence */
160 {0x08, 0x37, 0xa1, 0x1d, 0x99, 0x4d, 0x5a, 0xa8, 0x60, 0xd0, 0x69, 0x17,
161 0xa8, 0xa0, 0xf6, 0x3e, 0x31, 0x11, 0xb9, 0x56, 0x33, 0xde, 0xeb, 0x15,
162 0xee, 0xd9, 0x94, 0x93, 0x76, 0xf3, 0x7d, 0x36, }},
163 { { {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
164 185, 184, 183, 182, 181, 180,
165 179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166,
166 165, 164, 163, 162, 161, 160,
167 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146,
168 145, 144, 143, 142, 141, 140,
169 139}, 61}, /* 199..139 sequence */
170 {0xcf, 0x21, 0x4b, 0xb2, 0xdd, 0x40, 0x98, 0xdf, 0x3a, 0xb7, 0x21, 0xb4,
171 0x69, 0x0e, 0x19, 0x36, 0x24, 0xa9, 0xbe, 0x30, 0xf7, 0xd0, 0x75, 0xb0,
172 0x39, 0x94, 0x82, 0xda, 0x55, 0x97, 0xe4, 0x79}},
173 { { {255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242,
174 241, 240, 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228,
175 227, 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214,
176 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200,
177 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
178 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, 172,
179 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, 159, 158,
180 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144,
181 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130,
182 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116,
183 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102,
184 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85,
185 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67,
186 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,
187 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31,
188 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,
189 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 255}, /* 255..1 sequence */
190 {0x22, 0x31, 0xf2, 0xa1, 0xb4, 0x89, 0xb2, 0x44, 0xf7, 0x66, 0xa0, 0xb8,
191 0x31, 0xed, 0xb7, 0x73, 0x8a, 0x34, 0xdc, 0x11, 0xc8, 0x2c, 0xf2, 0xb5,
192 0x88, 0x60, 0x39, 0x6b, 0x5c, 0x06, 0x70, 0x37}},
193 { { {41, 35, 190, 132, 225, 108, 214, 174, 82, 144, 73, 241, 241, 187, 233,
194 235, 179, 166, 219, 60, 135, 12, 62, 153, 36, 94, 13, 28, 6, 183, 71,
195 222, 179, 18, 77, 200, 67, 187, 139, 166, 31, 3, 90, 125, 9, 56, 37,
196 31, 93, 212, 203, 252, 150, 245, 69, 59, 19, 13, 137, 10, 28, 219, 174,
197 50, 32, 154, 80, 238, 64, 120, 54, 253, 18, 73, 50, 246, 158, 125, 73,
198 220, 173, 79, 20, 242, 68, 64, 102, 208, 107, 196, 48, 183, 50, 59,
199 161, 34, 246, 34, 145, 157, 225, 139, 31, 218, 176, 202, 153, 2, 185,
200 114, 157, 73, 44, 128, 126, 197, 153, 213, 233, 128, 178, 234, 201,
201 204, 83, 191, 103, 214, 191, 20, 214, 126, 45, 220, 142, 102, 131, 239,
202 87, 73, 97, 255, 105, 143, 97, 205, 209, 30, 157, 156, 22, 114, 114,
203 230, 29, 240, 132, 79, 74, 119, 2, 215, 232, 57, 44, 83, 203, 201, 18,
204 30, 51, 116, 158, 12, 244, 213, 212, 159, 212, 164, 89, 126, 53, 207,
205 50, 34, 244, 204, 207, 211, 144, 45, 72, 211, 143, 117, 230, 217, 29,
206 42, 229, 192, 247, 43, 120, 129, 135, 68, 14, 95, 80, 0, 212, 97, 141,
207 190, 123, 5, 21, 7, 59, 51, 130, 31, 24, 112, 146, 218, 100, 84, 206,
208 177, 133, 62, 105, 21, 248, 70, 106, 4, 150, 115, 14, 217, 22, 47, 103,
209 104, 212, 247, 74, 74, 208, 87, 104}, 255}, /* pseudo-random data */
210 {0xb8, 0xdb, 0x2c, 0x2e, 0xf3, 0x12, 0x77, 0x14, 0xf9, 0x34, 0x2d, 0xfa,
211 0xda, 0x42, 0xbe, 0xfe, 0x67, 0x3a, 0x8a, 0xf6, 0x71, 0x36, 0x00, 0xff,
212 0x77, 0xa5, 0x83, 0x14, 0x55, 0x2a, 0x05, 0xaf}},
213 { { {66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
214 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
215 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
216 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
217 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
218 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
219 66, 66}, 110}, /* 'B' x 110 times */
220 {0xc8, 0x9e, 0x0d, 0x8f, 0x7b, 0x35, 0xfd, 0x3e, 0xdc, 0x90, 0x87, 0x64,
221 0x45, 0x94, 0x94, 0x21, 0xb3, 0x8e, 0xb5, 0xc7, 0x54, 0xc8, 0xee, 0xde,
222 0xfc, 0x77, 0xd6, 0xe3, 0x9f, 0x81, 0x8e, 0x78}},
223 { { {67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
224 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
225 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
226 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
227 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
228 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
229 67, 67, 67}, 111}, /* 'C' x 111 times */
230 {0x86, 0xca, 0x6d, 0x2a, 0x72, 0xe2, 0x8c, 0x17, 0x89, 0x86, 0x89, 0x1b,
231 0x36, 0xf9, 0x6d, 0xda, 0x8c, 0xd6, 0x30, 0xb2, 0xd3, 0x60, 0x39, 0xfb,
232 0xc9, 0x04, 0xc5, 0x11, 0xcd, 0x2d, 0xe3, 0x62}},
233 { { {68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
234 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
235 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
236 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
237 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
238 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
239 68, 68, 68, 68}, 112}, /* 'D' x 112 times */
240 {0xdf, 0x9d, 0x4a, 0xcf, 0x81, 0x0d, 0x3a, 0xd4, 0x8e, 0xa4, 0x65, 0x9e,
241 0x1e, 0x15, 0xe4, 0x15, 0x1b, 0x37, 0xb6, 0xeb, 0x17, 0xab, 0xf6, 0xb1,
242 0xbc, 0x30, 0x46, 0x34, 0x24, 0x56, 0x1c, 0x06}},
243 { { {69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
244 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
245 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
246 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
247 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
248 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
249 69, 69, 69, 69, 69}, 113}, /* 'E' x 113 times */
250 {0xa5, 0xf1, 0x47, 0x74, 0xf8, 0x2b, 0xed, 0x23, 0xe4, 0x10, 0x59, 0x8f,
251 0x7e, 0xb1, 0x30, 0xe5, 0x7e, 0xd1, 0x4b, 0xbc, 0x72, 0x58, 0x58, 0x81,
252 0xbb, 0xa0, 0xa5, 0xb6, 0x15, 0x39, 0x49, 0xa1}},
253 { { {70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
254 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
255 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
256 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
257 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
258 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
259 70, 70, 70, 70, 70, 70}, 114}, /* 'F' x 114 times */
260 {0xe6, 0xa3, 0xc9, 0x63, 0xd5, 0x28, 0x6e, 0x2d, 0xfb, 0x71, 0xdf, 0xd4,
261 0xff, 0xc2, 0xd4, 0x2b, 0x5d, 0x9b, 0x76, 0x28, 0xd2, 0xcb, 0x15, 0xc8,
262 0x81, 0x57, 0x14, 0x09, 0xc3, 0x8e, 0x92, 0xce}},
263 { { {76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
264 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
265 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
266 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
267 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
268 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
269 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
270 76}, 127}, /* 'L' x 127 times */
271 {0x5d, 0x18, 0xff, 0xd7, 0xbe, 0x23, 0xb2, 0xb2, 0xbd, 0xe3, 0x13, 0x12,
272 0x1c, 0x16, 0x89, 0x14, 0x4a, 0x42, 0xb4, 0x3f, 0xab, 0xc8, 0x41, 0x14,
273 0x62, 0x00, 0xb5, 0x53, 0xa7, 0xd6, 0xd5, 0x35}},
274 { { {77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
275 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
276 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
277 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
278 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
279 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
280 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
281 77, 77}, 128}, /* 'M' x 128 times */
282 {0x6e, 0xf0, 0xda, 0x81, 0x3d, 0x50, 0x1d, 0x31, 0xf1, 0x4a, 0xf8, 0xd9,
283 0x7d, 0xd2, 0x13, 0xdd, 0xa4, 0x46, 0x15, 0x0b, 0xb8, 0x5a, 0x8a, 0xc6,
284 0x1e, 0x3a, 0x1f, 0x21, 0x35, 0xa2, 0xbb, 0x4f}},
285 { { {78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
286 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
287 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
288 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
289 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
290 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
291 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
292 78, 78, 78}, 129}, /* 'N' x 129 times */
293 {0xee, 0xce, 0xd5, 0x34, 0xab, 0x14, 0x13, 0x9e, 0x8f, 0x5c, 0xb4, 0xef,
294 0xac, 0xaf, 0xc5, 0xeb, 0x1d, 0x2f, 0xe3, 0xc5, 0xca, 0x09, 0x29, 0x96,
295 0xfa, 0x84, 0xff, 0x12, 0x26, 0x6a, 0x50, 0x49}},
296 { { {97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
297 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
298 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
299 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
300 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
301 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
302 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
303 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
304 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
305 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
306 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
307 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
308 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
309 97, 97, 97, 97}, 238}, /* 'a' x 238 times */
310 {0xb4, 0x24, 0xe5, 0x7b, 0xa7, 0x37, 0xe3, 0xc4, 0xac, 0x35, 0x21, 0x17,
311 0x98, 0xec, 0xb9, 0xae, 0x45, 0x13, 0x24, 0xa4, 0x2c, 0x76, 0xae, 0x7d,
312 0x17, 0x75, 0x27, 0x8a, 0xaa, 0x4a, 0x48, 0x60}},
313 { { {98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
314 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
315 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
316 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
317 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
318 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
319 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
320 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
321 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
322 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
323 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
324 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
325 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
326 98, 98, 98, 98, 98}, 239}, /* 'b' x 239 times */
327 {0xcd, 0x93, 0xb8, 0xab, 0x6a, 0x74, 0xbd, 0x34, 0x8c, 0x43, 0x76, 0x0c,
328 0x2a, 0xd0, 0x6e, 0xd8, 0x76, 0xcf, 0xdf, 0x2a, 0x21, 0x04, 0xfb, 0xf6,
329 0x16, 0x53, 0x68, 0xf6, 0x10, 0xc3, 0xa1, 0xac}},
330 { { {99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
331 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
332 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
333 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
334 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
335 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
336 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
337 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
338 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
339 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
340 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
341 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
342 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
343 99, 99, 99, 99, 99, 99}, 240}, /* 'c' x 240 times */
344 {0x5f, 0x60, 0xea, 0x44, 0xb6, 0xc6, 0x9e, 0xfe, 0xfc, 0x0e, 0x6a, 0x0a,
345 0x99, 0x40, 0x1b, 0x61, 0x43, 0x58, 0xba, 0x4a, 0x0a, 0xee, 0x6b, 0x52,
346 0x10, 0xdb, 0x32, 0xd9, 0x7f, 0x12, 0xba, 0x70}},
347 { { {48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
348 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
349 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
350 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
351 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
352 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
353 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
354 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
355 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
356 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
357 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
358 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
359 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
360 48, 48, 48, 48, 48, 48, 48}, 241}, /* '0' x 241 times */
361 {0x3c, 0xcb, 0xcf, 0x50, 0x79, 0xd5, 0xb6, 0xf5, 0xbf, 0x25, 0x07, 0xfb,
362 0x4d, 0x1f, 0xa3, 0x77, 0xc3, 0x6f, 0xe8, 0xe3, 0xc4, 0x4b, 0xf8, 0xcd,
363 0x90, 0x93, 0xf1, 0x3e, 0x08, 0x09, 0xa7, 0x69}}
364};
365
366static const size_t units2_num = sizeof(data_units2) / sizeof(data_units2[0]);
367
368
369/*
370 * Helper functions
371 */
372
373/**
374 * Print bin as hex
375 *
376 * @param bin binary data
377 * @param len number of bytes in bin
378 * @param hex pointer to len*2+1 bytes buffer
379 */
380static void
381bin2hex (const uint8_t *bin,
382 size_t len,
383 char *hex)
384{
385 while (len-- > 0)
386 {
387 unsigned int b1, b2;
388 b1 = (*bin >> 4) & 0xf;
389 *hex++ = (char) ((b1 > 9) ? (b1 + 'A' - 10) : (b1 + '0'));
390 b2 = *bin++ & 0xf;
391 *hex++ = (char) ((b2 > 9) ? (b2 + 'A' - 10) : (b2 + '0'));
392 }
393 *hex = 0;
394}
395
396
397static int
398check_result (const char *test_name,
399 unsigned int check_num,
400 const uint8_t calculated[SHA512_256_DIGEST_SIZE],
401 const uint8_t expected[SHA512_256_DIGEST_SIZE])
402{
403 int failed = memcmp (calculated, expected, SHA512_256_DIGEST_SIZE);
404 check_num++; /* Print 1-based numbers */
405 if (failed)
406 {
407 char calc_str[SHA512_256_DIGEST_SIZE * 2 + 1];
408 char expc_str[SHA512_256_DIGEST_SIZE * 2 + 1];
409 bin2hex (calculated, SHA512_256_DIGEST_SIZE, calc_str);
410 bin2hex (expected, SHA512_256_DIGEST_SIZE, expc_str);
411 fprintf (stderr,
412 "FAILED: %s check %u: calculated digest %s, expected digest %s.\n",
413 test_name, check_num, calc_str, expc_str);
414 fflush (stderr);
415 }
416 else if (verbose)
417 {
418 char calc_str[SHA512_256_DIGEST_SIZE * 2 + 1];
419 bin2hex (calculated, SHA512_256_DIGEST_SIZE, calc_str);
420 printf (
421 "PASSED: %s check %u: calculated digest %s matches expected digest.\n",
422 test_name, check_num, calc_str);
423 fflush (stdout);
424 }
425 return failed ? 1 : 0;
426}
427
428
429/*
430 * Tests
431 */
432
433/* Calculated SHA-512/256 as one pass for whole data */
434static int
435test1_str (void)
436{
437 int num_failed = 0;
438 unsigned int i;
439
440 for (i = 0; i < units1_num; i++)
441 {
442 struct Sha512_256Ctx ctx;
443 uint8_t digest[SHA512_256_DIGEST_SIZE];
444
445 MHD_SHA512_256_init (&ctx);
446 MHD_SHA512_256_update (&ctx, (const uint8_t *) data_units1[i].str_l.str,
447 data_units1[i].str_l.len);
448 MHD_SHA512_256_finish (&ctx, digest);
449 num_failed += check_result (__FUNCTION__, i, digest,
450 data_units1[i].digest);
451 }
452 return num_failed;
453}
454
455
456static int
457test1_bin (void)
458{
459 int num_failed = 0;
460 unsigned int i;
461
462 for (i = 0; i < units2_num; i++)
463 {
464 struct Sha512_256Ctx ctx;
465 uint8_t digest[SHA512_256_DIGEST_SIZE];
466
467 MHD_SHA512_256_init (&ctx);
468 MHD_SHA512_256_update (&ctx, data_units2[i].bin_l.bin,
469 data_units2[i].bin_l.len);
470 MHD_SHA512_256_finish (&ctx, digest);
471 num_failed += check_result (__FUNCTION__, i, digest,
472 data_units2[i].digest);
473 }
474 return num_failed;
475}
476
477
478/* Calculated SHA-512/256 as two iterations for whole data */
479static int
480test2_str (void)
481{
482 int num_failed = 0;
483 unsigned int i;
484
485 for (i = 0; i < units1_num; i++)
486 {
487 struct Sha512_256Ctx ctx;
488 uint8_t digest[SHA512_256_DIGEST_SIZE];
489 size_t part_s = data_units1[i].str_l.len / 4;
490
491 MHD_SHA512_256_init (&ctx);
492 MHD_SHA512_256_update (&ctx, (const uint8_t *) data_units1[i].str_l.str,
493 part_s);
494 MHD_SHA512_256_update (&ctx, (const uint8_t *) data_units1[i].str_l.str
495 + part_s,
496 data_units1[i].str_l.len - part_s);
497 MHD_SHA512_256_finish (&ctx, digest);
498 num_failed += check_result (__FUNCTION__, i, digest,
499 data_units1[i].digest);
500 }
501 return num_failed;
502}
503
504
505static int
506test2_bin (void)
507{
508 int num_failed = 0;
509 unsigned int i;
510
511 for (i = 0; i < units2_num; i++)
512 {
513 struct Sha512_256Ctx ctx;
514 uint8_t digest[SHA512_256_DIGEST_SIZE];
515 size_t part_s = data_units2[i].bin_l.len * 2 / 3;
516
517 MHD_SHA512_256_init (&ctx);
518 MHD_SHA512_256_update (&ctx, data_units2[i].bin_l.bin, part_s);
519 MHD_SHA512_256_update (&ctx, data_units2[i].bin_l.bin + part_s,
520 data_units2[i].bin_l.len - part_s);
521 MHD_SHA512_256_finish (&ctx, digest);
522 num_failed += check_result (__FUNCTION__, i, digest,
523 data_units2[i].digest);
524 }
525 return num_failed;
526}
527
528
529/* Use data set number 7 as it has the longest sequence */
530#define DATA_POS 6
531#define MAX_OFFSET 63
532
533static int
534test_unaligned (void)
535{
536 int num_failed = 0;
537 unsigned int offset;
538 uint8_t *buf;
539 uint8_t *digest_buf;
540
541 const struct data_unit2 *const tdata = data_units2 + DATA_POS;
542
543 buf = malloc (tdata->bin_l.len + MAX_OFFSET);
544 digest_buf = malloc (SHA512_256_DIGEST_SIZE + MAX_OFFSET);
545 if ((NULL == buf) || (NULL == digest_buf))
546 exit (99);
547
548 for (offset = MAX_OFFSET; offset >= 1; --offset)
549 {
550 struct Sha512_256Ctx ctx;
551 uint8_t *unaligned_digest;
552 uint8_t *unaligned_buf;
553
554 unaligned_buf = buf + offset;
555 memcpy (unaligned_buf, tdata->bin_l.bin, tdata->bin_l.len);
556 unaligned_digest = digest_buf + MAX_OFFSET - offset;
557 memset (unaligned_digest, 0, SHA512_256_DIGEST_SIZE);
558
559 MHD_SHA512_256_init (&ctx);
560 MHD_SHA512_256_update (&ctx, unaligned_buf, tdata->bin_l.len);
561 MHD_SHA512_256_finish (&ctx, unaligned_digest);
562 num_failed += check_result (__FUNCTION__, MAX_OFFSET - offset,
563 unaligned_digest, tdata->digest);
564 }
565 free (digest_buf);
566 free (buf);
567 return num_failed;
568}
569
570
571int
572main (int argc, char *argv[])
573{
574 int num_failed = 0;
575 (void) has_in_name; /* Mute compiler warning. */
576 if (has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose"))
577 verbose = 1;
578
579 num_failed += test1_str ();
580 num_failed += test1_bin ();
581
582 num_failed += test2_str ();
583 num_failed += test2_bin ();
584
585 num_failed += test_unaligned ();
586
587 return num_failed ? 1 : 0;
588}