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