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$");
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;
63157304Spjd	uint32_t ip;
646596Sphk
65157304Spjd	for (i = 0; i < len / 4; i++) {
66157304Spjd		ip = input[i];
67157304Spjd		*output++ = ip;
68157304Spjd		*output++ = ip >> 8;
69157304Spjd		*output++ = ip >> 16;
70157304Spjd		*output++ = ip >> 24;
71157304Spjd	}
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
8098756SmuxDecode (u_int32_t *output, const unsigned char *input, unsigned int len)
816596Sphk{
8298756Smux	unsigned int i;
836596Sphk
84157304Spjd	for (i = 0; i < len; i += 4) {
85157304Spjd		*output++ = input[i] | (input[i+1] << 8) | (input[i+2] << 16) |
86157304Spjd		    (input[i+3] << 24);
87157304Spjd	}
886596Sphk}
8998756Smux#endif
906596Sphk
911802Sphkstatic unsigned char PADDING[64] = {
921802Sphk  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
931802Sphk  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
941802Sphk  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
951802Sphk};
961802Sphk
9720785Sphk/* F, G, H and I are basic MD5 functions. */
981802Sphk#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
991802Sphk#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
1001802Sphk#define H(x, y, z) ((x) ^ (y) ^ (z))
1011802Sphk#define I(x, y, z) ((y) ^ ((x) | (~z)))
1021802Sphk
10320785Sphk/* ROTATE_LEFT rotates x left n bits. */
1041802Sphk#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
1051802Sphk
10620785Sphk/*
10720785Sphk * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
10820785Sphk * Rotation is separate from addition to prevent recomputation.
1091802Sphk */
1101802Sphk#define FF(a, b, c, d, x, s, ac) { \
11120785Sphk	(a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
11220785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
11320785Sphk	(a) += (b); \
11420785Sphk	}
1151802Sphk#define GG(a, b, c, d, x, s, ac) { \
11620785Sphk	(a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
11720785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
11820785Sphk	(a) += (b); \
11920785Sphk	}
1201802Sphk#define HH(a, b, c, d, x, s, ac) { \
12120785Sphk	(a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
12220785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
12320785Sphk	(a) += (b); \
12420785Sphk	}
1251802Sphk#define II(a, b, c, d, x, s, ac) { \
12620785Sphk	(a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
12720785Sphk	(a) = ROTATE_LEFT ((a), (s)); \
12820785Sphk	(a) += (b); \
12920785Sphk	}
1301802Sphk
13120785Sphk/* MD5 initialization. Begins an MD5 operation, writing a new context. */
13220785Sphk
13320785Sphkvoid
13420785SphkMD5Init (context)
13520785Sphk	MD5_CTX *context;
1361802Sphk{
13720785Sphk
13820785Sphk	context->count[0] = context->count[1] = 0;
13920785Sphk
14020785Sphk	/* Load magic initialization constants.  */
14120785Sphk	context->state[0] = 0x67452301;
14220785Sphk	context->state[1] = 0xefcdab89;
14320785Sphk	context->state[2] = 0x98badcfe;
14420785Sphk	context->state[3] = 0x10325476;
1451802Sphk}
1461802Sphk
14720785Sphk/*
14820785Sphk * MD5 block update operation. Continues an MD5 message-digest
14920785Sphk * operation, processing another message block, and updating the
15020785Sphk * context.
1511802Sphk */
15220785Sphk
15320785Sphkvoid
154154479SphkMD5Update (context, in, inputLen)
15520785Sphk	MD5_CTX *context;
156154479Sphk	const void *in;
15720785Sphk	unsigned int inputLen;
1581802Sphk{
15920785Sphk	unsigned int i, index, partLen;
160154479Sphk	const unsigned char *input = in;
1611802Sphk
16220785Sphk	/* Compute number of bytes mod 64 */
16320785Sphk	index = (unsigned int)((context->count[0] >> 3) & 0x3F);
1641802Sphk
16520785Sphk	/* Update number of bits */
16620785Sphk	if ((context->count[0] += ((u_int32_t)inputLen << 3))
16720785Sphk	    < ((u_int32_t)inputLen << 3))
16820785Sphk		context->count[1]++;
16920785Sphk	context->count[1] += ((u_int32_t)inputLen >> 29);
1701802Sphk
17120785Sphk	partLen = 64 - index;
1721802Sphk
17320785Sphk	/* Transform as many times as possible. */
17420785Sphk	if (inputLen >= partLen) {
17530631Sphk		memcpy((void *)&context->buffer[index], (const void *)input,
17620785Sphk		    partLen);
17720785Sphk		MD5Transform (context->state, context->buffer);
1781802Sphk
17920785Sphk		for (i = partLen; i + 63 < inputLen; i += 64)
18020785Sphk			MD5Transform (context->state, &input[i]);
1811802Sphk
18220785Sphk		index = 0;
18320785Sphk	}
18420785Sphk	else
18520785Sphk		i = 0;
1861802Sphk
18720785Sphk	/* Buffer remaining input */
18830631Sphk	memcpy ((void *)&context->buffer[index], (const void *)&input[i],
18920785Sphk	    inputLen-i);
1901802Sphk}
1911802Sphk
19220785Sphk/*
19334909Sphk * MD5 padding. Adds padding followed by original length.
1941802Sphk */
19520785Sphk
196141632Sphkstatic void
197141632SphkMD5Pad (MD5_CTX *context)
1981802Sphk{
19920785Sphk	unsigned char bits[8];
20020785Sphk	unsigned int index, padLen;
2011802Sphk
20220785Sphk	/* Save number of bits */
20320785Sphk	Encode (bits, context->count, 8);
2041802Sphk
20520785Sphk	/* Pad out to 56 mod 64. */
20620785Sphk	index = (unsigned int)((context->count[0] >> 3) & 0x3f);
20720785Sphk	padLen = (index < 56) ? (56 - index) : (120 - index);
20820785Sphk	MD5Update (context, PADDING, padLen);
2091802Sphk
21020785Sphk	/* Append length (before padding) */
21120785Sphk	MD5Update (context, bits, 8);
21234909Sphk}
2131802Sphk
21434909Sphk/*
21534909Sphk * MD5 finalization. Ends an MD5 message-digest operation, writing the
21634909Sphk * the message digest and zeroizing the context.
21734909Sphk */
21834909Sphk
21934909Sphkvoid
22034909SphkMD5Final (digest, context)
22134909Sphk	unsigned char digest[16];
22234909Sphk	MD5_CTX *context;
22334909Sphk{
22434909Sphk	/* Do padding. */
22534909Sphk	MD5Pad (context);
22634909Sphk
22720785Sphk	/* Store state in digest */
22820785Sphk	Encode (digest, context->state, 16);
22920785Sphk
23020785Sphk	/* Zeroize sensitive information. */
23120785Sphk	memset ((void *)context, 0, sizeof (*context));
2321802Sphk}
2331802Sphk
23420785Sphk/* MD5 basic transformation. Transforms state based on block. */
23520785Sphk
23698756Smuxstatic void
23720785SphkMD5Transform (state, block)
23820785Sphk	u_int32_t state[4];
23920785Sphk	const unsigned char block[64];
2401802Sphk{
24120785Sphk	u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
2421802Sphk
24320785Sphk	Decode (x, block, 64);
2441802Sphk
24520785Sphk	/* Round 1 */
24620785Sphk#define S11 7
24720785Sphk#define S12 12
24820785Sphk#define S13 17
24920785Sphk#define S14 22
25020785Sphk	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
25120785Sphk	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
25220785Sphk	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
25320785Sphk	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
25420785Sphk	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
25520785Sphk	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
25620785Sphk	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
25720785Sphk	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
25820785Sphk	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
25920785Sphk	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
26020785Sphk	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
26120785Sphk	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
26220785Sphk	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
26320785Sphk	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
26420785Sphk	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
26520785Sphk	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
2661802Sphk
26720785Sphk	/* Round 2 */
26820785Sphk#define S21 5
26920785Sphk#define S22 9
27020785Sphk#define S23 14
27120785Sphk#define S24 20
27220785Sphk	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
27320785Sphk	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
27420785Sphk	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
27520785Sphk	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
27620785Sphk	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
27720785Sphk	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
27820785Sphk	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
27920785Sphk	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
28020785Sphk	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
28120785Sphk	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
28220785Sphk	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
28320785Sphk	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
28420785Sphk	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
28520785Sphk	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
28620785Sphk	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
28720785Sphk	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
2881802Sphk
28920785Sphk	/* Round 3 */
29020785Sphk#define S31 4
29120785Sphk#define S32 11
29220785Sphk#define S33 16
29320785Sphk#define S34 23
29420785Sphk	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
29520785Sphk	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
29620785Sphk	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
29720785Sphk	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
29820785Sphk	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
29920785Sphk	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
30020785Sphk	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
30120785Sphk	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
30220785Sphk	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
30320785Sphk	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
30420785Sphk	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
30520785Sphk	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
30620785Sphk	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
30720785Sphk	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
30820785Sphk	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
30920785Sphk	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
3101802Sphk
31120785Sphk	/* Round 4 */
31220785Sphk#define S41 6
31320785Sphk#define S42 10
31420785Sphk#define S43 15
31520785Sphk#define S44 21
31620785Sphk	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
31720785Sphk	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
31820785Sphk	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
31920785Sphk	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
32020785Sphk	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
32120785Sphk	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
32220785Sphk	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
32320785Sphk	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
32420785Sphk	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
32520785Sphk	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
32620785Sphk	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
32720785Sphk	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
32820785Sphk	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
32920785Sphk	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
33020785Sphk	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
33120785Sphk	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
3321802Sphk
33320785Sphk	state[0] += a;
33420785Sphk	state[1] += b;
33520785Sphk	state[2] += c;
33620785Sphk	state[3] += d;
3371802Sphk
33820785Sphk	/* Zeroize sensitive information. */
33920785Sphk	memset ((void *)x, 0, sizeof (x));
3401802Sphk}
341