aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-05-18 22:17:29 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-05-18 22:17:29 +0300
commitf959b8435217a903d0b5ddaa2deaa23af54812ab (patch)
tree27cea2f945fde723aabd0e1a6e6c6a79e4e75fd6
parent7b3e010b6159017b65a1621478fc7b22e34df119 (diff)
downloadlibmicrohttpd-f959b8435217a903d0b5ddaa2deaa23af54812ab.tar.gz
libmicrohttpd-f959b8435217a903d0b5ddaa2deaa23af54812ab.zip
Fixed unaligned data processing in SHA-256 and MD5
-rw-r--r--src/microhttpd/md5.c79
-rw-r--r--src/microhttpd/mhd_bithelpers.h32
-rw-r--r--src/microhttpd/sha1.c2
-rw-r--r--src/microhttpd/sha1.h2
-rw-r--r--src/microhttpd/sha256.c68
-rw-r--r--src/microhttpd/sha256.h23
6 files changed, 160 insertions, 46 deletions
diff --git a/src/microhttpd/md5.c b/src/microhttpd/md5.c
index 05a2c9e6..785873b5 100644
--- a/src/microhttpd/md5.c
+++ b/src/microhttpd/md5.c
@@ -26,6 +26,12 @@
26#include "mhd_bithelpers.h" 26#include "mhd_bithelpers.h"
27#include "mhd_assert.h" 27#include "mhd_assert.h"
28 28
29/**
30 * Number of bytes in single MD5 word
31 * used to process data
32 */
33#define MD5_BYTES_IN_WORD (32 / 8)
34
29 35
30/** 36/**
31 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 37 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
@@ -87,26 +93,37 @@ MHD_MD5Final (void *ctx_,
87 93
88 /* Put number of bits */ 94 /* Put number of bits */
89 count_bits = ctx->count << 3; 95 count_bits = ctx->count << 3;
90 _MHD_PUT_64BIT_LE (ctx->buffer + 56, count_bits); 96 _MHD_PUT_64BIT_LE_SAFE (ctx->buffer + 56, count_bits);
91 MD5Transform (ctx->state, ctx->buffer); 97 MD5Transform (ctx->state, ctx->buffer);
92 98
93 /* Put digest in LE mode */ 99 /* Put digest in LE mode */
94 _MHD_PUT_32BIT_LE (digest, ctx->state[0]); 100#ifndef _MHD_PUT_32BIT_LE_UNALIGNED
95 _MHD_PUT_32BIT_LE (digest + 4, ctx->state[1]); 101 if (0 != ((uintptr_t) digest) % _MHD_UINT32_ALIGN)
96 _MHD_PUT_32BIT_LE (digest + 8, ctx->state[2]); 102 {
97 _MHD_PUT_32BIT_LE (digest + 12, ctx->state[3]); 103 uint32_t alig_dgst[MD5_DIGEST_SIZE / MD5_BYTES_IN_WORD];
104 _MHD_PUT_32BIT_LE (alig_dgst + 0, ctx->state[0]);
105 _MHD_PUT_32BIT_LE (alig_dgst + 1, ctx->state[1]);
106 _MHD_PUT_32BIT_LE (alig_dgst + 2, ctx->state[2]);
107 _MHD_PUT_32BIT_LE (alig_dgst + 3, ctx->state[3]);
108 /* Copy result to unaligned destination address */
109 memcpy (digest, alig_dgst, MD5_DIGEST_SIZE);
110 }
111 else
112#else /* _MHD_PUT_32BIT_LE_UNALIGNED */
113 if (1)
114#endif /* _MHD_PUT_32BIT_LE_UNALIGNED */
115 {
116 _MHD_PUT_32BIT_LE (digest, ctx->state[0]);
117 _MHD_PUT_32BIT_LE (digest + 4, ctx->state[1]);
118 _MHD_PUT_32BIT_LE (digest + 8, ctx->state[2]);
119 _MHD_PUT_32BIT_LE (digest + 12, ctx->state[3]);
120 }
98 121
99 /* Erase buffer */ 122 /* Erase buffer */
100 memset (ctx, 0, sizeof(*ctx)); 123 memset (ctx, 0, sizeof(*ctx));
101} 124}
102 125
103 126
104/**
105 * Number of bytes in single SHA-256 word
106 * used to process data
107 */
108#define MD5_BYTES_IN_WORD (32 / 8)
109
110/* The four core functions - F1 is optimized somewhat */ 127/* The four core functions - F1 is optimized somewhat */
111 128
112/* #define F1(x, y, z) (x & y | ~x & z) */ 129/* #define F1(x, y, z) (x & y | ~x & z) */
@@ -129,18 +146,40 @@ MD5Transform (uint32_t state[4],
129 const uint8_t block[MD5_BLOCK_SIZE]) 146 const uint8_t block[MD5_BLOCK_SIZE])
130{ 147{
131 uint32_t a, b, c, d; 148 uint32_t a, b, c, d;
149 uint32_t data_buf[MD5_BLOCK_SIZE / MD5_BYTES_IN_WORD];
150 const uint32_t *in;
132 151
133#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN 152#if (_MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN) || \
134 const uint32_t *in = (const uint32_t *) block; 153 ! defined (_MHD_GET_32BIT_LE_UNALIGNED)
135#else 154 if (0 != (((uintptr_t) block) % _MHD_UINT32_ALIGN))
136 uint32_t in[MD5_BLOCK_SIZE / MD5_BYTES_IN_WORD];
137 int i;
138
139 for (i = 0; i < MD5_BLOCK_SIZE / MD5_BYTES_IN_WORD; i++)
140 { 155 {
141 in[i] = _MHD_GET_32BIT_LE (block + i * MD5_BYTES_IN_WORD); 156 /* Copy data to the aligned buffer */
157 memcpy (data_buf, block, MD5_BLOCK_SIZE);
158 in = data_buf;
142 } 159 }
143#endif 160 else
161 in = (const uint32_t *) block;
162#endif /* _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN) || \
163 ! _MHD_GET_32BIT_LE_UNALIGNED */
164#if _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN
165 data_buf[0] = _MHD_GET_32BIT_LE (in + 0);
166 data_buf[1] = _MHD_GET_32BIT_LE (in + 1);
167 data_buf[2] = _MHD_GET_32BIT_LE (in + 2);
168 data_buf[3] = _MHD_GET_32BIT_LE (in + 3);
169 data_buf[4] = _MHD_GET_32BIT_LE (in + 4);
170 data_buf[5] = _MHD_GET_32BIT_LE (in + 5);
171 data_buf[6] = _MHD_GET_32BIT_LE (in + 6);
172 data_buf[7] = _MHD_GET_32BIT_LE (in + 7);
173 data_buf[8] = _MHD_GET_32BIT_LE (in + 8);
174 data_buf[9] = _MHD_GET_32BIT_LE (in + 9);
175 data_buf[10] = _MHD_GET_32BIT_LE (in + 10);
176 data_buf[11] = _MHD_GET_32BIT_LE (in + 11);
177 data_buf[12] = _MHD_GET_32BIT_LE (in + 12);
178 data_buf[13] = _MHD_GET_32BIT_LE (in + 13);
179 data_buf[14] = _MHD_GET_32BIT_LE (in + 14);
180 data_buf[15] = _MHD_GET_32BIT_LE (in + 15);
181 in = data_buf;
182#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
144 183
145 a = state[0]; 184 a = state[0];
146 b = state[1]; 185 b = state[1];
diff --git a/src/microhttpd/mhd_bithelpers.h b/src/microhttpd/mhd_bithelpers.h
index 12e1a569..9bd2df79 100644
--- a/src/microhttpd/mhd_bithelpers.h
+++ b/src/microhttpd/mhd_bithelpers.h
@@ -99,6 +99,17 @@
99 * put native-endian 64-bit value64 to addr 99 * put native-endian 64-bit value64 to addr
100 * in little-endian mode. 100 * in little-endian mode.
101 */ 101 */
102/* Slow version that works with unaligned addr and with any bytes order */
103#define _MHD_PUT_64BIT_LE_SLOW(addr, value64) do { \
104 ((uint8_t*) (addr))[0] = (uint8_t) ((uint64_t) (value64)); \
105 ((uint8_t*) (addr))[1] = (uint8_t) (((uint64_t) (value64)) >> 8); \
106 ((uint8_t*) (addr))[2] = (uint8_t) (((uint64_t) (value64)) >> 16); \
107 ((uint8_t*) (addr))[3] = (uint8_t) (((uint64_t) (value64)) >> 24); \
108 ((uint8_t*) (addr))[4] = (uint8_t) (((uint64_t) (value64)) >> 32); \
109 ((uint8_t*) (addr))[5] = (uint8_t) (((uint64_t) (value64)) >> 40); \
110 ((uint8_t*) (addr))[6] = (uint8_t) (((uint64_t) (value64)) >> 48); \
111 ((uint8_t*) (addr))[7] = (uint8_t) (((uint64_t) (value64)) >> 56); \
112} while (0)
102#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN 113#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
103#define _MHD_PUT_64BIT_LE(addr, value64) \ 114#define _MHD_PUT_64BIT_LE(addr, value64) \
104 ((*(uint64_t*) (addr)) = (uint64_t) (value64)) 115 ((*(uint64_t*) (addr)) = (uint64_t) (value64))
@@ -117,8 +128,23 @@
117 ((uint8_t*) (addr))[6] = (uint8_t) (((uint64_t) (value64)) >> 48); \ 128 ((uint8_t*) (addr))[6] = (uint8_t) (((uint64_t) (value64)) >> 48); \
118 ((uint8_t*) (addr))[7] = (uint8_t) (((uint64_t) (value64)) >> 56); \ 129 ((uint8_t*) (addr))[7] = (uint8_t) (((uint64_t) (value64)) >> 56); \
119} while (0) 130} while (0)
131/* Indicate that _MHD_PUT_64BIT_LE does not need aligned pointer */
132#define _MHD_PUT_64BIT_LE_UNALIGNED 1
120#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ 133#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
121 134
135/* Put result safely to unaligned address */
136_MHD_static_inline void
137_MHD_PUT_64BIT_LE_SAFE (void *dst, uint64_t value)
138{
139#ifndef _MHD_PUT_64BIT_LE_UNALIGNED
140 if (0 != ((uintptr_t) dst) % (_MHD_UINT64_ALIGN))
141 _MHD_PUT_64BIT_LE_SLOW (dst, value);
142 else
143#endif /* ! _MHD_PUT_64BIT_BE_UNALIGNED */
144 _MHD_PUT_64BIT_LE (dst, value);
145}
146
147
122/* _MHD_PUT_32BIT_LE (addr, value32) 148/* _MHD_PUT_32BIT_LE (addr, value32)
123 * put native-endian 32-bit value32 to addr 149 * put native-endian 32-bit value32 to addr
124 * in little-endian mode. 150 * in little-endian mode.
@@ -137,6 +163,8 @@
137 ((uint8_t*) (addr))[2] = (uint8_t) (((uint32_t) (value32)) >> 16); \ 163 ((uint8_t*) (addr))[2] = (uint8_t) (((uint32_t) (value32)) >> 16); \
138 ((uint8_t*) (addr))[3] = (uint8_t) (((uint32_t) (value32)) >> 24); \ 164 ((uint8_t*) (addr))[3] = (uint8_t) (((uint32_t) (value32)) >> 24); \
139} while (0) 165} while (0)
166/* Indicate that _MHD_PUT_32BIT_LE does not need aligned pointer */
167#define _MHD_PUT_32BIT_LE_UNALIGNED 1
140#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ 168#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
141 169
142/* _MHD_GET_32BIT_LE (addr) 170/* _MHD_GET_32BIT_LE (addr)
@@ -156,6 +184,8 @@
156 | (((uint32_t) (((const uint8_t*) addr)[1])) << 8) \ 184 | (((uint32_t) (((const uint8_t*) addr)[1])) << 8) \
157 | (((uint32_t) (((const uint8_t*) addr)[2])) << 16) \ 185 | (((uint32_t) (((const uint8_t*) addr)[2])) << 16) \
158 | (((uint32_t) (((const uint8_t*) addr)[3])) << 24) ) 186 | (((uint32_t) (((const uint8_t*) addr)[3])) << 24) )
187/* Indicate that _MHD_GET_32BIT_LE does not need aligned pointer */
188#define _MHD_GET_32BIT_LE_UNALIGNED 1
159#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ 189#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
160 190
161 191
@@ -195,7 +225,7 @@ _MHD_PUT_64BIT_BE_SAFE (void *dst, uint64_t value)
195 if (0 != ((uintptr_t) dst) % (_MHD_UINT64_ALIGN)) 225 if (0 != ((uintptr_t) dst) % (_MHD_UINT64_ALIGN))
196 _MHD_PUT_64BIT_BE_SLOW (dst, value); 226 _MHD_PUT_64BIT_BE_SLOW (dst, value);
197 else 227 else
198#endif /* _MHD_BYTE_ORDER_IS_BIG_OR_LITTLE_ENDIAN */ 228#endif /* ! _MHD_PUT_64BIT_BE_UNALIGNED */
199 _MHD_PUT_64BIT_BE (dst, value); 229 _MHD_PUT_64BIT_BE (dst, value);
200} 230}
201 231
diff --git a/src/microhttpd/sha1.c b/src/microhttpd/sha1.c
index 2ed84208..5d4a5b93 100644
--- a/src/microhttpd/sha1.c
+++ b/src/microhttpd/sha1.c
@@ -109,7 +109,7 @@ sha1_transform (uint32_t H[_SHA1_DIGEST_LENGTH],
109 _MHD_GET_32BIT_BE (((const uint8_t*) (buf)) + (t) * SHA1_BYTES_IN_WORD) 109 _MHD_GET_32BIT_BE (((const uint8_t*) (buf)) + (t) * SHA1_BYTES_IN_WORD)
110 110
111#ifndef _MHD_GET_32BIT_BE_UNALIGNED 111#ifndef _MHD_GET_32BIT_BE_UNALIGNED
112 if (0 != ((size_t) data % _MHD_UINT32_ALIGN)) 112 if (0 != (((uintptr_t) data) % _MHD_UINT32_ALIGN))
113 { 113 {
114 /* Copy the unaligned input data to the aligned buffer */ 114 /* Copy the unaligned input data to the aligned buffer */
115 memcpy (W, data, SHA1_BLOCK_SIZE); 115 memcpy (W, data, SHA1_BLOCK_SIZE);
diff --git a/src/microhttpd/sha1.h b/src/microhttpd/sha1.h
index 59f00217..3464f268 100644
--- a/src/microhttpd/sha1.h
+++ b/src/microhttpd/sha1.h
@@ -36,7 +36,7 @@
36#define _SHA1_DIGEST_LENGTH 5 36#define _SHA1_DIGEST_LENGTH 5
37 37
38/** 38/**
39 * Number of bytes in single SHA-1 word 39 * Number of bits in single SHA-1 word
40 */ 40 */
41#define SHA1_WORD_SIZE_BITS 32 41#define SHA1_WORD_SIZE_BITS 32
42 42
diff --git a/src/microhttpd/sha256.c b/src/microhttpd/sha256.c
index 80c41eb5..df6a1aa3 100644
--- a/src/microhttpd/sha256.c
+++ b/src/microhttpd/sha256.c
@@ -60,12 +60,6 @@ MHD_SHA256_init (void *ctx_)
60 60
61 61
62/** 62/**
63 * Number of bytes in single SHA-256 word
64 * used to process data
65 */
66#define SHA256_BYTES_IN_WORD 4
67
68/**
69 * Base of SHA-256 transformation. 63 * Base of SHA-256 transformation.
70 * Gets full 64 bytes block of data and updates hash values; 64 * Gets full 64 bytes block of data and updates hash values;
71 * @param H hash values 65 * @param H hash values
@@ -126,6 +120,18 @@ sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH],
126 (vD) += ((vH) += SIG1 ((vE)) + Ch ((vE),(vF),(vG)) + (kt) + (wt)); \ 120 (vD) += ((vH) += SIG1 ((vE)) + Ch ((vE),(vF),(vG)) + (kt) + (wt)); \
127 (vH) += SIG0 ((vA)) + Maj ((vA),(vB),(vC)); } while (0) 121 (vH) += SIG0 ((vA)) + Maj ((vA),(vB),(vC)); } while (0)
128 122
123#ifndef _MHD_GET_32BIT_BE_UNALIGNED
124 if (0 != (((uintptr_t) data) % _MHD_UINT32_ALIGN))
125 {
126 /* Copy the unaligned input data to the aligned buffer */
127 memcpy (W, data, SHA256_BLOCK_SIZE);
128 /* The W[] buffer itself will be used as the source of the data,
129 * but data will be reloaded in correct bytes order during
130 * the next steps */
131 data = (uint8_t*) W;
132 }
133#endif /* _MHD_GET_32BIT_BE_UNALIGNED */
134
129 /* Get value of W(t) from input data buffer, 135 /* Get value of W(t) from input data buffer,
130 See FIPS PUB 180-4 paragraph 6.2. 136 See FIPS PUB 180-4 paragraph 6.2.
131 Input data must be read in big-endian bytes order, 137 Input data must be read in big-endian bytes order,
@@ -267,7 +273,7 @@ MHD_SHA256_update (void *ctx_,
267 return; /* Do nothing */ 273 return; /* Do nothing */
268 274
269 /* Note: (count & (SHA256_BLOCK_SIZE-1)) 275 /* Note: (count & (SHA256_BLOCK_SIZE-1))
270 equal (count % SHA256_BLOCK_SIZE) for this block size. */ 276 equals (count % SHA256_BLOCK_SIZE) for this block size. */
271 bytes_have = (unsigned) (ctx->count & (SHA256_BLOCK_SIZE - 1)); 277 bytes_have = (unsigned) (ctx->count & (SHA256_BLOCK_SIZE - 1));
272 ctx->count += length; 278 ctx->count += length;
273 279
@@ -275,7 +281,7 @@ MHD_SHA256_update (void *ctx_,
275 { 281 {
276 unsigned bytes_left = SHA256_BLOCK_SIZE - bytes_have; 282 unsigned bytes_left = SHA256_BLOCK_SIZE - bytes_have;
277 if (length >= bytes_left) 283 if (length >= bytes_left)
278 { /* Combine new data with data in buffer and 284 { /* Combine new data with data in the buffer and
279 process full block. */ 285 process full block. */
280 memcpy (ctx->buffer + bytes_have, 286 memcpy (ctx->buffer + bytes_have,
281 data, 287 data,
@@ -289,7 +295,7 @@ MHD_SHA256_update (void *ctx_,
289 295
290 while (SHA256_BLOCK_SIZE <= length) 296 while (SHA256_BLOCK_SIZE <= length)
291 { /* Process any full blocks of new data directly, 297 { /* Process any full blocks of new data directly,
292 without copying to buffer. */ 298 without copying to the buffer. */
293 sha256_transform (ctx->H, data); 299 sha256_transform (ctx->H, data);
294 data += SHA256_BLOCK_SIZE; 300 data += SHA256_BLOCK_SIZE;
295 length -= SHA256_BLOCK_SIZE; 301 length -= SHA256_BLOCK_SIZE;
@@ -297,7 +303,7 @@ MHD_SHA256_update (void *ctx_,
297 303
298 if (0 != length) 304 if (0 != length)
299 { /* Copy incomplete block of new data (if any) 305 { /* Copy incomplete block of new data (if any)
300 to buffer. */ 306 to the buffer. */
301 memcpy (ctx->buffer + bytes_have, data, length); 307 memcpy (ctx->buffer + bytes_have, data, length);
302 } 308 }
303} 309}
@@ -351,20 +357,42 @@ MHD_SHA256_finish (void *ctx_,
351 memset (ctx->buffer + bytes_have, 0, 357 memset (ctx->buffer + bytes_have, 0,
352 SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD - bytes_have); 358 SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD - bytes_have);
353 /* Put number of bits in processed message as big-endian value. */ 359 /* Put number of bits in processed message as big-endian value. */
354 _MHD_PUT_64BIT_BE (ctx->buffer + SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD, 360 _MHD_PUT_64BIT_BE_SAFE (ctx->buffer + SHA256_BLOCK_SIZE
355 num_bits); 361 - SHA256_SIZE_OF_LEN_ADD,
362 num_bits);
356 /* Process full final block. */ 363 /* Process full final block. */
357 sha256_transform (ctx->H, ctx->buffer); 364 sha256_transform (ctx->H, ctx->buffer);
358 365
359 /* Put final hash/digest in BE mode */ 366 /* Put final hash/digest in BE mode */
360 _MHD_PUT_32BIT_BE (digest + 0 * SHA256_BYTES_IN_WORD, ctx->H[0]); 367#ifndef _MHD_PUT_32BIT_BE_UNALIGNED
361 _MHD_PUT_32BIT_BE (digest + 1 * SHA256_BYTES_IN_WORD, ctx->H[1]); 368 if (0 != ((uintptr_t) digest) % _MHD_UINT32_ALIGN)
362 _MHD_PUT_32BIT_BE (digest + 2 * SHA256_BYTES_IN_WORD, ctx->H[2]); 369 {
363 _MHD_PUT_32BIT_BE (digest + 3 * SHA256_BYTES_IN_WORD, ctx->H[3]); 370 uint32_t alig_dgst[_SHA256_DIGEST_LENGTH];
364 _MHD_PUT_32BIT_BE (digest + 4 * SHA256_BYTES_IN_WORD, ctx->H[4]); 371 _MHD_PUT_32BIT_BE (alig_dgst + 0, ctx->H[0]);
365 _MHD_PUT_32BIT_BE (digest + 5 * SHA256_BYTES_IN_WORD, ctx->H[5]); 372 _MHD_PUT_32BIT_BE (alig_dgst + 1, ctx->H[1]);
366 _MHD_PUT_32BIT_BE (digest + 6 * SHA256_BYTES_IN_WORD, ctx->H[6]); 373 _MHD_PUT_32BIT_BE (alig_dgst + 2, ctx->H[2]);
367 _MHD_PUT_32BIT_BE (digest + 7 * SHA256_BYTES_IN_WORD, ctx->H[7]); 374 _MHD_PUT_32BIT_BE (alig_dgst + 3, ctx->H[3]);
375 _MHD_PUT_32BIT_BE (alig_dgst + 4, ctx->H[4]);
376 _MHD_PUT_32BIT_BE (alig_dgst + 5, ctx->H[5]);
377 _MHD_PUT_32BIT_BE (alig_dgst + 6, ctx->H[6]);
378 _MHD_PUT_32BIT_BE (alig_dgst + 7, ctx->H[7]);
379 /* Copy result to unaligned destination address */
380 memcpy (digest, alig_dgst, SHA256_DIGEST_SIZE);
381 }
382 else
383#else /* _MHD_PUT_32BIT_BE_UNALIGNED */
384 if (1)
385#endif /* _MHD_PUT_32BIT_BE_UNALIGNED */
386 {
387 _MHD_PUT_32BIT_BE (digest + 0 * SHA256_BYTES_IN_WORD, ctx->H[0]);
388 _MHD_PUT_32BIT_BE (digest + 1 * SHA256_BYTES_IN_WORD, ctx->H[1]);
389 _MHD_PUT_32BIT_BE (digest + 2 * SHA256_BYTES_IN_WORD, ctx->H[2]);
390 _MHD_PUT_32BIT_BE (digest + 3 * SHA256_BYTES_IN_WORD, ctx->H[3]);
391 _MHD_PUT_32BIT_BE (digest + 4 * SHA256_BYTES_IN_WORD, ctx->H[4]);
392 _MHD_PUT_32BIT_BE (digest + 5 * SHA256_BYTES_IN_WORD, ctx->H[5]);
393 _MHD_PUT_32BIT_BE (digest + 6 * SHA256_BYTES_IN_WORD, ctx->H[6]);
394 _MHD_PUT_32BIT_BE (digest + 7 * SHA256_BYTES_IN_WORD, ctx->H[7]);
395 }
368 396
369 /* Erase potentially sensitive data. */ 397 /* Erase potentially sensitive data. */
370 memset (ctx, 0, sizeof(struct sha256_ctx)); 398 memset (ctx, 0, sizeof(struct sha256_ctx));
diff --git a/src/microhttpd/sha256.h b/src/microhttpd/sha256.h
index 88a558fc..3b866af2 100644
--- a/src/microhttpd/sha256.h
+++ b/src/microhttpd/sha256.h
@@ -30,25 +30,42 @@
30#include <stdint.h> 30#include <stdint.h>
31#include <stddef.h> 31#include <stddef.h>
32 32
33
33/** 34/**
34 * Digest is kept internally as 8 32-bit words. 35 * Digest is kept internally as 8 32-bit words.
35 */ 36 */
36#define _SHA256_DIGEST_LENGTH 8 37#define _SHA256_DIGEST_LENGTH 8
37 38
38/** 39/**
40 * Number of bits in single SHA-256 word
41 */
42#define SHA256_WORD_SIZE_BITS 32
43
44/**
45 * Number of bytes in single SHA-256 word
46 * used to process data
47 */
48#define SHA256_BYTES_IN_WORD (SHA256_WORD_SIZE_BITS / 8)
49
50/**
39 * Size of SHA-256 digest in bytes 51 * Size of SHA-256 digest in bytes
40 */ 52 */
41#define SHA256_DIGEST_SIZE (_SHA256_DIGEST_LENGTH * 4) 53#define SHA256_DIGEST_SIZE (_SHA256_DIGEST_LENGTH * SHA256_BYTES_IN_WORD)
42 54
43/** 55/**
44 * Size of SHA-256 digest string in chars 56 * Size of SHA-256 digest string in chars including termination NUL
45 */ 57 */
46#define SHA256_DIGEST_STRING_SIZE ((SHA256_DIGEST_SIZE) * 2 + 1) 58#define SHA256_DIGEST_STRING_SIZE ((SHA256_DIGEST_SIZE) * 2 + 1)
47 59
48/** 60/**
61 * Size of single processing block in bits
62 */
63#define SHA256_BLOCK_SIZE_BITS 512
64
65/**
49 * Size of single processing block in bytes 66 * Size of single processing block in bytes
50 */ 67 */
51#define SHA256_BLOCK_SIZE 64 68#define SHA256_BLOCK_SIZE (SHA256_BLOCK_SIZE_BITS / 8)
52 69
53 70
54struct sha256_ctx 71struct sha256_ctx