PageRenderTime 78ms CodeModel.GetById 36ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/StormLib/stormlib/misc/md5.cpp

http://ghostcb.googlecode.com/
C++ | 252 lines | 193 code | 38 blank | 21 comment | 5 complexity | 4739ef966966f71bd4a528e5e1e921c9 MD5 | raw file
  1/*****************************************************************************/
  2/* md32.cpp                               Copyright (c) Ladislav Zezula 2007 */
  3/*---------------------------------------------------------------------------*/
  4/* Implementation of MD5                                                     */
  5/*---------------------------------------------------------------------------*/
  6/*   Date    Ver   Who  Comment                                              */
  7/* --------  ----  ---  -------                                              */
  8/* 11.06.07  1.00  Lad  The first version of md5.cpp                         */
  9/*****************************************************************************/
 10
 11#include <string.h>

 12#include "md5.h"

 13
 14/*
 15 * 32-bit integer manipulation macros (little endian)
 16 */
 17#ifndef GET_UINT32_LE

 18#define GET_UINT32_LE(n,b,i)                            \

 19{                                                       \
 20    (n) = ( (unsigned long) (b)[(i)    ]       )        \
 21        | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
 22        | ( (unsigned long) (b)[(i) + 2] << 16 )        \
 23        | ( (unsigned long) (b)[(i) + 3] << 24 );       \
 24}
 25#endif

 26#ifndef PUT_UINT32_LE

 27#define PUT_UINT32_LE(n,b,i)                            \

 28{                                                       \
 29    (b)[(i)    ] = (unsigned char) ( (n)       );       \
 30    (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
 31    (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
 32    (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
 33}
 34#endif

 35
 36void md5_process( md5_context *ctx, unsigned char data[64] )
 37{
 38    unsigned long X[16], A, B, C, D;
 39
 40    GET_UINT32_LE( X[0],  data,  0 );
 41    GET_UINT32_LE( X[1],  data,  4 );
 42    GET_UINT32_LE( X[2],  data,  8 );
 43    GET_UINT32_LE( X[3],  data, 12 );
 44    GET_UINT32_LE( X[4],  data, 16 );
 45    GET_UINT32_LE( X[5],  data, 20 );
 46    GET_UINT32_LE( X[6],  data, 24 );
 47    GET_UINT32_LE( X[7],  data, 28 );
 48    GET_UINT32_LE( X[8],  data, 32 );
 49    GET_UINT32_LE( X[9],  data, 36 );
 50    GET_UINT32_LE( X[10], data, 40 );
 51    GET_UINT32_LE( X[11], data, 44 );
 52    GET_UINT32_LE( X[12], data, 48 );
 53    GET_UINT32_LE( X[13], data, 52 );
 54    GET_UINT32_LE( X[14], data, 56 );
 55    GET_UINT32_LE( X[15], data, 60 );
 56
 57#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))

 58
 59#define P(a,b,c,d,k,s,t)                                \

 60{                                                       \
 61    a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
 62}
 63
 64    A = ctx->state[0];
 65    B = ctx->state[1];
 66    C = ctx->state[2];
 67    D = ctx->state[3];
 68
 69#define F(x,y,z) (z ^ (x & (y ^ z)))

 70
 71    P( A, B, C, D,  0,  7, 0xD76AA478 );
 72    P( D, A, B, C,  1, 12, 0xE8C7B756 );
 73    P( C, D, A, B,  2, 17, 0x242070DB );
 74    P( B, C, D, A,  3, 22, 0xC1BDCEEE );
 75    P( A, B, C, D,  4,  7, 0xF57C0FAF );
 76    P( D, A, B, C,  5, 12, 0x4787C62A );
 77    P( C, D, A, B,  6, 17, 0xA8304613 );
 78    P( B, C, D, A,  7, 22, 0xFD469501 );
 79    P( A, B, C, D,  8,  7, 0x698098D8 );
 80    P( D, A, B, C,  9, 12, 0x8B44F7AF );
 81    P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
 82    P( B, C, D, A, 11, 22, 0x895CD7BE );
 83    P( A, B, C, D, 12,  7, 0x6B901122 );
 84    P( D, A, B, C, 13, 12, 0xFD987193 );
 85    P( C, D, A, B, 14, 17, 0xA679438E );
 86    P( B, C, D, A, 15, 22, 0x49B40821 );
 87
 88#undef F

 89
 90#define F(x,y,z) (y ^ (z & (x ^ y)))

 91
 92    P( A, B, C, D,  1,  5, 0xF61E2562 );
 93    P( D, A, B, C,  6,  9, 0xC040B340 );
 94    P( C, D, A, B, 11, 14, 0x265E5A51 );
 95    P( B, C, D, A,  0, 20, 0xE9B6C7AA );
 96    P( A, B, C, D,  5,  5, 0xD62F105D );
 97    P( D, A, B, C, 10,  9, 0x02441453 );
 98    P( C, D, A, B, 15, 14, 0xD8A1E681 );
 99    P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
100    P( A, B, C, D,  9,  5, 0x21E1CDE6 );
101    P( D, A, B, C, 14,  9, 0xC33707D6 );
102    P( C, D, A, B,  3, 14, 0xF4D50D87 );
103    P( B, C, D, A,  8, 20, 0x455A14ED );
104    P( A, B, C, D, 13,  5, 0xA9E3E905 );
105    P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
106    P( C, D, A, B,  7, 14, 0x676F02D9 );
107    P( B, C, D, A, 12, 20, 0x8D2A4C8A );
108
109#undef F

110    
111#define F(x,y,z) (x ^ y ^ z)

112
113    P( A, B, C, D,  5,  4, 0xFFFA3942 );
114    P( D, A, B, C,  8, 11, 0x8771F681 );
115    P( C, D, A, B, 11, 16, 0x6D9D6122 );
116    P( B, C, D, A, 14, 23, 0xFDE5380C );
117    P( A, B, C, D,  1,  4, 0xA4BEEA44 );
118    P( D, A, B, C,  4, 11, 0x4BDECFA9 );
119    P( C, D, A, B,  7, 16, 0xF6BB4B60 );
120    P( B, C, D, A, 10, 23, 0xBEBFBC70 );
121    P( A, B, C, D, 13,  4, 0x289B7EC6 );
122    P( D, A, B, C,  0, 11, 0xEAA127FA );
123    P( C, D, A, B,  3, 16, 0xD4EF3085 );
124    P( B, C, D, A,  6, 23, 0x04881D05 );
125    P( A, B, C, D,  9,  4, 0xD9D4D039 );
126    P( D, A, B, C, 12, 11, 0xE6DB99E5 );
127    P( C, D, A, B, 15, 16, 0x1FA27CF8 );
128    P( B, C, D, A,  2, 23, 0xC4AC5665 );
129
130#undef F

131
132#define F(x,y,z) (y ^ (x | ~z))

133
134    P( A, B, C, D,  0,  6, 0xF4292244 );
135    P( D, A, B, C,  7, 10, 0x432AFF97 );
136    P( C, D, A, B, 14, 15, 0xAB9423A7 );
137    P( B, C, D, A,  5, 21, 0xFC93A039 );
138    P( A, B, C, D, 12,  6, 0x655B59C3 );
139    P( D, A, B, C,  3, 10, 0x8F0CCC92 );
140    P( C, D, A, B, 10, 15, 0xFFEFF47D );
141    P( B, C, D, A,  1, 21, 0x85845DD1 );
142    P( A, B, C, D,  8,  6, 0x6FA87E4F );
143    P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
144    P( C, D, A, B,  6, 15, 0xA3014314 );
145    P( B, C, D, A, 13, 21, 0x4E0811A1 );
146    P( A, B, C, D,  4,  6, 0xF7537E82 );
147    P( D, A, B, C, 11, 10, 0xBD3AF235 );
148    P( C, D, A, B,  2, 15, 0x2AD7D2BB );
149    P( B, C, D, A,  9, 21, 0xEB86D391 );
150
151#undef F

152
153    ctx->state[0] += A;
154    ctx->state[1] += B;
155    ctx->state[2] += C;
156    ctx->state[3] += D;
157}
158
159/*
160 * MD5 context setup
161 */
162
163void MD5_Init( md5_context *ctx )
164{
165    ctx->total[0] = 0;
166    ctx->total[1] = 0;
167
168    ctx->state[0] = 0x67452301;
169    ctx->state[1] = 0xEFCDAB89;
170    ctx->state[2] = 0x98BADCFE;
171    ctx->state[3] = 0x10325476;
172}
173
174/*
175 * MD5 process buffer
176 */
177void MD5_Update( md5_context *ctx, unsigned char *input, int ilen )
178{
179    int fill;
180    unsigned long left;
181
182    if( ilen <= 0 )
183        return;
184
185    left = ctx->total[0] & 0x3F;
186    fill = 64 - left;
187
188    ctx->total[0] += ilen;
189    ctx->total[0] &= 0xFFFFFFFF;
190
191    if( ctx->total[0] < (unsigned long) ilen )
192        ctx->total[1]++;
193
194    if( left && ilen >= fill )
195    {
196        memcpy( (void *) (ctx->buffer + left),
197                (void *) input, fill );
198        md5_process( ctx, ctx->buffer );
199        input += fill;
200        ilen  -= fill;
201        left = 0;
202    }
203
204    while( ilen >= 64 )
205    {
206        md5_process( ctx, input );
207        input += 64;
208        ilen  -= 64;
209    }
210
211    if( ilen > 0 )
212    {
213        memcpy( (void *) (ctx->buffer + left),
214                (void *) input, ilen );
215    }
216}
217
218static const unsigned char md5_padding[64] =
219{
220 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
222    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
224};
225
226/*
227 * MD5 final digest
228 */
229void MD5_Finish( md5_context *ctx, unsigned char output[16] )
230{
231    unsigned long last, padn;
232    unsigned long high, low;
233    unsigned char msglen[8];
234
235    high = ( ctx->total[0] >> 29 )
236         | ( ctx->total[1] <<  3 );
237    low  = ( ctx->total[0] <<  3 );
238
239    PUT_UINT32_LE( low,  msglen, 0 );
240    PUT_UINT32_LE( high, msglen, 4 );
241
242    last = ctx->total[0] & 0x3F;
243    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
244
245    MD5_Update( ctx, (unsigned char *) md5_padding, padn );
246    MD5_Update( ctx, msglen, 8 );
247
248    PUT_UINT32_LE( ctx->state[0], output,  0 );
249    PUT_UINT32_LE( ctx->state[1], output,  4 );
250    PUT_UINT32_LE( ctx->state[2], output,  8 );
251    PUT_UINT32_LE( ctx->state[3], output, 12 );
252}