00001
00002
00003
00004
00005
00006
00007 #include "md5.h"
00008 #include "../Build.h"
00009
00010 #define GET_UINT32(n,b,i) \
00011 { \
00012 (n) = (uint32) ((uint8 *) b)[(i)] \
00013 | (((uint32) ((uint8 *) b)[(i)+1]) << 8) \
00014 | (((uint32) ((uint8 *) b)[(i)+2]) << 16) \
00015 | (((uint32) ((uint8 *) b)[(i)+3]) << 24); \
00016 }
00017
00018 #define PUT_UINT32(n,b,i) \
00019 { \
00020 (((uint8 *) b)[(i)] ) = (uint8) (((n) ) & 0xFF); \
00021 (((uint8 *) b)[(i)+1]) = (uint8) (((n) >> 8) & 0xFF); \
00022 (((uint8 *) b)[(i)+2]) = (uint8) (((n) >> 16) & 0xFF); \
00023 (((uint8 *) b)[(i)+3]) = (uint8) (((n) >> 24) & 0xFF); \
00024 }
00025
00026 void md5_starts( struct md5_context *ctx )
00027 {
00028 ctx->total[0] = 0;
00029 ctx->total[1] = 0;
00030 ctx->state[0] = 0x67452301;
00031 ctx->state[1] = 0xEFCDAB89;
00032 ctx->state[2] = 0x98BADCFE;
00033 ctx->state[3] = 0x10325476;
00034 }
00035
00036 void md5_process( struct md5_context *ctx, uint8 data[64] )
00037 {
00038 uint32 A, B, C, D, X[16];
00039
00040 GET_UINT32( X[0], data, 0 );
00041 GET_UINT32( X[1], data, 4 );
00042 GET_UINT32( X[2], data, 8 );
00043 GET_UINT32( X[3], data, 12 );
00044 GET_UINT32( X[4], data, 16 );
00045 GET_UINT32( X[5], data, 20 );
00046 GET_UINT32( X[6], data, 24 );
00047 GET_UINT32( X[7], data, 28 );
00048 GET_UINT32( X[8], data, 32 );
00049 GET_UINT32( X[9], data, 36 );
00050 GET_UINT32( X[10], data, 40 );
00051 GET_UINT32( X[11], data, 44 );
00052 GET_UINT32( X[12], data, 48 );
00053 GET_UINT32( X[13], data, 52 );
00054 GET_UINT32( X[14], data, 56 );
00055 GET_UINT32( X[15], data, 60 );
00056
00057 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00058
00059 #define P(a,b,c,d,k,s,t) \
00060 { \
00061 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
00062 }
00063
00064 A = ctx->state[0];
00065 B = ctx->state[1];
00066 C = ctx->state[2];
00067 D = ctx->state[3];
00068
00069 #define F(x,y,z) (z ^ (x & (y ^ z)))
00070
00071 P( A, B, C, D, 0, 7, 0xD76AA478 );
00072 P( D, A, B, C, 1, 12, 0xE8C7B756 );
00073 P( C, D, A, B, 2, 17, 0x242070DB );
00074 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
00075 P( A, B, C, D, 4, 7, 0xF57C0FAF );
00076 P( D, A, B, C, 5, 12, 0x4787C62A );
00077 P( C, D, A, B, 6, 17, 0xA8304613 );
00078 P( B, C, D, A, 7, 22, 0xFD469501 );
00079 P( A, B, C, D, 8, 7, 0x698098D8 );
00080 P( D, A, B, C, 9, 12, 0x8B44F7AF );
00081 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
00082 P( B, C, D, A, 11, 22, 0x895CD7BE );
00083 P( A, B, C, D, 12, 7, 0x6B901122 );
00084 P( D, A, B, C, 13, 12, 0xFD987193 );
00085 P( C, D, A, B, 14, 17, 0xA679438E );
00086 P( B, C, D, A, 15, 22, 0x49B40821 );
00087
00088 #undef F
00089
00090 #define F(x,y,z) (y ^ (z & (x ^ y)))
00091
00092 P( A, B, C, D, 1, 5, 0xF61E2562 );
00093 P( D, A, B, C, 6, 9, 0xC040B340 );
00094 P( C, D, A, B, 11, 14, 0x265E5A51 );
00095 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
00096 P( A, B, C, D, 5, 5, 0xD62F105D );
00097 P( D, A, B, C, 10, 9, 0x02441453 );
00098 P( C, D, A, B, 15, 14, 0xD8A1E681 );
00099 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
00100 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
00101 P( D, A, B, C, 14, 9, 0xC33707D6 );
00102 P( C, D, A, B, 3, 14, 0xF4D50D87 );
00103 P( B, C, D, A, 8, 20, 0x455A14ED );
00104 P( A, B, C, D, 13, 5, 0xA9E3E905 );
00105 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
00106 P( C, D, A, B, 7, 14, 0x676F02D9 );
00107 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
00108
00109 #undef F
00110
00111 #define F(x,y,z) (x ^ y ^ z)
00112
00113 P( A, B, C, D, 5, 4, 0xFFFA3942 );
00114 P( D, A, B, C, 8, 11, 0x8771F681 );
00115 P( C, D, A, B, 11, 16, 0x6D9D6122 );
00116 P( B, C, D, A, 14, 23, 0xFDE5380C );
00117 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
00118 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
00119 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
00120 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
00121 P( A, B, C, D, 13, 4, 0x289B7EC6 );
00122 P( D, A, B, C, 0, 11, 0xEAA127FA );
00123 P( C, D, A, B, 3, 16, 0xD4EF3085 );
00124 P( B, C, D, A, 6, 23, 0x04881D05 );
00125 P( A, B, C, D, 9, 4, 0xD9D4D039 );
00126 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
00127 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
00128 P( B, C, D, A, 2, 23, 0xC4AC5665 );
00129
00130 #undef F
00131
00132 #define F(x,y,z) (y ^ (x | ~z))
00133
00134 P( A, B, C, D, 0, 6, 0xF4292244 );
00135 P( D, A, B, C, 7, 10, 0x432AFF97 );
00136 P( C, D, A, B, 14, 15, 0xAB9423A7 );
00137 P( B, C, D, A, 5, 21, 0xFC93A039 );
00138 P( A, B, C, D, 12, 6, 0x655B59C3 );
00139 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
00140 P( C, D, A, B, 10, 15, 0xFFEFF47D );
00141 P( B, C, D, A, 1, 21, 0x85845DD1 );
00142 P( A, B, C, D, 8, 6, 0x6FA87E4F );
00143 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
00144 P( C, D, A, B, 6, 15, 0xA3014314 );
00145 P( B, C, D, A, 13, 21, 0x4E0811A1 );
00146 P( A, B, C, D, 4, 6, 0xF7537E82 );
00147 P( D, A, B, C, 11, 10, 0xBD3AF235 );
00148 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
00149 P( B, C, D, A, 9, 21, 0xEB86D391 );
00150
00151 #undef F
00152
00153 ctx->state[0] += A;
00154 ctx->state[1] += B;
00155 ctx->state[2] += C;
00156 ctx->state[3] += D;
00157 }
00158
00159 void md5_update( struct md5_context *ctx, uint8 *input, uint32 length )
00160 {
00161 uint32 left, fill;
00162
00163 if( ! length ) return;
00164
00165 left = ( ctx->total[0] >> 3 ) & 0x3F;
00166 fill = 64 - left;
00167
00168 ctx->total[0] += length << 3;
00169 ctx->total[1] += length >> 29;
00170
00171 ctx->total[0] &= 0xFFFFFFFF;
00172 ctx->total[1] += ctx->total[0] < ( length << 3 );
00173
00174 if( left && length >= fill )
00175 {
00176 memcpy( (void *) (ctx->buffer + left), (void *) input, fill );
00177 md5_process( ctx, ctx->buffer );
00178 length -= fill;
00179 input += fill;
00180 left = 0;
00181 }
00182
00183 while( length >= 64 )
00184 {
00185 md5_process( ctx, input );
00186 length -= 64;
00187 input += 64;
00188 }
00189
00190 if( length )
00191 {
00192 memcpy( (void *) (ctx->buffer + left), (void *) input, length );
00193 }
00194 }
00195
00196 static uint8 md5_padding[64] =
00197 {
00198 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00202 };
00203
00204 void md5_finish( struct md5_context *ctx, uint8 digest[16] )
00205 {
00206 uint32 last, padn;
00207 uint8 msglen[8];
00208
00209 PUT_UINT32( ctx->total[0], msglen, 0 );
00210 PUT_UINT32( ctx->total[1], msglen, 4 );
00211
00212 last = ( ctx->total[0] >> 3 ) & 0x3F;
00213 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00214
00215 md5_update( ctx, md5_padding, padn );
00216 md5_update( ctx, msglen, 8 );
00217
00218 PUT_UINT32( ctx->state[0], digest, 0 );
00219 PUT_UINT32( ctx->state[1], digest, 4 );
00220 PUT_UINT32( ctx->state[2], digest, 8 );
00221 PUT_UINT32( ctx->state[3], digest, 12 );
00222 }
00223
00224
00225
00226 void Getmd5Hash(char *buffer, unsigned int len, unsigned char *result ) {
00227 struct md5_context ctx;
00228 unsigned char md5sum[16];
00229 #define a md5sum
00230
00231 md5_starts( &ctx );
00232 md5_update( &ctx, (unsigned char *)buffer, len );
00233 md5_finish( &ctx, md5sum);
00234
00235 snprintf((char *)result,sizeof(md5sum)*2+1,
00236 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
00237 a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
00238 a[8], a[9], a[10],a[11],a[12],a[13],a[14],a[15]);
00239 }
00240
00241
00242
00243