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