1/*
2 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 */
5
6#pragma ident	"%Z%%M%	%I%	%E% SMI"
7
8#include "md5.h"
9
10/*
11**************************************************************************
12** md5.c -- the source code for MD5 routines				**
13** RSA Data Security, Inc. MD5 Message-Digest Algorithm			**
14** Created: 2/17/90 RLR							**
15** Revised: 1/91 SRD, AJ, BSK, JT Reference C ver., 7/10 constant corr.	**
16**************************************************************************
17*/
18
19/*
20**************************************************************************
21** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.	**
22**									**
23** License to copy and use this software is granted provided that	**
24** it is identified as the "RSA Data Security, Inc. MD5 Message-	**
25** Digest Algorithm" in all material mentioning or referencing this	**
26** software or this function.						**
27**									**
28** License is also granted to make and use derivative works		**
29** provided that such works are identified as "derived from the RSA	**
30** Data Security, Inc. MD5 Message-Digest Algorithm" in all		**
31** material mentioning or referencing the derived work.			**
32**									**
33** RSA Data Security, Inc. makes no representations concerning		**
34** either the merchantability of this software or the suitability	**
35** of this software for any particular purpose.  It is provided "as	**
36** is" without express or implied warranty of any kind.			**
37**									**
38** These notices must be retained in any copies of any part of this	**
39** documentation and/or software.					**
40**************************************************************************
41*/
42
43
44/*
45**************************************************************************
46**  Message-digest routines:						**
47**  To form the message digest for a message M				**
48**    (1) Initialize a context buffer mdContext using MD5Init		**
49**    (2) Call MD5Update on mdContext and M				**
50**    (3) Call MD5Final on mdContext					**
51**  The message digest is now in mdContext->digest[0...15]		**
52**************************************************************************
53*/
54
55/* forward declaration */
56static void Transform (UINT4 *buf, UINT4 *in);
57
58static unsigned char PADDING[64] = {
59	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
67	};
68
69/* F, G, H and I are basic MD5 functions */
70#define	F(x, y, z) (((x) & (y)) | ((~x) & (z)))
71#define	G(x, y, z) (((x) & (z)) | ((y) & (~z)))
72#define	H(x, y, z) ((x) ^ (y) ^ (z))
73#define	I(x, y, z) ((y) ^ ((x) | (~z)))
74
75/* ROTATE_LEFT rotates x left n bits */
76#define	ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
77
78/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
79/* Rotation is separate from addition to prevent recomputation */
80#define	FF(a, b, c, d, x, s, ac) \
81	{(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
82	(a) = ROTATE_LEFT ((a), (s)); \
83	(a) += (b); \
84	}
85#define	GG(a, b, c, d, x, s, ac) \
86	{(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
87	(a) = ROTATE_LEFT ((a), (s)); \
88	(a) += (b); \
89	}
90#define	HH(a, b, c, d, x, s, ac) \
91	{(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
92	(a) = ROTATE_LEFT ((a), (s)); \
93	(a) += (b); \
94	}
95#define	II(a, b, c, d, x, s, ac) \
96	{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
97	(a) = ROTATE_LEFT ((a), (s)); \
98	(a) += (b); \
99	}
100
101/*
102* The routine MD5Init initializes the message-digest context
103* mdContext. All fields are set to zero.
104*/
105void MD5Init (MD5_CTX *mdContext)
106{
107	mdContext->i[0] = mdContext->i[1] = (UINT4)0;
108
109	/*
110	* Load magic initialization constants.
111	*/
112	mdContext->buf[0] = (UINT4)0x67452301;
113	mdContext->buf[1] = (UINT4)0xefcdab89;
114	mdContext->buf[2] = (UINT4)0x98badcfe;
115	mdContext->buf[3] = (UINT4)0x10325476;
116}
117
118/*
119* The routine MD5Update updates the message-digest context to
120* account for the presence of each of the characters inBuf[0..inLen-1]
121* in the message whose digest is being computed.
122*/
123void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
124{
125	UINT4 in[16];
126	int mdi;
127	unsigned int i, ii;
128
129	/* compute number of bytes mod 64 */
130	mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
131
132	/* update number of bits */
133	if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
134		mdContext->i[1]++;
135	mdContext->i[0] += ((UINT4)inLen << 3);
136	mdContext->i[1] += ((UINT4)inLen >> 29);
137
138	while (inLen--) {
139		/* add new character to buffer, increment mdi */
140		mdContext->in[mdi++] = *inBuf++;
141
142		/* transform if necessary */
143		if (mdi == 0x40) {
144			for (i = 0, ii = 0; i < 16; i++, ii += 4)
145				in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
146					(((UINT4)mdContext->in[ii+2]) << 16) |
147					(((UINT4)mdContext->in[ii+1]) << 8) |
148					((UINT4)mdContext->in[ii]);
149			Transform (mdContext->buf, in);
150			mdi = 0;
151		}
152	}
153}
154
155/*
156* The routine MD5Final terminates the message-digest computation and
157* ends with the desired message digest in mdContext->digest[0...15].
158*/
159void MD5Final (MD5_CTX *mdContext)
160{
161	UINT4 in[16];
162	int mdi;
163	unsigned int i, ii;
164	unsigned int padLen;
165
166	/* save number of bits */
167	in[14] = mdContext->i[0];
168	in[15] = mdContext->i[1];
169
170	/* compute number of bytes mod 64 */
171	mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
172
173	/* pad out to 56 mod 64 */
174	padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
175	MD5Update (mdContext, PADDING, padLen);
176
177	/* append length in bits and transform */
178	for (i = 0, ii = 0; i < 14; i++, ii += 4)
179		in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
180			(((UINT4)mdContext->in[ii+2]) << 16) |
181			(((UINT4)mdContext->in[ii+1]) << 8) |
182			((UINT4)mdContext->in[ii]);
183			Transform (mdContext->buf, in);
184
185	/* store buffer in digest */
186	for (i = 0, ii = 0; i < 4; i++, ii += 4) {
187		mdContext->digest[ii] =
188				(unsigned char)(mdContext->buf[i] & 0xFF);
189		mdContext->digest[ii+1] =
190			(unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
191		mdContext->digest[ii+2] =
192			(unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
193		mdContext->digest[ii+3] =
194			(unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
195	}
196}
197
198/*
199* Basic MD5 step. Transforms buf based on in.
200*/
201static void Transform (UINT4 *buf, UINT4 *in)
202{
203	UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
204
205/* Round 1 */
206#define	S11	7
207#define	S12	12
208#define	S13	17
209#define	S14	22
210	FF (a, b, c, d, in[ 0], S11, 3614090360U); /* 1 */
211	FF (d, a, b, c, in[ 1], S12, 3905402710U); /* 2 */
212	FF (c, d, a, b, in[ 2], S13,  606105819U); /* 3 */
213	FF (b, c, d, a, in[ 3], S14, 3250441966U); /* 4 */
214	FF (a, b, c, d, in[ 4], S11, 4118548399U); /* 5 */
215	FF (d, a, b, c, in[ 5], S12, 1200080426U); /* 6 */
216	FF (c, d, a, b, in[ 6], S13, 2821735955U); /* 7 */
217	FF (b, c, d, a, in[ 7], S14, 4249261313U); /* 8 */
218	FF (a, b, c, d, in[ 8], S11, 1770035416U); /* 9 */
219	FF (d, a, b, c, in[ 9], S12, 2336552879U); /* 10 */
220	FF (c, d, a, b, in[10], S13, 4294925233U); /* 11 */
221	FF (b, c, d, a, in[11], S14, 2304563134U); /* 12 */
222	FF (a, b, c, d, in[12], S11, 1804603682U); /* 13 */
223	FF (d, a, b, c, in[13], S12, 4254626195U); /* 14 */
224	FF (c, d, a, b, in[14], S13, 2792965006U); /* 15 */
225	FF (b, c, d, a, in[15], S14, 1236535329U); /* 16 */
226
227/* Round 2 */
228#define	S21	5
229#define	S22	9
230#define	S23	14
231#define	S24	20
232	GG (a, b, c, d, in[ 1], S21, 4129170786U); /* 17 */
233	GG (d, a, b, c, in[ 6], S22, 3225465664U); /* 18 */
234	GG (c, d, a, b, in[11], S23,  643717713U); /* 19 */
235	GG (b, c, d, a, in[ 0], S24, 3921069994U); /* 20 */
236	GG (a, b, c, d, in[ 5], S21, 3593408605U); /* 21 */
237	GG (d, a, b, c, in[10], S22,   38016083U); /* 22 */
238	GG (c, d, a, b, in[15], S23, 3634488961U); /* 23 */
239	GG (b, c, d, a, in[ 4], S24, 3889429448U); /* 24 */
240	GG (a, b, c, d, in[ 9], S21,  568446438U); /* 25 */
241	GG (d, a, b, c, in[14], S22, 3275163606U); /* 26 */
242	GG (c, d, a, b, in[ 3], S23, 4107603335U); /* 27 */
243	GG (b, c, d, a, in[ 8], S24, 1163531501U); /* 28 */
244	GG (a, b, c, d, in[13], S21, 2850285829U); /* 29 */
245	GG (d, a, b, c, in[ 2], S22, 4243563512U); /* 30 */
246	GG (c, d, a, b, in[ 7], S23, 1735328473U); /* 31 */
247	GG (b, c, d, a, in[12], S24, 2368359562U); /* 32 */
248
249/* Round 3 */
250#define	S31	4
251#define	S32	11
252#define	S33	16
253#define	S34	23
254	HH (a, b, c, d, in[ 5], S31, 4294588738U); /* 33 */
255	HH (d, a, b, c, in[ 8], S32, 2272392833U); /* 34 */
256	HH (c, d, a, b, in[11], S33, 1839030562U); /* 35 */
257	HH (b, c, d, a, in[14], S34, 4259657740U); /* 36 */
258	HH (a, b, c, d, in[ 1], S31, 2763975236U); /* 37 */
259	HH (d, a, b, c, in[ 4], S32, 1272893353U); /* 38 */
260	HH (c, d, a, b, in[ 7], S33, 4139469664U); /* 39 */
261	HH (b, c, d, a, in[10], S34, 3200236656U); /* 40 */
262	HH (a, b, c, d, in[13], S31,  681279174U); /* 41 */
263	HH (d, a, b, c, in[ 0], S32, 3936430074U); /* 42 */
264	HH (c, d, a, b, in[ 3], S33, 3572445317U); /* 43 */
265	HH (b, c, d, a, in[ 6], S34,   76029189U); /* 44 */
266	HH (a, b, c, d, in[ 9], S31, 3654602809U); /* 45 */
267	HH (d, a, b, c, in[12], S32, 3873151461U); /* 46 */
268	HH (c, d, a, b, in[15], S33,  530742520U); /* 47 */
269	HH (b, c, d, a, in[ 2], S34, 3299628645U); /* 48 */
270
271/* Round 4 */
272#define	S41	6
273#define	S42	10
274#define	S43	15
275#define	S44	21
276	II (a, b, c, d, in[ 0], S41, 4096336452U); /* 49 */
277	II (d, a, b, c, in[ 7], S42, 1126891415U); /* 50 */
278	II (c, d, a, b, in[14], S43, 2878612391U); /* 51 */
279	II (b, c, d, a, in[ 5], S44, 4237533241U); /* 52 */
280	II (a, b, c, d, in[12], S41, 1700485571U); /* 53 */
281	II (d, a, b, c, in[ 3], S42, 2399980690U); /* 54 */
282	II (c, d, a, b, in[10], S43, 4293915773U); /* 55 */
283	II (b, c, d, a, in[ 1], S44, 2240044497U); /* 56 */
284	II (a, b, c, d, in[ 8], S41, 1873313359U); /* 57 */
285	II (d, a, b, c, in[15], S42, 4264355552U); /* 58 */
286	II (c, d, a, b, in[ 6], S43, 2734768916U); /* 59 */
287	II (b, c, d, a, in[13], S44, 1309151649U); /* 60 */
288	II (a, b, c, d, in[ 4], S41, 4149444226U); /* 61 */
289	II (d, a, b, c, in[11], S42, 3174756917U); /* 62 */
290	II (c, d, a, b, in[ 2], S43,  718787259U); /* 63 */
291	II (b, c, d, a, in[ 9], S44, 3951481745U); /* 64 */
292
293	buf[0] += a;
294	buf[1] += b;
295	buf[2] += c;
296	buf[3] += d;
297}
298