120785Sphk/*
220785Sphk * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
320785Sphk *
420785Sphk * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
520785Sphk * rights reserved.
620785Sphk *
720785Sphk * License to copy and use this software is granted provided that it
820785Sphk * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
920785Sphk * Algorithm" in all material mentioning or referencing this software
1020785Sphk * or this function.
1120785Sphk *
1220785Sphk * License is also granted to make and use derivative works provided
1320785Sphk * that such works are identified as "derived from the RSA Data
1420785Sphk * Security, Inc. MD5 Message-Digest Algorithm" in all material
1520785Sphk * mentioning or referencing the derived work.
1620785Sphk *
1720785Sphk * RSA Data Security, Inc. makes no representations concerning either
1820785Sphk * the merchantability of this software or the suitability of this
1920785Sphk * software for any particular purpose. It is provided "as is"
2020785Sphk * without express or implied warranty of any kind.
2120785Sphk *
2220785Sphk * These notices must be retained in any copies of any part of this
2320785Sphk * documentation and/or software.
2420785Sphk *
2520785Sphk * This code is the same as the code published by RSA Inc.  It has been
2620785Sphk * edited for clarity and style only.
271802Sphk */
281802Sphk
2984211Sdillon#include <sys/cdefs.h>
3084211Sdillon__FBSDID("$FreeBSD$");
3184211Sdillon
3220785Sphk#include <sys/types.h>
331802Sphk
3455206Speter#ifdef _KERNEL
3520785Sphk#include <sys/systm.h>
3620785Sphk#else
3719099Sphk#include <string.h>
3820785Sphk#endif
391802Sphk
4098615Sphk#include <machine/endian.h>
4198615Sphk#include <sys/endian.h>
4220785Sphk#include <sys/md5.h>
431802Sphk
4492917Sobrienstatic void MD5Transform(u_int32_t [4], const unsigned char [64]);
451802Sphk
4655206Speter#ifdef _KERNEL
4720785Sphk#define memset(x,y,z)	bzero(x,z);
4820785Sphk#define memcpy(x,y,z)	bcopy(y, x, z)
4920785Sphk#endif
501802Sphk
5198615Sphk#if (BYTE_ORDER == LITTLE_ENDIAN)
526596Sphk#define Encode memcpy
536596Sphk#define Decode memcpy
5498615Sphk#else
5520785Sphk
5620785Sphk/*
5720785Sphk * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
5820785Sphk * a multiple of 4.
596596Sphk */
6020785Sphk
6120785Sphkstatic void
6298615SphkEncode (unsigned char *output, u_int32_t *input, unsigned int len)
636596Sphk{
6498615Sphk	unsigned int i;
6598615Sphk	u_int32_t *op = (u_int32_t *)output;
666596Sphk
6798615Sphk	for (i = 0; i < len / 4; i++)
6898615Sphk		op[i] = htole32(input[i]);
696596Sphk}
706596Sphk
7120785Sphk/*
7220785Sphk * Decodes input (unsigned char) into output (u_int32_t). Assumes len is
7320785Sphk * a multiple of 4.
746596Sphk */
7520785Sphk
7620785Sphkstatic void
7798615SphkDecode (u_int32_t *output, const unsigned char *input, unsigned int len)
786596Sphk{
7998615Sphk	unsigned int i;
8098753Smux	const u_int32_t *ip = (const u_int32_t *)input;
816596Sphk
8298615Sphk	for (i = 0; i < len / 4; i++)
8398615Sphk		output[i] = le32toh(ip[i]);
846596Sphk}
8598615Sphk#endif
866596Sphk
871802Sphkstatic unsigned char PADDING[64] = {
881802Sphk  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
891802Sphk  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
901802Sphk  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
911802Sphk};
921802Sphk
9320785Sphk/* F, G, H and I are basic MD5 functions. */
941802Sphk#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
951802Sphk#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
961802Sphk#define H(x, y, z) ((x) ^ (y) ^ (z))
971802Sphk#define I(x, y, z) ((y) ^ ((x) | (~z)))
981802Sphk
9920785Sphk/* ROTATE_LEFT rotates x left n bits. */
1001802Sphk#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
1011802Sphk
10220785Sphk/*
10320785Sphk * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
10420785Sphk * Rotation is separate from addition to prevent recomputation.
1051802Sphk */
1061802Sphk#define FF(a, b, c, d, x, s, ac) { \
10720785Sphk	(a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
10820785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
10920785Sphk	(a) += (b); \
11020785Sphk	}
1111802Sphk#define GG(a, b, c, d, x, s, ac) { \
11220785Sphk	(a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
11320785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
11420785Sphk	(a) += (b); \
11520785Sphk	}
1161802Sphk#define HH(a, b, c, d, x, s, ac) { \
11720785Sphk	(a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
11820785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
11920785Sphk	(a) += (b); \
12020785Sphk	}
1211802Sphk#define II(a, b, c, d, x, s, ac) { \
12220785Sphk	(a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
12320785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
12420785Sphk	(a) += (b); \
12520785Sphk	}
1261802Sphk
12720785Sphk/* MD5 initialization. Begins an MD5 operation, writing a new context. */
12820785Sphk
12920785Sphkvoid
13020785SphkMD5Init (context)
13120785Sphk	MD5_CTX *context;
1321802Sphk{
13320785Sphk
13420785Sphk	context->count[0] = context->count[1] = 0;
13520785Sphk
13620785Sphk	/* Load magic initialization constants.  */
13720785Sphk	context->state[0] = 0x67452301;
13820785Sphk	context->state[1] = 0xefcdab89;
13920785Sphk	context->state[2] = 0x98badcfe;
14020785Sphk	context->state[3] = 0x10325476;
1411802Sphk}
1421802Sphk
14320785Sphk/*
14420785Sphk * MD5 block update operation. Continues an MD5 message-digest
14520785Sphk * operation, processing another message block, and updating the
14620785Sphk * context.
1471802Sphk */
14820785Sphk
14920785Sphkvoid
150154479SphkMD5Update (context, in, inputLen)
15120785Sphk	MD5_CTX *context;
152154479Sphk	const void *in;
15320785Sphk	unsigned int inputLen;
1541802Sphk{
155115872Smarkm	unsigned int i, idx, partLen;
156154479Sphk	const unsigned char *input = in;
1571802Sphk
15820785Sphk	/* Compute number of bytes mod 64 */
159115872Smarkm	idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
1601802Sphk
16120785Sphk	/* Update number of bits */
16220785Sphk	if ((context->count[0] += ((u_int32_t)inputLen << 3))
16320785Sphk	    < ((u_int32_t)inputLen << 3))
16420785Sphk		context->count[1]++;
16520785Sphk	context->count[1] += ((u_int32_t)inputLen >> 29);
1661802Sphk
167115872Smarkm	partLen = 64 - idx;
1681802Sphk
16920785Sphk	/* Transform as many times as possible. */
17020785Sphk	if (inputLen >= partLen) {
171115872Smarkm		memcpy((void *)&context->buffer[idx], (const void *)input,
17220785Sphk		    partLen);
17320785Sphk		MD5Transform (context->state, context->buffer);
1741802Sphk
17520785Sphk		for (i = partLen; i + 63 < inputLen; i += 64)
17620785Sphk			MD5Transform (context->state, &input[i]);
1771802Sphk
178115872Smarkm		idx = 0;
17920785Sphk	}
18020785Sphk	else
18120785Sphk		i = 0;
1821802Sphk
18320785Sphk	/* Buffer remaining input */
184115872Smarkm	memcpy ((void *)&context->buffer[idx], (const void *)&input[i],
18520785Sphk	    inputLen-i);
1861802Sphk}
1871802Sphk
18820785Sphk/*
18934909Sphk * MD5 padding. Adds padding followed by original length.
1901802Sphk */
19120785Sphk
19220785Sphkvoid
19334909SphkMD5Pad (context)
19420785Sphk	MD5_CTX *context;
1951802Sphk{
19620785Sphk	unsigned char bits[8];
197115872Smarkm	unsigned int idx, padLen;
1981802Sphk
19920785Sphk	/* Save number of bits */
20020785Sphk	Encode (bits, context->count, 8);
2011802Sphk
20220785Sphk	/* Pad out to 56 mod 64. */
203115872Smarkm	idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
204115872Smarkm	padLen = (idx < 56) ? (56 - idx) : (120 - idx);
20520785Sphk	MD5Update (context, PADDING, padLen);
2061802Sphk
20720785Sphk	/* Append length (before padding) */
20820785Sphk	MD5Update (context, bits, 8);
20934909Sphk}
2101802Sphk
21134909Sphk/*
21234909Sphk * MD5 finalization. Ends an MD5 message-digest operation, writing the
21334909Sphk * the message digest and zeroizing the context.
21434909Sphk */
21534909Sphk
21634909Sphkvoid
21734909SphkMD5Final (digest, context)
21834909Sphk	unsigned char digest[16];
21934909Sphk	MD5_CTX *context;
22034909Sphk{
22134909Sphk	/* Do padding. */
22234909Sphk	MD5Pad (context);
22334909Sphk
22420785Sphk	/* Store state in digest */
22520785Sphk	Encode (digest, context->state, 16);
22620785Sphk
22720785Sphk	/* Zeroize sensitive information. */
22820785Sphk	memset ((void *)context, 0, sizeof (*context));
2291802Sphk}
2301802Sphk
23120785Sphk/* MD5 basic transformation. Transforms state based on block. */
23220785Sphk
23320785Sphkstatic void
23420785SphkMD5Transform (state, block)
23520785Sphk	u_int32_t state[4];
23620785Sphk	const unsigned char block[64];
2371802Sphk{
23820785Sphk	u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
2391802Sphk
24020785Sphk	Decode (x, block, 64);
2411802Sphk
24220785Sphk	/* Round 1 */
24320785Sphk#define S11 7
24420785Sphk#define S12 12
24520785Sphk#define S13 17
24620785Sphk#define S14 22
24720785Sphk	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
24820785Sphk	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
24920785Sphk	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
25020785Sphk	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
25120785Sphk	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
25220785Sphk	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
25320785Sphk	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
25420785Sphk	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
25520785Sphk	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
25620785Sphk	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
25720785Sphk	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
25820785Sphk	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
25920785Sphk	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
26020785Sphk	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
26120785Sphk	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
26220785Sphk	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
2631802Sphk
26420785Sphk	/* Round 2 */
26520785Sphk#define S21 5
26620785Sphk#define S22 9
26720785Sphk#define S23 14
26820785Sphk#define S24 20
26920785Sphk	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
27020785Sphk	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
27120785Sphk	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
27220785Sphk	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
27320785Sphk	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
27420785Sphk	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
27520785Sphk	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
27620785Sphk	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
27720785Sphk	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
27820785Sphk	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
27920785Sphk	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
28020785Sphk	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
28120785Sphk	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
28220785Sphk	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
28320785Sphk	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
28420785Sphk	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
2851802Sphk
28620785Sphk	/* Round 3 */
28720785Sphk#define S31 4
28820785Sphk#define S32 11
28920785Sphk#define S33 16
29020785Sphk#define S34 23
29120785Sphk	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
29220785Sphk	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
29320785Sphk	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
29420785Sphk	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
29520785Sphk	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
29620785Sphk	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
29720785Sphk	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
29820785Sphk	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
29920785Sphk	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
30020785Sphk	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
30120785Sphk	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
30220785Sphk	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
30320785Sphk	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
30420785Sphk	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
30520785Sphk	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
30620785Sphk	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
3071802Sphk
30820785Sphk	/* Round 4 */
30920785Sphk#define S41 6
31020785Sphk#define S42 10
31120785Sphk#define S43 15
31220785Sphk#define S44 21
31320785Sphk	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
31420785Sphk	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
31520785Sphk	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
31620785Sphk	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
31720785Sphk	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
31820785Sphk	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
31920785Sphk	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
32020785Sphk	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
32120785Sphk	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
32220785Sphk	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
32320785Sphk	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
32420785Sphk	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
32520785Sphk	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
32620785Sphk	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
32720785Sphk	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
32820785Sphk	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
3291802Sphk
33020785Sphk	state[0] += a;
33120785Sphk	state[1] += b;
33220785Sphk	state[2] += c;
33320785Sphk	state[3] += d;
3341802Sphk
33520785Sphk	/* Zeroize sensitive information. */
33620785Sphk	memset ((void *)x, 0, sizeof (x));
3371802Sphk}
338