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