libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

md5.c (20981B)


      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 
     20 /**
     21  * @file microhttpd/md5.c
     22  * @brief  Calculation of MD5 digest as defined in RFC 1321
     23  * @author Karlson2k (Evgeny Grin)
     24  */
     25 
     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 
     35 /**
     36  * Initialise structure for MD5 calculation.
     37  *
     38  * @param ctx the calculation context
     39  */
     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 
     57 MHD_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE_
     58 
     59 /**
     60  * Base of MD5 transformation.
     61  * Gets full 64 bytes block of data and updates hash values;
     62  * @param H     hash values
     63  * @param M     the data buffer with #MD5_BLOCK_SIZE bytes block
     64  */
     65 static void
     66 md5_transform (uint32_t H[MD5_HASH_SIZE_WORDS],
     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; /**< Zero-based index */
    310 
    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 
    385 /**
    386  * Process portion of bytes.
    387  *
    388  * @param ctx the calculation context
    389  * @param data bytes to add to hash
    390  * @param length number of bytes in @a data
    391  */
    392 void
    393 MHD_MD5_update (struct Md5Ctx *ctx,
    394                 const uint8_t *data,
    395                 size_t length)
    396 {
    397   unsigned int bytes_have; /**< Number of bytes in the context buffer */
    398 
    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 
    443 /**
    444  * Size of "length" insertion in bits.
    445  * See RFC 1321, end of Clause 3.2 (step 2).
    446  */
    447 #define MD5_SIZE_OF_LEN_ADD_BITS 64
    448 
    449 /**
    450  * Size of "length" insertion in bytes.
    451  */
    452 #define MD5_SIZE_OF_LEN_ADD (MD5_SIZE_OF_LEN_ADD_BITS / 8)
    453 
    454 /**
    455  * Finalise MD5 calculation, return digest.
    456  *
    457  * @param ctx the calculation context
    458  * @param[out] digest set to the hash, must be #MD5_DIGEST_SIZE bytes
    459  */
    460 void
    461 MHD_MD5_finish (struct Md5Ctx *ctx,
    462                 uint8_t digest[MD5_DIGEST_SIZE])
    463 {
    464   uint64_t num_bits;   /**< Number of processed bits */
    465   unsigned int bytes_have; /**< Number of bytes in the context buffer */
    466 
    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). */
    504   _MHD_PUT_64BIT_LE_SAFE (ctx->buffer + MD5_BLOCK_SIZE_WORDS - 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 
    551 MHD_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE_