home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / lib / md5.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  8KB  |  278 lines

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