1 /*
2  * This code implements the MD5 message-digest algorithm.
3  * The algorithm was written by Ron Rivest.  This code was
4  * written by Colin Plumb in 1993, our understanding is
5  * that no copyright is claimed and that
6  * this code is in the public domain.
7  *
8  * Equivalent code is available from RSA Data Security, Inc.
9  * This code has been tested against that, and is
10  * functionally equivalent,
11  *
12  * To compute the message digest of a chunk of bytes, declare an
13  * MD5Context structure, pass it to MD5Init, call MD5Update as
14  * needed on buffers full of bytes, and then call MD5Final, which
15  * will fill a supplied 16-byte array with the digest.
16  */
17 
18 #include "md5.h"
19 
20 /* If we haven't brought in an accelerated MD5, use our own */
21 #ifndef WORDS_BIGENDIAN
22 #define byteReverse(buf, len)	       /* Nothing */
23 #else
24 void byteReverse(unsigned char *buf, unsigned longs);
25 
26 #ifndef ASM_MD5
27 /*
28  * Note: this code is harmless on little-endian machines.
29  */
byteReverse(unsigned char * buf,unsigned longs)30 void byteReverse(unsigned char *buf, unsigned longs)
31 {
32     uint32_t t;
33     do {
34 	t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
35 	    ((unsigned) buf[1] << 8 | buf[0]);
36 	*(uint32_t *) buf = t;
37 	buf += 4;
38     } while (--longs);
39 }
40 #endif  // ifndef ASM_MD5
41 #endif  // ifndef WORDS_BIGENDIAN
42 
43 
44 
45 
46 
47 /*
48  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
49  * initialization constants.
50  */
MD5Init(context_md5_t * ctx)51 void MD5Init(context_md5_t *ctx)
52 {
53     ctx->buf[0] = 0x67452301;
54     ctx->buf[1] = 0xefcdab89;
55     ctx->buf[2] = 0x98badcfe;
56     ctx->buf[3] = 0x10325476;
57 
58     ctx->bits[0] = 0;
59     ctx->bits[1] = 0;
60 }
61 
62 /*
63  * Update context to reflect the concatenation of another buffer full
64  * of bytes.
65  */
MD5Update(context_md5_t * ctx,const unsigned char * buf,size_t len)66 void MD5Update(context_md5_t *ctx, const unsigned char *buf, size_t len)
67 {
68     uint32_t t;
69 
70     /* Update bitcount */
71 
72     t = ctx->bits[0];
73     if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
74 	ctx->bits[1]++;		/* Carry from low to high */
75     ctx->bits[1] += len >> 29;
76 
77     t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
78 
79     /* Handle any leading odd-sized chunks */
80 
81     if (t) {
82 	unsigned char *p = (unsigned char *) ctx->in + t;
83 
84 	t = 64 - t;
85 	if (len < t) {
86 	    memcpy(p, buf, len);
87 	    return;
88 	}
89 	memcpy(p, buf, t);
90 	byteReverse(ctx->in, 16);
91 	MD5Transform(ctx->buf, (uint32_t *) ctx->in);
92 	buf += t;
93 	len -= t;
94     }
95     /* Process data in 64-byte chunks */
96 
97     while (len >= 64) {
98 	memcpy(ctx->in, buf, 64);
99 	byteReverse(ctx->in, 16);
100 	MD5Transform(ctx->buf, (uint32_t *) ctx->in);
101 	buf += 64;
102 	len -= 64;
103     }
104 
105     /* Handle any remaining bytes of data. */
106 
107     memcpy(ctx->in, buf, len);
108 }
109 
110 /*
111  * Final wrapup - pad to 64-byte boundary with the bit pattern
112  * 1 0* (64-bit count of bits processed, MSB-first)
113  */
MD5Final(unsigned char digest[16],context_md5_t * ctx)114 void MD5Final(unsigned char digest[16], context_md5_t *ctx)
115 {
116     unsigned count;
117     unsigned char *p;
118 
119     /* Compute number of bytes mod 64 */
120     count = (ctx->bits[0] >> 3) & 0x3F;
121 
122     /* Set the first char of padding to 0x80.  This is safe since there is
123        always at least one byte free */
124     p = ctx->in + count;
125     *p++ = 0x80;
126 
127     /* Bytes of padding needed to make 64 bytes */
128     count = 64 - 1 - count;
129 
130     /* Pad out to 56 mod 64 */
131     if (count < 8) {
132 	/* Two lots of padding:  Pad the first block to 64 bytes */
133 	memset(p, 0, count);
134 	byteReverse(ctx->in, 16);
135 	MD5Transform(ctx->buf, (uint32_t *) ctx->in);
136 
137 	/* Now fill the next block with 56 bytes */
138 	memset(ctx->in, 0, 56);
139     } else {
140 	/* Pad block to 56 bytes */
141 	memset(p, 0, count - 8);
142     }
143     byteReverse(ctx->in, 14);
144 
145     /* Append length in bits and transform */
146 
147     // the two lines below generated this error:
148     // "md5.c:147:5: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]"
149 
150     //((uint32_t *) ctx->in)[14] = ctx->bits[0];
151     //((uint32_t *) ctx->in)[15] = ctx->bits[1];
152 
153     // We will manually expand the cast into two statements to make
154     // the compiler happy...
155 
156     uint32_t *ctxin = (uint32_t *)ctx->in;
157     ctxin[14] = ctx->bits[0];
158     ctxin[15] = ctx->bits[1];
159 
160     MD5Transform(ctx->buf, (uint32_t *) ctx->in);
161     byteReverse((unsigned char *) ctx->buf, 4);
162     memcpy(digest, ctx->buf, 16);
163 
164     memset(ctx, 0, sizeof(* ctx));	/* In case it's sensitive */
165     /* The original version of this code omitted the asterisk. In
166        effect, only the first part of ctx was wiped with zeros, not
167        the whole thing. Bug found by Derek Jones. Original line: */
168     // memset(ctx, 0, sizeof(ctx));	/* In case it's sensitive */
169 }
170 
171 #ifndef ASM_MD5
172 
173 /* The four core functions - F1 is optimized somewhat */
174 
175 /* #define F1(x, y, z) (x & y | ~x & z) */
176 #define F1(x, y, z) (z ^ (x & (y ^ z)))
177 #define F2(x, y, z) F1(z, x, y)
178 #define F3(x, y, z) (x ^ y ^ z)
179 #define F4(x, y, z) (y ^ (x | ~z))
180 
181 /* This is the central step in the MD5 algorithm. */
182 #ifdef __PUREC__
183 #define MD5STEP(f, w, x, y, z, data, s) \
184 	( w += f /*(x, y, z)*/ + data,  w = w<<s | w>>(32-s),  w += x )
185 #else
186 #define MD5STEP(f, w, x, y, z, data, s) \
187 	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
188 #endif
189 
190 /*
191  * The core of the MD5 algorithm, this alters an existing MD5 hash to
192  * reflect the addition of 16 longwords of new data.  MD5Update blocks
193  * the data and converts bytes into longwords for this routine.
194  */
MD5Transform(uint32_t buf[4],uint32_t const in[16])195 void MD5Transform(uint32_t buf[4], uint32_t const in[16])
196 {
197     register uint32_t a, b, c, d;
198 
199     a = buf[0];
200     b = buf[1];
201     c = buf[2];
202     d = buf[3];
203 
204 #ifdef __PUREC__	/* PureC Weirdness... (GG) */
205     MD5STEP(F1(b,c,d), a, b, c, d, in[0] + 0xd76aa478L, 7);
206     MD5STEP(F1(a,b,c), d, a, b, c, in[1] + 0xe8c7b756L, 12);
207     MD5STEP(F1(d,a,b), c, d, a, b, in[2] + 0x242070dbL, 17);
208     MD5STEP(F1(c,d,a), b, c, d, a, in[3] + 0xc1bdceeeL, 22);
209     MD5STEP(F1(b,c,d), a, b, c, d, in[4] + 0xf57c0fafL, 7);
210     MD5STEP(F1(a,b,c), d, a, b, c, in[5] + 0x4787c62aL, 12);
211     MD5STEP(F1(d,a,b), c, d, a, b, in[6] + 0xa8304613L, 17);
212     MD5STEP(F1(c,d,a), b, c, d, a, in[7] + 0xfd469501L, 22);
213     MD5STEP(F1(b,c,d), a, b, c, d, in[8] + 0x698098d8L, 7);
214     MD5STEP(F1(a,b,c), d, a, b, c, in[9] + 0x8b44f7afL, 12);
215     MD5STEP(F1(d,a,b), c, d, a, b, in[10] + 0xffff5bb1L, 17);
216     MD5STEP(F1(c,d,a), b, c, d, a, in[11] + 0x895cd7beL, 22);
217     MD5STEP(F1(b,c,d), a, b, c, d, in[12] + 0x6b901122L, 7);
218     MD5STEP(F1(a,b,c), d, a, b, c, in[13] + 0xfd987193L, 12);
219     MD5STEP(F1(d,a,b), c, d, a, b, in[14] + 0xa679438eL, 17);
220     MD5STEP(F1(c,d,a), b, c, d, a, in[15] + 0x49b40821L, 22);
221 
222     MD5STEP(F2(b,c,d), a, b, c, d, in[1] + 0xf61e2562L, 5);
223     MD5STEP(F2(a,b,c), d, a, b, c, in[6] + 0xc040b340L, 9);
224     MD5STEP(F2(d,a,b), c, d, a, b, in[11] + 0x265e5a51L, 14);
225     MD5STEP(F2(c,d,a), b, c, d, a, in[0] + 0xe9b6c7aaL, 20);
226     MD5STEP(F2(b,c,d), a, b, c, d, in[5] + 0xd62f105dL, 5);
227     MD5STEP(F2(a,b,c), d, a, b, c, in[10] + 0x02441453L, 9);
228     MD5STEP(F2(d,a,b), c, d, a, b, in[15] + 0xd8a1e681L, 14);
229     MD5STEP(F2(c,d,a), b, c, d, a, in[4] + 0xe7d3fbc8L, 20);
230     MD5STEP(F2(b,c,d), a, b, c, d, in[9] + 0x21e1cde6L, 5);
231     MD5STEP(F2(a,b,c), d, a, b, c, in[14] + 0xc33707d6L, 9);
232     MD5STEP(F2(d,a,b), c, d, a, b, in[3] + 0xf4d50d87L, 14);
233     MD5STEP(F2(c,d,a), b, c, d, a, in[8] + 0x455a14edL, 20);
234     MD5STEP(F2(b,c,d), a, b, c, d, in[13] + 0xa9e3e905L, 5);
235     MD5STEP(F2(a,b,c), d, a, b, c, in[2] + 0xfcefa3f8L, 9);
236     MD5STEP(F2(d,a,b), c, d, a, b, in[7] + 0x676f02d9L, 14);
237     MD5STEP(F2(c,d,a), b, c, d, a, in[12] + 0x8d2a4c8aL, 20);
238 
239     MD5STEP(F3(b,c,d), a, b, c, d, in[5] + 0xfffa3942L, 4);
240     MD5STEP(F3(a,b,c), d, a, b, c, in[8] + 0x8771f681L, 11);
241     MD5STEP(F3(d,a,b), c, d, a, b, in[11] + 0x6d9d6122L, 16);
242     MD5STEP(F3(c,d,a), b, c, d, a, in[14] + 0xfde5380cL, 23);
243     MD5STEP(F3(b,c,d), a, b, c, d, in[1] + 0xa4beea44L, 4);
244     MD5STEP(F3(a,b,c), d, a, b, c, in[4] + 0x4bdecfa9L, 11);
245     MD5STEP(F3(d,a,b), c, d, a, b, in[7] + 0xf6bb4b60L, 16);
246     MD5STEP(F3(c,d,a), b, c, d, a, in[10] + 0xbebfbc70L, 23);
247     MD5STEP(F3(b,c,d), a, b, c, d, in[13] + 0x289b7ec6L, 4);
248     MD5STEP(F3(a,b,c), d, a, b, c, in[0] + 0xeaa127faL, 11);
249     MD5STEP(F3(d,a,b), c, d, a, b, in[3] + 0xd4ef3085L, 16);
250     MD5STEP(F3(c,d,a), b, c, d, a, in[6] + 0x04881d05L, 23);
251     MD5STEP(F3(b,c,d), a, b, c, d, in[9] + 0xd9d4d039L, 4);
252     MD5STEP(F3(a,b,c), d, a, b, c, in[12] + 0xe6db99e5L, 11);
253     MD5STEP(F3(d,a,b), c, d, a, b, in[15] + 0x1fa27cf8L, 16);
254     MD5STEP(F3(c,d,a), b, c, d, a, in[2] + 0xc4ac5665L, 23);
255 
256     MD5STEP(F4(b,c,d), a, b, c, d, in[0] + 0xf4292244L, 6);
257     MD5STEP(F4(a,b,c), d, a, b, c, in[7] + 0x432aff97L, 10);
258     MD5STEP(F4(d,a,b), c, d, a, b, in[14] + 0xab9423a7L, 15);
259     MD5STEP(F4(c,d,a), b, c, d, a, in[5] + 0xfc93a039L, 21);
260     MD5STEP(F4(b,c,d), a, b, c, d, in[12] + 0x655b59c3L, 6);
261     MD5STEP(F4(a,b,c), d, a, b, c, in[3] + 0x8f0ccc92L, 10);
262     MD5STEP(F4(d,a,b), c, d, a, b, in[10] + 0xffeff47dL, 15);
263     MD5STEP(F4(c,d,a), b, c, d, a, in[1] + 0x85845dd1L, 21);
264     MD5STEP(F4(b,c,d), a, b, c, d, in[8] + 0x6fa87e4fL, 6);
265     MD5STEP(F4(a,b,c), d, a, b, c, in[15] + 0xfe2ce6e0L, 10);
266     MD5STEP(F4(d,a,b), c, d, a, b, in[6] + 0xa3014314L, 15);
267     MD5STEP(F4(c,d,a), b, c, d, a, in[13] + 0x4e0811a1L, 21);
268     MD5STEP(F4(b,c,d), a, b, c, d, in[4] + 0xf7537e82L, 6);
269     MD5STEP(F4(a,b,c), d, a, b, c, in[11] + 0xbd3af235L, 10);
270     MD5STEP(F4(d,a,b), c, d, a, b, in[2] + 0x2ad7d2bbL, 15);
271     MD5STEP(F4(c,d,a), b, c, d, a, in[9] + 0xeb86d391L, 21);
272 #else
273     MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
274     MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
275     MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
276     MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
277     MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
278     MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
279     MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
280     MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
281     MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
282     MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
283     MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
284     MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
285     MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
286     MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
287     MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
288     MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
289 
290     MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
291     MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
292     MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
293     MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
294     MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
295     MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
296     MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
297     MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
298     MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
299     MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
300     MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
301     MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
302     MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
303     MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
304     MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
305     MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
306 
307     MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
308     MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
309     MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
310     MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
311     MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
312     MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
313     MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
314     MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
315     MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
316     MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
317     MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
318     MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
319     MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
320     MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
321     MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
322     MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
323 
324     MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
325     MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
326     MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
327     MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
328     MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
329     MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
330     MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
331     MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
332     MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
333     MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
334     MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
335     MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
336     MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
337     MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
338     MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
339     MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
340 #endif
341 
342     buf[0] += a;
343     buf[1] += b;
344     buf[2] += c;
345     buf[3] += d;
346 }
347 
348 #endif
349 
350 
hash_init_md5(void * ctx)351 void hash_init_md5(void * ctx)
352 {
353     MD5Init((context_md5_t *)ctx);
354 }
355 
hash_update_md5(void * ctx,const unsigned char * buf,size_t len)356 void hash_update_md5(void *ctx, const unsigned char *buf, size_t len)
357 {
358   MD5Update((context_md5_t *)ctx,buf,len);
359 }
360 
hash_final_md5(void * ctx,unsigned char * digest)361 void hash_final_md5(void *ctx, unsigned char *digest)
362 {
363   MD5Final(digest,(context_md5_t *)ctx);
364 }
365 
366 
367