home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / hash / md5.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-25  |  13.5 KB  |  417 lines  |  [TEXT/R*ch]

  1. /* @(#)md5.c    10.1 3/25/94 08:04:10 */
  2. /*
  3.  * md5 - RSA Data Security, Inc. MD5 Message-Digest Algorithm
  4.  *
  5.  * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH  REGARD  TO
  6.  * THIS  SOFTWARE,  INCLUDING  ALL IMPLIED WARRANTIES OF MER-
  7.  * CHANTABILITY AND FITNESS.  IN NO EVENT SHALL  LANDON  CURT
  8.  * NOLL  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  9.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM  LOSS  OF
  10.  * USE,  DATA  OR  PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  11.  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR  IN
  12.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  13.  *
  14.  * See md5drvr.c for version and modification history.
  15.  */
  16.  
  17. /*
  18.  ***********************************************************************
  19.  ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
  20.  **                                      **
  21.  ** License to copy and use this software is granted provided that    **
  22.  ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
  23.  ** Digest Algorithm" in all material mentioning or referencing this  **
  24.  ** software or this function.                          **
  25.  **                                      **
  26.  ** License is also granted to make and use derivative works          **
  27.  ** provided that such works are identified as "derived from the RSA  **
  28.  ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
  29.  ** material mentioning or referencing the derived work.          **
  30.  **                                      **
  31.  ** RSA Data Security, Inc. makes no representations concerning       **
  32.  ** either the merchantability of this software or the suitability    **
  33.  ** of this software for any particular purpose.  It is provided "as  **
  34.  ** is" without express or implied warranty of any kind.              **
  35.  **                                      **
  36.  ** These notices must be retained in any copies of any part of this  **
  37.  ** documentation and/or software.                      **
  38.  ***********************************************************************
  39.  */
  40.  
  41. /*
  42.  ***********************************************************************
  43.  **  Message-digest routines:                          **
  44.  **  To form the message digest for a message M               **
  45.  **    (1) Initialize a context buffer md5Ctx using MD5Init          **
  46.  **    (2) Call MD5Update on md5Ctx and M                  **
  47.  **    (3) Call MD5Final on md5Ctx                      **
  48.  **  The message digest is now in md5Ctx->digest[0...15]          **
  49.  ***********************************************************************
  50.  */
  51.  
  52.  
  53. #include "md5.h"
  54. #include "align.h"
  55. #include "endian.h"
  56.  
  57. char *MD5_what="@(#)";    /* #(@) if checked in */
  58.  
  59. /* almost zero fill */
  60. static BYTE PADDING[MD5_CHUNKSIZE] = {
  61.     0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  62.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  63.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  64.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  65.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  66.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  68.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  69. };
  70.  
  71. /*
  72.  * The F, G, H and I are basic MD5 functions.  The following
  73.  * identity saves one boolean operation.
  74.  *
  75.  * F: (((x) & (y)) | (~(x) & (z))) == ((z) ^ ((x) & ((y) ^ (z))))
  76.  * G: (((x) & (z)) | ((y) & ~(z))) == ((y) ^ ((z) & ((x) ^ (y))))
  77.  */
  78. /* F, G, H and I are basic MD5 functions */
  79. #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
  80. #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
  81. #define H(x, y, z) ((x) ^ (y) ^ (z))
  82. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  83.  
  84. /* rotate a 32 bit value */
  85. #define ROT(X,n) (((X)<<(n)) | ((X)>>(32-(n))))
  86.  
  87. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
  88. /* Rotation is separate from addition to prevent recomputation */
  89. #define S11 7
  90. #define S12 12
  91. #define S13 17
  92. #define S14 22
  93. #define FF(a, b, c, d, x, s, ac) \
  94.     {(a) += F((b), (c), (d)) + (x) + (ULONG)(ac); \
  95.      (a) = ROT((a), (s)); \
  96.      (a) += (b); \
  97.     }
  98. #define S21 5
  99. #define S22 9
  100. #define S23 14
  101. #define S24 20
  102. #define GG(a, b, c, d, x, s, ac) \
  103.     {(a) += G((b), (c), (d)) + (x) + (ULONG)(ac); \
  104.      (a) = ROT((a), (s)); \
  105.      (a) += (b); \
  106.     }
  107. #define S31 4
  108. #define S32 11
  109. #define S33 16
  110. #define S34 23
  111. #define HH(a, b, c, d, x, s, ac) \
  112.     {(a) += H((b), (c), (d)) + (x) + (ULONG)(ac); \
  113.      (a) = ROT((a), (s)); \
  114.      (a) += (b); \
  115.     }
  116. #define S41 6
  117. #define S42 10
  118. #define S43 15
  119. #define S44 21
  120. #define II(a, b, c, d, x, s, ac) \
  121.     {(a) += I((b), (c), (d)) + (x) + (ULONG)(ac); \
  122.      (a) = ROT((a), (s)); \
  123.      (a) += (b); \
  124.     }
  125.  
  126. /* forward declaration */
  127. static void MD5Transform P((ULONG*, ULONG*));
  128. static ULONG in[MD5_CHUNKWORDS];
  129.  
  130.  
  131. /*
  132.  * MD5Init - initiale the message-digest context
  133.  *
  134.  * The routine MD5Init initializes the message-digest context
  135.  * md5Ctx. All fields are set to zero.
  136.  */
  137. void
  138. MD5Init(md5Ctx)
  139.     MD5_CTX *md5Ctx;
  140. {
  141.     /* load magic initialization constants */
  142.     md5Ctx->buf[0] = (ULONG)0x67452301;
  143.     md5Ctx->buf[1] = (ULONG)0xefcdab89;
  144.     md5Ctx->buf[2] = (ULONG)0x98badcfe;
  145.     md5Ctx->buf[3] = (ULONG)0x10325476;
  146.  
  147.     /* Initialise bit count */
  148.     md5Ctx->countLo = 0L;
  149.     md5Ctx->countHi = 0L;
  150.     md5Ctx->datalen = 0L;
  151. }
  152.  
  153.  
  154. /*
  155.  * MD5Update - update message-digest context
  156.  *
  157.  * The routine MD5Update updates the message-digest context to
  158.  * account for the presence of each of the characters inBuf[0..inLen-1]
  159.  * in the message whose digest is being computed.
  160.  */
  161. void
  162. MD5Update(md5Ctx, inBuf, count)
  163.     MD5_CTX *md5Ctx;
  164.     BYTE *inBuf;
  165.     UINT count;
  166. {
  167.     ULONG datalen = md5Ctx->datalen;
  168. #if BYTE_ORDER == BIG_ENDIAN
  169.     ULONG tmp;
  170.     int cnt;
  171. #endif
  172.  
  173.     /*
  174.      * Catch the case of a non-empty data inBuf
  175.      */
  176.     if (datalen > 0) {
  177.  
  178.     /* determine the size we need to copy */
  179.     ULONG cpylen = MD5_CHUNKSIZE - datalen;
  180.  
  181.     /* case: new data will not fill the inBuf */
  182.     if (cpylen > count) {
  183.         memcpy((char *)(md5Ctx->in_byte)+datalen, (char *)inBuf, count);
  184.         md5Ctx->datalen = datalen+count;
  185.         return;
  186.  
  187.     /* case: inBuf will be filled */
  188.     } else {
  189.         memcpy((char *)(md5Ctx->in_byte)+datalen, (char *)inBuf, cpylen);
  190. #if BYTE_ORDER == BIG_ENDIAN
  191.         /* byte swap data into little endian order */
  192.         for (cnt=0; cnt < MD5_CHUNKWORDS; ++cnt) {
  193.         tmp = (md5Ctx->in_ulong[cnt] << 16) |
  194.             (md5Ctx->in_ulong[cnt] >> 16);
  195.         in[cnt] = ((tmp & 0xFF00FF00L) >> 8) |
  196.               ((tmp & 0x00FF00FFL) << 8);
  197.         }
  198.         MD5Transform(md5Ctx->buf, in);
  199. #else
  200.         MD5Transform(md5Ctx->buf, md5Ctx->in_ulong);
  201. #endif
  202.         inBuf += cpylen;
  203.         count -= cpylen;
  204.         md5Ctx->datalen = 0;
  205.     }
  206.     }
  207.  
  208.     /*
  209.      * Process data in MD5_CHUNKSIZE chunks
  210.      */
  211.     if (count >= MD5_CHUNKSIZE) {
  212.         MD5fullUpdate(md5Ctx, inBuf, count);
  213.     inBuf += (count/MD5_CHUNKSIZE)*MD5_CHUNKSIZE;
  214.     count %= MD5_CHUNKSIZE;
  215.     }
  216.  
  217.     /*
  218.      * Handle any remaining bytes of data.
  219.      * This should only happen once on the final lot of data
  220.      */
  221.     if (count > 0) {
  222.     memcpy(md5Ctx->in_byte, inBuf, count);
  223.     }
  224.     md5Ctx->datalen = count;
  225. }
  226.  
  227.  
  228. /*
  229.  * MD5fullUpdate - update message-digest context with a full set of chunks
  230.  *
  231.  * The routine MD5Update updates the message-digest context to
  232.  * account for the presence of each of the characters inBuf[0..inLen-1]
  233.  * in the message whose digest is being computed.
  234.  *
  235.  * Unlike MD5Update, this routine will assume that the input length is
  236.  * a mulitple of MD5_CHUNKSIZE bytes long.
  237.  */
  238. void
  239. MD5fullUpdate(md5Ctx, inBuf, count)
  240.     MD5_CTX *md5Ctx;
  241.     BYTE *inBuf;
  242.     UINT count;
  243. {
  244. #if BYTE_ORDER == BIG_ENDIAN
  245.     ULONG tmp;
  246.     int cnt;
  247. #endif
  248.  
  249.     /*
  250.      * Process data in MD5_CHUNKSIZE chunks
  251.      */
  252.     while (count >= MD5_CHUNKSIZE) {
  253. #if defined(MUST_ALIGN)
  254.     memcpy(in, inBuf, MD5_CHUNKSIZE);
  255. #if BYTE_ORDER == BIG_ENDIAN
  256.     /* byte swap data into little endian order */
  257.     for (cnt=0; cnt < MD5_CHUNKWORDS; ++cnt) {
  258.         tmp = (in[cnt] << 16) | (in[cnt] >> 16);
  259.         in[cnt] = ((tmp & 0xFF00FF00L) >> 8) | ((tmp & 0x00FF00FFL) << 8);
  260.     }
  261. #endif
  262.     MD5Transform(md5Ctx->buf, in);
  263. #else
  264. #if BYTE_ORDER == LITTLE_ENDIAN
  265.     MD5Transform(md5Ctx->buf, (ULONG *)inBuf);
  266. #else
  267.     /* byte swap data into little endian order */
  268.     for (cnt=0; cnt < MD5_CHUNKWORDS; ++cnt) {
  269.         tmp = (((ULONG *)inBuf)[cnt] << 16) | (((ULONG *)inBuf)[cnt] >> 16);
  270.         in[cnt] = ((tmp & 0xFF00FF00L) >> 8) | ((tmp & 0x00FF00FFL) << 8);
  271.     }
  272.     MD5Transform(md5Ctx->buf, in);
  273. #endif
  274. #endif
  275.     inBuf += MD5_CHUNKSIZE;
  276.     count -= MD5_CHUNKSIZE;
  277.     }
  278. }
  279.  
  280.  
  281. /*
  282.  * MD5Final - terminate the message-digest computation
  283.  *
  284.  * The routine MD5Final terminates the message-digest computation and
  285.  * ends with the desired message digest in md5Ctx->digest[0...15].
  286.  */
  287. void
  288. MD5Final(md5Ctx)
  289.     MD5_CTX *md5Ctx;
  290. {
  291.     UINT padLen;
  292.     int count = md5Ctx->datalen;
  293.     ULONG lowBitcount = md5Ctx->countLo;
  294.     ULONG highBitcount = md5Ctx->countHi;
  295. #if BYTE_ORDER == BIG_ENDIAN
  296.     ULONG tmp;
  297.     UINT i, ii;
  298. #endif
  299.  
  300.     /* pad out to 56 mod MD5_CHUNKSIZE */
  301.     padLen = (count < 56) ? (56 - count) : (120 - count);
  302.     MD5Update(md5Ctx, PADDING, padLen);
  303.  
  304.     /* append length in bits and transform */
  305. #if BYTE_ORDER == BIG_ENDIAN
  306.     for (i = 0; i < 14; i++) {
  307.     tmp = (md5Ctx->in_ulong[i] << 16) | (md5Ctx->in_ulong[i] >> 16);
  308.     md5Ctx->in_ulong[i] = ((tmp & 0xFF00FF00L) >> 8) |
  309.                   ((tmp & 0x00FF00FFL) << 8);
  310.     }
  311. #endif
  312.     md5Ctx->in_ulong[MD5_LOW] = (lowBitcount << 3);
  313.     md5Ctx->in_ulong[MD5_HIGH] = (highBitcount << 3) | (lowBitcount >> 29);
  314.     MD5Transform(md5Ctx->buf, md5Ctx->in_ulong);
  315.  
  316.     /* store buffer in digest */
  317. #if BYTE_ORDER == LITTLE_ENDIAN
  318.     memcpy((char *)md5Ctx->digest, (char *)md5Ctx->buf, sizeof(md5Ctx->digest));
  319. #else
  320.     for (i = 0, ii = 0; i < MD5_DIGESTWORDS; i++, ii += 4) {
  321.     md5Ctx->digest[ii] = (BYTE)(md5Ctx->buf[i] & 0xFF);
  322.     md5Ctx->digest[ii+1] = (BYTE)((md5Ctx->buf[i] >> 8) & 0xFF);
  323.     md5Ctx->digest[ii+2] = (BYTE)((md5Ctx->buf[i] >> 16) & 0xFF);
  324.     md5Ctx->digest[ii+3] = (BYTE)((md5Ctx->buf[i] >> 24) & 0xFF);
  325.     }
  326. #endif
  327. }
  328.  
  329.  
  330. /*
  331.  * Basic MD5 step. Transforms buf based on in.
  332.  */
  333. static void
  334. MD5Transform(buf, in)
  335.     ULONG *buf;
  336.     ULONG *in;
  337. {
  338.     ULONG a = buf[0], b = buf[1], c = buf[2], d = buf[3];
  339.  
  340.     /* Round 1 */
  341.     FF( a, b, c, d, in[ 0], S11, 3614090360UL); /* 1 */
  342.     FF( d, a, b, c, in[ 1], S12, 3905402710UL); /* 2 */
  343.     FF( c, d, a, b, in[ 2], S13,  606105819UL); /* 3 */
  344.     FF( b, c, d, a, in[ 3], S14, 3250441966UL); /* 4 */
  345.     FF( a, b, c, d, in[ 4], S11, 4118548399UL); /* 5 */
  346.     FF( d, a, b, c, in[ 5], S12, 1200080426UL); /* 6 */
  347.     FF( c, d, a, b, in[ 6], S13, 2821735955UL); /* 7 */
  348.     FF( b, c, d, a, in[ 7], S14, 4249261313UL); /* 8 */
  349.     FF( a, b, c, d, in[ 8], S11, 1770035416UL); /* 9 */
  350.     FF( d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */
  351.     FF( c, d, a, b, in[10], S13, 4294925233UL); /* 11 */
  352.     FF( b, c, d, a, in[11], S14, 2304563134UL); /* 12 */
  353.     FF( a, b, c, d, in[12], S11, 1804603682UL); /* 13 */
  354.     FF( d, a, b, c, in[13], S12, 4254626195UL); /* 14 */
  355.     FF( c, d, a, b, in[14], S13, 2792965006UL); /* 15 */
  356.     FF( b, c, d, a, in[15], S14, 1236535329UL); /* 16 */
  357.  
  358.     /* Round 2 */
  359.     GG( a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */
  360.     GG( d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */
  361.     GG( c, d, a, b, in[11], S23,  643717713UL); /* 19 */
  362.     GG( b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */
  363.     GG( a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */
  364.     GG( d, a, b, c, in[10], S22,   38016083UL); /* 22 */
  365.     GG( c, d, a, b, in[15], S23, 3634488961UL); /* 23 */
  366.     GG( b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */
  367.     GG( a, b, c, d, in[ 9], S21,  568446438UL); /* 25 */
  368.     GG( d, a, b, c, in[14], S22, 3275163606UL); /* 26 */
  369.     GG( c, d, a, b, in[ 3], S23, 4107603335UL); /* 27 */
  370.     GG( b, c, d, a, in[ 8], S24, 1163531501UL); /* 28 */
  371.     GG( a, b, c, d, in[13], S21, 2850285829UL); /* 29 */
  372.     GG( d, a, b, c, in[ 2], S22, 4243563512UL); /* 30 */
  373.     GG( c, d, a, b, in[ 7], S23, 1735328473UL); /* 31 */
  374.     GG( b, c, d, a, in[12], S24, 2368359562UL); /* 32 */
  375.  
  376.     /* Round 3 */
  377.     HH( a, b, c, d, in[ 5], S31, 4294588738UL); /* 33 */
  378.     HH( d, a, b, c, in[ 8], S32, 2272392833UL); /* 34 */
  379.     HH( c, d, a, b, in[11], S33, 1839030562UL); /* 35 */
  380.     HH( b, c, d, a, in[14], S34, 4259657740UL); /* 36 */
  381.     HH( a, b, c, d, in[ 1], S31, 2763975236UL); /* 37 */
  382.     HH( d, a, b, c, in[ 4], S32, 1272893353UL); /* 38 */
  383.     HH( c, d, a, b, in[ 7], S33, 4139469664UL); /* 39 */
  384.     HH( b, c, d, a, in[10], S34, 3200236656UL); /* 40 */
  385.     HH( a, b, c, d, in[13], S31,  681279174UL); /* 41 */
  386.     HH( d, a, b, c, in[ 0], S32, 3936430074UL); /* 42 */
  387.     HH( c, d, a, b, in[ 3], S33, 3572445317UL); /* 43 */
  388.     HH( b, c, d, a, in[ 6], S34,   76029189UL); /* 44 */
  389.     HH( a, b, c, d, in[ 9], S31, 3654602809UL); /* 45 */
  390.     HH( d, a, b, c, in[12], S32, 3873151461UL); /* 46 */
  391.     HH( c, d, a, b, in[15], S33,  530742520UL); /* 47 */
  392.     HH( b, c, d, a, in[ 2], S34, 3299628645UL); /* 48 */
  393.  
  394.     /* Round 4 */
  395.     II( a, b, c, d, in[ 0], S41, 4096336452UL); /* 49 */
  396.     II( d, a, b, c, in[ 7], S42, 1126891415UL); /* 50 */
  397.     II( c, d, a, b, in[14], S43, 2878612391UL); /* 51 */
  398.     II( b, c, d, a, in[ 5], S44, 4237533241UL); /* 52 */
  399.     II( a, b, c, d, in[12], S41, 1700485571UL); /* 53 */
  400.     II( d, a, b, c, in[ 3], S42, 2399980690UL); /* 54 */
  401.     II( c, d, a, b, in[10], S43, 4293915773UL); /* 55 */
  402.     II( b, c, d, a, in[ 1], S44, 2240044497UL); /* 56 */
  403.     II( a, b, c, d, in[ 8], S41, 1873313359UL); /* 57 */
  404.     II( d, a, b, c, in[15], S42, 4264355552UL); /* 58 */
  405.     II( c, d, a, b, in[ 6], S43, 2734768916UL); /* 59 */
  406.     II( b, c, d, a, in[13], S44, 1309151649UL); /* 60 */
  407.     II( a, b, c, d, in[ 4], S41, 4149444226UL); /* 61 */
  408.     II( d, a, b, c, in[11], S42, 3174756917UL); /* 62 */
  409.     II( c, d, a, b, in[ 2], S43,  718787259UL); /* 63 */
  410.     II( b, c, d, a, in[ 9], S44, 3951481745UL); /* 64 */
  411.  
  412.     buf[0] += a;
  413.     buf[1] += b;
  414.     buf[2] += c;
  415.     buf[3] += d;
  416. }
  417.