GNU libmicrohttpd  1.0.1
md5.c
Go to the documentation of this file.
1 /*
2  This file is part of GNU libmicrohttpd
3  Copyright (C) 2022-2023 Evgeny Grin (Karlson2k)
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 
26 #include "md5.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 
40 void
41 MHD_MD5_init (struct Md5Ctx *ctx)
42 {
43  /* Initial hash values, see RFC 1321, Clause 3.3 (step 3). */
44  /* Note: values specified in RFC by bytes and should be loaded in
45  little-endian mode, therefore hash values here are initialised with
46  original bytes used in little-endian order. */
47  ctx->H[0] = UINT32_C (0x67452301);
48  ctx->H[1] = UINT32_C (0xefcdab89);
49  ctx->H[2] = UINT32_C (0x98badcfe);
50  ctx->H[3] = UINT32_C (0x10325476);
51 
52  /* Initialise the number of bytes. */
53  ctx->count = 0;
54 }
55 
56 
58 
65 static void
67  const void *M)
68 {
69  /* Working variables,
70  See RFC 1321, Clause 3.4 (step 4). */
71  uint32_t A = H[0];
72  uint32_t B = H[1];
73  uint32_t C = H[2];
74  uint32_t D = H[3];
75 
76  /* The data buffer. See RFC 1321, Clause 3.4 (step 4). */
77  uint32_t X[16];
78 
79 #ifndef _MHD_GET_32BIT_LE_UNALIGNED
80  if (0 != (((uintptr_t) M) % _MHD_UINT32_ALIGN))
81  { /* The input data is unaligned. */
82  /* Copy the unaligned input data to the aligned buffer. */
83  memcpy (X, M, sizeof(X));
84  /* The X[] buffer itself will be used as the source of the data,
85  * but the data will be reloaded in correct bytes order on
86  * the next steps. */
87  M = (const void *) X;
88  }
89 #endif /* _MHD_GET_32BIT_LE_UNALIGNED */
90 
91  /* Four auxiliary functions, see RFC 1321, Clause 3.4 (step 4). */
92  /* Some optimisations used. */
93 /* #define F_FUNC(x,y,z) (((x)&(y)) | ((~(x))&(z))) */ /* Original version */
94 #define F_FUNC(x,y,z) ((((y) ^ (z)) & (x)) ^ (z))
95 /* #define G_FUNC_1(x,y,z) (((x)&(z)) | ((y)&(~(z)))) */ /* Original version */
96 /* #define G_FUNC_2(x,y,z) UINT32_C(0) */ /* Original version */
97 #ifndef MHD_FAVOR_SMALL_CODE
98 # define G_FUNC_1(x,y,z) ((~(z)) & (y))
99 # define G_FUNC_2(x,y,z) ((z) & (x))
100 #else /* MHD_FAVOR_SMALL_CODE */
101 # define G_FUNC_1(x,y,z) ((((x) ^ (y)) & (z)) ^ (y))
102 # define G_FUNC_2(x,y,z) UINT32_C(0)
103 #endif /* MHD_FAVOR_SMALL_CODE */
104 #define H_FUNC(x,y,z) ((x) ^ (y) ^ (z)) /* Original version */
105 /* #define I_FUNC(x,y,z) ((y) ^ ((x) | (~(z)))) */ /* Original version */
106 #define I_FUNC(x,y,z) (((~(z)) | (x)) ^ (y))
107 
108  /* One step of round 1 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
109  The original function was modified to use X[k] and T[i] as
110  direct inputs. */
111 #define MD5STEP_R1(va,vb,vc,vd,vX,vs,vT) do { \
112  (va) += (vX) + (vT); \
113  (va) += F_FUNC((vb),(vc),(vd)); \
114  (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
115 
116  /* Get value of X(k) from input data buffer.
117  See RFC 1321 Clause 3.4 (step 4). */
118 #define GET_X_FROM_DATA(buf,t) \
119  _MHD_GET_32BIT_LE (((const uint32_t*) (buf)) + (t))
120 
121  /* One step of round 2 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
122  The original function was modified to use X[k] and T[i] as
123  direct inputs. */
124 #define MD5STEP_R2(va,vb,vc,vd,vX,vs,vT) do { \
125  (va) += (vX) + (vT); \
126  (va) += G_FUNC_1((vb),(vc),(vd)); \
127  (va) += G_FUNC_2((vb),(vc),(vd)); \
128  (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
129 
130  /* One step of round 3 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
131  The original function was modified to use X[k] and T[i] as
132  direct inputs. */
133 #define MD5STEP_R3(va,vb,vc,vd,vX,vs,vT) do { \
134  (va) += (vX) + (vT); \
135  (va) += H_FUNC((vb),(vc),(vd)); \
136  (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
137 
138  /* One step of round 4 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
139  The original function was modified to use X[k] and T[i] as
140  direct inputs. */
141 #define MD5STEP_R4(va,vb,vc,vd,vX,vs,vT) do { \
142  (va) += (vX) + (vT); \
143  (va) += I_FUNC((vb),(vc),(vd)); \
144  (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
145 
146 #if ! defined(MHD_FAVOR_SMALL_CODE)
147 
148  /* Round 1. */
149 
150 #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
151  if ((const void *) X == M)
152  {
153  /* The input data is already in the data buffer X[] in correct bytes
154  order. */
155  MD5STEP_R1 (A, B, C, D, X[0], 7, UINT32_C (0xd76aa478));
156  MD5STEP_R1 (D, A, B, C, X[1], 12, UINT32_C (0xe8c7b756));
157  MD5STEP_R1 (C, D, A, B, X[2], 17, UINT32_C (0x242070db));
158  MD5STEP_R1 (B, C, D, A, X[3], 22, UINT32_C (0xc1bdceee));
159 
160  MD5STEP_R1 (A, B, C, D, X[4], 7, UINT32_C (0xf57c0faf));
161  MD5STEP_R1 (D, A, B, C, X[5], 12, UINT32_C (0x4787c62a));
162  MD5STEP_R1 (C, D, A, B, X[6], 17, UINT32_C (0xa8304613));
163  MD5STEP_R1 (B, C, D, A, X[7], 22, UINT32_C (0xfd469501));
164 
165  MD5STEP_R1 (A, B, C, D, X[8], 7, UINT32_C (0x698098d8));
166  MD5STEP_R1 (D, A, B, C, X[9], 12, UINT32_C (0x8b44f7af));
167  MD5STEP_R1 (C, D, A, B, X[10], 17, UINT32_C (0xffff5bb1));
168  MD5STEP_R1 (B, C, D, A, X[11], 22, UINT32_C (0x895cd7be));
169 
170  MD5STEP_R1 (A, B, C, D, X[12], 7, UINT32_C (0x6b901122));
171  MD5STEP_R1 (D, A, B, C, X[13], 12, UINT32_C (0xfd987193));
172  MD5STEP_R1 (C, D, A, B, X[14], 17, UINT32_C (0xa679438e));
173  MD5STEP_R1 (B, C, D, A, X[15], 22, UINT32_C (0x49b40821));
174  }
175  else /* Combined with the next 'if' */
176 #endif /* _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN */
177  if (1)
178  {
179  /* The input data is loaded in correct (little-endian) format before
180  calculations on each step. */
181  MD5STEP_R1 (A, B, C, D, X[0] = GET_X_FROM_DATA (M, 0), 7, \
182  UINT32_C (0xd76aa478));
183  MD5STEP_R1 (D, A, B, C, X[1] = GET_X_FROM_DATA (M, 1), 12, \
184  UINT32_C (0xe8c7b756));
185  MD5STEP_R1 (C, D, A, B, X[2] = GET_X_FROM_DATA (M, 2), 17, \
186  UINT32_C (0x242070db));
187  MD5STEP_R1 (B, C, D, A, X[3] = GET_X_FROM_DATA (M, 3), 22, \
188  UINT32_C (0xc1bdceee));
189 
190  MD5STEP_R1 (A, B, C, D, X[4] = GET_X_FROM_DATA (M, 4), 7, \
191  UINT32_C (0xf57c0faf));
192  MD5STEP_R1 (D, A, B, C, X[5] = GET_X_FROM_DATA (M, 5), 12, \
193  UINT32_C (0x4787c62a));
194  MD5STEP_R1 (C, D, A, B, X[6] = GET_X_FROM_DATA (M, 6), 17, \
195  UINT32_C (0xa8304613));
196  MD5STEP_R1 (B, C, D, A, X[7] = GET_X_FROM_DATA (M, 7), 22, \
197  UINT32_C (0xfd469501));
198 
199  MD5STEP_R1 (A, B, C, D, X[8] = GET_X_FROM_DATA (M, 8), 7, \
200  UINT32_C (0x698098d8));
201  MD5STEP_R1 (D, A, B, C, X[9] = GET_X_FROM_DATA (M, 9), 12, \
202  UINT32_C (0x8b44f7af));
203  MD5STEP_R1 (C, D, A, B, X[10] = GET_X_FROM_DATA (M, 10), 17, \
204  UINT32_C (0xffff5bb1));
205  MD5STEP_R1 (B, C, D, A, X[11] = GET_X_FROM_DATA (M, 11), 22, \
206  UINT32_C (0x895cd7be));
207 
208  MD5STEP_R1 (A, B, C, D, X[12] = GET_X_FROM_DATA (M, 12), 7, \
209  UINT32_C (0x6b901122));
210  MD5STEP_R1 (D, A, B, C, X[13] = GET_X_FROM_DATA (M, 13), 12, \
211  UINT32_C (0xfd987193));
212  MD5STEP_R1 (C, D, A, B, X[14] = GET_X_FROM_DATA (M, 14), 17, \
213  UINT32_C (0xa679438e));
214  MD5STEP_R1 (B, C, D, A, X[15] = GET_X_FROM_DATA (M, 15), 22, \
215  UINT32_C (0x49b40821));
216  }
217 
218  /* Round 2. */
219 
220  MD5STEP_R2 (A, B, C, D, X[1], 5, UINT32_C (0xf61e2562));
221  MD5STEP_R2 (D, A, B, C, X[6], 9, UINT32_C (0xc040b340));
222  MD5STEP_R2 (C, D, A, B, X[11], 14, UINT32_C (0x265e5a51));
223  MD5STEP_R2 (B, C, D, A, X[0], 20, UINT32_C (0xe9b6c7aa));
224 
225  MD5STEP_R2 (A, B, C, D, X[5], 5, UINT32_C (0xd62f105d));
226  MD5STEP_R2 (D, A, B, C, X[10], 9, UINT32_C (0x02441453));
227  MD5STEP_R2 (C, D, A, B, X[15], 14, UINT32_C (0xd8a1e681));
228  MD5STEP_R2 (B, C, D, A, X[4], 20, UINT32_C (0xe7d3fbc8));
229 
230  MD5STEP_R2 (A, B, C, D, X[9], 5, UINT32_C (0x21e1cde6));
231  MD5STEP_R2 (D, A, B, C, X[14], 9, UINT32_C (0xc33707d6));
232  MD5STEP_R2 (C, D, A, B, X[3], 14, UINT32_C (0xf4d50d87));
233  MD5STEP_R2 (B, C, D, A, X[8], 20, UINT32_C (0x455a14ed));
234 
235  MD5STEP_R2 (A, B, C, D, X[13], 5, UINT32_C (0xa9e3e905));
236  MD5STEP_R2 (D, A, B, C, X[2], 9, UINT32_C (0xfcefa3f8));
237  MD5STEP_R2 (C, D, A, B, X[7], 14, UINT32_C (0x676f02d9));
238  MD5STEP_R2 (B, C, D, A, X[12], 20, UINT32_C (0x8d2a4c8a));
239 
240  /* Round 3. */
241 
242  MD5STEP_R3 (A, B, C, D, X[5], 4, UINT32_C (0xfffa3942));
243  MD5STEP_R3 (D, A, B, C, X[8], 11, UINT32_C (0x8771f681));
244  MD5STEP_R3 (C, D, A, B, X[11], 16, UINT32_C (0x6d9d6122));
245  MD5STEP_R3 (B, C, D, A, X[14], 23, UINT32_C (0xfde5380c));
246 
247  MD5STEP_R3 (A, B, C, D, X[1], 4, UINT32_C (0xa4beea44));
248  MD5STEP_R3 (D, A, B, C, X[4], 11, UINT32_C (0x4bdecfa9));
249  MD5STEP_R3 (C, D, A, B, X[7], 16, UINT32_C (0xf6bb4b60));
250  MD5STEP_R3 (B, C, D, A, X[10], 23, UINT32_C (0xbebfbc70));
251 
252  MD5STEP_R3 (A, B, C, D, X[13], 4, UINT32_C (0x289b7ec6));
253  MD5STEP_R3 (D, A, B, C, X[0], 11, UINT32_C (0xeaa127fa));
254  MD5STEP_R3 (C, D, A, B, X[3], 16, UINT32_C (0xd4ef3085));
255  MD5STEP_R3 (B, C, D, A, X[6], 23, UINT32_C (0x04881d05));
256 
257  MD5STEP_R3 (A, B, C, D, X[9], 4, UINT32_C (0xd9d4d039));
258  MD5STEP_R3 (D, A, B, C, X[12], 11, UINT32_C (0xe6db99e5));
259  MD5STEP_R3 (C, D, A, B, X[15], 16, UINT32_C (0x1fa27cf8));
260  MD5STEP_R3 (B, C, D, A, X[2], 23, UINT32_C (0xc4ac5665));
261 
262  /* Round 4. */
263 
264  MD5STEP_R4 (A, B, C, D, X[0], 6, UINT32_C (0xf4292244));
265  MD5STEP_R4 (D, A, B, C, X[7], 10, UINT32_C (0x432aff97));
266  MD5STEP_R4 (C, D, A, B, X[14], 15, UINT32_C (0xab9423a7));
267  MD5STEP_R4 (B, C, D, A, X[5], 21, UINT32_C (0xfc93a039));
268 
269  MD5STEP_R4 (A, B, C, D, X[12], 6, UINT32_C (0x655b59c3));
270  MD5STEP_R4 (D, A, B, C, X[3], 10, UINT32_C (0x8f0ccc92));
271  MD5STEP_R4 (C, D, A, B, X[10], 15, UINT32_C (0xffeff47d));
272  MD5STEP_R4 (B, C, D, A, X[1], 21, UINT32_C (0x85845dd1));
273 
274  MD5STEP_R4 (A, B, C, D, X[8], 6, UINT32_C (0x6fa87e4f));
275  MD5STEP_R4 (D, A, B, C, X[15], 10, UINT32_C (0xfe2ce6e0));
276  MD5STEP_R4 (C, D, A, B, X[6], 15, UINT32_C (0xa3014314));
277  MD5STEP_R4 (B, C, D, A, X[13], 21, UINT32_C (0x4e0811a1));
278 
279  MD5STEP_R4 (A, B, C, D, X[4], 6, UINT32_C (0xf7537e82));
280  MD5STEP_R4 (D, A, B, C, X[11], 10, UINT32_C (0xbd3af235));
281  MD5STEP_R4 (C, D, A, B, X[2], 15, UINT32_C (0x2ad7d2bb));
282  MD5STEP_R4 (B, C, D, A, X[9], 21, UINT32_C (0xeb86d391));
283 #else /* MHD_FAVOR_SMALL_CODE */
284  if (1)
285  {
286  static const uint32_t T[64] =
287  { UINT32_C (0xd76aa478), UINT32_C (0xe8c7b756), UINT32_C (0x242070db),
288  UINT32_C (0xc1bdceee), UINT32_C (0xf57c0faf), UINT32_C (0x4787c62a),
289  UINT32_C (0xa8304613), UINT32_C (0xfd469501), UINT32_C (0x698098d8),
290  UINT32_C (0x8b44f7af), UINT32_C (0xffff5bb1), UINT32_C (0x895cd7be),
291  UINT32_C (0x6b901122), UINT32_C (0xfd987193), UINT32_C (0xa679438e),
292  UINT32_C (0x49b40821), UINT32_C (0xf61e2562), UINT32_C (0xc040b340),
293  UINT32_C (0x265e5a51), UINT32_C (0xe9b6c7aa), UINT32_C (0xd62f105d),
294  UINT32_C (0x02441453), UINT32_C (0xd8a1e681), UINT32_C (0xe7d3fbc8),
295  UINT32_C (0x21e1cde6), UINT32_C (0xc33707d6), UINT32_C (0xf4d50d87),
296  UINT32_C (0x455a14ed), UINT32_C (0xa9e3e905), UINT32_C (0xfcefa3f8),
297  UINT32_C (0x676f02d9), UINT32_C (0x8d2a4c8a), UINT32_C (0xfffa3942),
298  UINT32_C (0x8771f681), UINT32_C (0x6d9d6122), UINT32_C (0xfde5380c),
299  UINT32_C (0xa4beea44), UINT32_C (0x4bdecfa9), UINT32_C (0xf6bb4b60),
300  UINT32_C (0xbebfbc70), UINT32_C (0x289b7ec6), UINT32_C (0xeaa127fa),
301  UINT32_C (0xd4ef3085), UINT32_C (0x04881d05), UINT32_C (0xd9d4d039),
302  UINT32_C (0xe6db99e5), UINT32_C (0x1fa27cf8), UINT32_C (0xc4ac5665),
303  UINT32_C (0xf4292244), UINT32_C (0x432aff97), UINT32_C (0xab9423a7),
304  UINT32_C (0xfc93a039), UINT32_C (0x655b59c3), UINT32_C (0x8f0ccc92),
305  UINT32_C (0xffeff47d), UINT32_C (0x85845dd1), UINT32_C (0x6fa87e4f),
306  UINT32_C (0xfe2ce6e0), UINT32_C (0xa3014314), UINT32_C (0x4e0811a1),
307  UINT32_C (0xf7537e82), UINT32_C (0xbd3af235), UINT32_C (0x2ad7d2bb),
308  UINT32_C (0xeb86d391) };
309  unsigned int i;
311  /* Round 1. */
312 
313  i = 0;
314  do
315  {
316  /* The input data is loaded in correct (little-endian) format before
317  calculations on each step. */
318  MD5STEP_R1 (A, B, C, D, X[i] = GET_X_FROM_DATA (M, i), 7, T[i]);
319  ++i;
320  MD5STEP_R1 (D, A, B, C, X[i] = GET_X_FROM_DATA (M, i), 12, T[i]);
321  ++i;
322  MD5STEP_R1 (C, D, A, B, X[i] = GET_X_FROM_DATA (M, i), 17, T[i]);
323  ++i;
324  MD5STEP_R1 (B, C, D, A, X[i] = GET_X_FROM_DATA (M, i), 22, T[i]);
325  ++i;
326  } while (i < 16);
327 
328  /* Round 2. */
329 
330  do
331  {
332  const unsigned int idx_add = i;
333  MD5STEP_R2 (A, B, C, D, X[(1U + idx_add) & 15U], 5, T[i]);
334  ++i;
335  MD5STEP_R2 (D, A, B, C, X[(6U + idx_add) & 15U], 9, T[i]);
336  ++i;
337  MD5STEP_R2 (C, D, A, B, X[(11U + idx_add) & 15U], 14, T[i]);
338  ++i;
339  MD5STEP_R2 (B, C, D, A, X[(0U + idx_add) & 15U], 20, T[i]);
340  ++i;
341  } while (i < 32);
342 
343  /* Round 3. */
344 
345  do
346  {
347  const unsigned int idx_add = i;
348  MD5STEP_R3 (A, B, C, D, X[(5U + 64U - idx_add) & 15U], 4, T[i]);
349  ++i;
350  MD5STEP_R3 (D, A, B, C, X[(8U + 64U - idx_add) & 15U], 11, T[i]);
351  ++i;
352  MD5STEP_R3 (C, D, A, B, X[(11U + 64U - idx_add) & 15U], 16, T[i]);
353  ++i;
354  MD5STEP_R3 (B, C, D, A, X[(14U + 64U - idx_add) & 15U], 23, T[i]);
355  ++i;
356  } while (i < 48);
357 
358  /* Round 4. */
359 
360  do
361  {
362  const unsigned int idx_add = i;
363  MD5STEP_R4 (A, B, C, D, X[(0U + 64U - idx_add) & 15U], 6, T[i]);
364  ++i;
365  MD5STEP_R4 (D, A, B, C, X[(7U + 64U - idx_add) & 15U], 10, T[i]);
366  ++i;
367  MD5STEP_R4 (C, D, A, B, X[(14U + 64U - idx_add) & 15U], 15, T[i]);
368  ++i;
369  MD5STEP_R4 (B, C, D, A, X[(5U + 64U - idx_add) & 15U], 21, T[i]);
370  ++i;
371  } while (i < 64);
372  }
373 #endif /* MHD_FAVOR_SMALL_CODE */
374 
375  /* Finally increment and store working variables.
376  See RFC 1321, end of Clause 3.4 (step 4). */
377 
378  H[0] += A;
379  H[1] += B;
380  H[2] += C;
381  H[3] += D;
382 }
383 
384 
392 void
393 MHD_MD5_update (struct Md5Ctx *ctx,
394  const uint8_t *data,
395  size_t length)
396 {
397  unsigned int bytes_have;
399  mhd_assert ((data != NULL) || (length == 0));
400 
401 #ifndef MHD_FAVOR_SMALL_CODE
402  if (0 == length)
403  return; /* Shortcut, do nothing */
404 #endif /* MHD_FAVOR_SMALL_CODE */
405 
406  /* Note: (count & (MD5_BLOCK_SIZE-1))
407  equals (count % MD5_BLOCK_SIZE) for this block size. */
408  bytes_have = (unsigned int) (ctx->count & (MD5_BLOCK_SIZE - 1));
409  ctx->count += length;
410 
411  if (0 != bytes_have)
412  {
413  unsigned int bytes_left = MD5_BLOCK_SIZE - bytes_have;
414  if (length >= bytes_left)
415  { /* Combine new data with data in the buffer and
416  process the full block. */
417  memcpy (((uint8_t *) ctx->buffer) + bytes_have,
418  data,
419  bytes_left);
420  data += bytes_left;
421  length -= bytes_left;
422  md5_transform (ctx->H, ctx->buffer);
423  bytes_have = 0;
424  }
425  }
426 
427  while (MD5_BLOCK_SIZE <= length)
428  { /* Process any full blocks of new data directly,
429  without copying to the buffer. */
430  md5_transform (ctx->H, data);
431  data += MD5_BLOCK_SIZE;
432  length -= MD5_BLOCK_SIZE;
433  }
434 
435  if (0 != length)
436  { /* Copy incomplete block of new data (if any)
437  to the buffer. */
438  memcpy (((uint8_t *) ctx->buffer) + bytes_have, data, length);
439  }
440 }
441 
442 
447 #define MD5_SIZE_OF_LEN_ADD_BITS 64
448 
452 #define MD5_SIZE_OF_LEN_ADD (MD5_SIZE_OF_LEN_ADD_BITS / 8)
453 
460 void
461 MHD_MD5_finish (struct Md5Ctx *ctx,
462  uint8_t digest[MD5_DIGEST_SIZE])
463 {
464  uint64_t num_bits;
465  unsigned int bytes_have;
467  /* Memorise the number of processed bits.
468  The padding and other data added here during the postprocessing must
469  not change the amount of hashed data. */
470  num_bits = ctx->count << 3;
471 
472  /* Note: (count & (MD5_BLOCK_SIZE-1))
473  equals (count % MD5_BLOCK_SIZE) for this block size. */
474  bytes_have = (unsigned int) (ctx->count & (MD5_BLOCK_SIZE - 1));
475 
476  /* Input data must be padded with a single bit "1", then with zeros and
477  the finally the length of data in bits must be added as the final bytes
478  of the last block.
479  See RFC 1321, Clauses 3.1 and 3.2 (steps 1 and 2). */
480  /* Data is always processed in form of bytes (not by individual bits),
481  therefore position of the first padding bit in byte is always
482  predefined (0x80). */
483  /* Buffer always have space for one byte at least (as full buffers are
484  processed immediately). */
485  ((uint8_t *) ctx->buffer)[bytes_have++] = 0x80;
486 
487  if (MD5_BLOCK_SIZE - bytes_have < MD5_SIZE_OF_LEN_ADD)
488  { /* No space in the current block to put the total length of message.
489  Pad the current block with zeros and process it. */
490  if (bytes_have < MD5_BLOCK_SIZE)
491  memset (((uint8_t *) ctx->buffer) + bytes_have, 0,
492  MD5_BLOCK_SIZE - bytes_have);
493  /* Process the full block. */
494  md5_transform (ctx->H, ctx->buffer);
495  /* Start the new block. */
496  bytes_have = 0;
497  }
498 
499  /* Pad the rest of the buffer with zeros. */
500  memset (((uint8_t *) ctx->buffer) + bytes_have, 0,
501  MD5_BLOCK_SIZE - MD5_SIZE_OF_LEN_ADD - bytes_have);
502  /* Put the number of bits in processed data as little-endian value.
503  See RFC 1321, clauses 2 and 3.2 (step 2). */
505  num_bits);
506  /* Process the full final block. */
507  md5_transform (ctx->H, ctx->buffer);
508 
509  /* Put in LE mode the hash as the final digest.
510  See RFC 1321, clauses 2 and 3.5 (step 5). */
511 #ifndef _MHD_PUT_32BIT_LE_UNALIGNED
512  if (1
513 #ifndef MHD_FAVOR_SMALL_CODE
514  && (0 != ((uintptr_t) digest) % _MHD_UINT32_ALIGN)
515 #endif /* MHD_FAVOR_SMALL_CODE */
516  )
517  {
518  /* If storing of the final result requires aligned address and
519  the destination address is not aligned or compact code is used,
520  store the final digest in aligned temporary buffer first, then
521  copy it to the destination. */
522  uint32_t alig_dgst[MD5_DIGEST_SIZE_WORDS];
523  _MHD_PUT_32BIT_LE (alig_dgst + 0, ctx->H[0]);
524  _MHD_PUT_32BIT_LE (alig_dgst + 1, ctx->H[1]);
525  _MHD_PUT_32BIT_LE (alig_dgst + 2, ctx->H[2]);
526  _MHD_PUT_32BIT_LE (alig_dgst + 3, ctx->H[3]);
527  /* Copy result to the unaligned destination address. */
528  memcpy (digest, alig_dgst, MD5_DIGEST_SIZE);
529  }
530 #ifndef MHD_FAVOR_SMALL_CODE
531  else /* Combined with the next 'if' */
532 #endif /* MHD_FAVOR_SMALL_CODE */
533 #endif /* ! _MHD_PUT_32BIT_LE_UNALIGNED */
534 #if ! defined(MHD_FAVOR_SMALL_CODE) || defined(_MHD_PUT_32BIT_LE_UNALIGNED)
535  if (1)
536  {
537  /* Use cast to (void*) here to mute compiler alignment warnings.
538  * Compilers are not smart enough to see that alignment has been checked. */
539  _MHD_PUT_32BIT_LE ((void *) (digest + 0 * MD5_BYTES_IN_WORD), ctx->H[0]);
540  _MHD_PUT_32BIT_LE ((void *) (digest + 1 * MD5_BYTES_IN_WORD), ctx->H[1]);
541  _MHD_PUT_32BIT_LE ((void *) (digest + 2 * MD5_BYTES_IN_WORD), ctx->H[2]);
542  _MHD_PUT_32BIT_LE ((void *) (digest + 3 * MD5_BYTES_IN_WORD), ctx->H[3]);
543  }
544 #endif /* ! MHD_FAVOR_SMALL_CODE || _MHD_PUT_32BIT_LE_UNALIGNED */
545 
546  /* Erase potentially sensitive data. */
547  memset (ctx, 0, sizeof(struct Md5Ctx));
548 }
549 
550 
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
#define NULL
Definition: reason_phrase.c:30
#define MD5STEP_R3(va, vb, vc, vd, vX, vs, vT)
void MHD_MD5_finish(struct Md5Ctx *ctx, uint8_t digest[MD5_DIGEST_SIZE])
Definition: md5.c:461
#define GET_X_FROM_DATA(buf, t)
static MHD_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE_ void md5_transform(uint32_t H[MD5_HASH_SIZE_WORDS], const void *M)
Definition: md5.c:66
#define MD5STEP_R2(va, vb, vc, vd, vX, vs, vT)
void MHD_MD5_update(struct Md5Ctx *ctx, const uint8_t *data, size_t length)
Definition: md5.c:393
#define MD5_SIZE_OF_LEN_ADD
Definition: md5.c:452
#define MD5STEP_R4(va, vb, vc, vd, vX, vs, vT)
void MHD_MD5_init(struct Md5Ctx *ctx)
Definition: md5.c:41
#define MD5STEP_R1(va, vb, vc, vd, vX, vs, vT)
Calculation of MD5 digest.
#define MD5_DIGEST_SIZE_WORDS
Definition: md5.h:55
#define MD5_BLOCK_SIZE
Definition: md5.h:76
#define MD5_BLOCK_SIZE_WORDS
Definition: md5.h:81
#define MD5_HASH_SIZE_WORDS
Definition: md5.h:49
#define MD5_DIGEST_SIZE
Definition: md5.h:61
#define MD5_BYTES_IN_WORD
Definition: md5.h:43
#define _MHD_UINT32_ALIGN
Definition: mhd_align.h:85
macros for bits manipulations
_MHD_static_inline void _MHD_PUT_64BIT_LE_SAFE(void *dst, uint64_t value)
#define _MHD_PUT_32BIT_LE(addr, value32)
#define MHD_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE_
Definition: mhd_options.h:176
#define MHD_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE_
Definition: mhd_options.h:177
macros for mhd_assert()
void * data
Definition: microhttpd.h:3968
Definition: md5.h:88
uint64_t count
Definition: md5.h:91
uint32_t buffer[MD5_BLOCK_SIZE_WORDS]
Definition: md5.h:90
uint32_t H[MD5_HASH_SIZE_WORDS]
Definition: md5.h:89