DCL 4.0
Loading...
Searching...
No Matches
MD5.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h> // memset
6#include <wchar.h> // swprintf
7
8#include <dcl/Object.h>
9
10#if __DCL_HAVE_ALLOC_DEBUG
11#undef __DCL_ALLOC_LEVEL
12#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
13#endif
14
15#include <dcl/MD5.h>
16
17#ifdef UINT2
18#undef UINT2
19#endif
20
21#ifdef UINT4
22#undef UINT4
23#endif
24
25#ifdef POINTER
26#undef POINTER
27#endif
28
29typedef unsigned short int UINT2;
30typedef unsigned long int UINT4;
31typedef unsigned char* POINTER;
32
33// md5.h
34
35/* MD5 context. */
36typedef struct {
37 UINT4 state[4]; /* state (ABCD) */
38 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
39 unsigned char buffer[64]; /* input buffer */
40} MD5_CTX;
41
42//void MD5Init(MD5_CTX *);
43//void MD5Update(MD5_CTX *, unsigned char *, size_t);
44//void MD5Final(unsigned char [16], MD5_CTX *);
45
46static void MD5Init(MD5_CTX *);
47static void MD5Update(MD5_CTX *, const unsigned char *, size_t);
48static void MD5Final(unsigned char [16], MD5_CTX *);
49
50#if __DCL_HAVE_THIS_FILE__
51#undef __THIS_FILE__
52static const char_t __THIS_FILE__[] = __T("dcl/MD5.cpp");
53#endif
54
55__DCL_BEGIN_NAMESPACE
56
58{
59 __context = malloc(sizeof(MD5_CTX));
60 __DCL_ASSERT(__context != NULL);
61
62 MD5Init((MD5_CTX*)__context);
63}
64
66{
67 free(__context);
68}
69
70void MD5::update(const void* _p, size_t _n)
71{
72 MD5Update((MD5_CTX*)__context, (const unsigned char*)_p, _n);
73}
74
75void MD5::final(byte_t digest[16])
76{
77 MD5Final(digest, (MD5_CTX*)__context);
78}
79
80String MD5::final()
81{
82 byte_t digest[16];
83 final(digest);
84
85 return String::toHexString((const char*) digest, sizeof(digest), (size_t)-1, false);
86}
87
88// static
89String MD5::final(const String& _s)
90{
91 return MD5::final(_s.data(), _s.length() * sizeof(wchar_t));
92}
93
94String MD5::final(const ByteString& _s)
95{
96 return MD5::final(_s.data(), _s.length() * sizeof(char));
97}
98
99String MD5::final(const void* _p, size_t _n)
100{
101 MD5 m;
102 m.update(_p, _n);
103 return m.final();
104}
105
106__DCL_END_NAMESPACE
107
108
109// The remaining code is the reference MD5 code(md5c.c) from rfc1321
110
111/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
112 */
113/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
114rights reserved.
115
116License to copy and use this software is granted provided that it
117is identified as the "RSA Data Security, Inc. MD5 Message-Digest
118Algorithm" in all material mentioning or referencing this software
119or this function.
120
121License is also granted to make and use derivative works provided
122that such works are identified as "derived from the RSA Data
123Security, Inc. MD5 Message-Digest Algorithm" in all material
124mentioning or referencing the derived work.
125
126RSA Data Security, Inc. makes no representations concerning either
127the merchantability of this software or the suitability of this
128software for any particular purpose. It is provided "as is"
129without express or implied warranty of any kind.
130
131These notices must be retained in any copies of any part of this
132documentation and/or software.
133 */
134
135// md5c.c
136/* Constants for MD5Transform routine.
137 */
138
139#define S11 7
140#define S12 12
141#define S13 17
142#define S14 22
143#define S21 5
144#define S22 9
145#define S23 14
146#define S24 20
147#define S31 4
148#define S32 11
149#define S33 16
150#define S34 23
151#define S41 6
152#define S42 10
153#define S43 15
154#define S44 21
155
156static void MD5Transform(UINT4 state[4], const unsigned char block[64]);
157static void Encode(unsigned char* output, UINT4* input, size_t len);
158static void Decode(UINT4* output, const unsigned char* input, size_t len);
159
160/*
161static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, size_t));
162static void MD5_memset PROTO_LIST ((POINTER, int, size_t));
163*/
164
165static unsigned char PADDING[64] = {
166 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
169};
170
171/* F, G, H and I are basic MD5 functions.
172 */
173#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
174#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
175#define H(x, y, z) ((x) ^ (y) ^ (z))
176#define I(x, y, z) ((y) ^ ((x) | (~z)))
177
178/* ROTATE_LEFT rotates x left n bits. */
179#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
180
181/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
182Rotation is separate from addition to prevent recomputation. */
183#define FF(a, b, c, d, x, s, ac) { \
184 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
185 (a) = ROTATE_LEFT ((a), (s)); \
186 (a) += (b); \
187 }
188#define GG(a, b, c, d, x, s, ac) { \
189 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
190 (a) = ROTATE_LEFT ((a), (s)); \
191 (a) += (b); \
192 }
193#define HH(a, b, c, d, x, s, ac) { \
194 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
195 (a) = ROTATE_LEFT ((a), (s)); \
196 (a) += (b); \
197 }
198#define II(a, b, c, d, x, s, ac) { \
199 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
200 (a) = ROTATE_LEFT ((a), (s)); \
201 (a) += (b); \
202 }
203
204/* MD5 initialization. Begins an MD5 operation, writing a new context. */
205static void MD5Init(MD5_CTX *context) /* context */
206{
207 context->count[0] = context->count[1] = 0;
208 /* Load magic initialization constants.*/
209 context->state[0] = 0x67452301;
210 context->state[1] = 0xefcdab89;
211 context->state[2] = 0x98badcfe;
212 context->state[3] = 0x10325476;
213}
214
215/* MD5 block update operation. Continues an MD5 message-digest
216 operation, processing another message block, and updating the
217 context. */
218//void MD5Update(MD5_CTX* context, unsigned char* input, size_t inputLen)
219static void MD5Update(MD5_CTX* context, const unsigned char* input, size_t inputLen)
220
221//MD5_CTX *context; /* context */
222//unsigned char *input; /* input block */
223//size_t inputLen; /* length of input block */
224{
225 size_t i, index, partLen;
226
227 /* Compute number of bytes mod 64 */
228 index = (size_t)((context->count[0] >> 3) & 0x3F);
229
230 /* Update number of bits */
231 if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
232 context->count[1]++;
233 context->count[1] += ((UINT4)inputLen >> 29);
234
235 partLen = 64 - index;
236
237 /* Transform as many times as possible. */
238 if (inputLen >= partLen)
239 {
240 //MD5_memcpy
241 memcpy
242 ((POINTER)&context->buffer[index], (POINTER)input, partLen);
243 MD5Transform (context->state, context->buffer);
244
245 for (i = partLen; i + 63 < inputLen; i += 64)
246 MD5Transform (context->state, &input[i]);
247
248 index = 0;
249 }
250 else
251 i = 0;
252
253 /* Buffer remaining input */
254 //MD5_memcpy
255 memcpy
256 ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);
257}
258
259/* MD5 finalization. Ends an MD5 message-digest operation, writing the
260 the message digest and zeroizing the context. */
261
262//void MD5Final (digest, context)
263//unsigned char digest[16]; /* message digest */
264//MD5_CTX *context; /* context */
265static void MD5Final(unsigned char digest[16], MD5_CTX* context)
266{
267 unsigned char bits[8];
268 size_t index, padLen;
269
270 /* Save number of bits */
271 Encode (bits, context->count, 8);
272
273 /* Pad out to 56 mod 64.*/
274 index = (size_t)((context->count[0] >> 3) & 0x3f);
275 padLen = (index < 56) ? (56 - index) : (120 - index);
276 MD5Update (context, PADDING, padLen);
277
278 /* Append length (before padding) */
279 MD5Update (context, bits, 8);
280
281 /* Store state in digest */
282 Encode (digest, context->state, 16);
283
284 /* Zeroize sensitive information. */
285// MD5_memset
286 memset((POINTER)context, 0, sizeof (*context));
287}
288
289/* MD5 basic transformation. Transforms state based on block. */
290//static void MD5Transform (state, block)
291//UINT4 state[4];
292//unsigned char block[64];
293//static void MD5Transform(UINT4 state[4], unsigned char block[64])
294static void MD5Transform(UINT4 state[4], const unsigned char block[64])
295{
296 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
297
298 Decode (x, block, 64);
299
300 /* Round 1 */
301 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
302 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
303 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
304 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
305 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
306 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
307 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
308 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
309 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
310 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
311 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
312 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
313 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
314 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
315 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
316 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
317
318 /* Round 2 */
319 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
320 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
321 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
322 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
323 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
324 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
325 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
326 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
327 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
328 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
329 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
330
331 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
332 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
333 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
334 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
335 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
336
337 /* Round 3 */
338 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
339 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
340 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
341 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
342 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
343 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
344 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
345 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
346 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
347 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
348 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
349 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
350 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
351 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
352 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
353 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
354
355 /* Round 4 */
356 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
357 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
358 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
359 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
360 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
361 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
362 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
363 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
364 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
365 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
366 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
367 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
368 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
369 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
370 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
371 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
372
373 state[0] += a;
374 state[1] += b;
375 state[2] += c;
376 state[3] += d;
377
378 /* Zeroize sensitive information.*/
379// MD5_memset
380 memset((POINTER)x, 0, sizeof (x));
381}
382
383/* Encodes input (UINT4) into output (unsigned char). Assumes len is
384 a multiple of 4. */
385//static void Encode (output, input, len)
386//unsigned char *output;
387//UINT4 *input;
388//size_t len;
389static void Encode(unsigned char* output, UINT4* input, size_t len)
390{
391 size_t i, j;
392
393 for (i = 0, j = 0; j < len; i++, j += 4)
394 {
395 output[j] = (unsigned char)(input[i] & 0xff);
396 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
397 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
398 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
399 }
400}
401
402/* Decodes input (unsigned char) into output (UINT4). Assumes len is
403 a multiple of 4. */
404//static void Decode (output, input, len)
405//UINT4 *output;
406//unsigned char *input;
407//size_t len;
408static void Decode(UINT4* output, const unsigned char* input, size_t len)
409{
410 size_t i, j;
411
412 for (i = 0, j = 0; j < len; i++, j += 4)
413 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
414 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
415}
416
417/* Note: Replace "for loop" with standard memcpy if possible.
418 */
419/*
420static void MD5_memcpy (output, input, len)
421POINTER output;
422POINTER input;
423size_t len;
424{
425 size_t i;
426
427 for (i = 0; i < len; i++)
428
429 output[i] = input[i];
430}
431*/
432/* Note: Replace "for loop" with standard memset if possible.
433 */
434/*
435static void MD5_memset (output, value, len)
436POINTER output;
437int value;
438size_t len;
439{
440 size_t i;
441
442 for (i = 0; i < len; i++)
443 ((char *)output)[i] = (char)value;
444}
445*/
446
448
449
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:340
wchar_t char_t
Definition Config.h:275
unsigned char byte_t
Definition Config.h:274
#define FF(a, b, c, d, x, s, ac)
Definition MD5.cpp:183
#define S24
Definition MD5.cpp:146
#define S33
Definition MD5.cpp:149
#define S32
Definition MD5.cpp:148
#define S12
Definition MD5.cpp:140
#define S42
Definition MD5.cpp:152
#define S11
Definition MD5.cpp:139
#define S43
Definition MD5.cpp:153
#define S23
Definition MD5.cpp:145
#define GG(a, b, c, d, x, s, ac)
Definition MD5.cpp:188
#define S44
Definition MD5.cpp:154
unsigned char * POINTER
Definition MD5.cpp:31
#define S14
Definition MD5.cpp:142
#define HH(a, b, c, d, x, s, ac)
Definition MD5.cpp:193
#define S13
Definition MD5.cpp:141
#define S41
Definition MD5.cpp:151
#define S21
Definition MD5.cpp:143
unsigned long int UINT4
Definition MD5.cpp:30
#define II(a, b, c, d, x, s, ac)
Definition MD5.cpp:198
#define S22
Definition MD5.cpp:144
#define S31
Definition MD5.cpp:147
unsigned short int UINT2
Definition MD5.cpp:29
#define S34
Definition MD5.cpp:150
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define __T(str)
Definition Object.h:44
size_t len
String final()
Definition MD5.cpp:80
~MD5()
Definition MD5.cpp:65
MD5()
Definition MD5.cpp:57
void update(const void *_p, size_t _n)
Definition MD5.cpp:70
void final(byte_t digest[16])
Definition MD5.cpp:75
unsigned char buffer[64]
Definition MD5.cpp:39
UINT4 state[4]
Definition MD5.cpp:37
UINT4 count[2]
Definition MD5.cpp:38