LCOV - code coverage report
Current view: top level - crypto - md5.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 113 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: md5.c,v 1.4 2014/12/28 10:04:35 tedu Exp $    */
       2             : 
       3             : /*
       4             :  * This code implements the MD5 message-digest algorithm.
       5             :  * The algorithm is due to Ron Rivest.  This code was
       6             :  * written by Colin Plumb in 1993, no copyright is claimed.
       7             :  * This code is in the public domain; do with it what you wish.
       8             :  *
       9             :  * Equivalent code is available from RSA Data Security, Inc.
      10             :  * This code has been tested against that, and is equivalent,
      11             :  * except that you don't need to include two pages of legalese
      12             :  * with every copy.
      13             :  *
      14             :  * To compute the message digest of a chunk of bytes, declare an
      15             :  * MD5Context structure, pass it to MD5Init, call MD5Update as
      16             :  * needed on buffers full of bytes, and then call MD5Final, which
      17             :  * will fill a supplied 16-byte array with the digest.
      18             :  */
      19             : 
      20             : #include <sys/param.h>
      21             : #include <sys/systm.h>
      22             : #include <crypto/md5.h>
      23             : 
      24             : #define PUT_64BIT_LE(cp, value) do {                                    \
      25             :         (cp)[7] = (value) >> 56;                                  \
      26             :         (cp)[6] = (value) >> 48;                                  \
      27             :         (cp)[5] = (value) >> 40;                                  \
      28             :         (cp)[4] = (value) >> 32;                                  \
      29             :         (cp)[3] = (value) >> 24;                                  \
      30             :         (cp)[2] = (value) >> 16;                                  \
      31             :         (cp)[1] = (value) >> 8;                                           \
      32             :         (cp)[0] = (value); } while (0)
      33             : 
      34             : #define PUT_32BIT_LE(cp, value) do {                                    \
      35             :         (cp)[3] = (value) >> 24;                                  \
      36             :         (cp)[2] = (value) >> 16;                                  \
      37             :         (cp)[1] = (value) >> 8;                                           \
      38             :         (cp)[0] = (value); } while (0)
      39             : 
      40             : static u_int8_t PADDING[MD5_BLOCK_LENGTH] = {
      41             :         0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      42             :         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      43             :         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
      44             : };
      45             : 
      46             : /*
      47             :  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
      48             :  * initialization constants.
      49             :  */
      50             : void
      51           0 : MD5Init(MD5_CTX *ctx)
      52             : {
      53           0 :         ctx->count = 0;
      54           0 :         ctx->state[0] = 0x67452301;
      55           0 :         ctx->state[1] = 0xefcdab89;
      56           0 :         ctx->state[2] = 0x98badcfe;
      57           0 :         ctx->state[3] = 0x10325476;
      58           0 : }
      59             : 
      60             : /*
      61             :  * Update context to reflect the concatenation of another buffer full
      62             :  * of bytes.
      63             :  */
      64             : void
      65           0 : MD5Update(MD5_CTX *ctx, const void *inputptr, size_t len)
      66             : {
      67             :         const uint8_t *input = inputptr;
      68             :         size_t have, need;
      69             : 
      70             :         /* Check how many bytes we already have and how many more we need. */
      71           0 :         have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
      72           0 :         need = MD5_BLOCK_LENGTH - have;
      73             : 
      74             :         /* Update bitcount */
      75           0 :         ctx->count += (u_int64_t)len << 3;
      76             : 
      77           0 :         if (len >= need) {
      78           0 :                 if (have != 0) {
      79           0 :                         memcpy(ctx->buffer + have, input, need);
      80           0 :                         MD5Transform(ctx->state, ctx->buffer);
      81           0 :                         input += need;
      82           0 :                         len -= need;
      83             :                         have = 0;
      84           0 :                 }
      85             : 
      86             :                 /* Process data in MD5_BLOCK_LENGTH-byte chunks. */
      87           0 :                 while (len >= MD5_BLOCK_LENGTH) {
      88           0 :                         MD5Transform(ctx->state, input);
      89           0 :                         input += MD5_BLOCK_LENGTH;
      90           0 :                         len -= MD5_BLOCK_LENGTH;
      91             :                 }
      92             :         }
      93             : 
      94             :         /* Handle any remaining bytes of data. */
      95           0 :         if (len != 0)
      96           0 :                 memcpy(ctx->buffer + have, input, len);
      97           0 : }
      98             : 
      99             : /*
     100             :  * Final wrapup - pad to 64-byte boundary with the bit pattern
     101             :  * 1 0* (64-bit count of bits processed, MSB-first)
     102             :  */
     103             : void
     104           0 : MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
     105             : {
     106           0 :         u_int8_t count[8];
     107             :         size_t padlen;
     108             :         int i;
     109             : 
     110             :         /* Convert count to 8 bytes in little endian order. */
     111           0 :         PUT_64BIT_LE(count, ctx->count);
     112             : 
     113             :         /* Pad out to 56 mod 64. */
     114           0 :         padlen = MD5_BLOCK_LENGTH -
     115           0 :             ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
     116           0 :         if (padlen < 1 + 8)
     117           0 :                 padlen += MD5_BLOCK_LENGTH;
     118           0 :         MD5Update(ctx, PADDING, padlen - 8);            /* padlen - 8 <= 64 */
     119           0 :         MD5Update(ctx, count, 8);
     120             : 
     121           0 :         for (i = 0; i < 4; i++)
     122           0 :                 PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
     123           0 :         explicit_bzero(ctx, sizeof(*ctx));      /* in case it's sensitive */
     124           0 : }
     125             : 
     126             : 
     127             : /* The four core functions - F1 is optimized somewhat */
     128             : 
     129             : /* #define F1(x, y, z) (x & y | ~x & z) */
     130             : #define F1(x, y, z) (z ^ (x & (y ^ z)))
     131             : #define F2(x, y, z) F1(z, x, y)
     132             : #define F3(x, y, z) (x ^ y ^ z)
     133             : #define F4(x, y, z) (y ^ (x | ~z))
     134             : 
     135             : /* This is the central step in the MD5 algorithm. */
     136             : #define MD5STEP(f, w, x, y, z, data, s) \
     137             :         ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
     138             : 
     139             : /*
     140             :  * The core of the MD5 algorithm, this alters an existing MD5 hash to
     141             :  * reflect the addition of 16 longwords of new data.  MD5Update blocks
     142             :  * the data and converts bytes into longwords for this routine.
     143             :  */
     144             : void
     145           0 : MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH])
     146             : {
     147             :         u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
     148             : 
     149             : #if BYTE_ORDER == LITTLE_ENDIAN
     150           0 :         memcpy(in, block, sizeof(in));
     151             : #else
     152             :         for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
     153             :                 in[a] = (u_int32_t)(
     154             :                     (u_int32_t)(block[a * 4 + 0]) |
     155             :                     (u_int32_t)(block[a * 4 + 1]) <<  8 |
     156             :                     (u_int32_t)(block[a * 4 + 2]) << 16 |
     157             :                     (u_int32_t)(block[a * 4 + 3]) << 24);
     158             :         }
     159             : #endif
     160             : 
     161           0 :         a = state[0];
     162           0 :         b = state[1];
     163           0 :         c = state[2];
     164           0 :         d = state[3];
     165             : 
     166           0 :         MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
     167           0 :         MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
     168           0 :         MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
     169           0 :         MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
     170           0 :         MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
     171           0 :         MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
     172           0 :         MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
     173           0 :         MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
     174           0 :         MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
     175           0 :         MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
     176           0 :         MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
     177           0 :         MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
     178           0 :         MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
     179           0 :         MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
     180           0 :         MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
     181           0 :         MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
     182             : 
     183           0 :         MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
     184           0 :         MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
     185           0 :         MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
     186           0 :         MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
     187           0 :         MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
     188           0 :         MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
     189           0 :         MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
     190           0 :         MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
     191           0 :         MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
     192           0 :         MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
     193           0 :         MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
     194           0 :         MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
     195           0 :         MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
     196           0 :         MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
     197           0 :         MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
     198           0 :         MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
     199             : 
     200           0 :         MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
     201           0 :         MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
     202           0 :         MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
     203           0 :         MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
     204           0 :         MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
     205           0 :         MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
     206           0 :         MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
     207           0 :         MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
     208           0 :         MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
     209           0 :         MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
     210           0 :         MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
     211           0 :         MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
     212           0 :         MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
     213           0 :         MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
     214           0 :         MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
     215           0 :         MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
     216             : 
     217           0 :         MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
     218           0 :         MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
     219           0 :         MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
     220           0 :         MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
     221           0 :         MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
     222           0 :         MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
     223           0 :         MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
     224           0 :         MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
     225           0 :         MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6);
     226           0 :         MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
     227           0 :         MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
     228           0 :         MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
     229           0 :         MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6);
     230           0 :         MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
     231           0 :         MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
     232           0 :         MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
     233             : 
     234           0 :         state[0] += a;
     235           0 :         state[1] += b;
     236           0 :         state[2] += c;
     237           0 :         state[3] += d;
     238           0 : }

Generated by: LCOV version 1.13