diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-09-14 11:30:50 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-09-25 18:39:42 +0300 |
commit | 9e1fcbbf26c009c1dc732a1db9d3fb8b592e50ea (patch) | |
tree | f9363b582568de8e4bf8767f7c723fdc3c505464 /src/microhttpd/md5.c | |
parent | f11a6dcedefc58e454957536812fe27b1ef8fb52 (diff) | |
download | libmicrohttpd-9e1fcbbf26c009c1dc732a1db9d3fb8b592e50ea.tar.gz libmicrohttpd-9e1fcbbf26c009c1dc732a1db9d3fb8b592e50ea.zip |
md5: added compact code version
Diffstat (limited to 'src/microhttpd/md5.c')
-rw-r--r-- | src/microhttpd/md5.c | 167 |
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)); |