1 /*
2 ** Copyright 1998 - 2000 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5 
6 #define	MD5_INTERNAL
7 #include	"md5.h"
8 #include	<string.h>
9 #include	<stdlib.h>
10 
11 
12 #define	MD5_BYTE	unsigned char
13 
14 #define	MD5_ROL(w,n)	\
15 		( (w) << (n) | ( (w) >> (32-(n)) ) )
16 
17 static	MD5_WORD	T[64]={
18 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
19 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
20 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
21 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
22 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
23 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
24 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
25 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
26 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
27 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
28 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
29 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
30 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
31 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
32 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
33 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
34 
md5_context_init(struct MD5_CONTEXT * c)35 void md5_context_init(struct MD5_CONTEXT *c)
36 {
37 	if (sizeof(MD5_WORD) != 4)	abort();
38 
39 	c->A=0x67452301;
40 	c->B=0xefcdab89;
41 	c->C=0x98badcfe;
42 	c->D=0x10325476;
43 
44 	c->blk_ptr=0;
45 }
46 
md5_context_hash(struct MD5_CONTEXT * c,const unsigned char blk[MD5_BLOCK_SIZE])47 void md5_context_hash(struct MD5_CONTEXT *c,
48 	const unsigned char blk[MD5_BLOCK_SIZE])
49 {
50 MD5_WORD	x[16];
51 unsigned	i, j;
52 MD5_WORD	A, B, C, D;
53 MD5_WORD	zz;
54 
55 	for (i=j=0; i<16; i++)
56 	{
57 	MD5_WORD	w=(MD5_WORD)blk[j++];
58 
59 		w |= (MD5_WORD)blk[j++] << 8;
60 		w |= (MD5_WORD)blk[j++] << 16;
61 		w |= (MD5_WORD)blk[j++] << 24;
62 		x[i]= w;
63 	}
64 
65 #define	F(X,Y,Z)	( ((X) & (Y)) | ( (~(X)) & (Z)))
66 #define	G(X,Y,Z)	( ((X) & (Z)) | ( (Y) & (~(Z))))
67 #define	H(X,Y,Z)	( (X) ^ (Y) ^ (Z) )
68 #define	I(X,Y,Z)	( (Y) ^ ( (X) | (~(Z))))
69 
70 	A=c->A;
71 	B=c->B;
72 	C=c->C;
73 	D=c->D;
74 
75 #define	ROUND1(a,b,c,d,k,s,i)	\
76 	{ zz=(a + F(b,c,d) + x[k] + T[i]); a=b+MD5_ROL(zz,s); }
77 
78 	ROUND1(A,B,C,D,0,7,0);
79 	ROUND1(D,A,B,C,1,12,1);
80 	ROUND1(C,D,A,B,2,17,2);
81 	ROUND1(B,C,D,A,3,22,3);
82 	ROUND1(A,B,C,D,4,7,4);
83 	ROUND1(D,A,B,C,5,12,5);
84 	ROUND1(C,D,A,B,6,17,6);
85 	ROUND1(B,C,D,A,7,22,7);
86 	ROUND1(A,B,C,D,8,7,8);
87 	ROUND1(D,A,B,C,9,12,9);
88 	ROUND1(C,D,A,B,10,17,10);
89 	ROUND1(B,C,D,A,11,22,11);
90 	ROUND1(A,B,C,D,12,7,12);
91 	ROUND1(D,A,B,C,13,12,13);
92 	ROUND1(C,D,A,B,14,17,14);
93 	ROUND1(B,C,D,A,15,22,15);
94 
95 #define	ROUND2(a,b,c,d,k,s,i)	\
96 	{ zz=(a + G(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); }
97 
98 	ROUND2(A,B,C,D,1,5,16);
99 	ROUND2(D,A,B,C,6,9,17);
100 	ROUND2(C,D,A,B,11,14,18);
101 	ROUND2(B,C,D,A,0,20,19);
102 	ROUND2(A,B,C,D,5,5,20);
103 	ROUND2(D,A,B,C,10,9,21);
104 	ROUND2(C,D,A,B,15,14,22);
105 	ROUND2(B,C,D,A,4,20,23);
106 	ROUND2(A,B,C,D,9,5,24);
107 	ROUND2(D,A,B,C,14,9,25);
108 	ROUND2(C,D,A,B,3,14,26);
109 	ROUND2(B,C,D,A,8,20,27);
110 	ROUND2(A,B,C,D,13,5,28);
111 	ROUND2(D,A,B,C,2,9,29);
112 	ROUND2(C,D,A,B,7,14,30);
113 	ROUND2(B,C,D,A,12,20,31);
114 
115 #define	ROUND3(a,b,c,d,k,s,i)	\
116 	{ zz=(a + H(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); }
117 
118 	ROUND3(A,B,C,D,5,4,32);
119 	ROUND3(D,A,B,C,8,11,33);
120 	ROUND3(C,D,A,B,11,16,34);
121 	ROUND3(B,C,D,A,14,23,35);
122 	ROUND3(A,B,C,D,1,4,36);
123 	ROUND3(D,A,B,C,4,11,37);
124 	ROUND3(C,D,A,B,7,16,38);
125 	ROUND3(B,C,D,A,10,23,39);
126 	ROUND3(A,B,C,D,13,4,40);
127 	ROUND3(D,A,B,C,0,11,41);
128 	ROUND3(C,D,A,B,3,16,42);
129 	ROUND3(B,C,D,A,6,23,43);
130 	ROUND3(A,B,C,D,9,4,44);
131 	ROUND3(D,A,B,C,12,11,45);
132 	ROUND3(C,D,A,B,15,16,46);
133 	ROUND3(B,C,D,A,2,23,47);
134 
135 #define	ROUND4(a,b,c,d,k,s,i)	\
136 	{ zz=(a + I(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); }
137 
138 	ROUND4(A,B,C,D,0,6,48);
139 	ROUND4(D,A,B,C,7,10,49);
140 	ROUND4(C,D,A,B,14,15,50);
141 	ROUND4(B,C,D,A,5,21,51);
142 	ROUND4(A,B,C,D,12,6,52);
143 	ROUND4(D,A,B,C,3,10,53);
144 	ROUND4(C,D,A,B,10,15,54);
145 	ROUND4(B,C,D,A,1,21,55);
146 	ROUND4(A,B,C,D,8,6,56);
147 	ROUND4(D,A,B,C,15,10,57);
148 	ROUND4(C,D,A,B,6,15,58);
149 	ROUND4(B,C,D,A,13,21,59);
150 	ROUND4(A,B,C,D,4,6,60);
151 	ROUND4(D,A,B,C,11,10,61);
152 	ROUND4(C,D,A,B,2,15,62);
153 	ROUND4(B,C,D,A,9,21,63);
154 
155 	c->A += A;
156 	c->B += B;
157 	c->C += C;
158 	c->D += D;
159 }
160 
md5_context_hashstream(struct MD5_CONTEXT * c,const void * p,unsigned l)161 void md5_context_hashstream(struct MD5_CONTEXT *c, const void *p, unsigned l)
162 {
163 const unsigned char *cp=(const unsigned char *)p;
164 unsigned ll;
165 
166 	while (l)
167 	{
168 		if (c->blk_ptr == 0 && l >= MD5_BLOCK_SIZE)
169 		{
170 			md5_context_hash(c, cp);
171 			cp += MD5_BLOCK_SIZE;
172 			l -= MD5_BLOCK_SIZE;
173 			continue;
174 		}
175 
176 		ll=l;
177 		if (ll > MD5_BLOCK_SIZE - c->blk_ptr)
178 			ll=MD5_BLOCK_SIZE - c->blk_ptr;
179 		memcpy(c->blk + c->blk_ptr, cp, ll);
180 		c->blk_ptr += ll;
181 		cp += ll;
182 		l -= ll;
183 		if (c->blk_ptr >= MD5_BLOCK_SIZE)
184 		{
185 			md5_context_hash(c, c->blk);
186 			c->blk_ptr=0;
187 		}
188 	}
189 }
190 
md5_context_endstream(struct MD5_CONTEXT * c,unsigned long ll)191 void md5_context_endstream(struct MD5_CONTEXT *c, unsigned long ll)
192 {
193 unsigned char buf[8];
194 
195 static unsigned char zero[MD5_BLOCK_SIZE-8];
196 MD5_WORD	l;
197 
198 	buf[0]=0x80;
199 	md5_context_hashstream(c, buf, 1);
200 	while (c->blk_ptr != MD5_BLOCK_SIZE - 8)
201 	{
202 		if (c->blk_ptr > MD5_BLOCK_SIZE - 8)
203 		{
204 			md5_context_hashstream(c, zero,
205 				MD5_BLOCK_SIZE - c->blk_ptr);
206 			continue;
207 		}
208 		md5_context_hashstream(c, zero,
209 			MD5_BLOCK_SIZE - 8 - c->blk_ptr);
210 	}
211 
212 	l= ll;
213 
214 	l <<= 3;
215 
216 	buf[0]=l;
217 	l >>= 8;
218 	buf[1]=l;
219 	l >>= 8;
220 	buf[2]=l;
221 	l >>= 8;
222 	buf[3]=l;
223 
224 	l= ll;
225 	l >>= 29;
226 	buf[4]=l;
227 	l >>= 8;
228 	buf[5]=l;
229 	l >>= 8;
230 	buf[6]=l;
231 	l >>= 8;
232 	buf[7]=l;
233 
234 	md5_context_hashstream(c, buf, 8);
235 }
236 
md5_context_digest(struct MD5_CONTEXT * c,MD5_DIGEST d)237 void md5_context_digest(struct MD5_CONTEXT *c, MD5_DIGEST d)
238 {
239 unsigned char *dp=d;
240 MD5_WORD	w;
241 
242 #define	PUT(c) (w=(c), *dp++ = w, w >>= 8, *dp++ = w, w >>= 8, *dp++ = w, w >>= 8, *dp++ = w)
243 
244 	PUT(c->A);
245 	PUT(c->B);
246 	PUT(c->C);
247 	PUT(c->D);
248 #undef	PUT
249 }
250 
md5_context_restore(struct MD5_CONTEXT * c,const MD5_DIGEST d)251 void md5_context_restore(struct MD5_CONTEXT *c, const MD5_DIGEST d)
252 {
253 const unsigned char *dp=(unsigned char *)d+MD5_DIGEST_SIZE;
254 MD5_WORD	w;
255 
256 #define	GET	\
257 	w=*--dp; w=(w << 8) | *--dp; w=(w << 8) | *--dp; w=(w << 8) | *--dp;
258 
259 	GET
260 	c->D=w;
261 	GET
262 	c->C=w;
263 	GET
264 	c->B=w;
265 	GET
266 	c->A=w;
267 	c->blk_ptr=0;
268 }
269 
md5_digest(const void * msg,unsigned int len,MD5_DIGEST d)270 void md5_digest(const void *msg, unsigned int len, MD5_DIGEST d)
271 {
272 struct MD5_CONTEXT	c;
273 
274 	md5_context_init(&c);
275 	md5_context_hashstream(&c, msg, len);
276 	md5_context_endstream(&c, len);
277 	md5_context_digest(&c, d);
278 }
279