md5c.c revision 55206
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 *
2550477Speter * $FreeBSD: head/sys/kern/md5c.c 55206 1999-12-29 05:07:58Z peter $
2620785Sphk *
2720785Sphk * This code is the same as the code published by RSA Inc.  It has been
2820785Sphk * edited for clarity and style only.
291802Sphk */
301802Sphk
3120785Sphk#include <sys/types.h>
321802Sphk
3355206Speter#ifdef _KERNEL
3420785Sphk#include <sys/systm.h>
3520785Sphk#else
3619099Sphk#include <string.h>
3720785Sphk#endif
381802Sphk
3920785Sphk#include <sys/md5.h>
401802Sphk
411802Sphk
4255206Speter#ifdef _KERNEL
4320785Sphk#define memset(x,y,z)	bzero(x,z);
4420785Sphk#define memcpy(x,y,z)	bcopy(y, x, z)
4520785Sphk#endif
461802Sphk
4736735Sdfr#if defined(__i386__) || defined(__alpha__)
486596Sphk#define Encode memcpy
496596Sphk#define Decode memcpy
5035596Sbde#else /* __i386__ */
5120785Sphk
5220785Sphk/*
5320785Sphk * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
5420785Sphk * a multiple of 4.
556596Sphk */
5620785Sphk
5735210Sbde/* XXX not prototyped, and not compatible with memcpy(). */
5820785Sphkstatic void
5920785SphkEncode (output, input, len)
6020785Sphk	unsigned char *output;
6120785Sphk	u_int32_t *input;
6220785Sphk	unsigned int len;
636596Sphk{
6420785Sphk	unsigned int i, j;
656596Sphk
6620785Sphk	for (i = 0, j = 0; j < len; i++, j += 4) {
6720785Sphk		output[j] = (unsigned char)(input[i] & 0xff);
6820785Sphk		output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
6920785Sphk		output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
7020785Sphk		output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
7120785Sphk	}
726596Sphk}
736596Sphk
7420785Sphk/*
7520785Sphk * Decodes input (unsigned char) into output (u_int32_t). Assumes len is
7620785Sphk * a multiple of 4.
776596Sphk */
7820785Sphk
7920785Sphkstatic void
8020785SphkDecode (output, input, len)
8120785Sphk	u_int32_t *output;
8220785Sphk	const unsigned char *input;
8320785Sphk	unsigned int len;
846596Sphk{
8520785Sphk	unsigned int i, j;
866596Sphk
8720785Sphk	for (i = 0, j = 0; j < len; i++, j += 4)
8820785Sphk		output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) |
8920785Sphk		    (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24);
906596Sphk}
916596Sphk#endif /* i386 */
926596Sphk
931802Sphkstatic unsigned char PADDING[64] = {
941802Sphk  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
951802Sphk  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
961802Sphk  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
971802Sphk};
981802Sphk
9920785Sphk/* F, G, H and I are basic MD5 functions. */
1001802Sphk#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
1011802Sphk#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
1021802Sphk#define H(x, y, z) ((x) ^ (y) ^ (z))
1031802Sphk#define I(x, y, z) ((y) ^ ((x) | (~z)))
1041802Sphk
10520785Sphk/* ROTATE_LEFT rotates x left n bits. */
1061802Sphk#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
1071802Sphk
10820785Sphk/*
10920785Sphk * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
11020785Sphk * Rotation is separate from addition to prevent recomputation.
1111802Sphk */
1121802Sphk#define FF(a, b, c, d, x, s, ac) { \
11320785Sphk	(a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
11420785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
11520785Sphk	(a) += (b); \
11620785Sphk	}
1171802Sphk#define GG(a, b, c, d, x, s, ac) { \
11820785Sphk	(a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
11920785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
12020785Sphk	(a) += (b); \
12120785Sphk	}
1221802Sphk#define HH(a, b, c, d, x, s, ac) { \
12320785Sphk	(a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
12420785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
12520785Sphk	(a) += (b); \
12620785Sphk	}
1271802Sphk#define II(a, b, c, d, x, s, ac) { \
12820785Sphk	(a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
12920785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
13020785Sphk	(a) += (b); \
13120785Sphk	}
1321802Sphk
13320785Sphk/* MD5 initialization. Begins an MD5 operation, writing a new context. */
13420785Sphk
13520785Sphkvoid
13620785SphkMD5Init (context)
13720785Sphk	MD5_CTX *context;
1381802Sphk{
13920785Sphk
14020785Sphk	context->count[0] = context->count[1] = 0;
14120785Sphk
14220785Sphk	/* Load magic initialization constants.  */
14320785Sphk	context->state[0] = 0x67452301;
14420785Sphk	context->state[1] = 0xefcdab89;
14520785Sphk	context->state[2] = 0x98badcfe;
14620785Sphk	context->state[3] = 0x10325476;
1471802Sphk}
1481802Sphk
14920785Sphk/*
15020785Sphk * MD5 block update operation. Continues an MD5 message-digest
15120785Sphk * operation, processing another message block, and updating the
15220785Sphk * context.
1531802Sphk */
15420785Sphk
15520785Sphkvoid
15620785SphkMD5Update (context, input, inputLen)
15720785Sphk	MD5_CTX *context;
15820785Sphk	const unsigned char *input;
15920785Sphk	unsigned int inputLen;
1601802Sphk{
16120785Sphk	unsigned int i, index, partLen;
1621802Sphk
16320785Sphk	/* Compute number of bytes mod 64 */
16420785Sphk	index = (unsigned int)((context->count[0] >> 3) & 0x3F);
1651802Sphk
16620785Sphk	/* Update number of bits */
16720785Sphk	if ((context->count[0] += ((u_int32_t)inputLen << 3))
16820785Sphk	    < ((u_int32_t)inputLen << 3))
16920785Sphk		context->count[1]++;
17020785Sphk	context->count[1] += ((u_int32_t)inputLen >> 29);
1711802Sphk
17220785Sphk	partLen = 64 - index;
1731802Sphk
17420785Sphk	/* Transform as many times as possible. */
17520785Sphk	if (inputLen >= partLen) {
17630631Sphk		memcpy((void *)&context->buffer[index], (const void *)input,
17720785Sphk		    partLen);
17820785Sphk		MD5Transform (context->state, context->buffer);
1791802Sphk
18020785Sphk		for (i = partLen; i + 63 < inputLen; i += 64)
18120785Sphk			MD5Transform (context->state, &input[i]);
1821802Sphk
18320785Sphk		index = 0;
18420785Sphk	}
18520785Sphk	else
18620785Sphk		i = 0;
1871802Sphk
18820785Sphk	/* Buffer remaining input */
18930631Sphk	memcpy ((void *)&context->buffer[index], (const void *)&input[i],
19020785Sphk	    inputLen-i);
1911802Sphk}
1921802Sphk
19320785Sphk/*
19434909Sphk * MD5 padding. Adds padding followed by original length.
1951802Sphk */
19620785Sphk
19720785Sphkvoid
19834909SphkMD5Pad (context)
19920785Sphk	MD5_CTX *context;
2001802Sphk{
20120785Sphk	unsigned char bits[8];
20220785Sphk	unsigned int index, padLen;
2031802Sphk
20420785Sphk	/* Save number of bits */
20520785Sphk	Encode (bits, context->count, 8);
2061802Sphk
20720785Sphk	/* Pad out to 56 mod 64. */
20820785Sphk	index = (unsigned int)((context->count[0] >> 3) & 0x3f);
20920785Sphk	padLen = (index < 56) ? (56 - index) : (120 - index);
21020785Sphk	MD5Update (context, PADDING, padLen);
2111802Sphk
21220785Sphk	/* Append length (before padding) */
21320785Sphk	MD5Update (context, bits, 8);
21434909Sphk}
2151802Sphk
21634909Sphk/*
21734909Sphk * MD5 finalization. Ends an MD5 message-digest operation, writing the
21834909Sphk * the message digest and zeroizing the context.
21934909Sphk */
22034909Sphk
22134909Sphkvoid
22234909SphkMD5Final (digest, context)
22334909Sphk	unsigned char digest[16];
22434909Sphk	MD5_CTX *context;
22534909Sphk{
22634909Sphk	/* Do padding. */
22734909Sphk	MD5Pad (context);
22834909Sphk
22920785Sphk	/* Store state in digest */
23020785Sphk	Encode (digest, context->state, 16);
23120785Sphk
23220785Sphk	/* Zeroize sensitive information. */
23320785Sphk	memset ((void *)context, 0, sizeof (*context));
2341802Sphk}
2351802Sphk
23620785Sphk/* MD5 basic transformation. Transforms state based on block. */
23720785Sphk
23834944Sphkvoid
23920785SphkMD5Transform (state, block)
24020785Sphk	u_int32_t state[4];
24120785Sphk	const unsigned char block[64];
2421802Sphk{
24320785Sphk	u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
2441802Sphk
24520785Sphk	Decode (x, block, 64);
2461802Sphk
24720785Sphk	/* Round 1 */
24820785Sphk#define S11 7
24920785Sphk#define S12 12
25020785Sphk#define S13 17
25120785Sphk#define S14 22
25220785Sphk	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
25320785Sphk	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
25420785Sphk	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
25520785Sphk	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
25620785Sphk	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
25720785Sphk	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
25820785Sphk	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
25920785Sphk	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
26020785Sphk	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
26120785Sphk	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
26220785Sphk	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
26320785Sphk	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
26420785Sphk	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
26520785Sphk	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
26620785Sphk	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
26720785Sphk	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
2681802Sphk
26920785Sphk	/* Round 2 */
27020785Sphk#define S21 5
27120785Sphk#define S22 9
27220785Sphk#define S23 14
27320785Sphk#define S24 20
27420785Sphk	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
27520785Sphk	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
27620785Sphk	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
27720785Sphk	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
27820785Sphk	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
27920785Sphk	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
28020785Sphk	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
28120785Sphk	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
28220785Sphk	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
28320785Sphk	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
28420785Sphk	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
28520785Sphk	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
28620785Sphk	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
28720785Sphk	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
28820785Sphk	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
28920785Sphk	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
2901802Sphk
29120785Sphk	/* Round 3 */
29220785Sphk#define S31 4
29320785Sphk#define S32 11
29420785Sphk#define S33 16
29520785Sphk#define S34 23
29620785Sphk	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
29720785Sphk	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
29820785Sphk	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
29920785Sphk	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
30020785Sphk	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
30120785Sphk	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
30220785Sphk	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
30320785Sphk	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
30420785Sphk	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
30520785Sphk	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
30620785Sphk	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
30720785Sphk	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
30820785Sphk	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
30920785Sphk	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
31020785Sphk	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
31120785Sphk	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
3121802Sphk
31320785Sphk	/* Round 4 */
31420785Sphk#define S41 6
31520785Sphk#define S42 10
31620785Sphk#define S43 15
31720785Sphk#define S44 21
31820785Sphk	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
31920785Sphk	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
32020785Sphk	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
32120785Sphk	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
32220785Sphk	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
32320785Sphk	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
32420785Sphk	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
32520785Sphk	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
32620785Sphk	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
32720785Sphk	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
32820785Sphk	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
32920785Sphk	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
33020785Sphk	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
33120785Sphk	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
33220785Sphk	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
33320785Sphk	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
3341802Sphk
33520785Sphk	state[0] += a;
33620785Sphk	state[1] += b;
33720785Sphk	state[2] += c;
33820785Sphk	state[3] += d;
3391802Sphk
34020785Sphk	/* Zeroize sensitive information. */
34120785Sphk	memset ((void *)x, 0, sizeof (x));
3421802Sphk}
343