ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

crypt_md5.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001 Nikos Mavroyanopoulos
00003  * Copyright (C) 2004 Hans Leidekker
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00018  */
00019 
00020 /*
00021  * This code implements the MD5 message-digest algorithm.
00022  * It is based on code in the public domain written by Colin
00023  * Plumb in 1993. The algorithm is due to Ron Rivest.
00024  *
00025  * Equivalent code is available from RSA Data Security, Inc.
00026  * This code has been tested against that, and is equivalent,
00027  * except that you don't need to include two pages of legalese
00028  * with every copy.
00029  *
00030  * To compute the message digest of a chunk of bytes, declare an
00031  * MD5_CTX structure, pass it to MD5Init, call MD5Update as
00032  * needed on buffers full of bytes, and then call MD5Final, which
00033  * will fill a supplied 16-byte array with the digest.
00034  */
00035 
00036 #include <advapi32.h>
00037 
00038 typedef struct
00039 {
00040     unsigned int i[2];
00041     unsigned int buf[4];
00042     unsigned char in[64];
00043     unsigned char digest[16];
00044 } MD5_CTX;
00045 
00046 
00047 /* The four core functions - F1 is optimized somewhat */
00048 
00049 /* #define F1( x, y, z ) (x & y | ~x & z) */
00050 #define F1( x, y, z ) (z ^ (x & (y ^ z)))
00051 #define F2( x, y, z ) F1( z, x, y )
00052 #define F3( x, y, z ) (x ^ y ^ z)
00053 #define F4( x, y, z ) (y ^ (x | ~z))
00054 
00055 /* This is the central step in the MD5 algorithm. */
00056 #define MD5STEP( f, w, x, y, z, data, s ) \
00057         ( w += f( x, y, z ) + data,  w = w << s | w >> (32 - s),  w += x )
00058 
00059 /*
00060  * The core of the MD5 algorithm, this alters an existing MD5 hash to
00061  * reflect the addition of 16 longwords of new data.  MD5Update blocks
00062  * the data and converts bytes into longwords for this routine.
00063  */
00064 static void MD5Transform( unsigned int buf[4], const unsigned int in[16] )
00065 {
00066     register unsigned int a, b, c, d;
00067 
00068     a = buf[0];
00069     b = buf[1];
00070     c = buf[2];
00071     d = buf[3];
00072 
00073     MD5STEP( F1, a, b, c, d, in[0] + 0xd76aa478, 7 );
00074     MD5STEP( F1, d, a, b, c, in[1] + 0xe8c7b756, 12 );
00075     MD5STEP( F1, c, d, a, b, in[2] + 0x242070db, 17 );
00076     MD5STEP( F1, b, c, d, a, in[3] + 0xc1bdceee, 22 );
00077     MD5STEP( F1, a, b, c, d, in[4] + 0xf57c0faf, 7 );
00078     MD5STEP( F1, d, a, b, c, in[5] + 0x4787c62a, 12 );
00079     MD5STEP( F1, c, d, a, b, in[6] + 0xa8304613, 17 );
00080     MD5STEP( F1, b, c, d, a, in[7] + 0xfd469501, 22 );
00081     MD5STEP( F1, a, b, c, d, in[8] + 0x698098d8, 7 );
00082     MD5STEP( F1, d, a, b, c, in[9] + 0x8b44f7af, 12 );
00083     MD5STEP( F1, c, d, a, b, in[10] + 0xffff5bb1, 17 );
00084     MD5STEP( F1, b, c, d, a, in[11] + 0x895cd7be, 22 );
00085     MD5STEP( F1, a, b, c, d, in[12] + 0x6b901122, 7 );
00086     MD5STEP( F1, d, a, b, c, in[13] + 0xfd987193, 12 );
00087     MD5STEP( F1, c, d, a, b, in[14] + 0xa679438e, 17 );
00088     MD5STEP( F1, b, c, d, a, in[15] + 0x49b40821, 22 );
00089 
00090     MD5STEP( F2, a, b, c, d, in[1] + 0xf61e2562, 5 );
00091     MD5STEP( F2, d, a, b, c, in[6] + 0xc040b340, 9 );
00092     MD5STEP( F2, c, d, a, b, in[11] + 0x265e5a51, 14 );
00093     MD5STEP( F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20 );
00094     MD5STEP( F2, a, b, c, d, in[5] + 0xd62f105d, 5 );
00095     MD5STEP( F2, d, a, b, c, in[10] + 0x02441453, 9 );
00096     MD5STEP( F2, c, d, a, b, in[15] + 0xd8a1e681, 14 );
00097     MD5STEP( F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20 );
00098     MD5STEP( F2, a, b, c, d, in[9] + 0x21e1cde6, 5 );
00099     MD5STEP( F2, d, a, b, c, in[14] + 0xc33707d6, 9 );
00100     MD5STEP( F2, c, d, a, b, in[3] + 0xf4d50d87, 14 );
00101     MD5STEP( F2, b, c, d, a, in[8] + 0x455a14ed, 20 );
00102     MD5STEP( F2, a, b, c, d, in[13] + 0xa9e3e905, 5 );
00103     MD5STEP( F2, d, a, b, c, in[2] + 0xfcefa3f8, 9 );
00104     MD5STEP( F2, c, d, a, b, in[7] + 0x676f02d9, 14 );
00105     MD5STEP( F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20 );
00106 
00107     MD5STEP( F3, a, b, c, d, in[5] + 0xfffa3942, 4 );
00108     MD5STEP( F3, d, a, b, c, in[8] + 0x8771f681, 11 );
00109     MD5STEP( F3, c, d, a, b, in[11] + 0x6d9d6122, 16 );
00110     MD5STEP( F3, b, c, d, a, in[14] + 0xfde5380c, 23 );
00111     MD5STEP( F3, a, b, c, d, in[1] + 0xa4beea44, 4 );
00112     MD5STEP( F3, d, a, b, c, in[4] + 0x4bdecfa9, 11 );
00113     MD5STEP( F3, c, d, a, b, in[7] + 0xf6bb4b60, 16 );
00114     MD5STEP( F3, b, c, d, a, in[10] + 0xbebfbc70, 23 );
00115     MD5STEP( F3, a, b, c, d, in[13] + 0x289b7ec6, 4 );
00116     MD5STEP( F3, d, a, b, c, in[0] + 0xeaa127fa, 11 );
00117     MD5STEP( F3, c, d, a, b, in[3] + 0xd4ef3085, 16 );
00118     MD5STEP( F3, b, c, d, a, in[6] + 0x04881d05, 23 );
00119     MD5STEP( F3, a, b, c, d, in[9] + 0xd9d4d039, 4 );
00120     MD5STEP( F3, d, a, b, c, in[12] + 0xe6db99e5, 11 );
00121     MD5STEP( F3, c, d, a, b, in[15] + 0x1fa27cf8, 16 );
00122     MD5STEP( F3, b, c, d, a, in[2] + 0xc4ac5665, 23 );
00123 
00124     MD5STEP( F4, a, b, c, d, in[0] + 0xf4292244, 6 );
00125     MD5STEP( F4, d, a, b, c, in[7] + 0x432aff97, 10 );
00126     MD5STEP( F4, c, d, a, b, in[14] + 0xab9423a7, 15 );
00127     MD5STEP( F4, b, c, d, a, in[5] + 0xfc93a039, 21 );
00128     MD5STEP( F4, a, b, c, d, in[12] + 0x655b59c3, 6 );
00129     MD5STEP( F4, d, a, b, c, in[3] + 0x8f0ccc92, 10 );
00130     MD5STEP( F4, c, d, a, b, in[10] + 0xffeff47d, 15 );
00131     MD5STEP( F4, b, c, d, a, in[1] + 0x85845dd1, 21 );
00132     MD5STEP( F4, a, b, c, d, in[8] + 0x6fa87e4f, 6 );
00133     MD5STEP( F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10 );
00134     MD5STEP( F4, c, d, a, b, in[6] + 0xa3014314, 15 );
00135     MD5STEP( F4, b, c, d, a, in[13] + 0x4e0811a1, 21 );
00136     MD5STEP( F4, a, b, c, d, in[4] + 0xf7537e82, 6 );
00137     MD5STEP( F4, d, a, b, c, in[11] + 0xbd3af235, 10 );
00138     MD5STEP( F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15 );
00139     MD5STEP( F4, b, c, d, a, in[9] + 0xeb86d391, 21 );
00140 
00141     buf[0] += a;
00142     buf[1] += b;
00143     buf[2] += c;
00144     buf[3] += d;
00145 }
00146 
00147 /*
00148  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
00149  * initialization constants.
00150  */
00151 VOID WINAPI MD5Init( MD5_CTX *ctx )
00152 {
00153     ctx->buf[0] = 0x67452301;
00154     ctx->buf[1] = 0xefcdab89;
00155     ctx->buf[2] = 0x98badcfe;
00156     ctx->buf[3] = 0x10325476;
00157 
00158     ctx->i[0] = ctx->i[1] = 0;
00159 }
00160 
00161 /*
00162  * Update context to reflect the concatenation of another buffer full
00163  * of bytes.
00164  */
00165 VOID WINAPI MD5Update( MD5_CTX *ctx, const unsigned char *buf, unsigned int len )
00166 {
00167     register unsigned int t;
00168 
00169     /* Update bitcount */
00170     t = ctx->i[0];
00171 
00172     if ((ctx->i[0] = t + (len << 3)) < t)
00173         ctx->i[1]++;        /* Carry from low to high */
00174 
00175     ctx->i[1] += len >> 29;
00176     t = (t >> 3) & 0x3f;
00177 
00178     /* Handle any leading odd-sized chunks */
00179     if (t)
00180     {
00181         unsigned char *p = (unsigned char *)ctx->in + t;
00182         t = 64 - t;
00183 
00184         if (len < t)
00185         {
00186             memcpy( p, buf, len );
00187             return;
00188         }
00189 
00190         memcpy( p, buf, t );
00191         byteReverse( ctx->in, 16 );
00192 
00193         MD5Transform( ctx->buf, (unsigned int *)ctx->in );
00194 
00195         buf += t;
00196         len -= t;
00197     }
00198 
00199     /* Process data in 64-byte chunks */
00200     while (len >= 64)
00201     {
00202         memcpy( ctx->in, buf, 64 );
00203         byteReverse( ctx->in, 16 );
00204 
00205         MD5Transform( ctx->buf, (unsigned int *)ctx->in );
00206 
00207         buf += 64;
00208         len -= 64;
00209     }
00210 
00211     /* Handle any remaining bytes of data. */
00212     memcpy( ctx->in, buf, len );
00213 }
00214 
00215 /*
00216  * Final wrapup - pad to 64-byte boundary with the bit pattern 
00217  * 1 0* (64-bit count of bits processed, MSB-first)
00218  */
00219 VOID WINAPI MD5Final( MD5_CTX *ctx )
00220 {
00221     unsigned int count;
00222     unsigned char *p;
00223 
00224     /* Compute number of bytes mod 64 */
00225     count = (ctx->i[0] >> 3) & 0x3F;
00226 
00227     /* Set the first char of padding to 0x80.  This is safe since there is
00228        always at least one byte free */
00229     p = ctx->in + count;
00230     *p++ = 0x80;
00231 
00232     /* Bytes of padding needed to make 64 bytes */
00233     count = 64 - 1 - count;
00234 
00235     /* Pad out to 56 mod 64 */
00236     if (count < 8)
00237     {
00238         /* Two lots of padding:  Pad the first block to 64 bytes */
00239         memset( p, 0, count );
00240         byteReverse( ctx->in, 16 );
00241         MD5Transform( ctx->buf, (unsigned int *)ctx->in );
00242 
00243         /* Now fill the next block with 56 bytes */
00244         memset( ctx->in, 0, 56 );
00245     }
00246     else
00247     {
00248         /* Pad block to 56 bytes */
00249         memset( p, 0, count - 8 );
00250     }
00251 
00252     byteReverse( ctx->in, 14 );
00253 
00254     /* Append length in bits and transform */
00255     ((unsigned int *)ctx->in)[14] = ctx->i[0];
00256     ((unsigned int *)ctx->in)[15] = ctx->i[1];
00257 
00258     MD5Transform( ctx->buf, (unsigned int *)ctx->in );
00259     byteReverse( (unsigned char *)ctx->buf, 4 );
00260     memcpy( ctx->digest, ctx->buf, 16 );
00261 }

Generated on Sun May 27 2012 04:22:39 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.