LCOV - code coverage report
Current view: top level - lib - md5.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 111 119 93.3 %
Date: 2014-11-16 Functions: 4 4 100.0 %
Branches: 6 10 60.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *****************************************************************************
       3                 :            :  *
       4                 :            :  * File:    md5.c
       5                 :            :  *
       6                 :            :  * Purpose: Implementation of the MD5 message-digest algorithm for libfwknop.
       7                 :            :  *
       8                 :            :  * This code implements the MD5 message-digest algorithm.
       9                 :            :  *
      10                 :            :  * The algorithm is due to Ron Rivest. This code was
      11                 :            :  * written by Colin Plumb in 1993, no copyright is claimed.
      12                 :            :  * This code is in the public domain; do with it what you wish.
      13                 :            :  *
      14                 :            :  * Equivalent code is available from RSA Data Security, Inc.
      15                 :            :  * This code has been tested against that, and is equivalent,
      16                 :            :  * except that you don't need to include two pages of legalese
      17                 :            :  * with every copy.
      18                 :            :  *
      19                 :            :  * To compute the message digest of a chunk of bytes, declare an
      20                 :            :  * MD5Context structure, pass it to MD5Init, call MD5Update as
      21                 :            :  * needed on buffers full of bytes, and then call MD5Final, which
      22                 :            :  * will fill a supplied 16-byte array with the digest.
      23                 :            :  *
      24                 :            :  * This program is distributed in the hope that it will be useful,
      25                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      26                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      27                 :            :  *
      28                 :            :  *****************************************************************************
      29                 :            : */
      30                 :            : #include "md5.h"
      31                 :            : #include "fko_common.h"
      32                 :            : 
      33                 :            : #if BYTEORDER == 1234
      34                 :            :   #define byteReverse(buf, len)    /* Nothing */
      35                 :            : #elif BYTEORDER == 4321
      36                 :            :   /* Note: this code is harmless on little-endian machines.
      37                 :            :   */
      38                 :            :   void byteReverse(unsigned char *buf, unsigned longs)
      39                 :            :   {
      40                 :            :       uint32_t t;
      41                 :            :       do {
      42                 :            :           t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
      43                 :            :               ((unsigned) buf[1] << 8 | buf[0]);
      44                 :            :           *(uint32_t *) buf = t;
      45                 :            :           buf += 4;
      46                 :            :       } while (--longs);
      47                 :            :   }
      48                 :            : #else
      49                 :            :   #define byteReverse(buf, len)    /* Nothing */
      50                 :            :   #ifndef WIN32
      51                 :            :     #warning Undetermined or unsupported Byte Order... We will try LITTLE_ENDIAN
      52                 :            :   #endif
      53                 :            : #endif
      54                 :            : 
      55                 :            : /*
      56                 :            :  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
      57                 :            :  * initialization constants.
      58                 :            :  */
      59                 :            : void
      60                 :   15696410 : MD5Init(MD5Context *ctx)
      61                 :            : {
      62                 :   15696410 :     ctx->buf[0] = 0x67452301;
      63                 :   15696410 :     ctx->buf[1] = 0xefcdab89;
      64                 :   15696410 :     ctx->buf[2] = 0x98badcfe;
      65                 :   15696410 :     ctx->buf[3] = 0x10325476;
      66                 :            : 
      67                 :   15696410 :     ctx->bits[0] = 0;
      68                 :   15696410 :     ctx->bits[1] = 0;
      69                 :   15696410 : }
      70                 :            : 
      71                 :            : /* Update context to reflect the concatenation of another buffer full
      72                 :            :  * of bytes.
      73                 :            :  */
      74                 :            : void
      75                 :   16084952 : MD5Update(MD5Context *ctx, unsigned char *buf, unsigned len)
      76                 :            : {
      77                 :            :     uint32_t t;
      78                 :            : 
      79                 :            :     /* Update bitcount
      80                 :            :     */
      81                 :   16084952 :     t = ctx->bits[0];
      82         [ -  + ]:   16084952 :     if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
      83                 :          0 :     ctx->bits[1]++;     /* Carry from low to high */
      84                 :   16084952 :     ctx->bits[1] += len >> 29;
      85                 :            : 
      86                 :   16084952 :     t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
      87                 :            : 
      88                 :            :     /* Handle any leading odd-sized chunks
      89                 :            :     */
      90         [ -  + ]:   16084952 :     if (t) {
      91                 :          0 :         unsigned char *p = (unsigned char *) ctx->in + t;
      92                 :            : 
      93                 :          0 :         t = 64 - t;
      94                 :            : 
      95         [ #  # ]:          0 :         if (len < t) {
      96                 :          0 :             memcpy(p, buf, len);
      97                 :   16084952 :             return;
      98                 :            :         }
      99                 :            : 
     100                 :          0 :         memcpy(p, buf, t);
     101                 :            :         byteReverse(ctx->in, 16);
     102                 :          0 :         MD5Transform(ctx->buf, (uint32_t *) ctx->in);
     103                 :          0 :         buf += t;
     104                 :   16084952 :         len -= t;
     105                 :            :     }
     106                 :            : 
     107                 :            :     /* Process data in 64-byte chunks
     108                 :            :     */
     109         [ +  + ]:   17550077 :     while (len >= 64) {
     110                 :    1465125 :         memcpy(ctx->in, buf, 64);
     111                 :            :         byteReverse(ctx->in, 16);
     112                 :    1465125 :         MD5Transform(ctx->buf, (uint32_t *) ctx->in);
     113                 :    1465125 :         buf += 64;
     114                 :    1465125 :         len -= 64;
     115                 :            :     }
     116                 :            : 
     117                 :            :     /* Handle any remaining bytes of data.
     118                 :            :     */
     119                 :   16084952 :     memcpy(ctx->in, buf, len);
     120                 :            : }
     121                 :            : 
     122                 :            : /* Final wrapup - pad to 64-byte boundary with the bit pattern 
     123                 :            :  * 1 0* (64-bit count of bits processed, MSB-first)
     124                 :            :  */
     125                 :            : void
     126                 :   15696410 : MD5Final(unsigned char digest[16], MD5Context *ctx)
     127                 :            : {
     128                 :            :     unsigned count;
     129                 :            :     unsigned char *p;
     130                 :            : 
     131                 :            :     /* Compute number of bytes mod 64
     132                 :            :     */
     133                 :   15696410 :     count = (ctx->bits[0] >> 3) & 0x3F;
     134                 :            : 
     135                 :            :     /* Set the first char of padding to 0x80.  This is safe since there is
     136                 :            :      * always at least one byte free
     137                 :            :     */
     138                 :   15696410 :     p = ctx->in + count;
     139                 :   15696410 :     *p++ = 0x80;
     140                 :            : 
     141                 :            :     /* Bytes of padding needed to make 64 bytes
     142                 :            :     */
     143                 :   15696410 :     count = 64 - 1 - count;
     144                 :            : 
     145                 :            :     /* Pad out to 56 mod 64
     146                 :            :     */
     147         [ +  + ]:   15696410 :     if (count < 8) {
     148                 :            :         /* Two lots of padding:  Pad the first block to 64 bytes
     149                 :            :         */
     150                 :    2799586 :         memset(p, 0, count);
     151                 :            :         byteReverse(ctx->in, 16);
     152                 :    2799586 :         MD5Transform(ctx->buf, (uint32_t *) ctx->in);
     153                 :            : 
     154                 :            :         /* Now fill the next block with 56 bytes
     155                 :            :         */
     156                 :    2799586 :         memset(ctx->in, 0, 56);
     157                 :            :     } else {
     158                 :            :         /* Pad block to 56 bytes
     159                 :            :         */
     160                 :   12896824 :         memset(p, 0, count - 8);
     161                 :            :     }
     162                 :            : 
     163                 :            :     byteReverse(ctx->in, 14);
     164                 :            : 
     165                 :            :     /* Append length in bits and transform
     166                 :            :     */
     167                 :   15696410 :     memcpy(&(ctx->in[56]), &(ctx->bits[0]), sizeof(uint32_t));
     168                 :   15696410 :     memcpy(&(ctx->in[60]), &(ctx->bits[1]), sizeof(uint32_t));
     169                 :            : 
     170                 :   15696410 :     MD5Transform(ctx->buf, (uint32_t *) ctx->in);
     171                 :            :     byteReverse((unsigned char *) ctx->buf, 4);
     172                 :   15696410 :     memcpy(digest, ctx->buf, 16);
     173                 :            : 
     174                 :            :     memset(ctx, 0, sizeof(*ctx));        /* In case it's sensitive */
     175                 :   15696410 : }
     176                 :            : 
     177                 :            : 
     178                 :            : /* The four core functions
     179                 :            : */
     180                 :            : #define F1(x, y, z) (z ^ (x & (y ^ z)))
     181                 :            : #define F2(x, y, z) F1(z, x, y)
     182                 :            : #define F3(x, y, z) (x ^ y ^ z)
     183                 :            : #define F4(x, y, z) (y ^ (x | ~z))
     184                 :            : 
     185                 :            : /* This is the central step in the MD5 algorithm.
     186                 :            : */
     187                 :            : #define MD5STEP(f, w, x, y, z, data, s) \
     188                 :            :     ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
     189                 :            : 
     190                 :            : /* The core of the MD5 algorithm, this alters an existing MD5 hash to
     191                 :            :  * reflect the addition of 16 longwords of new data.  MD5Update blocks
     192                 :            :  * the data and converts bytes into longwords for this routine.
     193                 :            : */
     194                 :            : void
     195                 :   19961121 : MD5Transform(uint32_t buf[4], uint32_t in[16])
     196                 :            : {
     197                 :            :     register uint32_t a, b, c, d;
     198                 :            : 
     199                 :   19961121 :     a = buf[0];
     200                 :   19961121 :     b = buf[1];
     201                 :   19961121 :     c = buf[2];
     202                 :   19961121 :     d = buf[3];
     203                 :            : 
     204                 :   19961121 :     MD5STEP(F1, a, b, c, d, in[0]  + 0xd76aa478, 7);
     205                 :   19961121 :     MD5STEP(F1, d, a, b, c, in[1]  + 0xe8c7b756, 12);
     206                 :   19961121 :     MD5STEP(F1, c, d, a, b, in[2]  + 0x242070db, 17);
     207                 :   19961121 :     MD5STEP(F1, b, c, d, a, in[3]  + 0xc1bdceee, 22);
     208                 :   19961121 :     MD5STEP(F1, a, b, c, d, in[4]  + 0xf57c0faf, 7);
     209                 :   19961121 :     MD5STEP(F1, d, a, b, c, in[5]  + 0x4787c62a, 12);
     210                 :   19961121 :     MD5STEP(F1, c, d, a, b, in[6]  + 0xa8304613, 17);
     211                 :   19961121 :     MD5STEP(F1, b, c, d, a, in[7]  + 0xfd469501, 22);
     212                 :   19961121 :     MD5STEP(F1, a, b, c, d, in[8]  + 0x698098d8, 7);
     213                 :   19961121 :     MD5STEP(F1, d, a, b, c, in[9]  + 0x8b44f7af, 12);
     214                 :   19961121 :     MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
     215                 :   19961121 :     MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
     216                 :   19961121 :     MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
     217                 :   19961121 :     MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
     218                 :   19961121 :     MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
     219                 :   19961121 :     MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
     220                 :            : 
     221                 :   19961121 :     MD5STEP(F2, a, b, c, d, in[1]  + 0xf61e2562, 5);
     222                 :   19961121 :     MD5STEP(F2, d, a, b, c, in[6]  + 0xc040b340, 9);
     223                 :   19961121 :     MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
     224                 :   19961121 :     MD5STEP(F2, b, c, d, a, in[0]  + 0xe9b6c7aa, 20);
     225                 :   19961121 :     MD5STEP(F2, a, b, c, d, in[5]  + 0xd62f105d, 5);
     226                 :   19961121 :     MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
     227                 :   19961121 :     MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
     228                 :   19961121 :     MD5STEP(F2, b, c, d, a, in[4]  + 0xe7d3fbc8, 20);
     229                 :   19961121 :     MD5STEP(F2, a, b, c, d, in[9]  + 0x21e1cde6, 5);
     230                 :   19961121 :     MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
     231                 :   19961121 :     MD5STEP(F2, c, d, a, b, in[3]  + 0xf4d50d87, 14);
     232                 :   19961121 :     MD5STEP(F2, b, c, d, a, in[8]  + 0x455a14ed, 20);
     233                 :   19961121 :     MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
     234                 :   19961121 :     MD5STEP(F2, d, a, b, c, in[2]  + 0xfcefa3f8, 9);
     235                 :   19961121 :     MD5STEP(F2, c, d, a, b, in[7]  + 0x676f02d9, 14);
     236                 :   19961121 :     MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
     237                 :            : 
     238                 :   19961121 :     MD5STEP(F3, a, b, c, d, in[5]  + 0xfffa3942, 4);
     239                 :   19961121 :     MD5STEP(F3, d, a, b, c, in[8]  + 0x8771f681, 11);
     240                 :   19961121 :     MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
     241                 :   19961121 :     MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
     242                 :   19961121 :     MD5STEP(F3, a, b, c, d, in[1]  + 0xa4beea44, 4);
     243                 :   19961121 :     MD5STEP(F3, d, a, b, c, in[4]  + 0x4bdecfa9, 11);
     244                 :   19961121 :     MD5STEP(F3, c, d, a, b, in[7]  + 0xf6bb4b60, 16);
     245                 :   19961121 :     MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
     246                 :   19961121 :     MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
     247                 :   19961121 :     MD5STEP(F3, d, a, b, c, in[0]  + 0xeaa127fa, 11);
     248                 :   19961121 :     MD5STEP(F3, c, d, a, b, in[3]  + 0xd4ef3085, 16);
     249                 :   19961121 :     MD5STEP(F3, b, c, d, a, in[6]  + 0x04881d05, 23);
     250                 :   19961121 :     MD5STEP(F3, a, b, c, d, in[9]  + 0xd9d4d039, 4);
     251                 :   19961121 :     MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
     252                 :   19961121 :     MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
     253                 :   19961121 :     MD5STEP(F3, b, c, d, a, in[2]  + 0xc4ac5665, 23);
     254                 :            : 
     255                 :   19961121 :     MD5STEP(F4, a, b, c, d, in[0]  + 0xf4292244, 6);
     256                 :   19961121 :     MD5STEP(F4, d, a, b, c, in[7]  + 0x432aff97, 10);
     257                 :   19961121 :     MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
     258                 :   19961121 :     MD5STEP(F4, b, c, d, a, in[5]  + 0xfc93a039, 21);
     259                 :   19961121 :     MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
     260                 :   19961121 :     MD5STEP(F4, d, a, b, c, in[3]  + 0x8f0ccc92, 10);
     261                 :   19961121 :     MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
     262                 :   19961121 :     MD5STEP(F4, b, c, d, a, in[1]  + 0x85845dd1, 21);
     263                 :   19961121 :     MD5STEP(F4, a, b, c, d, in[8]  + 0x6fa87e4f, 6);
     264                 :   19961121 :     MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
     265                 :   19961121 :     MD5STEP(F4, c, d, a, b, in[6]  + 0xa3014314, 15);
     266                 :   19961121 :     MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
     267                 :   19961121 :     MD5STEP(F4, a, b, c, d, in[4]  + 0xf7537e82, 6);
     268                 :   19961121 :     MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
     269                 :   19961121 :     MD5STEP(F4, c, d, a, b, in[2]  + 0x2ad7d2bb, 15);
     270                 :   19961121 :     MD5STEP(F4, b, c, d, a, in[9]  + 0xeb86d391, 21);
     271                 :            : 
     272                 :   19961121 :     buf[0] += a;
     273                 :   19961121 :     buf[1] += b;
     274                 :   19961121 :     buf[2] += c;
     275                 :   19961121 :     buf[3] += d;
     276                 :   19961121 : } 
     277                 :            : 
     278                 :            : /***EOF***/

Generated by: LCOV version 1.10