1285031Sdes/*	$OpenBSD: md5.c,v 1.9 2014/01/08 06:14:57 tedu Exp $	*/
2285031Sdes
3285031Sdes/*
4285031Sdes * This code implements the MD5 message-digest algorithm.
5285031Sdes * The algorithm is due to Ron Rivest.	This code was
6285031Sdes * written by Colin Plumb in 1993, no copyright is claimed.
7285031Sdes * This code is in the public domain; do with it what you wish.
8285031Sdes *
9285031Sdes * Equivalent code is available from RSA Data Security, Inc.
10285031Sdes * This code has been tested against that, and is equivalent,
11285031Sdes * except that you don't need to include two pages of legalese
12285031Sdes * with every copy.
13285031Sdes *
14285031Sdes * To compute the message digest of a chunk of bytes, declare an
15285031Sdes * MD5Context structure, pass it to MD5Init, call MD5Update as
16285031Sdes * needed on buffers full of bytes, and then call MD5Final, which
17285031Sdes * will fill a supplied 16-byte array with the digest.
18285031Sdes */
19285031Sdes
20285031Sdes#include "includes.h"
21285031Sdes
22285031Sdes#ifndef WITH_OPENSSL
23285031Sdes
24285031Sdes#include <sys/types.h>
25285031Sdes#include <string.h>
26285031Sdes#include "md5.h"
27285031Sdes
28285031Sdes#define PUT_64BIT_LE(cp, value) do {					\
29285031Sdes	(cp)[7] = (value) >> 56;					\
30285031Sdes	(cp)[6] = (value) >> 48;					\
31285031Sdes	(cp)[5] = (value) >> 40;					\
32285031Sdes	(cp)[4] = (value) >> 32;					\
33285031Sdes	(cp)[3] = (value) >> 24;					\
34285031Sdes	(cp)[2] = (value) >> 16;					\
35285031Sdes	(cp)[1] = (value) >> 8;						\
36285031Sdes	(cp)[0] = (value); } while (0)
37285031Sdes
38285031Sdes#define PUT_32BIT_LE(cp, value) do {					\
39285031Sdes	(cp)[3] = (value) >> 24;					\
40285031Sdes	(cp)[2] = (value) >> 16;					\
41285031Sdes	(cp)[1] = (value) >> 8;						\
42285031Sdes	(cp)[0] = (value); } while (0)
43285031Sdes
44285031Sdesstatic u_int8_t PADDING[MD5_BLOCK_LENGTH] = {
45285031Sdes	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46285031Sdes	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47285031Sdes	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
48285031Sdes};
49285031Sdes
50285031Sdes/*
51285031Sdes * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
52285031Sdes * initialization constants.
53285031Sdes */
54285031Sdesvoid
55285031SdesMD5Init(MD5_CTX *ctx)
56285031Sdes{
57285031Sdes	ctx->count = 0;
58285031Sdes	ctx->state[0] = 0x67452301;
59285031Sdes	ctx->state[1] = 0xefcdab89;
60285031Sdes	ctx->state[2] = 0x98badcfe;
61285031Sdes	ctx->state[3] = 0x10325476;
62285031Sdes}
63285031Sdes
64285031Sdes/*
65285031Sdes * Update context to reflect the concatenation of another buffer full
66285031Sdes * of bytes.
67285031Sdes */
68285031Sdesvoid
69285031SdesMD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)
70285031Sdes{
71285031Sdes	size_t have, need;
72285031Sdes
73285031Sdes	/* Check how many bytes we already have and how many more we need. */
74285031Sdes	have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
75285031Sdes	need = MD5_BLOCK_LENGTH - have;
76285031Sdes
77285031Sdes	/* Update bitcount */
78285031Sdes	ctx->count += (u_int64_t)len << 3;
79285031Sdes
80285031Sdes	if (len >= need) {
81285031Sdes		if (have != 0) {
82285031Sdes			memcpy(ctx->buffer + have, input, need);
83285031Sdes			MD5Transform(ctx->state, ctx->buffer);
84285031Sdes			input += need;
85285031Sdes			len -= need;
86285031Sdes			have = 0;
87285031Sdes		}
88285031Sdes
89285031Sdes		/* Process data in MD5_BLOCK_LENGTH-byte chunks. */
90285031Sdes		while (len >= MD5_BLOCK_LENGTH) {
91285031Sdes			MD5Transform(ctx->state, input);
92285031Sdes			input += MD5_BLOCK_LENGTH;
93285031Sdes			len -= MD5_BLOCK_LENGTH;
94285031Sdes		}
95285031Sdes	}
96285031Sdes
97285031Sdes	/* Handle any remaining bytes of data. */
98285031Sdes	if (len != 0)
99285031Sdes		memcpy(ctx->buffer + have, input, len);
100285031Sdes}
101285031Sdes
102285031Sdes/*
103285031Sdes * Pad pad to 64-byte boundary with the bit pattern
104285031Sdes * 1 0* (64-bit count of bits processed, MSB-first)
105285031Sdes */
106285031Sdesvoid
107285031SdesMD5Pad(MD5_CTX *ctx)
108285031Sdes{
109285031Sdes	u_int8_t count[8];
110285031Sdes	size_t padlen;
111285031Sdes
112285031Sdes	/* Convert count to 8 bytes in little endian order. */
113285031Sdes	PUT_64BIT_LE(count, ctx->count);
114285031Sdes
115285031Sdes	/* Pad out to 56 mod 64. */
116285031Sdes	padlen = MD5_BLOCK_LENGTH -
117285031Sdes	    ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
118285031Sdes	if (padlen < 1 + 8)
119285031Sdes		padlen += MD5_BLOCK_LENGTH;
120285031Sdes	MD5Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
121285031Sdes	MD5Update(ctx, count, 8);
122285031Sdes}
123285031Sdes
124285031Sdes/*
125285031Sdes * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
126285031Sdes */
127285031Sdesvoid
128285031SdesMD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
129285031Sdes{
130285031Sdes	int i;
131285031Sdes
132285031Sdes	MD5Pad(ctx);
133285031Sdes	for (i = 0; i < 4; i++)
134285031Sdes		PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
135285031Sdes	memset(ctx, 0, sizeof(*ctx));
136285031Sdes}
137285031Sdes
138285031Sdes
139285031Sdes/* The four core functions - F1 is optimized somewhat */
140285031Sdes
141285031Sdes/* #define F1(x, y, z) (x & y | ~x & z) */
142285031Sdes#define F1(x, y, z) (z ^ (x & (y ^ z)))
143285031Sdes#define F2(x, y, z) F1(z, x, y)
144285031Sdes#define F3(x, y, z) (x ^ y ^ z)
145285031Sdes#define F4(x, y, z) (y ^ (x | ~z))
146285031Sdes
147285031Sdes/* This is the central step in the MD5 algorithm. */
148285031Sdes#define MD5STEP(f, w, x, y, z, data, s) \
149285031Sdes	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
150285031Sdes
151285031Sdes/*
152285031Sdes * The core of the MD5 algorithm, this alters an existing MD5 hash to
153285031Sdes * reflect the addition of 16 longwords of new data.  MD5Update blocks
154285031Sdes * the data and converts bytes into longwords for this routine.
155285031Sdes */
156285031Sdesvoid
157285031SdesMD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH])
158285031Sdes{
159285031Sdes	u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
160285031Sdes
161285031Sdes#if BYTE_ORDER == LITTLE_ENDIAN
162285031Sdes	memcpy(in, block, sizeof(in));
163285031Sdes#else
164285031Sdes	for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
165285031Sdes		in[a] = (u_int32_t)(
166285031Sdes		    (u_int32_t)(block[a * 4 + 0]) |
167285031Sdes		    (u_int32_t)(block[a * 4 + 1]) <<  8 |
168285031Sdes		    (u_int32_t)(block[a * 4 + 2]) << 16 |
169285031Sdes		    (u_int32_t)(block[a * 4 + 3]) << 24);
170285031Sdes	}
171285031Sdes#endif
172285031Sdes
173285031Sdes	a = state[0];
174285031Sdes	b = state[1];
175285031Sdes	c = state[2];
176285031Sdes	d = state[3];
177285031Sdes
178285031Sdes	MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
179285031Sdes	MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
180285031Sdes	MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
181285031Sdes	MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
182285031Sdes	MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
183285031Sdes	MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
184285031Sdes	MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
185285031Sdes	MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
186285031Sdes	MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
187285031Sdes	MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
188285031Sdes	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
189285031Sdes	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
190285031Sdes	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
191285031Sdes	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
192285031Sdes	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
193285031Sdes	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
194285031Sdes
195285031Sdes	MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
196285031Sdes	MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
197285031Sdes	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
198285031Sdes	MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
199285031Sdes	MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
200285031Sdes	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
201285031Sdes	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
202285031Sdes	MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
203285031Sdes	MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
204285031Sdes	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
205285031Sdes	MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
206285031Sdes	MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
207285031Sdes	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
208285031Sdes	MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
209285031Sdes	MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
210285031Sdes	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
211285031Sdes
212285031Sdes	MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
213285031Sdes	MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
214285031Sdes	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
215285031Sdes	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
216285031Sdes	MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
217285031Sdes	MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
218285031Sdes	MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
219285031Sdes	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
220285031Sdes	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
221285031Sdes	MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
222285031Sdes	MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
223285031Sdes	MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
224285031Sdes	MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
225285031Sdes	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
226285031Sdes	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
227285031Sdes	MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
228285031Sdes
229285031Sdes	MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
230285031Sdes	MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
231285031Sdes	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
232285031Sdes	MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
233285031Sdes	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
234285031Sdes	MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
235285031Sdes	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
236285031Sdes	MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
237285031Sdes	MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6);
238285031Sdes	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
239285031Sdes	MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
240285031Sdes	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
241285031Sdes	MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6);
242285031Sdes	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
243285031Sdes	MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
244285031Sdes	MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
245285031Sdes
246285031Sdes	state[0] += a;
247285031Sdes	state[1] += b;
248285031Sdes	state[2] += c;
249285031Sdes	state[3] += d;
250285031Sdes}
251285031Sdes#endif /* !WITH_OPENSSL */
252