md5c.c revision 141632
1139804Simp/*-
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
2998756Smux/*
3098756Smux * This file should be kept in sync with src/lib/libmd/md5c.c
3198756Smux */
3298756Smux#include <sys/cdefs.h>
3398756Smux__FBSDID("$FreeBSD: head/sys/kern/md5c.c 141632 2005-02-10 12:20:42Z phk $");
3498756Smux
3520785Sphk#include <sys/types.h>
361802Sphk
3755206Speter#ifdef _KERNEL
3820785Sphk#include <sys/systm.h>
3920785Sphk#else
4019099Sphk#include <string.h>
4120785Sphk#endif
421802Sphk
4398756Smux#include <machine/endian.h>
4498756Smux#include <sys/endian.h>
4520785Sphk#include <sys/md5.h>
461802Sphk
4798756Smuxstatic void MD5Transform(u_int32_t [4], const unsigned char [64]);
481802Sphk
4998756Smux#if (BYTE_ORDER == LITTLE_ENDIAN)
506596Sphk#define Encode memcpy
516596Sphk#define Decode memcpy
5298756Smux#else
5320785Sphk
5420785Sphk/*
5520785Sphk * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
5620785Sphk * a multiple of 4.
576596Sphk */
5820785Sphk
5920785Sphkstatic void
6098756SmuxEncode (unsigned char *output, u_int32_t *input, unsigned int len)
616596Sphk{
6298756Smux	unsigned int i;
6398756Smux	u_int32_t *op = (u_int32_t *)output;
646596Sphk
6598756Smux	for (i = 0; i < len / 4; i++)
6698756Smux		op[i] = htole32(input[i]);
676596Sphk}
686596Sphk
6920785Sphk/*
7020785Sphk * Decodes input (unsigned char) into output (u_int32_t). Assumes len is
7120785Sphk * a multiple of 4.
726596Sphk */
7320785Sphk
7420785Sphkstatic void
7598756SmuxDecode (u_int32_t *output, const unsigned char *input, unsigned int len)
766596Sphk{
7798756Smux	unsigned int i;
7898756Smux	const u_int32_t *ip = (const u_int32_t *)input;
796596Sphk
8098756Smux	for (i = 0; i < len / 4; i++)
81114706Sphk		output[i] = le32dec(&ip[i]);
826596Sphk}
8398756Smux#endif
846596Sphk
851802Sphkstatic unsigned char PADDING[64] = {
861802Sphk  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
871802Sphk  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
881802Sphk  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
891802Sphk};
901802Sphk
9120785Sphk/* F, G, H and I are basic MD5 functions. */
921802Sphk#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
931802Sphk#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
941802Sphk#define H(x, y, z) ((x) ^ (y) ^ (z))
951802Sphk#define I(x, y, z) ((y) ^ ((x) | (~z)))
961802Sphk
9720785Sphk/* ROTATE_LEFT rotates x left n bits. */
981802Sphk#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
991802Sphk
10020785Sphk/*
10120785Sphk * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
10220785Sphk * Rotation is separate from addition to prevent recomputation.
1031802Sphk */
1041802Sphk#define FF(a, b, c, d, x, s, ac) { \
10520785Sphk	(a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
10620785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
10720785Sphk	(a) += (b); \
10820785Sphk	}
1091802Sphk#define GG(a, b, c, d, x, s, ac) { \
11020785Sphk	(a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
11120785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
11220785Sphk	(a) += (b); \
11320785Sphk	}
1141802Sphk#define HH(a, b, c, d, x, s, ac) { \
11520785Sphk	(a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
11620785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
11720785Sphk	(a) += (b); \
11820785Sphk	}
1191802Sphk#define II(a, b, c, d, x, s, ac) { \
12020785Sphk	(a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
12120785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
12220785Sphk	(a) += (b); \
12320785Sphk	}
1241802Sphk
12520785Sphk/* MD5 initialization. Begins an MD5 operation, writing a new context. */
12620785Sphk
12720785Sphkvoid
12820785SphkMD5Init (context)
12920785Sphk	MD5_CTX *context;
1301802Sphk{
13120785Sphk
13220785Sphk	context->count[0] = context->count[1] = 0;
13320785Sphk
13420785Sphk	/* Load magic initialization constants.  */
13520785Sphk	context->state[0] = 0x67452301;
13620785Sphk	context->state[1] = 0xefcdab89;
13720785Sphk	context->state[2] = 0x98badcfe;
13820785Sphk	context->state[3] = 0x10325476;
1391802Sphk}
1401802Sphk
14120785Sphk/*
14220785Sphk * MD5 block update operation. Continues an MD5 message-digest
14320785Sphk * operation, processing another message block, and updating the
14420785Sphk * context.
1451802Sphk */
14620785Sphk
14720785Sphkvoid
14820785SphkMD5Update (context, input, inputLen)
14920785Sphk	MD5_CTX *context;
15020785Sphk	const unsigned char *input;
15120785Sphk	unsigned int inputLen;
1521802Sphk{
15320785Sphk	unsigned int i, index, partLen;
1541802Sphk
15520785Sphk	/* Compute number of bytes mod 64 */
15620785Sphk	index = (unsigned int)((context->count[0] >> 3) & 0x3F);
1571802Sphk
15820785Sphk	/* Update number of bits */
15920785Sphk	if ((context->count[0] += ((u_int32_t)inputLen << 3))
16020785Sphk	    < ((u_int32_t)inputLen << 3))
16120785Sphk		context->count[1]++;
16220785Sphk	context->count[1] += ((u_int32_t)inputLen >> 29);
1631802Sphk
16420785Sphk	partLen = 64 - index;
1651802Sphk
16620785Sphk	/* Transform as many times as possible. */
16720785Sphk	if (inputLen >= partLen) {
16830631Sphk		memcpy((void *)&context->buffer[index], (const void *)input,
16920785Sphk		    partLen);
17020785Sphk		MD5Transform (context->state, context->buffer);
1711802Sphk
17220785Sphk		for (i = partLen; i + 63 < inputLen; i += 64)
17320785Sphk			MD5Transform (context->state, &input[i]);
1741802Sphk
17520785Sphk		index = 0;
17620785Sphk	}
17720785Sphk	else
17820785Sphk		i = 0;
1791802Sphk
18020785Sphk	/* Buffer remaining input */
18130631Sphk	memcpy ((void *)&context->buffer[index], (const void *)&input[i],
18220785Sphk	    inputLen-i);
1831802Sphk}
1841802Sphk
18520785Sphk/*
18634909Sphk * MD5 padding. Adds padding followed by original length.
1871802Sphk */
18820785Sphk
189141632Sphkstatic void
190141632SphkMD5Pad (MD5_CTX *context)
1911802Sphk{
19220785Sphk	unsigned char bits[8];
19320785Sphk	unsigned int index, padLen;
1941802Sphk
19520785Sphk	/* Save number of bits */
19620785Sphk	Encode (bits, context->count, 8);
1971802Sphk
19820785Sphk	/* Pad out to 56 mod 64. */
19920785Sphk	index = (unsigned int)((context->count[0] >> 3) & 0x3f);
20020785Sphk	padLen = (index < 56) ? (56 - index) : (120 - index);
20120785Sphk	MD5Update (context, PADDING, padLen);
2021802Sphk
20320785Sphk	/* Append length (before padding) */
20420785Sphk	MD5Update (context, bits, 8);
20534909Sphk}
2061802Sphk
20734909Sphk/*
20834909Sphk * MD5 finalization. Ends an MD5 message-digest operation, writing the
20934909Sphk * the message digest and zeroizing the context.
21034909Sphk */
21134909Sphk
21234909Sphkvoid
21334909SphkMD5Final (digest, context)
21434909Sphk	unsigned char digest[16];
21534909Sphk	MD5_CTX *context;
21634909Sphk{
21734909Sphk	/* Do padding. */
21834909Sphk	MD5Pad (context);
21934909Sphk
22020785Sphk	/* Store state in digest */
22120785Sphk	Encode (digest, context->state, 16);
22220785Sphk
22320785Sphk	/* Zeroize sensitive information. */
22420785Sphk	memset ((void *)context, 0, sizeof (*context));
2251802Sphk}
2261802Sphk
22720785Sphk/* MD5 basic transformation. Transforms state based on block. */
22820785Sphk
22998756Smuxstatic void
23020785SphkMD5Transform (state, block)
23120785Sphk	u_int32_t state[4];
23220785Sphk	const unsigned char block[64];
2331802Sphk{
23420785Sphk	u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
2351802Sphk
23620785Sphk	Decode (x, block, 64);
2371802Sphk
23820785Sphk	/* Round 1 */
23920785Sphk#define S11 7
24020785Sphk#define S12 12
24120785Sphk#define S13 17
24220785Sphk#define S14 22
24320785Sphk	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
24420785Sphk	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
24520785Sphk	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
24620785Sphk	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
24720785Sphk	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
24820785Sphk	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
24920785Sphk	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
25020785Sphk	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
25120785Sphk	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
25220785Sphk	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
25320785Sphk	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
25420785Sphk	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
25520785Sphk	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
25620785Sphk	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
25720785Sphk	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
25820785Sphk	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
2591802Sphk
26020785Sphk	/* Round 2 */
26120785Sphk#define S21 5
26220785Sphk#define S22 9
26320785Sphk#define S23 14
26420785Sphk#define S24 20
26520785Sphk	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
26620785Sphk	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
26720785Sphk	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
26820785Sphk	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
26920785Sphk	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
27020785Sphk	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
27120785Sphk	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
27220785Sphk	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
27320785Sphk	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
27420785Sphk	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
27520785Sphk	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
27620785Sphk	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
27720785Sphk	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
27820785Sphk	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
27920785Sphk	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
28020785Sphk	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
2811802Sphk
28220785Sphk	/* Round 3 */
28320785Sphk#define S31 4
28420785Sphk#define S32 11
28520785Sphk#define S33 16
28620785Sphk#define S34 23
28720785Sphk	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
28820785Sphk	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
28920785Sphk	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
29020785Sphk	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
29120785Sphk	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
29220785Sphk	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
29320785Sphk	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
29420785Sphk	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
29520785Sphk	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
29620785Sphk	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
29720785Sphk	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
29820785Sphk	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
29920785Sphk	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
30020785Sphk	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
30120785Sphk	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
30220785Sphk	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
3031802Sphk
30420785Sphk	/* Round 4 */
30520785Sphk#define S41 6
30620785Sphk#define S42 10
30720785Sphk#define S43 15
30820785Sphk#define S44 21
30920785Sphk	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
31020785Sphk	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
31120785Sphk	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
31220785Sphk	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
31320785Sphk	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
31420785Sphk	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
31520785Sphk	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
31620785Sphk	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
31720785Sphk	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
31820785Sphk	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
31920785Sphk	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
32020785Sphk	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
32120785Sphk	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
32220785Sphk	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
32320785Sphk	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
32420785Sphk	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
3251802Sphk
32620785Sphk	state[0] += a;
32720785Sphk	state[1] += b;
32820785Sphk	state[2] += c;
32920785Sphk	state[3] += d;
3301802Sphk
33120785Sphk	/* Zeroize sensitive information. */
33220785Sphk	memset ((void *)x, 0, sizeof (x));
3331802Sphk}
334