1/*	$KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $	*/
2/*
3 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the project nor the names of its contributors
15 *    may be used to endorse or promote products derived from this software
16 *    without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#if 0
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
34
35#include <sys/types.h>
36#include <sys/cdefs.h>
37#include <sys/time.h>
38#include <sys/systm.h>
39#include <crypto/md5.h>
40#endif
41
42#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
43
44#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
45#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
46#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
47#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
48
49#define ROUND1(a, b, c, d, k, s, i) { \
50	(a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
51	(a) = SHIFT((a), (s)); \
52	(a) = (b) + (a); \
53}
54
55#define ROUND2(a, b, c, d, k, s, i) { \
56	(a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
57	(a) = SHIFT((a), (s)); \
58	(a) = (b) + (a); \
59}
60
61#define ROUND3(a, b, c, d, k, s, i) { \
62	(a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
63	(a) = SHIFT((a), (s)); \
64	(a) = (b) + (a); \
65}
66
67#define ROUND4(a, b, c, d, k, s, i) { \
68	(a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
69	(a) = SHIFT((a), (s)); \
70	(a) = (b) + (a); \
71}
72
73#define Sa	 7
74#define Sb	12
75#define Sc	17
76#define Sd	22
77
78#define Se	 5
79#define Sf	 9
80#define Sg	14
81#define Sh	20
82
83#define Si	 4
84#define Sj	11
85#define Sk	16
86#define Sl	23
87
88#define Sm	 6
89#define Sn	10
90#define So	15
91#define Sp	21
92
93#define MD5_A0	0x67452301
94#define MD5_B0	0xefcdab89
95#define MD5_C0	0x98badcfe
96#define MD5_D0	0x10325476
97
98/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
99static const u_int32_t T[65] = {
100	0,
101	0xd76aa478, 	0xe8c7b756,	0x242070db,	0xc1bdceee,
102	0xf57c0faf,	0x4787c62a, 	0xa8304613,	0xfd469501,
103	0x698098d8,	0x8b44f7af,	0xffff5bb1,	0x895cd7be,
104	0x6b901122, 	0xfd987193, 	0xa679438e,	0x49b40821,
105
106	0xf61e2562,	0xc040b340, 	0x265e5a51, 	0xe9b6c7aa,
107	0xd62f105d,	0x2441453,	0xd8a1e681,	0xe7d3fbc8,
108	0x21e1cde6,	0xc33707d6, 	0xf4d50d87, 	0x455a14ed,
109	0xa9e3e905,	0xfcefa3f8, 	0x676f02d9, 	0x8d2a4c8a,
110
111	0xfffa3942,	0x8771f681, 	0x6d9d6122, 	0xfde5380c,
112	0xa4beea44, 	0x4bdecfa9, 	0xf6bb4b60, 	0xbebfbc70,
113	0x289b7ec6, 	0xeaa127fa, 	0xd4ef3085,	0x4881d05,
114	0xd9d4d039, 	0xe6db99e5, 	0x1fa27cf8, 	0xc4ac5665,
115
116	0xf4292244, 	0x432aff97, 	0xab9423a7, 	0xfc93a039,
117	0x655b59c3, 	0x8f0ccc92, 	0xffeff47d, 	0x85845dd1,
118	0x6fa87e4f, 	0xfe2ce6e0, 	0xa3014314, 	0x4e0811a1,
119	0xf7537e82, 	0xbd3af235, 	0x2ad7d2bb, 	0xeb86d391,
120};
121
122static const u_int8_t md5_paddat[MD5_BUFLEN] = {
123	0x80,	0,	0,	0,	0,	0,	0,	0,
124	0,	0,	0,	0,	0,	0,	0,	0,
125	0,	0,	0,	0,	0,	0,	0,	0,
126	0,	0,	0,	0,	0,	0,	0,	0,
127	0,	0,	0,	0,	0,	0,	0,	0,
128	0,	0,	0,	0,	0,	0,	0,	0,
129	0,	0,	0,	0,	0,	0,	0,	0,
130	0,	0,	0,	0,	0,	0,	0,	0,
131};
132
133static void md5_calc(u_int8_t *, md5_ctxt *);
134
135void md5_init(ctxt)
136	md5_ctxt *ctxt;
137{
138	ctxt->md5_n = 0;
139	ctxt->md5_i = 0;
140	ctxt->md5_sta = MD5_A0;
141	ctxt->md5_stb = MD5_B0;
142	ctxt->md5_stc = MD5_C0;
143	ctxt->md5_std = MD5_D0;
144	bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
145}
146
147void md5_loop(ctxt, input, len)
148	md5_ctxt *ctxt;
149	u_int8_t *input;
150	u_int len; /* number of bytes */
151{
152	u_int gap, i;
153
154	ctxt->md5_n += len * 8; /* byte to bit */
155	gap = MD5_BUFLEN - ctxt->md5_i;
156
157	if (len >= gap) {
158		bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
159			gap);
160		md5_calc(ctxt->md5_buf, ctxt);
161
162		for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
163			md5_calc((u_int8_t *)(input + i), ctxt);
164		}
165
166		ctxt->md5_i = len - i;
167		bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
168	} else {
169		bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
170			len);
171		ctxt->md5_i += len;
172	}
173}
174
175void md5_pad(ctxt)
176	md5_ctxt *ctxt;
177{
178	u_int gap;
179
180	/* Don't count up padding. Keep md5_n. */
181	gap = MD5_BUFLEN - ctxt->md5_i;
182	if (gap > 8) {
183		bcopy(md5_paddat,
184		      (void *)(ctxt->md5_buf + ctxt->md5_i),
185		      gap - sizeof(ctxt->md5_n));
186	} else {
187		/* including gap == 8 */
188		bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
189			gap);
190		md5_calc(ctxt->md5_buf, ctxt);
191		bcopy((md5_paddat + gap),
192		      (void *)ctxt->md5_buf,
193		      MD5_BUFLEN - sizeof(ctxt->md5_n));
194	}
195
196	/* 8 byte word */
197#if BYTE_ORDER == LITTLE_ENDIAN
198	bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
199#endif
200#if BYTE_ORDER == BIG_ENDIAN
201	ctxt->md5_buf[56] = ctxt->md5_n8[7];
202	ctxt->md5_buf[57] = ctxt->md5_n8[6];
203	ctxt->md5_buf[58] = ctxt->md5_n8[5];
204	ctxt->md5_buf[59] = ctxt->md5_n8[4];
205	ctxt->md5_buf[60] = ctxt->md5_n8[3];
206	ctxt->md5_buf[61] = ctxt->md5_n8[2];
207	ctxt->md5_buf[62] = ctxt->md5_n8[1];
208	ctxt->md5_buf[63] = ctxt->md5_n8[0];
209#endif
210
211	md5_calc(ctxt->md5_buf, ctxt);
212}
213
214void md5_result(digest, ctxt)
215	u_int8_t *digest;
216	md5_ctxt *ctxt;
217{
218	/* 4 byte words */
219#if BYTE_ORDER == LITTLE_ENDIAN
220	bcopy(&ctxt->md5_st8[0], digest, 16);
221#endif
222#if BYTE_ORDER == BIG_ENDIAN
223	digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
224	digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
225	digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
226	digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
227	digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
228	digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
229	digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
230	digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
231#endif
232}
233
234static void md5_calc(b64, ctxt)
235	u_int8_t *b64;
236	md5_ctxt *ctxt;
237{
238	u_int32_t A = ctxt->md5_sta;
239	u_int32_t B = ctxt->md5_stb;
240	u_int32_t C = ctxt->md5_stc;
241	u_int32_t D = ctxt->md5_std;
242#if BYTE_ORDER == LITTLE_ENDIAN
243	u_int32_t *X = (u_int32_t *)b64;
244#endif
245#if BYTE_ORDER == BIG_ENDIAN
246	/* 4 byte words */
247	/* what a brute force but fast! */
248	u_int32_t X[16];
249	u_int8_t *y = (u_int8_t *)X;
250	y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
251	y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
252	y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
253	y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
254	y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
255	y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
256	y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
257	y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
258	y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
259	y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
260	y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
261	y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
262	y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
263	y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
264	y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
265	y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
266#endif
267
268	ROUND1(A, B, C, D,  0, Sa,  1); ROUND1(D, A, B, C,  1, Sb,  2);
269	ROUND1(C, D, A, B,  2, Sc,  3); ROUND1(B, C, D, A,  3, Sd,  4);
270	ROUND1(A, B, C, D,  4, Sa,  5); ROUND1(D, A, B, C,  5, Sb,  6);
271	ROUND1(C, D, A, B,  6, Sc,  7); ROUND1(B, C, D, A,  7, Sd,  8);
272	ROUND1(A, B, C, D,  8, Sa,  9); ROUND1(D, A, B, C,  9, Sb, 10);
273	ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
274	ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
275	ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
276
277	ROUND2(A, B, C, D,  1, Se, 17); ROUND2(D, A, B, C,  6, Sf, 18);
278	ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A,  0, Sh, 20);
279	ROUND2(A, B, C, D,  5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
280	ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A,  4, Sh, 24);
281	ROUND2(A, B, C, D,  9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
282	ROUND2(C, D, A, B,  3, Sg, 27); ROUND2(B, C, D, A,  8, Sh, 28);
283	ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C,  2, Sf, 30);
284	ROUND2(C, D, A, B,  7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
285
286	ROUND3(A, B, C, D,  5, Si, 33); ROUND3(D, A, B, C,  8, Sj, 34);
287	ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
288	ROUND3(A, B, C, D,  1, Si, 37); ROUND3(D, A, B, C,  4, Sj, 38);
289	ROUND3(C, D, A, B,  7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
290	ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C,  0, Sj, 42);
291	ROUND3(C, D, A, B,  3, Sk, 43); ROUND3(B, C, D, A,  6, Sl, 44);
292	ROUND3(A, B, C, D,  9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
293	ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A,  2, Sl, 48);
294
295	ROUND4(A, B, C, D,  0, Sm, 49); ROUND4(D, A, B, C,  7, Sn, 50);
296	ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A,  5, Sp, 52);
297	ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C,  3, Sn, 54);
298	ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A,  1, Sp, 56);
299	ROUND4(A, B, C, D,  8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
300	ROUND4(C, D, A, B,  6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
301	ROUND4(A, B, C, D,  4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
302	ROUND4(C, D, A, B,  2, So, 63); ROUND4(B, C, D, A,  9, Sp, 64);
303
304	ctxt->md5_sta += A;
305	ctxt->md5_stb += B;
306	ctxt->md5_stc += C;
307	ctxt->md5_std += D;
308}
309