aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/md5.c
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-09-14 11:30:50 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-09-25 18:39:42 +0300
commit9e1fcbbf26c009c1dc732a1db9d3fb8b592e50ea (patch)
treef9363b582568de8e4bf8767f7c723fdc3c505464 /src/microhttpd/md5.c
parentf11a6dcedefc58e454957536812fe27b1ef8fb52 (diff)
downloadlibmicrohttpd-9e1fcbbf26c009c1dc732a1db9d3fb8b592e50ea.tar.gz
libmicrohttpd-9e1fcbbf26c009c1dc732a1db9d3fb8b592e50ea.zip
md5: added compact code version
Diffstat (limited to 'src/microhttpd/md5.c')
-rw-r--r--src/microhttpd/md5.c167
1 files changed, 136 insertions, 31 deletions
diff --git a/src/microhttpd/md5.c b/src/microhttpd/md5.c
index fceffdd1..609ed50f 100644
--- a/src/microhttpd/md5.c
+++ b/src/microhttpd/md5.c
@@ -106,8 +106,6 @@ md5_transform (uint32_t H[MD5_HASH_SIZE_WORDS],
106 /* One step of round 1 of MD5 computation, see RFC 1321, Clause 3.4 (step 4). 106 /* One step of round 1 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
107 The original function was modified to use X[k] and T[i] as 107 The original function was modified to use X[k] and T[i] as
108 direct inputs. */ 108 direct inputs. */
109 /* The input data is loaded in correct format before
110 calculations on each step. */
111#define MD5STEP_R1(va,vb,vc,vd,vX,vs,vT) do { \ 109#define MD5STEP_R1(va,vb,vc,vd,vX,vs,vT) do { \
112 (va) += (vX) + (vT); \ 110 (va) += (vX) + (vT); \
113 (va) += F_FUNC((vb),(vc),(vd)); \ 111 (va) += F_FUNC((vb),(vc),(vd)); \
@@ -118,9 +116,36 @@ md5_transform (uint32_t H[MD5_HASH_SIZE_WORDS],
118#define GET_X_FROM_DATA(buf,t) \ 116#define GET_X_FROM_DATA(buf,t) \
119 _MHD_GET_32BIT_LE (((const uint32_t*) (buf)) + (t)) 117 _MHD_GET_32BIT_LE (((const uint32_t*) (buf)) + (t))
120 118
119 /* One step of round 2 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
120 The original function was modified to use X[k] and T[i] as
121 direct inputs. */
122#define MD5STEP_R2(va,vb,vc,vd,vX,vs,vT) do { \
123 (va) += (vX) + (vT); \
124 (va) += G_FUNC_1((vb),(vc),(vd)); \
125 (va) += G_FUNC_2((vb),(vc),(vd)); \
126 (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
127
128 /* One step of round 3 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
129 The original function was modified to use X[k] and T[i] as
130 direct inputs. */
131#define MD5STEP_R3(va,vb,vc,vd,vX,vs,vT) do { \
132 (va) += (vX) + (vT); \
133 (va) += H_FUNC((vb),(vc),(vd)); \
134 (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
135
136 /* One step of round 4 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
137 The original function was modified to use X[k] and T[i] as
138 direct inputs. */
139#define MD5STEP_R4(va,vb,vc,vd,vX,vs,vT) do { \
140 (va) += (vX) + (vT); \
141 (va) += I_FUNC((vb),(vc),(vd)); \
142 (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
143
144#if ! defined(MHD_FAVOR_SMALL_CODE)
145
121 /* Round 1. */ 146 /* Round 1. */
122 147
123#if ! defined(MHD_FAVOR_SMALL_CODE) && (_MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN) 148#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
124 if ((const void *) X == M) 149 if ((const void *) X == M)
125 { 150 {
126 /* The input data is already in the data buffer X[] in correct bytes 151 /* The input data is already in the data buffer X[] in correct bytes
@@ -146,9 +171,11 @@ md5_transform (uint32_t H[MD5_HASH_SIZE_WORDS],
146 MD5STEP_R1 (B, C, D, A, X[15], 22, UINT32_C (0x49b40821)); 171 MD5STEP_R1 (B, C, D, A, X[15], 22, UINT32_C (0x49b40821));
147 } 172 }
148 else /* Combined with the next 'if' */ 173 else /* Combined with the next 'if' */
149#endif /* ! MHD_FAVOR_SMALL_CODE && (_MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN) */ 174#endif /* _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN */
150 if (1) 175 if (1)
151 { 176 {
177 /* The input data is loaded in correct (little-endian) format before
178 calculations on each step. */
152 MD5STEP_R1 (A, B, C, D, X[0] = GET_X_FROM_DATA (M, 0), 7, \ 179 MD5STEP_R1 (A, B, C, D, X[0] = GET_X_FROM_DATA (M, 0), 7, \
153 UINT32_C (0xd76aa478)); 180 UINT32_C (0xd76aa478));
154 MD5STEP_R1 (D, A, B, C, X[1] = GET_X_FROM_DATA (M, 1), 12, \ 181 MD5STEP_R1 (D, A, B, C, X[1] = GET_X_FROM_DATA (M, 1), 12, \
@@ -186,15 +213,6 @@ md5_transform (uint32_t H[MD5_HASH_SIZE_WORDS],
186 UINT32_C (0x49b40821)); 213 UINT32_C (0x49b40821));
187 } 214 }
188 215
189 /* One step of round 2 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
190 The original function was modified to use X[k] and T[i] as
191 direct inputs. */
192#define MD5STEP_R2(va,vb,vc,vd,vX,vs,vT) do { \
193 (va) += (vX) + (vT); \
194 (va) += G_FUNC_1((vb),(vc),(vd)); \
195 (va) += G_FUNC_2((vb),(vc),(vd)); \
196 (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
197
198 /* Round 2. */ 216 /* Round 2. */
199 217
200 MD5STEP_R2 (A, B, C, D, X[1], 5, UINT32_C (0xf61e2562)); 218 MD5STEP_R2 (A, B, C, D, X[1], 5, UINT32_C (0xf61e2562));
@@ -217,14 +235,6 @@ md5_transform (uint32_t H[MD5_HASH_SIZE_WORDS],
217 MD5STEP_R2 (C, D, A, B, X[7], 14, UINT32_C (0x676f02d9)); 235 MD5STEP_R2 (C, D, A, B, X[7], 14, UINT32_C (0x676f02d9));
218 MD5STEP_R2 (B, C, D, A, X[12], 20, UINT32_C (0x8d2a4c8a)); 236 MD5STEP_R2 (B, C, D, A, X[12], 20, UINT32_C (0x8d2a4c8a));
219 237
220 /* One step of round 3 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
221 The original function was modified to use X[k] and T[i] as
222 direct inputs. */
223#define MD5STEP_R3(va,vb,vc,vd,vX,vs,vT) do { \
224 (va) += (vX) + (vT); \
225 (va) += H_FUNC((vb),(vc),(vd)); \
226 (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
227
228 /* Round 3. */ 238 /* Round 3. */
229 239
230 MD5STEP_R3 (A, B, C, D, X[5], 4, UINT32_C (0xfffa3942)); 240 MD5STEP_R3 (A, B, C, D, X[5], 4, UINT32_C (0xfffa3942));
@@ -247,14 +257,6 @@ md5_transform (uint32_t H[MD5_HASH_SIZE_WORDS],
247 MD5STEP_R3 (C, D, A, B, X[15], 16, UINT32_C (0x1fa27cf8)); 257 MD5STEP_R3 (C, D, A, B, X[15], 16, UINT32_C (0x1fa27cf8));
248 MD5STEP_R3 (B, C, D, A, X[2], 23, UINT32_C (0xc4ac5665)); 258 MD5STEP_R3 (B, C, D, A, X[2], 23, UINT32_C (0xc4ac5665));
249 259
250 /* One step of round 4 of MD5 computation, see RFC 1321, Clause 3.4 (step 4).
251 The original function was modified to use X[k] and T[i] as
252 direct inputs. */
253#define MD5STEP_R4(va,vb,vc,vd,vX,vs,vT) do { \
254 (va) += (vX) + (vT); \
255 (va) += I_FUNC((vb),(vc),(vd)); \
256 (va) = _MHD_ROTL32((va),(vs)) + (vb); } while (0)
257
258 /* Round 4. */ 260 /* Round 4. */
259 261
260 MD5STEP_R4 (A, B, C, D, X[0], 6, UINT32_C (0xf4292244)); 262 MD5STEP_R4 (A, B, C, D, X[0], 6, UINT32_C (0xf4292244));
@@ -276,6 +278,97 @@ md5_transform (uint32_t H[MD5_HASH_SIZE_WORDS],
276 MD5STEP_R4 (D, A, B, C, X[11], 10, UINT32_C (0xbd3af235)); 278 MD5STEP_R4 (D, A, B, C, X[11], 10, UINT32_C (0xbd3af235));
277 MD5STEP_R4 (C, D, A, B, X[2], 15, UINT32_C (0x2ad7d2bb)); 279 MD5STEP_R4 (C, D, A, B, X[2], 15, UINT32_C (0x2ad7d2bb));
278 MD5STEP_R4 (B, C, D, A, X[9], 21, UINT32_C (0xeb86d391)); 280 MD5STEP_R4 (B, C, D, A, X[9], 21, UINT32_C (0xeb86d391));
281#else /* MHD_FAVOR_SMALL_CODE */
282 if (1)
283 {
284 static const uint32_t T[64] =
285 { UINT32_C (0xd76aa478), UINT32_C (0xe8c7b756), UINT32_C (0x242070db),
286 UINT32_C (0xc1bdceee), UINT32_C (0xf57c0faf), UINT32_C (0x4787c62a),
287 UINT32_C (0xa8304613), UINT32_C (0xfd469501), UINT32_C (0x698098d8),
288 UINT32_C (0x8b44f7af), UINT32_C (0xffff5bb1), UINT32_C (0x895cd7be),
289 UINT32_C (0x6b901122), UINT32_C (0xfd987193), UINT32_C (0xa679438e),
290 UINT32_C (0x49b40821), UINT32_C (0xf61e2562), UINT32_C (0xc040b340),
291 UINT32_C (0x265e5a51), UINT32_C (0xe9b6c7aa), UINT32_C (0xd62f105d),
292 UINT32_C (0x02441453), UINT32_C (0xd8a1e681), UINT32_C (0xe7d3fbc8),
293 UINT32_C (0x21e1cde6), UINT32_C (0xc33707d6), UINT32_C (0xf4d50d87),
294 UINT32_C (0x455a14ed), UINT32_C (0xa9e3e905), UINT32_C (0xfcefa3f8),
295 UINT32_C (0x676f02d9), UINT32_C (0x8d2a4c8a), UINT32_C (0xfffa3942),
296 UINT32_C (0x8771f681), UINT32_C (0x6d9d6122), UINT32_C (0xfde5380c),
297 UINT32_C (0xa4beea44), UINT32_C (0x4bdecfa9), UINT32_C (0xf6bb4b60),
298 UINT32_C (0xbebfbc70), UINT32_C (0x289b7ec6), UINT32_C (0xeaa127fa),
299 UINT32_C (0xd4ef3085), UINT32_C (0x04881d05), UINT32_C (0xd9d4d039),
300 UINT32_C (0xe6db99e5), UINT32_C (0x1fa27cf8), UINT32_C (0xc4ac5665),
301 UINT32_C (0xf4292244), UINT32_C (0x432aff97), UINT32_C (0xab9423a7),
302 UINT32_C (0xfc93a039), UINT32_C (0x655b59c3), UINT32_C (0x8f0ccc92),
303 UINT32_C (0xffeff47d), UINT32_C (0x85845dd1), UINT32_C (0x6fa87e4f),
304 UINT32_C (0xfe2ce6e0), UINT32_C (0xa3014314), UINT32_C (0x4e0811a1),
305 UINT32_C (0xf7537e82), UINT32_C (0xbd3af235), UINT32_C (0x2ad7d2bb),
306 UINT32_C (0xeb86d391) };
307 unsigned int i; /**< Zero-based index */
308
309 /* Round 1. */
310
311 i = 0;
312 do
313 {
314 /* The input data is loaded in correct (little-endian) format before
315 calculations on each step. */
316 MD5STEP_R1 (A, B, C, D, X[i] = GET_X_FROM_DATA (M, i), 7, T[i]);
317 ++i;
318 MD5STEP_R1 (D, A, B, C, X[i] = GET_X_FROM_DATA (M, i), 12, T[i]);
319 ++i;
320 MD5STEP_R1 (C, D, A, B, X[i] = GET_X_FROM_DATA (M, i), 17, T[i]);
321 ++i;
322 MD5STEP_R1 (B, C, D, A, X[i] = GET_X_FROM_DATA (M, i), 22, T[i]);
323 ++i;
324 } while (i < 16);
325
326 /* Round 2. */
327
328 do
329 {
330 const unsigned int idx_add = i;
331 MD5STEP_R2 (A, B, C, D, X[(1U + idx_add) & 15U], 5, T[i]);
332 ++i;
333 MD5STEP_R2 (D, A, B, C, X[(6U + idx_add) & 15U], 9, T[i]);
334 ++i;
335 MD5STEP_R2 (C, D, A, B, X[(11U + idx_add) & 15U], 14, T[i]);
336 ++i;
337 MD5STEP_R2 (B, C, D, A, X[(0U + idx_add) & 15U], 20, T[i]);
338 ++i;
339 } while (i < 32);
340
341 /* Round 3. */
342
343 do
344 {
345 const unsigned int idx_add = i;
346 MD5STEP_R3 (A, B, C, D, X[(5U + 64U - idx_add) & 15U], 4, T[i]);
347 ++i;
348 MD5STEP_R3 (D, A, B, C, X[(8U + 64U - idx_add) & 15U], 11, T[i]);
349 ++i;
350 MD5STEP_R3 (C, D, A, B, X[(11U + 64U - idx_add) & 15U], 16, T[i]);
351 ++i;
352 MD5STEP_R3 (B, C, D, A, X[(14U + 64U - idx_add) & 15U], 23, T[i]);
353 ++i;
354 } while (i < 48);
355
356 /* Round 4. */
357
358 do
359 {
360 const unsigned int idx_add = i;
361 MD5STEP_R4 (A, B, C, D, X[(0U + 64U - idx_add) & 15U], 6, T[i]);
362 ++i;
363 MD5STEP_R4 (D, A, B, C, X[(7U + 64U - idx_add) & 15U], 10, T[i]);
364 ++i;
365 MD5STEP_R4 (C, D, A, B, X[(14U + 64U - idx_add) & 15U], 15, T[i]);
366 ++i;
367 MD5STEP_R4 (B, C, D, A, X[(5U + 64U - idx_add) & 15U], 21, T[i]);
368 ++i;
369 } while (i < 64);
370 }
371#endif /* MHD_FAVOR_SMALL_CODE */
279 372
280 /* Finally increment and store working variables. 373 /* Finally increment and store working variables.
281 See RFC 1321, end of Clause 3.4 (step 4). */ 374 See RFC 1321, end of Clause 3.4 (step 4). */
@@ -414,8 +507,16 @@ MHD_MD5_finish (struct Md5Ctx *ctx,
414 /* Put in LE mode the hash as the final digest. 507 /* Put in LE mode the hash as the final digest.
415 See RFC 1321, clauses 2 and 3.5 (step 5). */ 508 See RFC 1321, clauses 2 and 3.5 (step 5). */
416#ifndef _MHD_PUT_32BIT_LE_UNALIGNED 509#ifndef _MHD_PUT_32BIT_LE_UNALIGNED
417 if (0 != ((uintptr_t) digest) % _MHD_UINT32_ALIGN) 510 if (1
418 { /* The destination is unaligned */ 511#ifndef MHD_FAVOR_SMALL_CODE
512 && (0 != ((uintptr_t) digest) % _MHD_UINT32_ALIGN)
513#endif /* MHD_FAVOR_SMALL_CODE */
514 )
515 {
516 /* If storing of the final result requires aligned address and
517 the destination address is not aligned or compact code is used,
518 store the final digest in aligned temporary buffer first, then
519 copy it to the destination. */
419 uint32_t alig_dgst[MD5_DIGEST_SIZE_WORDS]; 520 uint32_t alig_dgst[MD5_DIGEST_SIZE_WORDS];
420 _MHD_PUT_32BIT_LE (alig_dgst + 0, ctx->H[0]); 521 _MHD_PUT_32BIT_LE (alig_dgst + 0, ctx->H[0]);
421 _MHD_PUT_32BIT_LE (alig_dgst + 1, ctx->H[1]); 522 _MHD_PUT_32BIT_LE (alig_dgst + 1, ctx->H[1]);
@@ -424,8 +525,11 @@ MHD_MD5_finish (struct Md5Ctx *ctx,
424 /* Copy result to the unaligned destination address. */ 525 /* Copy result to the unaligned destination address. */
425 memcpy (digest, alig_dgst, MD5_DIGEST_SIZE); 526 memcpy (digest, alig_dgst, MD5_DIGEST_SIZE);
426 } 527 }
528#ifndef MHD_FAVOR_SMALL_CODE
427 else /* Combined with the next 'if' */ 529 else /* Combined with the next 'if' */
530#endif /* MHD_FAVOR_SMALL_CODE */
428#endif /* ! _MHD_PUT_32BIT_LE_UNALIGNED */ 531#endif /* ! _MHD_PUT_32BIT_LE_UNALIGNED */
532#if ! defined(MHD_FAVOR_SMALL_CODE) || defined(_MHD_PUT_32BIT_LE_UNALIGNED)
429 if (1) 533 if (1)
430 { 534 {
431 /* Use cast to (void*) here to mute compiler alignment warnings. 535 /* Use cast to (void*) here to mute compiler alignment warnings.
@@ -435,6 +539,7 @@ MHD_MD5_finish (struct Md5Ctx *ctx,
435 _MHD_PUT_32BIT_LE ((void *) (digest + 2 * MD5_BYTES_IN_WORD), ctx->H[2]); 539 _MHD_PUT_32BIT_LE ((void *) (digest + 2 * MD5_BYTES_IN_WORD), ctx->H[2]);
436 _MHD_PUT_32BIT_LE ((void *) (digest + 3 * MD5_BYTES_IN_WORD), ctx->H[3]); 540 _MHD_PUT_32BIT_LE ((void *) (digest + 3 * MD5_BYTES_IN_WORD), ctx->H[3]);
437 } 541 }
542#endif /* ! MHD_FAVOR_SMALL_CODE || _MHD_PUT_32BIT_LE_UNALIGNED */
438 543
439 /* Erase potentially sensitive data. */ 544 /* Erase potentially sensitive data. */
440 memset (ctx, 0, sizeof(struct Md5Ctx)); 545 memset (ctx, 0, sizeof(struct Md5Ctx));