MD5.cpp
  1  #include "MD5.h"
  2  
  3  MD5::MD5()
  4  {
  5  	//nothing
  6  	return;
  7  }
  8  
  9  char* MD5::make_digest(const unsigned char *digest, int len) /* {{{ */
 10  {
 11  	char * md5str = (char*) malloc(sizeof(char)*(len*2+1));
 12  	static const char hexits[17] = "0123456789abcdef";
 13  	int i;
 14  
 15  	for (i = 0; i < len; i++) {
 16  		md5str[i * 2]       = hexits[digest[i] >> 4];
 17  		md5str[(i * 2) + 1] = hexits[digest[i] &  0x0F];
 18  	}
 19  	md5str[len * 2] = '\0';
 20  	return md5str;
 21  }
 22  
 23  /*
 24   * The basic MD5 functions.
 25   *
 26   * E and G are optimized compared to their RFC 1321 definitions for
 27   * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
 28   * implementation.
 29   * E() has been used instead of F() because F() is already defined in the Arduino core
 30   */
 31  #define E(x, y, z)			((z) ^ ((x) & ((y) ^ (z))))
 32  #define G(x, y, z)			((y) ^ ((z) & ((x) ^ (y))))
 33  #define H(x, y, z)			((x) ^ (y) ^ (z))
 34  #define I(x, y, z)			((y) ^ ((x) | ~(z)))
 35  
 36  /*
 37   * The MD5 transformation for all four rounds.
 38   */
 39  #define STEP(f, a, b, c, d, x, t, s) \
 40  	(a) += f((b), (c), (d)) + (x) + (t); \
 41  	(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
 42  	(a) += (b);
 43  
 44  /*
 45   * SET reads 4 input bytes in little-endian byte order and stores them
 46   * in a properly aligned word in host byte order.
 47   *
 48   * The check for little-endian architectures that tolerate unaligned
 49   * memory accesses is just an optimization.  Nothing will break if it
 50   * doesn't work.
 51   */
 52  #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
 53  # define SET(n) \
 54  	(*(MD5_u32plus *)&ptr[(n) * 4])
 55  # define GET(n) \
 56  	SET(n)
 57  #else
 58  # define SET(n) \
 59  	(ctx->block[(n)] = \
 60  	(MD5_u32plus)ptr[(n) * 4] | \
 61  	((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
 62  	((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
 63  	((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
 64  # define GET(n) \
 65  	(ctx->block[(n)])
 66  #endif
 67  
 68  /*
 69   * This processes one or more 64-byte data blocks, but does NOT update
 70   * the bit counters.  There are no alignment requirements.
 71   */
 72  const void *MD5::body(void *ctxBuf, const void *data, size_t size)
 73  {
 74  	MD5_CTX *ctx = (MD5_CTX*)ctxBuf;
 75  	const unsigned char *ptr;
 76  	MD5_u32plus a, b, c, d;
 77  	MD5_u32plus saved_a, saved_b, saved_c, saved_d;
 78  
 79  	ptr = (unsigned char*)data;
 80  
 81  	a = ctx->a;
 82  	b = ctx->b;
 83  	c = ctx->c;
 84  	d = ctx->d;
 85  
 86  	do {
 87  		saved_a = a;
 88  		saved_b = b;
 89  		saved_c = c;
 90  		saved_d = d;
 91  
 92  /* Round 1
 93   * E() has been used instead of F() because F() is already defined in the Arduino core
 94   */
 95  		STEP(E, a, b, c, d, SET(0), 0xd76aa478, 7)
 96  		STEP(E, d, a, b, c, SET(1), 0xe8c7b756, 12)
 97  		STEP(E, c, d, a, b, SET(2), 0x242070db, 17)
 98  		STEP(E, b, c, d, a, SET(3), 0xc1bdceee, 22)
 99  		STEP(E, a, b, c, d, SET(4), 0xf57c0faf, 7)
100  		STEP(E, d, a, b, c, SET(5), 0x4787c62a, 12)
101  		STEP(E, c, d, a, b, SET(6), 0xa8304613, 17)
102  		STEP(E, b, c, d, a, SET(7), 0xfd469501, 22)
103  		STEP(E, a, b, c, d, SET(8), 0x698098d8, 7)
104  		STEP(E, d, a, b, c, SET(9), 0x8b44f7af, 12)
105  		STEP(E, c, d, a, b, SET(10), 0xffff5bb1, 17)
106  		STEP(E, b, c, d, a, SET(11), 0x895cd7be, 22)
107  		STEP(E, a, b, c, d, SET(12), 0x6b901122, 7)
108  		STEP(E, d, a, b, c, SET(13), 0xfd987193, 12)
109  		STEP(E, c, d, a, b, SET(14), 0xa679438e, 17)
110  		STEP(E, b, c, d, a, SET(15), 0x49b40821, 22)
111  
112  /* Round 2 */
113  		STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
114  		STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
115  		STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
116  		STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
117  		STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
118  		STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
119  		STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
120  		STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
121  		STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
122  		STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
123  		STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
124  		STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
125  		STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
126  		STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
127  		STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
128  		STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
129  
130  /* Round 3 */
131  		STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
132  		STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
133  		STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
134  		STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
135  		STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
136  		STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
137  		STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
138  		STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
139  		STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
140  		STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
141  		STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
142  		STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
143  		STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
144  		STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
145  		STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
146  		STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
147  
148  /* Round 4 */
149  		STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
150  		STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
151  		STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
152  		STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
153  		STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
154  		STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
155  		STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
156  		STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
157  		STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
158  		STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
159  		STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
160  		STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
161  		STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
162  		STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
163  		STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
164  		STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
165  
166  		a += saved_a;
167  		b += saved_b;
168  		c += saved_c;
169  		d += saved_d;
170  
171  		ptr += 64;
172  	} while (size -= 64);
173  
174  	ctx->a = a;
175  	ctx->b = b;
176  	ctx->c = c;
177  	ctx->d = d;
178  
179  	return ptr;
180  }
181  
182  void MD5::MD5Init(void *ctxBuf)
183  {
184  	MD5_CTX *ctx = (MD5_CTX*)ctxBuf;
185  	ctx->a = 0x67452301;
186  	ctx->b = 0xefcdab89;
187  	ctx->c = 0x98badcfe;
188  	ctx->d = 0x10325476;
189  
190  	ctx->lo = 0;
191  	ctx->hi = 0;
192  
193      memset(ctx->block, 0, sizeof(ctx->block));
194      memset(ctx->buffer, 0, sizeof(ctx->buffer));
195  }
196  
197  void MD5::MD5Update(void *ctxBuf, const void *data, size_t size)
198  {
199  	MD5_CTX *ctx = (MD5_CTX*)ctxBuf;
200  	MD5_u32plus saved_lo;
201  	MD5_u32plus used, free;
202  
203  	saved_lo = ctx->lo;
204  	if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) {
205  		ctx->hi++;
206  	}
207  	ctx->hi += size >> 29;
208  
209  	used = saved_lo & 0x3f;
210  
211  	if (used) {
212  		free = 64 - used;
213  
214  		if (size < free) {
215  			memcpy(&ctx->buffer[used], data, size);
216  			return;
217  		}
218  
219  		memcpy(&ctx->buffer[used], data, free);
220  		data = (unsigned char *)data + free;
221  		size -= free;
222  		body(ctx, ctx->buffer, 64);
223  	}
224  
225  	if (size >= 64) {
226  		data = body(ctx, data, size & ~(size_t)0x3f);
227  		size &= 0x3f;
228  	}
229  
230  	memcpy(ctx->buffer, data, size);
231  }
232  
233  void MD5::MD5Final(unsigned char *result, void *ctxBuf)
234  {
235  	MD5_CTX *ctx = (MD5_CTX*)ctxBuf;
236  	MD5_u32plus used, free;
237  
238  	used = ctx->lo & 0x3f;
239  
240  	ctx->buffer[used++] = 0x80;
241  
242  	free = 64 - used;
243  
244  	if (free < 8) {
245  		memset(&ctx->buffer[used], 0, free);
246  		body(ctx, ctx->buffer, 64);
247  		used = 0;
248  		free = 64;
249  	}
250  
251  	memset(&ctx->buffer[used], 0, free - 8);
252  
253  	ctx->lo <<= 3;
254  	ctx->buffer[56] = ctx->lo;
255  	ctx->buffer[57] = ctx->lo >> 8;
256  	ctx->buffer[58] = ctx->lo >> 16;
257  	ctx->buffer[59] = ctx->lo >> 24;
258  	ctx->buffer[60] = ctx->hi;
259  	ctx->buffer[61] = ctx->hi >> 8;
260  	ctx->buffer[62] = ctx->hi >> 16;
261  	ctx->buffer[63] = ctx->hi >> 24;
262  
263  	body(ctx, ctx->buffer, 64);
264  
265  	result[0] = ctx->a;
266  	result[1] = ctx->a >> 8;
267  	result[2] = ctx->a >> 16;
268  	result[3] = ctx->a >> 24;
269  	result[4] = ctx->b;
270  	result[5] = ctx->b >> 8;
271  	result[6] = ctx->b >> 16;
272  	result[7] = ctx->b >> 24;
273  	result[8] = ctx->c;
274  	result[9] = ctx->c >> 8;
275  	result[10] = ctx->c >> 16;
276  	result[11] = ctx->c >> 24;
277  	result[12] = ctx->d;
278  	result[13] = ctx->d >> 8;
279  	result[14] = ctx->d >> 16;
280  	result[15] = ctx->d >> 24;
281  
282  	memset(ctx, 0, sizeof(*ctx));
283  }
284  unsigned char* MD5::make_hash(char *arg)
285  {
286  	MD5_CTX context;
287  	unsigned char * hash = (unsigned char *) malloc(16);
288  	MD5Init(&context);
289  	MD5Update(&context, arg, strlen(arg));
290  	MD5Final(hash, &context);
291  	return hash;
292  }
293  unsigned char* MD5::make_hash(char *arg,size_t size)
294  {
295  	MD5_CTX context;
296  	unsigned char * hash = (unsigned char *) malloc(16);
297  	MD5Init(&context);
298  	MD5Update(&context, arg, size);
299  	MD5Final(hash, &context);
300  	return hash;
301  }