#include "os.h"
#include <libsec.h>

/*
 *  This MD4 is implemented from the description in Stinson's Cryptography,
 *  theory and practice. -- presotto
 */

/*
 *	Rotate ammounts used in the algorithm
 */
enum
{
	S11=	3,
	S12=	7,
	S13=	11,
	S14=	19,

	S21=	3,
	S22=	5,
	S23=	9,
	S24=	13,

	S31=	3,
	S32=	9,
	S33=	11,
	S34=	15,
};

typedef struct MD4Table MD4Table;
struct MD4Table
{
	uchar	x;	/* index into data block */
	uchar	rot;	/* amount to rotate left by */
};

static MD4Table tab[] =
{
	/* round 1 */
/*[0]*/	{ 0,	S11},	
	{ 1,	S12},	
	{ 2,	S13},	
	{ 3,	S14},	
	{ 4,	S11},	
	{ 5,	S12},	
	{ 6,	S13},	
	{ 7,	S14},	
	{ 8,	S11},	
	{ 9,	S12},	
	{ 10,	S13},	
	{ 11,	S14},	
	{ 12,	S11},	
	{ 13,	S12},	
	{ 14,	S13},	
	{ 15,	S14},

	/* round 2 */
/*[16]*/{ 0,	S21},	
	{ 4,	S22},	
	{ 8,	S23},	
	{ 12,	S24},	
	{ 1,	S21},	
	{ 5,	S22},	
	{ 9,	S23},	
	{ 13,	S24},	
	{ 2,	S21},	
	{ 6,	S22},	
	{ 10,	S23},	
	{ 14,	S24},	
	{ 3,	S21},	
	{ 7,	S22},	
	{ 11,	S23},	
	{ 15,	S24},

	/* round 3 */
/*[32]*/{ 0,	S31},	
	{ 8,	S32},	
	{ 4,	S33},	
	{ 12,	S34},	
	{ 2,	S31},	
	{ 10,	S32},	
	{ 6,	S33},	
	{ 14,	S34},	
	{ 1,	S31},	
	{ 9,	S32},	
	{ 5,	S33},	
	{ 13,	S34},	
	{ 3,	S31},	
	{ 11,	S32},	
	{ 7,	S33},	
	{ 15,	S34},	
};

static void encode(uchar*, u32int*, ulong);
static void decode(u32int*, uchar*, ulong);

static void
md4block(uchar *p, ulong len, MD4state *s)
{
	int i;
	u32int a, b, c, d, tmp;
	MD4Table *t;
	uchar *end;
	u32int x[16];

	for(end = p+len; p < end; p += 64){
		a = s->state[0];
		b = s->state[1];
		c = s->state[2];
		d = s->state[3];

		decode(x, p, 64);
	
		for(i = 0; i < 48; i++){
			t = tab + i;
			switch(i>>4){
			case 0:
				a += (b & c) | (~b & d);
				break;
			case 1:
				a += ((b & c) | (b & d) | (c & d)) + 0x5A827999;
				break;
			case 2:
				a += (b ^ c ^ d) + 0x6ED9EBA1;
				break;
			}
			a += x[t->x];
			a = (a << t->rot) | (a >> (32 - t->rot));
	
			/* rotate variables */
			tmp = d;
			d = c;
			c = b;
			b = a;
			a = tmp;
		}

		s->state[0] += a;
		s->state[1] += b;
		s->state[2] += c;
		s->state[3] += d;

		s->len += 64;
	}
}

MD4state*
md4(uchar *p, ulong len, uchar *digest, MD4state *s)
{
	u32int x[16];
	uchar buf[128];
	int i;
	uchar *e;

	if(s == nil){
		s = malloc(sizeof(*s));
		if(s == nil)
			return nil;
		memset(s, 0, sizeof(*s));
		s->malloced = 1;
	}

	if(s->seeded == 0){
		/* seed the state, these constants would look nicer big-endian */
		s->state[0] = 0x67452301;
		s->state[1] = 0xefcdab89;
		s->state[2] = 0x98badcfe;
		s->state[3] = 0x10325476;
		s->seeded = 1;
	}

	/* fill out the partial 64 byte block from previous calls */
	if(s->blen){
		i = 64 - s->blen;
		if(len < i)
			i = len;
		memmove(s->buf + s->blen, p, i);
		len -= i;
		s->blen += i;
		p += i;
		if(s->blen == 64){
			md4block(s->buf, s->blen, s);
			s->blen = 0;
		}
	}

	/* do 64 byte blocks */
	i = len & ~0x3f;
	if(i){
		md4block(p, i, s);
		len -= i;
		p += i;
	}

	/* save the left overs if not last call */
	if(digest == 0){
		if(len){
			memmove(s->buf, p, len);
			s->blen += len;
		}
		return s;
	}

	/*
	 *  this is the last time through, pad what's left with 0x80,
	 *  0's, and the input count to create a multiple of 64 bytes
	 */
	if(s->blen){
		p = s->buf;
		len = s->blen;
	} else {
		memmove(buf, p, len);
		p = buf;
	}
	s->len += len;
	e = p + len;
	if(len < 56)
		i = 56 - len;
	else
		i = 120 - len;
	memset(e, 0, i);
	*e = 0x80;
	len += i;

	/* append the count */
	x[0] = s->len<<3;
	x[1] = s->len>>29;
	encode(p+len, x, 8);

	/* digest the last part */
	md4block(p, len+8, s);

	/* return result and free state */
	encode(digest, s->state, MD4dlen);
	if(s->malloced == 1)
		free(s);
	return nil;
}

/*
 *	encodes input (u32int) into output (uchar). Assumes len is
 *	a multiple of 4.
 */
static void
encode(uchar *output, u32int *input, ulong len)
{
	u32int x;
	uchar *e;

	for(e = output + len; output < e;) {
		x = *input++;
		*output++ = x;
		*output++ = x >> 8;
		*output++ = x >> 16;
		*output++ = x >> 24;
	}
}

/*
 *	decodes input (uchar) into output (u32int). Assumes len is
 *	a multiple of 4.
 */
static void
decode(u32int *output, uchar *input, ulong len)
{
	uchar *e;

	for(e = input+len; input < e; input += 4)
		*output++ = input[0] | (input[1] << 8) |
			(input[2] << 16) | (input[3] << 24);
}
