/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *
 * File: michael.cpp
 *
 * Purpose: The implementation of LIST data structure.
 *
 * Author: Kyle Hsu
 *
 * Date: Sep 4, 2002
 *
 * Functions:
 *      s_dwGetUINT32 - Convert from BYTE[] to DWORD in a portable way
 *      s_vPutUINT32 - Convert from DWORD to BYTE[] in a portable way
 *      s_vClear - Reset the state to the empty message.
 *      s_vSetKey - Set the key.
 *      MIC_vInit - Set the key.
 *      s_vAppendByte - Append the byte to our word-sized buffer.
 *      MIC_vAppend - call s_vAppendByte.
 *      MIC_vGetMIC - Append the minimum padding and call s_vAppendByte.
 *
 * Revision History:
 *
 */

#include "tmacro.h"
#include "michael.h"

/*---------------------  Static Definitions -------------------------*/

/*---------------------  Static Variables  --------------------------*/

/*---------------------  Static Functions  --------------------------*/
/*
 * static DWORD s_dwGetUINT32(BYTE * p);         Get DWORD from
 *							4 bytes LSByte first
 * static void s_vPutUINT32(BYTE* p, DWORD val); Put DWORD into
 *							4 bytes LSByte first
 */
static void s_vClear(void);		/* Clear the internal message,
					 * resets the object to the
					 * state just after construction. */
static void s_vSetKey(DWORD dwK0, DWORD dwK1);
static void s_vAppendByte(BYTE b);	/* Add a single byte to the internal
					 * message */

/*---------------------  Export Variables  --------------------------*/
static DWORD  L, R;		/* Current state */
static DWORD  K0, K1;		/* Key */
static DWORD  M;		/* Message accumulator (single word) */
static unsigned int   nBytesInM;	/* # bytes in M */

/*---------------------  Export Functions  --------------------------*/

/*
static DWORD s_dwGetUINT32 (BYTE * p)
// Convert from BYTE[] to DWORD in a portable way
{
	DWORD res = 0;
	unsigned int i;
	for(i=0; i<4; i++ )
		res |= (*p++) << (8*i);
	return res;
}

static void s_vPutUINT32(BYTE *p, DWORD val)
// Convert from DWORD to BYTE[] in a portable way
{
	unsigned int i;
	for(i=0; i<4; i++ ) {
		*p++ = (BYTE) (val & 0xff);
		val >>= 8;
	}
}
*/

static void s_vClear(void)
{
	/* Reset the state to the empty message. */
	L = K0;
	R = K1;
	nBytesInM = 0;
	M = 0;
}

static void s_vSetKey(DWORD dwK0, DWORD dwK1)
{
	/* Set the key */
	K0 = dwK0;
	K1 = dwK1;
	/* and reset the message */
	s_vClear();
}

static void s_vAppendByte(BYTE b)
{
	/* Append the byte to our word-sized buffer */
	M |= b << (8*nBytesInM);
	nBytesInM++;
	/* Process the word if it is full. */
	if (nBytesInM >= 4) {
		L ^= M;
		R ^= ROL32(L, 17);
		L += R;
		R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
		L += R;
		R ^= ROL32(L, 3);
		L += R;
		R ^= ROR32(L, 2);
		L += R;
		/* Clear the buffer */
		M = 0;
		nBytesInM = 0;
	}
}

void MIC_vInit(DWORD dwK0, DWORD dwK1)
{
	/* Set the key */
	s_vSetKey(dwK0, dwK1);
}


void MIC_vUnInit(void)
{
	/* Wipe the key material */
	K0 = 0;
	K1 = 0;

	/* And the other fields as well. */
	/* Note that this sets (L,R) to (K0,K1) which is just fine. */
	s_vClear();
}

void MIC_vAppend(PBYTE src, unsigned int nBytes)
{
    /* This is simple */
	while (nBytes > 0) {
		s_vAppendByte(*src++);
		nBytes--;
	}
}

void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR)
{
	/* Append the minimum padding */
	s_vAppendByte(0x5a);
	s_vAppendByte(0);
	s_vAppendByte(0);
	s_vAppendByte(0);
	s_vAppendByte(0);
	/* and then zeroes until the length is a multiple of 4 */
	while (nBytesInM != 0)
		s_vAppendByte(0);
	/* The s_vAppendByte function has already computed the result. */
	*pdwL = L;
	*pdwR = R;
	/* Reset to the empty message. */
	s_vClear();
}
