1 /*
2  * RFC 1321 compliant MD5 implementation,
3  * by Christophe Devine <devine@cr0.net>;
4  * this program is licensed under the GPL.
5  */
6 
7 /* Modified October 3, 2003, to remove testing code, and add
8 		include of "fceu-types.h".
9 
10 		Added simple MD5 to ASCII string conversion function.
11 		-Xodnizel
12 */
13 
14 #include <string.h>
15 #include "fceu-types.h"
16 #include "md5.h"
17 
18 #define GET_UINT32(n, b, i)	\
19 {	\
20 	(n) =	((uint32)(b)[(i) + 3] << 24) |	\
21 			((uint32)(b)[(i) + 2] << 16) |	\
22 			((uint32)(b)[(i) + 1] <<  8) |	\
23 			((uint32)(b)[(i)    ]);	\
24 }
25 
26 #define PUT_UINT32(n, b, i)	\
27 {	\
28 	(b)[(i)    ] = (uint8)((n));	\
29 	(b)[(i) + 1] = (uint8)((n) >>  8);	\
30 	(b)[(i) + 2] = (uint8)((n) >> 16);	\
31 	(b)[(i) + 3] = (uint8)((n) >> 24);	\
32 }
33 
md5_starts(struct md5_context * ctx)34 void md5_starts(struct md5_context *ctx) {
35 	ctx->total[0] = 0;
36 	ctx->total[1] = 0;
37 	ctx->state[0] = 0x67452301;
38 	ctx->state[1] = 0xEFCDAB89;
39 	ctx->state[2] = 0x98BADCFE;
40 	ctx->state[3] = 0x10325476;
41 }
42 
md5_process(struct md5_context * ctx,uint8 data[64])43 void md5_process(struct md5_context *ctx, uint8 data[64]) {
44 	uint32 A, B, C, D, X[16];
45 
46 	GET_UINT32(X[0], data, 0);
47 	GET_UINT32(X[1], data, 4);
48 	GET_UINT32(X[2], data, 8);
49 	GET_UINT32(X[3], data, 12);
50 	GET_UINT32(X[4], data, 16);
51 	GET_UINT32(X[5], data, 20);
52 	GET_UINT32(X[6], data, 24);
53 	GET_UINT32(X[7], data, 28);
54 	GET_UINT32(X[8], data, 32);
55 	GET_UINT32(X[9], data, 36);
56 	GET_UINT32(X[10], data, 40);
57 	GET_UINT32(X[11], data, 44);
58 	GET_UINT32(X[12], data, 48);
59 	GET_UINT32(X[13], data, 52);
60 	GET_UINT32(X[14], data, 56);
61 	GET_UINT32(X[15], data, 60);
62 
63 #define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
64 
65 #define P(a, b, c, d, k, s, t)		  \
66 	{					\
67 		a += F(b, c, d) + X[k] + t; a = S(a, s) + b;	 \
68 	}
69 
70 	A = ctx->state[0];
71 	B = ctx->state[1];
72 	C = ctx->state[2];
73 	D = ctx->state[3];
74 
75 #define F(x, y, z) (z ^ (x & (y ^ z)))
76 
77 	P(A, B, C, D, 0, 7, 0xD76AA478);
78 	P(D, A, B, C, 1, 12, 0xE8C7B756);
79 	P(C, D, A, B, 2, 17, 0x242070DB);
80 	P(B, C, D, A, 3, 22, 0xC1BDCEEE);
81 	P(A, B, C, D, 4, 7, 0xF57C0FAF);
82 	P(D, A, B, C, 5, 12, 0x4787C62A);
83 	P(C, D, A, B, 6, 17, 0xA8304613);
84 	P(B, C, D, A, 7, 22, 0xFD469501);
85 	P(A, B, C, D, 8, 7, 0x698098D8);
86 	P(D, A, B, C, 9, 12, 0x8B44F7AF);
87 	P(C, D, A, B, 10, 17, 0xFFFF5BB1);
88 	P(B, C, D, A, 11, 22, 0x895CD7BE);
89 	P(A, B, C, D, 12, 7, 0x6B901122);
90 	P(D, A, B, C, 13, 12, 0xFD987193);
91 	P(C, D, A, B, 14, 17, 0xA679438E);
92 	P(B, C, D, A, 15, 22, 0x49B40821);
93 
94 #undef F
95 
96 #define F(x, y, z) (y ^ (z & (x ^ y)))
97 
98 	P(A, B, C, D, 1, 5, 0xF61E2562);
99 	P(D, A, B, C, 6, 9, 0xC040B340);
100 	P(C, D, A, B, 11, 14, 0x265E5A51);
101 	P(B, C, D, A, 0, 20, 0xE9B6C7AA);
102 	P(A, B, C, D, 5, 5, 0xD62F105D);
103 	P(D, A, B, C, 10, 9, 0x02441453);
104 	P(C, D, A, B, 15, 14, 0xD8A1E681);
105 	P(B, C, D, A, 4, 20, 0xE7D3FBC8);
106 	P(A, B, C, D, 9, 5, 0x21E1CDE6);
107 	P(D, A, B, C, 14, 9, 0xC33707D6);
108 	P(C, D, A, B, 3, 14, 0xF4D50D87);
109 	P(B, C, D, A, 8, 20, 0x455A14ED);
110 	P(A, B, C, D, 13, 5, 0xA9E3E905);
111 	P(D, A, B, C, 2, 9, 0xFCEFA3F8);
112 	P(C, D, A, B, 7, 14, 0x676F02D9);
113 	P(B, C, D, A, 12, 20, 0x8D2A4C8A);
114 
115 #undef F
116 
117 #define F(x, y, z) (x ^ y ^ z)
118 
119 	P(A, B, C, D, 5, 4, 0xFFFA3942);
120 	P(D, A, B, C, 8, 11, 0x8771F681);
121 	P(C, D, A, B, 11, 16, 0x6D9D6122);
122 	P(B, C, D, A, 14, 23, 0xFDE5380C);
123 	P(A, B, C, D, 1, 4, 0xA4BEEA44);
124 	P(D, A, B, C, 4, 11, 0x4BDECFA9);
125 	P(C, D, A, B, 7, 16, 0xF6BB4B60);
126 	P(B, C, D, A, 10, 23, 0xBEBFBC70);
127 	P(A, B, C, D, 13, 4, 0x289B7EC6);
128 	P(D, A, B, C, 0, 11, 0xEAA127FA);
129 	P(C, D, A, B, 3, 16, 0xD4EF3085);
130 	P(B, C, D, A, 6, 23, 0x04881D05);
131 	P(A, B, C, D, 9, 4, 0xD9D4D039);
132 	P(D, A, B, C, 12, 11, 0xE6DB99E5);
133 	P(C, D, A, B, 15, 16, 0x1FA27CF8);
134 	P(B, C, D, A, 2, 23, 0xC4AC5665);
135 
136 #undef F
137 
138 #define F(x, y, z) (y ^ (x | ~z))
139 
140 	P(A, B, C, D, 0, 6, 0xF4292244);
141 	P(D, A, B, C, 7, 10, 0x432AFF97);
142 	P(C, D, A, B, 14, 15, 0xAB9423A7);
143 	P(B, C, D, A, 5, 21, 0xFC93A039);
144 	P(A, B, C, D, 12, 6, 0x655B59C3);
145 	P(D, A, B, C, 3, 10, 0x8F0CCC92);
146 	P(C, D, A, B, 10, 15, 0xFFEFF47D);
147 	P(B, C, D, A, 1, 21, 0x85845DD1);
148 	P(A, B, C, D, 8, 6, 0x6FA87E4F);
149 	P(D, A, B, C, 15, 10, 0xFE2CE6E0);
150 	P(C, D, A, B, 6, 15, 0xA3014314);
151 	P(B, C, D, A, 13, 21, 0x4E0811A1);
152 	P(A, B, C, D, 4, 6, 0xF7537E82);
153 	P(D, A, B, C, 11, 10, 0xBD3AF235);
154 	P(C, D, A, B, 2, 15, 0x2AD7D2BB);
155 	P(B, C, D, A, 9, 21, 0xEB86D391);
156 
157 #undef F
158 
159 	ctx->state[0] += A;
160 	ctx->state[1] += B;
161 	ctx->state[2] += C;
162 	ctx->state[3] += D;
163 }
164 
md5_update(struct md5_context * ctx,uint8 * input,uint32 length)165 void md5_update(struct md5_context *ctx, uint8 *input, uint32 length) {
166 	uint32 left, fill;
167 
168 	if (!length) return;
169 
170 	left = (ctx->total[0] >> 3) & 0x3F;
171 	fill = 64 - left;
172 
173 	ctx->total[0] += length << 3;
174 	ctx->total[1] += length >> 29;
175 
176 	ctx->total[0] &= 0xFFFFFFFF;
177 	ctx->total[1] += ctx->total[0] < (length << 3);
178 
179 	if (left && length >= fill) {
180 		memcpy((void*)(ctx->buffer + left), (void*)input, fill);
181 		md5_process(ctx, ctx->buffer);
182 		length -= fill;
183 		input += fill;
184 		left = 0;
185 	}
186 
187 	while (length >= 64) {
188 		md5_process(ctx, input);
189 		length -= 64;
190 		input += 64;
191 	}
192 
193 	if (length) {
194 		memcpy((void*)(ctx->buffer + left), (void*)input, length);
195 	}
196 }
197 
198 static uint8 md5_padding[64] =
199 {
200 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
204 };
205 
md5_finish(struct md5_context * ctx,uint8 digest[16])206 void md5_finish(struct md5_context *ctx, uint8 digest[16]) {
207 	uint32 last, padn;
208 	uint8 msglen[8];
209 
210 	PUT_UINT32(ctx->total[0], msglen, 0);
211 	PUT_UINT32(ctx->total[1], msglen, 4);
212 
213 	last = (ctx->total[0] >> 3) & 0x3F;
214 	padn = (last < 56) ? (56 - last) : (120 - last);
215 
216 	md5_update(ctx, md5_padding, padn);
217 	md5_update(ctx, msglen, 8);
218 
219 	PUT_UINT32(ctx->state[0], digest, 0);
220 	PUT_UINT32(ctx->state[1], digest, 4);
221 	PUT_UINT32(ctx->state[2], digest, 8);
222 	PUT_UINT32(ctx->state[3], digest, 12);
223 }
224 
225 
226 /* Uses a static buffer, so beware of how it's used. */
md5_asciistr(uint8 digest[16])227 char *md5_asciistr(uint8 digest[16]) {
228 	static char str[33];
229 	static char trans[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
230 	int x;
231 
232 	for (x = 0; x < 16; x++) {
233 		str[x * 2] = trans[digest[x] >> 4];
234 		str[x * 2 + 1] = trans[digest[x] & 0x0F];
235 	}
236 	return(str);
237 }
238