1 #pragma prototyped
2
3 /*
4 * md5
5 */
6
7 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
8 rights reserved.
9
10 License to copy and use this software is granted provided that it
11 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
12 Method" in all material mentioning or referencing this software
13 or this function.
14
15 License is also granted to make and use derivative works provided
16 that such works are identified as "derived from the RSA Data
17 Security, Inc. MD5 Message-Digest Method" in all material
18 mentioning or referencing the derived work.
19
20 RSA Data Security, Inc. makes no representations concerning either
21 the merchantability of this software or the suitability of this
22 software for any particular purpose. It is provided "as is"
23 without express or implied warranty of any kind.
24
25 These notices must be retained in any copies of any part of this
26 documentation and/or software.
27 */
28
29 #define md5_description \
30 "The RSA Data Security, Inc. MD5 Message-Digest Method, 1991-2, \
31 used with permission. The block count is not printed."
32 #define md5_options "[+(version)?md5 (RSA Data Security, Inc. MD5 Message-Digest, 1991-2) 1996-02-29]"
33 #define md5_match "md5|MD5"
34 #define md5_scale 0
35
36 typedef uint32_t UINT4;
37
38 typedef struct Md5_s
39 {
40 _SUM_PUBLIC_
41 _SUM_PRIVATE_
42 UINT4 state[4]; /* state (ABCD) */
43 UINT4 count[2]; /* # bits handled mod 2^64 (lsb)*/
44 unsigned char buffer[64]; /* input buffer */
45 unsigned char digest[16]; /* final digest */
46 unsigned char digest_sum[16]; /* sum of all digests */
47 } Md5_t;
48
49 static const unsigned char md5_pad[] =
50 {
51 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
59 };
60
61 /*
62 * encode input into output
63 * len must be a multiple of 4
64 */
65
66 static void
md5_encode(register unsigned char * output,register UINT4 * input,unsigned int len)67 md5_encode(register unsigned char* output, register UINT4* input, unsigned int len)
68 {
69 register unsigned int i;
70 register unsigned int j;
71
72 for (i = j = 0; j < len; i++, j += 4)
73 {
74 output[j] = (unsigned char)(input[i] & 0xff);
75 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
76 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
77 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
78 }
79 }
80
81 /*
82 * decode input into output
83 * len must be a multiple of 4
84 */
85
86 static void
md5_decode(register UINT4 * output,register unsigned char * input,unsigned int len)87 md5_decode(register UINT4* output, register unsigned char* input, unsigned int len)
88 {
89 unsigned int i;
90 unsigned int j;
91
92 for (i = j = 0; j < len; i++, j += 4)
93 output[i] = ((UINT4)input[j]) |
94 (((UINT4)input[j+1]) << 8) |
95 (((UINT4)input[j+2]) << 16) |
96 (((UINT4)input[j+3]) << 24);
97 }
98
99 static int
md5_init(Sum_t * p)100 md5_init(Sum_t* p)
101 {
102 register Md5_t* context = (Md5_t*)p;
103
104 context->count[0] = context->count[1] = 0;
105 context->state[0] = 0x67452301;
106 context->state[1] = 0xefcdab89;
107 context->state[2] = 0x98badcfe;
108 context->state[3] = 0x10325476;
109 return 0;
110 }
111
112 static Sum_t*
md5_open(const Method_t * method,const char * name)113 md5_open(const Method_t* method, const char* name)
114 {
115 Md5_t* p;
116
117 if (p = newof(0, Md5_t, 1, 0))
118 {
119 p->method = (Method_t*)method;
120 p->name = name;
121 md5_init((Sum_t*)p);
122 }
123 return (Sum_t*)p;
124 }
125
126 /*
127 * basic MD5 step -- transforms buf based on in
128 */
129
130 #define S11 7
131 #define S12 12
132 #define S13 17
133 #define S14 22
134 #define S21 5
135 #define S22 9
136 #define S23 14
137 #define S24 20
138 #define S31 4
139 #define S32 11
140 #define S33 16
141 #define S34 23
142 #define S41 6
143 #define S42 10
144 #define S43 15
145 #define S44 21
146
147 /* F, G, H and I are basic MD5 functions */
148 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
149 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
150 #define H(x, y, z) ((x) ^ (y) ^ (z))
151 #define I(x, y, z) ((y) ^ ((x) | (~z)))
152
153 /* ROTATE_LEFT rotates x left n bits */
154 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
155
156 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
157 /* Rotation is separate from addition to prevent recomputation */
158 #define FF(a, b, c, d, x, s, ac) { \
159 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
160 (a) = ROTATE_LEFT ((a), (s)); \
161 (a) += (b); \
162 }
163 #define GG(a, b, c, d, x, s, ac) { \
164 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
165 (a) = ROTATE_LEFT ((a), (s)); \
166 (a) += (b); \
167 }
168 #define HH(a, b, c, d, x, s, ac) { \
169 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
170 (a) = ROTATE_LEFT ((a), (s)); \
171 (a) += (b); \
172 }
173 #define II(a, b, c, d, x, s, ac) { \
174 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
175 (a) = ROTATE_LEFT ((a), (s)); \
176 (a) += (b); \
177 }
178
179 static void
md5_transform(UINT4 state[4],unsigned char block[64])180 md5_transform(UINT4 state[4], unsigned char block[64])
181 {
182 UINT4 a = state[0];
183 UINT4 b = state[1];
184 UINT4 c = state[2];
185 UINT4 d = state[3];
186 UINT4 x[16];
187
188 md5_decode(x, block, 64);
189
190 /* round 1 */
191 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
192 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
193 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
194 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
195 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
196 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
197 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
198 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
199 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
200 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
201 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
202 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
203 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
204 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
205 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
206 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
207
208 /* round 2 */
209 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
210 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
211 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
212 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
213 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
214 GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */
215 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
216 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
217 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
218 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
219 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
220 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
221 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
222 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
223 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
224 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
225
226 /* round 3 */
227 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
228 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
229 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
230 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
231 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
232 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
233 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
234 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
235 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
236 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
237 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
238 HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */
239 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
240 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
241 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
242 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
243
244 /* round 4 */
245 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
246 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
247 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
248 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
249 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
250 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
251 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
252 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
253 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
254 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
255 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
256 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
257 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
258 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
259 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
260 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
261
262 state[0] += a;
263 state[1] += b;
264 state[2] += c;
265 state[3] += d;
266 }
267
268 static int
md5_block(Sum_t * p,const void * s,size_t inputLen)269 md5_block(Sum_t* p, const void* s, size_t inputLen)
270 {
271 register Md5_t* context = (Md5_t*)p;
272 unsigned char* input = (unsigned char*)s;
273 unsigned int i;
274 unsigned int index;
275 unsigned int partLen;
276
277 /* compute number of bytes mod 64 */
278 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
279
280 /* update number of bits */
281 if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
282 context->count[1]++;
283 context->count[1] += ((UINT4)inputLen >> 29);
284 partLen = 64 - index;
285
286 /* transform as many times as possible */
287 if (inputLen >= partLen)
288 {
289 memcpy(&context->buffer[index], input, partLen);
290 md5_transform(context->state, context->buffer);
291 for (i = partLen; i + 63 < inputLen; i += 64)
292 md5_transform(context->state, &input[i]);
293 index = 0;
294 }
295 else
296 i = 0;
297
298 /* buffer remaining input */
299 memcpy(&context->buffer[index], &input[i], inputLen - i);
300
301 return 0;
302 }
303
304 static int
md5_done(Sum_t * p)305 md5_done(Sum_t* p)
306 {
307 register Md5_t* context = (Md5_t*)p;
308 unsigned char bits[8];
309 unsigned int index;
310 unsigned int padLen;
311
312 /* save number of bits */
313 md5_encode(bits, context->count, sizeof(bits));
314
315 /* pad out to 56 mod 64 */
316 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
317 padLen = (index < 56) ? (56 - index) : (120 - index);
318 md5_block(p, md5_pad, padLen);
319
320 /* append length (before padding) */
321 md5_block(p, bits, sizeof(bits));
322
323 /* store state in digest */
324 md5_encode(context->digest, context->state, sizeof(context->digest));
325
326 /* accumulate the digests */
327 for (index = 0; index < elementsof(context->digest); index++)
328 context->digest_sum[index] ^= context->digest[index];
329
330 return 0;
331 }
332
333 static int
md5_print(Sum_t * p,Sfio_t * sp,register int flags,size_t scale)334 md5_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
335 {
336 register Md5_t* x = (Md5_t*)p;
337 register unsigned char* d;
338 register int n;
339
340 d = (flags & SUM_TOTAL) ? x->digest_sum : x->digest;
341 for (n = 0; n < elementsof(x->digest); n++)
342 sfprintf(sp, "%02x", d[n]);
343 return 0;
344 }
345
346 static int
md5_data(Sum_t * p,Sumdata_t * data)347 md5_data(Sum_t* p, Sumdata_t* data)
348 {
349 register Md5_t* x = (Md5_t*)p;
350
351 data->size = elementsof(x->digest);
352 data->num = 0;
353 data->buf = x->digest;
354 return 0;
355 }
356