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