/*
 * <insert one-line description of what the program does>
 * Copyright (c) <2008-2009>, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *

File Name:          TPMCtrl.c

Description:

    This file implements class TPMCtrl.
	1.support provision packet save funcation
	2.support user date read form tpm funcation
	this file used by TDEngine file

Environment (opt):
    OS: Metasys
    SE: SUSE 10.2

Notes (opt):
****************************************************************************/

#include <time.h>
#include <string.h>
#include <stdlib.h>
#include "TPMCtrl/TPMInterface.h"
#include "TPMCtrl/TPMCtrl.h"

// When init get the user data already in tpm
// it include booy tick boot count hardware ID ExpiryDate.
int TPMCtrl_Construct(TPMCtrl *this)
{	
/*	unsigned char writeStr[400], readStr[400];
	int i;

	strcpy(writeStr, "12345678901234567890");
	TPM_SaveUserDataToTPM(writeStr);
	printf("write user data to TPM -> %s\n", writeStr);
	TPM_ReadUserDataFromTPM(readStr);
	printf("read user data from TPM -> ");
	for(i = 0; i < 24; i ++)
	{
		printf("%02X ", readStr[i]);
	}
	printf("\n");

	for(i = 0; i < TDAGENT_PACKET_LENGTH; i ++)
	{
		writeStr[i] = 0x55;
	}
	TPM_SaveProvisionPacketToTPM(writeStr, TDAGENT_PACKET_LENGTH);
	TPM_ReadProvisionPacketFromTPM(readStr);
	printf("read packet from TPM -> ");
	for(i = 0; i < TDAGENT_PACKET_LENGTH; i ++)
	{
		printf("%02X ", readStr[i]);
	}
	printf("\n");
	
	for(i = 0; i < TDAGENT_SHAREDSECRET_LENGTH; i ++)
	{
		writeStr[i] = 0x33;
	}
	TPM_SaveSharedSecretToTPM(writeStr);
	TPM_ReadSharedSecretFromTPM(readStr);
	printf("read shared secret from TPM -> ");
	for(i = 0; i < 128; i ++)
	{
		printf("%02X ", readStr[i]);
	}
	printf("\n");
	return SUCCESS;*/

	// Check if input parameter is availabe
	if(this == NULL)
	{
		return TPMCtrl_ExceptionStatus_ParamError;
	}

	if(TPMCtrl_GetUserData(this) == SUCCESS)
	{
		return SUCCESS;
	}
	else
	{
		WriteLog(TPMCtrl_ExceptionStatus_GetUserDataFailed);
		return TPMCtrl_ExceptionStatus_GetUserDataFailed;
	}
}

// Save the Provision Packet to TPM
// <param name="Packet">Packet byte stream</param>
// <returns>0 if seccess</returns>
int  TPMCtrl_SaveProvisionPacket(byte *Packet, int PacketSize)
{
	int ret = SUCCESS;

	// Check if input parameter is availabe
	if(Packet == NULL)
	{
		return TPMCtrl_ExceptionStatus_ParamError;
	}
		
	if(TPM_SaveProvisionPacketToTPM(Packet, PacketSize) == SUCCESS)
	{
		ret = SUCCESS;
	}
	else
	{
		WriteLog(TPMCtrl_ExceptionStatus_WriteTPMFailed);
		ret = TPMCtrl_ExceptionStatus_WriteTPMFailed;
	}
	return ret;
}

// Read the User Data from TPM
int TPMCtrl_GetUserData(TPMCtrl *this)
{
	byte* pUserData = this -> m_UserData;

	// Check if input parameter is availabe
	if(this == NULL)
	{
		return TPMCtrl_ExceptionStatus_ParamError;
	}

	if(TPM_ReadUserDataFromTPM(pUserData) == SUCCESS)
	{
		return SUCCESS;
	}
	else 
	{
		WriteLog(TPMCtrl_ExceptionStatus_ReadTPMFailed);
		return TPMCtrl_ExceptionStatus_ReadTPMFailed;
	}
}

// int boot tick property
int TPMCtrl_Bootick(TPMCtrl *this, int *pBootTick)
{
	byte Bootick[BOOTTICK_LENGTH];
	byte temp = 0;

	// Check if input parameter is availabe
	if(this == NULL || pBootTick == NULL)
	{
		return TPMCtrl_ExceptionStatus_ParamError;
	}

	// format boot tick 
	memcpy(Bootick, this -> m_UserData + BOOTTICK_OFFSET, BOOTTICK_LENGTH);
	temp = Bootick[0];
	Bootick[0] = Bootick[2];
	Bootick[2] = temp;
	*pBootTick = Bootick[2] * 65536 + Bootick[1] * 256 + Bootick[0];
	return SUCCESS;
}

// int boot count property
int TPMCtrl_BootCount(TPMCtrl *this, int *pBootCount)
{
	byte BootCount[BOOTCOUNT_LENGTH];
	byte temp = 0;

	// Check if input parameter is availabe
	if(this == NULL || pBootCount == NULL)
	{
		return TPMCtrl_ExceptionStatus_ParamError;
	}

	// format boot count 
	memcpy(BootCount, this -> m_UserData + BOOTCOUNT_OFFSET, BOOTCOUNT_LENGTH);
	temp = BootCount[0];
	BootCount[0] = BootCount[2];
	BootCount[2] = temp;
	*pBootCount = BootCount[2] * 65536 + BootCount[1] * 256 + BootCount[0];
	return SUCCESS;
}

// DateTime ExpiryDate property
int	TPMCtrl_ExpiryDate(TPMCtrl *this, DateTime * pDtExpiryDate)
{
	struct tm	*pTmNow = NULL;
	time_t		timeNow;
	byte		ExpiryDate[EXPIRYDATE_LENGTH];
	byte		btYear[DATE_BUFFER_LEN];
	byte		btMonth[DATE_BUFFER_LEN];
	byte		btDay[DATE_BUFFER_LEN];
	int			iYear = 0;
	int			iMonth = 0;
	int			iDay = 0;

	// Check if input parameter is availabe
	if(this == NULL || pDtExpiryDate == NULL)
	{
		return TPMCtrl_ExceptionStatus_ParamError;
	}

	time(&timeNow);
	pTmNow = localtime(&timeNow);
	pDtExpiryDate -> Year = pTmNow -> tm_year;
	pDtExpiryDate -> Month = pTmNow -> tm_mon;
	pDtExpiryDate -> Day = pTmNow -> tm_mday;
	// format Expiry Date
	memcpy(ExpiryDate, this -> m_UserData + EXPIRYDATE_OFFSET, EXPIRYDATE_LENGTH);
	memcpy(btYear, ExpiryDate, 2); 
	iYear = 2000 + atoi((char *)btYear); 				
	// Get month of expiration
	memcpy(btMonth, ExpiryDate + 2, 2); 
	iMonth = atoi((char *)btMonth); 
	// Get day of expiratione
	memcpy(btDay, ExpiryDate + 4, 2); 
	iDay = atoi((char *)btDay);
	// save expiration date
	pDtExpiryDate -> Year = iYear;
	pDtExpiryDate -> Month = iMonth;
	pDtExpiryDate -> Day = iDay;
	return SUCCESS;
}

// Get HWID property
int TPMCtrl_HWID(TPMCtrl *this, string strHWID)
{
	byte HWID[HWID_LENGTH + 1];

	// Check if input parameter is availabe
	if(this == NULL || strHWID == NULL)
	{
		return TPMCtrl_ExceptionStatus_ParamError;
	}

	memcpy(HWID, this -> m_UserData + HWID_OFFSET, HWID_LENGTH);
	HWID[HWID_LENGTH] = 0;
	strcpy(strHWID, (string)HWID);
	return SUCCESS;
}

