aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-05-16 18:20:10 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-05-16 18:21:27 +0300
commit714c5735e4a1ffce8f3124835dc4bb59a8735c0b (patch)
treeb84a01251b38a912ab6953bf83283b6e10cd6257
parentb25cc0f30166152a56b0035241807e8f4d6f74e1 (diff)
downloadlibmicrohttpd-714c5735e4a1ffce8f3124835dc4bb59a8735c0b.tar.gz
libmicrohttpd-714c5735e4a1ffce8f3124835dc4bb59a8735c0b.zip
Implemented SHA-1 calculation
-rw-r--r--src/microhttpd/Makefile.am5
-rw-r--r--src/microhttpd/mhd_bithelpers.h27
-rw-r--r--src/microhttpd/sha1.c353
-rw-r--r--src/microhttpd/sha1.h98
-rw-r--r--src/microhttpd/test_sha1.c417
5 files changed, 900 insertions, 0 deletions
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index 1e252d5a..84fe4f81 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -160,6 +160,7 @@ check_PROGRAMS = \
160 test_str_token \ 160 test_str_token \
161 test_http_reasons \ 161 test_http_reasons \
162 test_md5 \ 162 test_md5 \
163 test_sha1 \
163 test_sha256 \ 164 test_sha256 \
164 test_start_stop \ 165 test_start_stop \
165 test_daemon \ 166 test_daemon \
@@ -364,6 +365,10 @@ test_sha256_SOURCES = \
364 test_sha256.c test_helpers.h \ 365 test_sha256.c test_helpers.h \
365 sha256.c sha256.h mhd_bithelpers.h 366 sha256.c sha256.h mhd_bithelpers.h
366 367
368test_sha1_SOURCES = \
369 test_sha1.c test_helpers.h \
370 sha1.c sha1.h mhd_bithelpers.h
371
367test_options_SOURCES = \ 372test_options_SOURCES = \
368 test_options.c 373 test_options.c
369test_options_LDADD = \ 374test_options_LDADD = \
diff --git a/src/microhttpd/mhd_bithelpers.h b/src/microhttpd/mhd_bithelpers.h
index ea7682aa..c8c814ac 100644
--- a/src/microhttpd/mhd_bithelpers.h
+++ b/src/microhttpd/mhd_bithelpers.h
@@ -238,6 +238,33 @@ _MHD_ROTR32 (uint32_t value32, int bits)
238 /* Defined in form which modern compiler could optimize. */ 238 /* Defined in form which modern compiler could optimize. */
239 return (value32 >> bits) | (value32 << (32 - bits)); 239 return (value32 >> bits) | (value32 << (32 - bits));
240} 240}
241
242
243#endif /* ! _MSC_FULL_VER */
244
245
246/**
247 * Rotate left 32-bit value by number of bits.
248 * bits parameter must be more than zero and must be less than 32.
249 */
250#if defined(_MSC_FULL_VER) && (! defined(__clang__) || (defined(__c2__) && \
251 defined(__OPTIMIZE__)))
252/* Clang/C2 do not inline this function if optimizations are turned off. */
253#ifndef __clang__
254#pragma intrinsic(_rotl)
255#endif /* ! __clang__ */
256#define _MHD_ROTL32(value32, bits) \
257 ((uint32_t) _rotl ((uint32_t) (value32),(bits)))
258#else /* ! _MSC_FULL_VER */
259_MHD_static_inline uint32_t
260_MHD_ROTL32 (uint32_t value32, int bits)
261{
262 mhd_assert (bits < 32);
263 /* Defined in form which modern compiler could optimize. */
264 return (value32 << bits) | (value32 >> (32 - bits));
265}
266
267
241#endif /* ! _MSC_FULL_VER */ 268#endif /* ! _MSC_FULL_VER */
242 269
243 270
diff --git a/src/microhttpd/sha1.c b/src/microhttpd/sha1.c
new file mode 100644
index 00000000..51deabaa
--- /dev/null
+++ b/src/microhttpd/sha1.c
@@ -0,0 +1,353 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2019-2021 Karlson2k (Evgeny Grin)
4
5 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/sha1.c
22 * @brief Calculation of SHA-1 digest as defined in FIPS PUB 180-4 (2015)
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#include "sha1.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-1 calculation.
37 *
38 * @param ctx_ must be a `struct sha1_ctx *`
39 */
40void
41MHD_SHA1_init (void *ctx_)
42{
43 struct sha1_ctx *const ctx = ctx_;
44 /* Initial hash values, see FIPS PUB 180-4 paragraph 5.3.1 */
45 /* Just some "magic" numbers defined by standard */
46 ctx->H[0] = 0x67452301UL;
47 ctx->H[1] = 0xefcdab89UL;
48 ctx->H[2] = 0x98badcfeUL;
49 ctx->H[3] = 0x10325476UL;
50 ctx->H[4] = 0xc3d2e1f0UL;
51
52 /* Initialise number of bytes. */
53 ctx->count = 0;
54}
55
56
57/**
58 * Number of bytes in single SHA-1 word
59 */
60#define SHA1_BYTES_IN_WORD (32 / 8)
61
62/**
63 * Base of SHA-1 transformation.
64 * Gets full 512 bits / 64 bytes block of data and updates hash values;
65 * @param H hash values
66 * @param data data, must be exactly 64 bytes long
67 */
68static void
69sha1_transform (uint32_t H[_SHA1_DIGEST_LENGTH],
70 const uint8_t data[SHA1_BLOCK_SIZE])
71{
72 /* Working variables,
73 see FIPS PUB 180-4 paragraph 6.1.3 */
74 uint32_t a = H[0];
75 uint32_t b = H[1];
76 uint32_t c = H[2];
77 uint32_t d = H[3];
78 uint32_t e = H[4];
79
80 /* Data buffer, used as cyclic buffer.
81 See FIPS PUB 180-4 paragraphs 5.2.1, 6.1.3 */
82 uint32_t W[16];
83
84 /* 'Ch' and 'Maj' macro functions are defined with
85 widely-used optimization.
86 See FIPS PUB 180-4 formulae 4.1. */
87#define Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) )
88#define Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
89 /* Unoptimized (original) versions: */
90/* #define Ch(x,y,z) ( ( (x) & (y) ) ^ ( ~(x) & (z) ) ) */
91/* #define Maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */
92#define Par(x,y,z) ( (x) ^ (y) ^ (z) )
93
94 /* Single step of SHA-1 computation,
95 see FIPS PUB 180-4 paragraph 6.1.3 step 3.
96 * Note: instead of reassigning all working variables on each step,
97 variables are rotated for each step:
98 SHA1STEP32 (a, b, c, d, e, func, K00, W[0]);
99 SHA1STEP32 (e, a, b, c, d, func, K00, W[1]);
100 so current 'vC' will be used as 'vD' on the next step,
101 current 'vE' will be used as 'vA' on the next step.
102 * Note: 'wt' must be used exactly one time in this macro as it change other data as well
103 every time when used. */
104
105#define SHA1STEP32(vA,vB,vC,vD,vE,ft,kt,wt) do { \
106 (vE) += _MHD_ROTL32 ((vA), 5) + ft ((vB), (vC), (vD)) + (kt) + (wt); \
107 (vB) = _MHD_ROTL32 ((vB), 30); } while (0)
108
109 /* Get value of W(t) from input data buffer,
110 See FIPS PUB 180-4 paragraph 6.1.3.
111 Input data must be read in big-endian bytes order,
112 see FIPS PUB 180-4 paragraph 3.1.2. */
113#define GET_W_FROM_DATA(buf,t) \
114 _MHD_GET_32BIT_BE (((const uint8_t*) (buf)) + (t) * SHA1_BYTES_IN_WORD)
115
116/* SHA-1 values of Kt for t=0..19, see FIPS PUB 180-4 paragraph 4.2.1. */
117#define K00 0x5a827999UL
118/* SHA-1 values of Kt for t=20..39, see FIPS PUB 180-4 paragraph 4.2.1.*/
119#define K20 0x6ed9eba1UL
120/* SHA-1 values of Kt for t=40..59, see FIPS PUB 180-4 paragraph 4.2.1.*/
121#define K40 0x8f1bbcdcUL
122/* SHA-1 values of Kt for t=60..79, see FIPS PUB 180-4 paragraph 4.2.1.*/
123#define K60 0xca62c1d6UL
124
125 /* During first 16 steps, before making any calculations on each step,
126 the W element is read from input data buffer as big-endian value and
127 stored in array of W elements. */
128 /* Note: instead of using K constants as array, all K values are specified
129 individually for each step. */
130 SHA1STEP32 (a, b, c, d, e, Ch, K00, W[0] = GET_W_FROM_DATA (data, 0));
131 SHA1STEP32 (e, a, b, c, d, Ch, K00, W[1] = GET_W_FROM_DATA (data, 1));
132 SHA1STEP32 (d, e, a, b, c, Ch, K00, W[2] = GET_W_FROM_DATA (data, 2));
133 SHA1STEP32 (c, d, e, a, b, Ch, K00, W[3] = GET_W_FROM_DATA (data, 3));
134 SHA1STEP32 (b, c, d, e, a, Ch, K00, W[4] = GET_W_FROM_DATA (data, 4));
135 SHA1STEP32 (a, b, c, d, e, Ch, K00, W[5] = GET_W_FROM_DATA (data, 5));
136 SHA1STEP32 (e, a, b, c, d, Ch, K00, W[6] = GET_W_FROM_DATA (data, 6));
137 SHA1STEP32 (d, e, a, b, c, Ch, K00, W[7] = GET_W_FROM_DATA (data, 7));
138 SHA1STEP32 (c, d, e, a, b, Ch, K00, W[8] = GET_W_FROM_DATA (data, 8));
139 SHA1STEP32 (b, c, d, e, a, Ch, K00, W[9] = GET_W_FROM_DATA (data, 9));
140 SHA1STEP32 (a, b, c, d, e, Ch, K00, W[10] = GET_W_FROM_DATA (data, 10));
141 SHA1STEP32 (e, a, b, c, d, Ch, K00, W[11] = GET_W_FROM_DATA (data, 11));
142 SHA1STEP32 (d, e, a, b, c, Ch, K00, W[12] = GET_W_FROM_DATA (data, 12));
143 SHA1STEP32 (c, d, e, a, b, Ch, K00, W[13] = GET_W_FROM_DATA (data, 13));
144 SHA1STEP32 (b, c, d, e, a, Ch, K00, W[14] = GET_W_FROM_DATA (data, 14));
145 SHA1STEP32 (a, b, c, d, e, Ch, K00, W[15] = GET_W_FROM_DATA (data, 15));
146
147 /* 'W' generation and assignment for 16 <= t <= 79.
148 See FIPS PUB 180-4 paragraph 6.1.3.
149 As only last 16 'W' are used in calculations, it is possible to
150 use 16 elements array of W as cyclic buffer. */
151#define Wgen(w,t) _MHD_ROTL32((w)[(t + 13) & 0xf] ^ (w)[(t + 8) & 0xf] \
152 ^ (w)[(t + 2) & 0xf] ^ (w)[t & 0xf], 1)
153
154 /* During last 60 steps, before making any calculations on each step,
155 W element is generated from W elements of cyclic buffer and generated value
156 stored back in cyclic buffer. */
157 /* Note: instead of using K constants as array, all K values are specified
158 individually for each step, see FIPS PUB 180-4 paragraph 4.2.1. */
159 SHA1STEP32 (e, a, b, c, d, Ch, K00, W[16 & 0xf] = Wgen (W, 16));
160 SHA1STEP32 (d, e, a, b, c, Ch, K00, W[17 & 0xf] = Wgen (W, 17));
161 SHA1STEP32 (c, d, e, a, b, Ch, K00, W[18 & 0xf] = Wgen (W, 18));
162 SHA1STEP32 (b, c, d, e, a, Ch, K00, W[19 & 0xf] = Wgen (W, 19));
163 SHA1STEP32 (a, b, c, d, e, Par, K20, W[20 & 0xf] = Wgen (W, 20));
164 SHA1STEP32 (e, a, b, c, d, Par, K20, W[21 & 0xf] = Wgen (W, 21));
165 SHA1STEP32 (d, e, a, b, c, Par, K20, W[22 & 0xf] = Wgen (W, 22));
166 SHA1STEP32 (c, d, e, a, b, Par, K20, W[23 & 0xf] = Wgen (W, 23));
167 SHA1STEP32 (b, c, d, e, a, Par, K20, W[24 & 0xf] = Wgen (W, 24));
168 SHA1STEP32 (a, b, c, d, e, Par, K20, W[25 & 0xf] = Wgen (W, 25));
169 SHA1STEP32 (e, a, b, c, d, Par, K20, W[26 & 0xf] = Wgen (W, 26));
170 SHA1STEP32 (d, e, a, b, c, Par, K20, W[27 & 0xf] = Wgen (W, 27));
171 SHA1STEP32 (c, d, e, a, b, Par, K20, W[28 & 0xf] = Wgen (W, 28));
172 SHA1STEP32 (b, c, d, e, a, Par, K20, W[29 & 0xf] = Wgen (W, 29));
173 SHA1STEP32 (a, b, c, d, e, Par, K20, W[30 & 0xf] = Wgen (W, 30));
174 SHA1STEP32 (e, a, b, c, d, Par, K20, W[31 & 0xf] = Wgen (W, 31));
175 SHA1STEP32 (d, e, a, b, c, Par, K20, W[32 & 0xf] = Wgen (W, 32));
176 SHA1STEP32 (c, d, e, a, b, Par, K20, W[33 & 0xf] = Wgen (W, 33));
177 SHA1STEP32 (b, c, d, e, a, Par, K20, W[34 & 0xf] = Wgen (W, 34));
178 SHA1STEP32 (a, b, c, d, e, Par, K20, W[35 & 0xf] = Wgen (W, 35));
179 SHA1STEP32 (e, a, b, c, d, Par, K20, W[36 & 0xf] = Wgen (W, 36));
180 SHA1STEP32 (d, e, a, b, c, Par, K20, W[37 & 0xf] = Wgen (W, 37));
181 SHA1STEP32 (c, d, e, a, b, Par, K20, W[38 & 0xf] = Wgen (W, 38));
182 SHA1STEP32 (b, c, d, e, a, Par, K20, W[39 & 0xf] = Wgen (W, 39));
183 SHA1STEP32 (a, b, c, d, e, Maj, K40, W[40 & 0xf] = Wgen (W, 40));
184 SHA1STEP32 (e, a, b, c, d, Maj, K40, W[41 & 0xf] = Wgen (W, 41));
185 SHA1STEP32 (d, e, a, b, c, Maj, K40, W[42 & 0xf] = Wgen (W, 42));
186 SHA1STEP32 (c, d, e, a, b, Maj, K40, W[43 & 0xf] = Wgen (W, 43));
187 SHA1STEP32 (b, c, d, e, a, Maj, K40, W[44 & 0xf] = Wgen (W, 44));
188 SHA1STEP32 (a, b, c, d, e, Maj, K40, W[45 & 0xf] = Wgen (W, 45));
189 SHA1STEP32 (e, a, b, c, d, Maj, K40, W[46 & 0xf] = Wgen (W, 46));
190 SHA1STEP32 (d, e, a, b, c, Maj, K40, W[47 & 0xf] = Wgen (W, 47));
191 SHA1STEP32 (c, d, e, a, b, Maj, K40, W[48 & 0xf] = Wgen (W, 48));
192 SHA1STEP32 (b, c, d, e, a, Maj, K40, W[49 & 0xf] = Wgen (W, 49));
193 SHA1STEP32 (a, b, c, d, e, Maj, K40, W[50 & 0xf] = Wgen (W, 50));
194 SHA1STEP32 (e, a, b, c, d, Maj, K40, W[51 & 0xf] = Wgen (W, 51));
195 SHA1STEP32 (d, e, a, b, c, Maj, K40, W[52 & 0xf] = Wgen (W, 52));
196 SHA1STEP32 (c, d, e, a, b, Maj, K40, W[53 & 0xf] = Wgen (W, 53));
197 SHA1STEP32 (b, c, d, e, a, Maj, K40, W[54 & 0xf] = Wgen (W, 54));
198 SHA1STEP32 (a, b, c, d, e, Maj, K40, W[55 & 0xf] = Wgen (W, 55));
199 SHA1STEP32 (e, a, b, c, d, Maj, K40, W[56 & 0xf] = Wgen (W, 56));
200 SHA1STEP32 (d, e, a, b, c, Maj, K40, W[57 & 0xf] = Wgen (W, 57));
201 SHA1STEP32 (c, d, e, a, b, Maj, K40, W[58 & 0xf] = Wgen (W, 58));
202 SHA1STEP32 (b, c, d, e, a, Maj, K40, W[59 & 0xf] = Wgen (W, 59));
203 SHA1STEP32 (a, b, c, d, e, Par, K60, W[60 & 0xf] = Wgen (W, 60));
204 SHA1STEP32 (e, a, b, c, d, Par, K60, W[61 & 0xf] = Wgen (W, 61));
205 SHA1STEP32 (d, e, a, b, c, Par, K60, W[62 & 0xf] = Wgen (W, 62));
206 SHA1STEP32 (c, d, e, a, b, Par, K60, W[63 & 0xf] = Wgen (W, 63));
207 SHA1STEP32 (b, c, d, e, a, Par, K60, W[64 & 0xf] = Wgen (W, 64));
208 SHA1STEP32 (a, b, c, d, e, Par, K60, W[65 & 0xf] = Wgen (W, 65));
209 SHA1STEP32 (e, a, b, c, d, Par, K60, W[66 & 0xf] = Wgen (W, 66));
210 SHA1STEP32 (d, e, a, b, c, Par, K60, W[67 & 0xf] = Wgen (W, 67));
211 SHA1STEP32 (c, d, e, a, b, Par, K60, W[68 & 0xf] = Wgen (W, 68));
212 SHA1STEP32 (b, c, d, e, a, Par, K60, W[69 & 0xf] = Wgen (W, 69));
213 SHA1STEP32 (a, b, c, d, e, Par, K60, W[70 & 0xf] = Wgen (W, 70));
214 SHA1STEP32 (e, a, b, c, d, Par, K60, W[71 & 0xf] = Wgen (W, 71));
215 SHA1STEP32 (d, e, a, b, c, Par, K60, W[72 & 0xf] = Wgen (W, 72));
216 SHA1STEP32 (c, d, e, a, b, Par, K60, W[73 & 0xf] = Wgen (W, 73));
217 SHA1STEP32 (b, c, d, e, a, Par, K60, W[74 & 0xf] = Wgen (W, 74));
218 SHA1STEP32 (a, b, c, d, e, Par, K60, W[75 & 0xf] = Wgen (W, 75));
219 SHA1STEP32 (e, a, b, c, d, Par, K60, W[76 & 0xf] = Wgen (W, 76));
220 SHA1STEP32 (d, e, a, b, c, Par, K60, W[77 & 0xf] = Wgen (W, 77));
221 SHA1STEP32 (c, d, e, a, b, Par, K60, W[78 & 0xf] = Wgen (W, 78));
222 SHA1STEP32 (b, c, d, e, a, Par, K60, W[79 & 0xf] = Wgen (W, 79));
223
224 /* Compute intermediate hash.
225 See FIPS PUB 180-4 paragraph 6.1.3 step 4. */
226 H[0] += a;
227 H[1] += b;
228 H[2] += c;
229 H[3] += d;
230 H[4] += e;
231}
232
233
234/**
235 * Process portion of bytes.
236 *
237 * @param ctx_ must be a `struct sha1_ctx *`
238 * @param data bytes to add to hash
239 * @param length number of bytes in @a data
240 */
241void
242MHD_SHA1_update (void *ctx_,
243 const uint8_t *data,
244 size_t length)
245{
246 struct sha1_ctx *const ctx = ctx_;
247 unsigned bytes_have; /**< Number of bytes in buffer */
248
249 mhd_assert ((data != NULL) || (length == 0));
250
251 if (0 == length)
252 return; /* Do nothing */
253
254 /* Note: (count & (SHA1_BLOCK_SIZE-1))
255 equal (count % SHA1_BLOCK_SIZE) for this block size. */
256 bytes_have = (unsigned) (ctx->count & (SHA1_BLOCK_SIZE - 1));
257 ctx->count += length;
258
259 if (0 != bytes_have)
260 {
261 unsigned bytes_left = SHA1_BLOCK_SIZE - bytes_have;
262 if (length >= bytes_left)
263 { /* Combine new data with the data in the buffer and
264 process the full block. */
265 memcpy (ctx->buffer + bytes_have,
266 data,
267 bytes_left);
268 data += bytes_left;
269 length -= bytes_left;
270 sha1_transform (ctx->H, ctx->buffer);
271 bytes_have = 0;
272 }
273 }
274
275 while (SHA1_BLOCK_SIZE <= length)
276 { /* Process any full blocks of new data directly,
277 without copying to the buffer. */
278 sha1_transform (ctx->H, data);
279 data += SHA1_BLOCK_SIZE;
280 length -= SHA1_BLOCK_SIZE;
281 }
282
283 if (0 != length)
284 { /* Copy incomplete block of new data (if any)
285 to the buffer. */
286 memcpy (ctx->buffer + bytes_have, data, length);
287 }
288}
289
290
291/**
292 * Size of "length" padding addition in bytes.
293 * See FIPS PUB 180-4 paragraph 5.1.1.
294 */
295#define SHA1_SIZE_OF_LEN_ADD (64 / 8)
296
297/**
298 * Finalise SHA-1 calculation, return digest.
299 *
300 * @param ctx_ must be a `struct sha1_ctx *`
301 * @param[out] digest set to the hash, must be #SHA1_DIGEST_SIZE bytes
302 */
303void
304MHD_SHA1_finish (void *ctx_,
305 uint8_t digest[SHA1_DIGEST_SIZE])
306{
307 struct sha1_ctx *const ctx = ctx_;
308 uint64_t num_bits; /**< Number of processed bits */
309 unsigned bytes_have; /**< Number of bytes in buffer */
310
311 num_bits = ctx->count << 3;
312 /* Note: (count & (SHA1_BLOCK_SIZE-1))
313 equal (count % SHA1_BLOCK_SIZE) for this block size. */
314 bytes_have = (unsigned) (ctx->count & (SHA1_BLOCK_SIZE - 1));
315
316 /* Input data must be padded with bit "1" and with length of data in bits.
317 See FIPS PUB 180-4 paragraph 5.1.1. */
318 /* Data is always processed in form of bytes (not by individual bits),
319 therefore position of first padding bit in byte is always predefined (0x80). */
320 /* Buffer always have space at least for one byte (as full buffers are
321 processed immediately). */
322 ctx->buffer[bytes_have++] = 0x80;
323
324 if (SHA1_BLOCK_SIZE - bytes_have < SHA1_SIZE_OF_LEN_ADD)
325 { /* No space in current block to put total length of message.
326 Pad current block with zeros and process it. */
327 if (SHA1_BLOCK_SIZE > bytes_have)
328 memset (ctx->buffer + bytes_have, 0, SHA1_BLOCK_SIZE - bytes_have);
329 /* Process full block. */
330 sha1_transform (ctx->H, ctx->buffer);
331 /* Start new block. */
332 bytes_have = 0;
333 }
334
335 /* Pad the rest of the buffer with zeros. */
336 memset (ctx->buffer + bytes_have, 0,
337 SHA1_BLOCK_SIZE - SHA1_SIZE_OF_LEN_ADD - bytes_have);
338 /* Put the number of bits in the processed message as a big-endian value. */
339 _MHD_PUT_64BIT_BE (ctx->buffer + SHA1_BLOCK_SIZE - SHA1_SIZE_OF_LEN_ADD,
340 num_bits);
341 /* Process the full final block. */
342 sha1_transform (ctx->H, ctx->buffer);
343
344 /* Put final hash/digest in BE mode */
345 _MHD_PUT_32BIT_BE (digest + 0 * SHA1_BYTES_IN_WORD, ctx->H[0]);
346 _MHD_PUT_32BIT_BE (digest + 1 * SHA1_BYTES_IN_WORD, ctx->H[1]);
347 _MHD_PUT_32BIT_BE (digest + 2 * SHA1_BYTES_IN_WORD, ctx->H[2]);
348 _MHD_PUT_32BIT_BE (digest + 3 * SHA1_BYTES_IN_WORD, ctx->H[3]);
349 _MHD_PUT_32BIT_BE (digest + 4 * SHA1_BYTES_IN_WORD, ctx->H[4]);
350
351 /* Erase potentially sensitive data. */
352 memset (ctx, 0, sizeof(struct sha1_ctx));
353}
diff --git a/src/microhttpd/sha1.h b/src/microhttpd/sha1.h
new file mode 100644
index 00000000..800a4909
--- /dev/null
+++ b/src/microhttpd/sha1.h
@@ -0,0 +1,98 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2019-2021 Karlson2k (Evgeny Grin)
4
5 This library 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/sha1.h
22 * @brief Calculation of SHA-1 digest
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#ifndef MHD_SHA1_H
27#define MHD_SHA1_H 1
28
29#include "mhd_options.h"
30#include <stdint.h>
31#include <stddef.h>
32
33/**
34 * SHA-1 digest is kept internally as 5 32-bit words.
35 */
36#define _SHA1_DIGEST_LENGTH 5
37
38/**
39 * Size of SHA-1 digest in bytes
40 */
41#define SHA1_DIGEST_SIZE (_SHA1_DIGEST_LENGTH * 4)
42
43/**
44 * Size of SHA-1 digest string in chars including termination NUL
45 */
46#define SHA1_DIGEST_STRING_SIZE ((SHA1_DIGEST_SIZE) * 2 + 1)
47
48/**
49 * Size of single processing block in bits
50 */
51#define SHA1_BLOCK_SIZE_BITS 512
52
53/**
54 * Size of single processing block in bytes
55 */
56#define SHA1_BLOCK_SIZE (SHA1_BLOCK_SIZE_BITS / 8)
57
58
59struct sha1_ctx
60{
61 uint32_t H[_SHA1_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */
62 uint8_t buffer[SHA1_BLOCK_SIZE]; /**< SHA256 input data buffer */
63 uint64_t count; /**< number of bytes, mod 2^64 */
64};
65
66/**
67 * Initialise structure for SHA-1 calculation.
68 *
69 * @param ctx must be a `struct sha1_ctx *`
70 */
71void
72MHD_SHA1_init (void *ctx_);
73
74
75/**
76 * Process portion of bytes.
77 *
78 * @param ctx_ must be a `struct sha1_ctx *`
79 * @param data bytes to add to hash
80 * @param length number of bytes in @a data
81 */
82void
83MHD_SHA1_update (void *ctx_,
84 const uint8_t *data,
85 size_t length);
86
87
88/**
89 * Finalise SHA-1 calculation, return digest.
90 *
91 * @param ctx_ must be a `struct sha1_ctx *`
92 * @param[out] digest set to the hash, must be #SHA1_DIGEST_SIZE bytes
93 */
94void
95MHD_SHA1_finish (void *ctx_,
96 uint8_t digest[SHA1_DIGEST_SIZE]);
97
98#endif /* MHD_SHA1_H */
diff --git a/src/microhttpd/test_sha1.c b/src/microhttpd/test_sha1.c
new file mode 100644
index 00000000..276c7838
--- /dev/null
+++ b/src/microhttpd/test_sha1.c
@@ -0,0 +1,417 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2019-2021 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_sha1.h
22 * @brief Unit tests for SHA-1 functions
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#include "mhd_options.h"
27#include "sha1.h"
28#include "test_helpers.h"
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32
33static int verbose = 0; /* verbose level (0-1)*/
34
35
36struct str_with_len
37{
38 const char *const str;
39 const size_t len;
40};
41
42#define D_STR_W_LEN(s) {(s), (sizeof((s)) / sizeof(char)) - 1}
43
44struct data_unit1
45{
46 const struct str_with_len str_l;
47 const uint8_t digest[SHA1_DIGEST_SIZE];
48};
49
50static const struct data_unit1 data_units1[] = {
51 {D_STR_W_LEN ("abc"),
52 {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 0x25, 0x71,
53 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D}},
54 {D_STR_W_LEN ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
55 {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1,
56 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1}},
57 {D_STR_W_LEN (""),
58 {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef,
59 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09}},
60 {D_STR_W_LEN ("The quick brown fox jumps over the lazy dog"),
61 {0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28, 0xfc, 0xed, 0x84, 0x9e, 0xe1,
62 0xbb, 0x76, 0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12}},
63 {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."),
64 {0xa7, 0x08, 0x9e, 0x3d, 0xe1, 0x6b, 0x63, 0xa3, 0x2a, 0x43, 0xa5, 0xe7,
65 0xf3, 0xb5, 0x4f, 0x80, 0x6a, 0xc8, 0x4f, 0x53}},
66 {D_STR_W_LEN ("Simple string."),
67 {0x6c, 0x6c, 0x9c, 0xef, 0x53, 0xff, 0x22, 0x39, 0x0c, 0x54, 0xc7, 0xba,
68 0x6d, 0x98, 0xe0, 0xd5, 0x6c, 0x24, 0x0d, 0x55}},
69 {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"),
70 {0x32, 0xd1, 0x0c, 0x7b, 0x8c, 0xf9, 0x65, 0x70, 0xca, 0x04, 0xce, 0x37,
71 0xf2, 0xa1, 0x9d, 0x84, 0x24, 0x0d, 0x3a, 0x89}},
72 {D_STR_W_LEN ("zyxwvutsrqponMLKJIHGFEDCBA"),
73 {0x59, 0x0f, 0xc8, 0xea, 0xde, 0xa2, 0x78, 0x65, 0x5a, 0xf2, 0xa1, 0xe5,
74 0xb4, 0xc9, 0x61, 0xa4, 0x3a, 0xc3, 0x6a, 0x83}},
75 {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"
76 "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"),
77 {0xa7, 0x87, 0x4c, 0x16, 0xc0, 0x4e, 0xd6, 0x24, 0x5f, 0x25, 0xbe, 0x06,
78 0x7b, 0x1b, 0x6b, 0xaf, 0xf4, 0x0e, 0x74, 0x0b}},
79};
80
81static const size_t units1_num = sizeof(data_units1) / sizeof(data_units1[0]);
82
83struct bin_with_len
84{
85 const uint8_t bin[512];
86 const size_t len;
87};
88
89struct data_unit2
90{
91 const struct bin_with_len bin_l;
92 const uint8_t digest[SHA1_DIGEST_SIZE];
93};
94
95/* Size must be less than 512 bytes! */
96static const struct data_unit2 data_units2[] = {
97 { { {97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
98 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122}, 26}, /* a..z ASCII sequence */
99 {0x32, 0xd1, 0x0c, 0x7b, 0x8c, 0xf9, 0x65, 0x70, 0xca, 0x04, 0xce, 0x37,
100 0xf2, 0xa1, 0x9d, 0x84, 0x24, 0x0d, 0x3a, 0x89}},
101 { { {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
102 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
103 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
104 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65},
105 72 }, /* 'A' x 72 times */
106 {0x41, 0xf9, 0x07, 0x05, 0x04, 0xf9, 0xc8, 0x1a, 0xbf, 0xbb, 0x61, 0x4d,
107 0xaa, 0xec, 0x3b, 0x26, 0xa2, 0xf9, 0x23, 0x7e}},
108 { { {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
109 37, 38, 39, 40, 41, 42,43, 44, 45, 46, 47, 48, 49, 50, 51, 52,53, 54,
110 55, 56, 57, 58, 59, 60,61, 62, 63, 64, 65, 66, 67,68, 69, 70, 71, 72,
111 73}, 55}, /* 19..73 sequence */
112 {0xf2, 0x50, 0xb2, 0x79, 0x62, 0xcc, 0xff, 0x4b, 0x1b, 0x61, 0x4a, 0x6f,
113 0x80, 0xec, 0x9b, 0x4d, 0xd0, 0xc0, 0xfb, 0x7b}},
114 { { {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
115 26, 27, 28, 29, 30, 31,32, 33, 34, 35, 36, 37, 38, 39, 40, 41,42, 43,
116 44, 45, 46, 47, 48, 49,50, 51, 52, 53, 54, 55, 56,57, 58, 59, 60, 61,
117 62, 63, 64, 65, 66, 67, 68, 69}, 63}, /* 7..69 sequence */
118 {0xf0, 0xa3, 0xfc, 0x4b, 0x90, 0x6f, 0x1b, 0x41, 0x68, 0xc8, 0x3e, 0x05,
119 0xb0, 0xc5, 0xac, 0xb7, 0x3d, 0xcd, 0x6b, 0x0f}},
120 { { {38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
121 56, 57, 58, 59, 60, 61,62, 63, 64, 65, 66, 67, 68, 69, 70, 71,72, 73,
122 74, 75, 76, 77, 78, 79,80, 81, 82, 83, 84, 85, 86,87, 88, 89, 90, 91,
123 92}, 55}, /* 38..92 sequence */
124 {0x93, 0xa4, 0x9c, 0x5f, 0xda, 0x22, 0x63, 0x73, 0x85, 0xeb, 0x70, 0xd2,
125 0x00, 0x52, 0x0c, 0xb0, 0x2e, 0x86, 0x9b, 0xa0 }},
126 { { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,21,
127 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,37, 38, 39,
128 40, 41, 42, 43, 44, 45,46, 47, 48, 49, 50, 51, 52,53, 54, 55, 56, 57,
129 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,71, 72},72}, /* 1..72 sequence */
130 {0x8b, 0x30, 0xd3, 0x41, 0x89, 0xb6, 0x1b, 0x66, 0x5a, 0x1a, 0x9a, 0x51,
131 0x64, 0x93, 0xab, 0x5e, 0x78, 0x81, 0x52, 0xb5}},
132 { { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
133 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,37, 38,
134 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,52, 53, 54, 55, 56,
135 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,70, 71, 72, 73, 74,
136 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,86, 87, 88, 89, 90, 91, 92,
137 93, 94, 95, 96, 97, 98, 99, 100,101, 102, 103, 104, 105, 106, 107, 108,
138 109, 110, 111, 112, 113, 114,115, 116, 117, 118, 119, 120, 121, 122,
139 123, 124, 125, 126, 127,128, 129, 130, 131, 132, 133, 134, 135, 136,
140 137, 138, 139, 140,141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
141 151, 152, 153, 154,155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
142 165, 166, 167,168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
143 179, 180,181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
144 193, 194,195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
145 207,208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,221,
146 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,235,
147 236, 237, 238, 239, 240,241, 242, 243, 244, 245, 246, 247,248, 249, 250,
148 251, 252, 253, 254, 255}, 256}, /* 0..255 sequence */
149 {0x49, 0x16, 0xd6, 0xbd, 0xb7, 0xf7, 0x8e, 0x68, 0x03, 0x69, 0x8c, 0xab,
150 0x32, 0xd1, 0x58, 0x6e, 0xa4, 0x57, 0xdf, 0xc8}},
151 { { {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,185,
152 184, 183, 182, 181, 180,179, 178, 177, 176, 175, 174, 173,172, 171, 170,
153 169, 168, 167, 166,165, 164, 163, 162, 161, 160,159, 158, 157, 156, 155,
154 154, 153, 152, 151, 150, 149, 148, 147, 146,145, 144, 143, 142, 141,
155 140,139}, 61}, /* 199..139 sequence */
156 {0xb3, 0xec, 0x61, 0x3c, 0xf7, 0x36, 0x57, 0x94, 0x61, 0xdb, 0xb2, 0x16,
157 0x75, 0xfe, 0x34, 0x60, 0x99, 0x94, 0xb5, 0xfc}},
158 { { {255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242,
159 241, 240, 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228,
160 227, 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214,
161 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200,
162 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
163 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, 172,
164 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, 159, 158,
165 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144,
166 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130,
167 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116,
168 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102,
169 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85,
170 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67,
171 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,
172 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31,
173 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,
174 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 255}, /* 255..1 sequence */
175 {0x99, 0x1d, 0xc6, 0x95, 0xe1, 0xaa, 0xcc, 0xc9, 0x35, 0x60, 0xbe, 0xe3,
176 0xe2, 0x41, 0x2b, 0xa7, 0xab, 0x49, 0x32, 0xf7}},
177 { { {41, 35, 190, 132, 225, 108, 214, 174, 82, 144, 73, 241, 241, 187, 233,
178 235, 179, 166, 219, 60, 135, 12, 62, 153, 36, 94, 13, 28, 6, 183, 71,
179 222, 179, 18, 77, 200, 67, 187, 139, 166, 31, 3, 90, 125, 9, 56, 37, 31,
180 93, 212, 203, 252, 150, 245, 69, 59, 19, 13, 137, 10, 28, 219, 174, 50,
181 32, 154, 80, 238, 64, 120, 54, 253, 18, 73, 50, 246, 158, 125, 73, 220,
182 173, 79, 20, 242, 68, 64, 102, 208, 107, 196, 48, 183, 50, 59, 161, 34,
183 246, 34, 145, 157, 225, 139, 31, 218, 176, 202, 153, 2, 185, 114, 157,
184 73, 44, 128, 126, 197, 153, 213, 233, 128, 178, 234, 201, 204, 83, 191,
185 103, 214, 191, 20, 214, 126, 45, 220, 142, 102, 131, 239, 87, 73, 97,
186 255, 105, 143, 97, 205, 209, 30, 157, 156, 22, 114, 114, 230, 29, 240,
187 132, 79, 74, 119, 2, 215, 232, 57, 44, 83, 203, 201, 18, 30, 51, 116,
188 158, 12, 244, 213, 212, 159, 212, 164, 89, 126, 53, 207, 50, 34, 244,
189 204, 207, 211, 144, 45, 72, 211, 143, 117, 230, 217, 29, 42, 229, 192,
190 247, 43, 120, 129, 135, 68, 14, 95, 80, 0, 212, 97, 141, 190, 123, 5,
191 21, 7, 59, 51, 130, 31, 24, 112, 146, 218, 100, 84, 206, 177, 133, 62,
192 105, 21, 248, 70, 106, 4, 150, 115, 14, 217, 22, 47, 103, 104, 212, 247,
193 74, 74, 208, 87, 104}, 255}, /* pseudo-random data */
194 {0x9e, 0xb6, 0xce, 0x48, 0xf4, 0x6e, 0x9c, 0xf4, 0x1b, 0x4f, 0x9f, 0x66,
195 0xdd, 0xe8, 0x41, 0x01, 0x71, 0xf6, 0xf5, 0xd6}}
196};
197
198static const size_t units2_num = sizeof(data_units2) / sizeof(data_units2[0]);
199
200
201/*
202 * Helper functions
203 */
204
205/**
206 * Print bin as hex
207 *
208 * @param bin binary data
209 * @param len number of bytes in bin
210 * @param hex pointer to len*2+1 bytes buffer
211 */
212static void
213bin2hex (const uint8_t *bin,
214 size_t len,
215 char *hex)
216{
217 while (len-- > 0)
218 {
219 unsigned int b1, b2;
220 b1 = (*bin >> 4) & 0xf;
221 *hex++ = (char) ((b1 > 9) ? (b1 + 'A' - 10) : (b1 + '0'));
222 b2 = *bin++ & 0xf;
223 *hex++ = (char) ((b2 > 9) ? (b2 + 'A' - 10) : (b2 + '0'));
224 }
225 *hex = 0;
226}
227
228
229static int
230check_result (const char *test_name,
231 unsigned int check_num,
232 const uint8_t calculated[SHA1_DIGEST_SIZE],
233 const uint8_t expected[SHA1_DIGEST_SIZE])
234{
235 int failed = memcmp (calculated, expected, SHA1_DIGEST_SIZE);
236 check_num++; /* Print 1-based numbers */
237 if (failed)
238 {
239 char calc_str[SHA1_DIGEST_STRING_SIZE];
240 char expc_str[SHA1_DIGEST_STRING_SIZE];
241 bin2hex (calculated, SHA1_DIGEST_SIZE, calc_str);
242 bin2hex (expected, SHA1_DIGEST_SIZE, expc_str);
243 fprintf (stderr,
244 "FAILED: %s check %u: calculated digest %s, expected digest %s.\n",
245 test_name, check_num, calc_str, expc_str);
246 fflush (stderr);
247 }
248 else if (verbose)
249 {
250 char calc_str[SHA1_DIGEST_STRING_SIZE];
251 bin2hex (calculated, SHA1_DIGEST_SIZE, calc_str);
252 printf (
253 "PASSED: %s check %u: calculated digest %s matches expected digest.\n",
254 test_name, check_num, calc_str);
255 fflush (stdout);
256 }
257 return failed ? 1 : 0;
258}
259
260
261/*
262 * Tests
263 */
264
265/* Calculated SHA-256 as one pass for whole data */
266static int
267test1_str (void)
268{
269 int num_failed = 0;
270 unsigned int i;
271
272 for (i = 0; i < units1_num; i++)
273 {
274 struct sha1_ctx ctx;
275 uint8_t digest[SHA1_DIGEST_SIZE];
276
277 MHD_SHA1_init (&ctx);
278 MHD_SHA1_update (&ctx, (const uint8_t*) data_units1[i].str_l.str,
279 data_units1[i].str_l.len);
280 MHD_SHA1_finish (&ctx, digest);
281 num_failed += check_result (__FUNCTION__, i, digest,
282 data_units1[i].digest);
283 }
284 return num_failed;
285}
286
287
288static int
289test1_bin (void)
290{
291 int num_failed = 0;
292 unsigned int i;
293
294 for (i = 0; i < units2_num; i++)
295 {
296 struct sha1_ctx ctx;
297 uint8_t digest[SHA1_DIGEST_SIZE];
298
299 MHD_SHA1_init (&ctx);
300 MHD_SHA1_update (&ctx, data_units2[i].bin_l.bin,
301 data_units2[i].bin_l.len);
302 MHD_SHA1_finish (&ctx, digest);
303 num_failed += check_result (__FUNCTION__, i, digest,
304 data_units2[i].digest);
305 }
306 return num_failed;
307}
308
309
310/* Calculated SHA-256 as two iterations for whole data */
311static int
312test2_str (void)
313{
314 int num_failed = 0;
315 unsigned int i;
316
317 for (i = 0; i < units1_num; i++)
318 {
319 struct sha1_ctx ctx;
320 uint8_t digest[SHA1_DIGEST_SIZE];
321 size_t part_s = data_units1[i].str_l.len / 4;
322
323 MHD_SHA1_init (&ctx);
324 MHD_SHA1_update (&ctx, (const uint8_t*) data_units1[i].str_l.str, part_s);
325 MHD_SHA1_update (&ctx, (const uint8_t*) data_units1[i].str_l.str + part_s,
326 data_units1[i].str_l.len - part_s);
327 MHD_SHA1_finish (&ctx, digest);
328 num_failed += check_result (__FUNCTION__, i, digest,
329 data_units1[i].digest);
330 }
331 return num_failed;
332}
333
334
335static int
336test2_bin (void)
337{
338 int num_failed = 0;
339 unsigned int i;
340
341 for (i = 0; i < units2_num; i++)
342 {
343 struct sha1_ctx ctx;
344 uint8_t digest[SHA1_DIGEST_SIZE];
345 size_t part_s = data_units2[i].bin_l.len * 2 / 3;
346
347 MHD_SHA1_init (&ctx);
348 MHD_SHA1_update (&ctx, data_units2[i].bin_l.bin, part_s);
349 MHD_SHA1_update (&ctx, data_units2[i].bin_l.bin + part_s,
350 data_units2[i].bin_l.len - part_s);
351 MHD_SHA1_finish (&ctx, digest);
352 num_failed += check_result (__FUNCTION__, i, digest,
353 data_units2[i].digest);
354 }
355 return num_failed;
356}
357
358
359/* Use data set number 7 as it is the longest sequence */
360#define DATA_POS 6
361#define MAX_OFFSET 31
362
363static int
364test_unaligned (void)
365{
366 int num_failed = 0;
367 unsigned int offset;
368 uint8_t *buf;
369 uint8_t *digest_buf;
370
371 const struct data_unit2 *const tdata = data_units2 + DATA_POS;
372
373 buf = malloc (tdata->bin_l.len + MAX_OFFSET);
374 digest_buf = malloc (SHA1_DIGEST_SIZE + MAX_OFFSET);
375 if ((NULL == buf) || (NULL == digest_buf))
376 _exit (99);
377
378 for (offset = MAX_OFFSET; offset >= 1; --offset)
379 {
380 struct sha1_ctx ctx;
381 uint8_t *unaligned_digest;
382 uint8_t *unaligned_buf;
383
384 unaligned_buf = buf + offset;
385 memcpy (unaligned_buf, tdata->bin_l.bin, tdata->bin_l.len);
386 unaligned_digest = digest_buf + MAX_OFFSET - offset;
387 memset (unaligned_digest, 0, SHA1_DIGEST_SIZE);
388
389 MHD_SHA1_init (&ctx);
390 MHD_SHA1_update (&ctx, unaligned_buf, tdata->bin_l.len);
391 MHD_SHA1_finish (&ctx, unaligned_digest);
392 num_failed += check_result (__FUNCTION__, MAX_OFFSET - offset,
393 unaligned_digest, tdata->digest);
394 }
395 free (buf);
396 return num_failed;
397}
398
399
400int
401main (int argc, char *argv[])
402{
403 int num_failed = 0;
404 (void) has_in_name; /* Mute compiler warning. */
405 if (has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose"))
406 verbose = 1;
407
408 num_failed += test1_str ();
409 num_failed += test1_bin ();
410
411 num_failed += test2_str ();
412 num_failed += test2_bin ();
413
414 num_failed += test_unaligned ();
415
416 return num_failed ? 1 : 0;
417}