|
|
// VCOM-TPM.cpp : Defines the entry point for the console application.
|
|
|
//
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
HANDLE hVCom = INVALID_HANDLE_VALUE;
|
|
|
LPCTSTR vcomPort = TEXT("COM6");
|
|
|
unsigned int vcomTimeout = 5 * 60 * 1000;
|
|
|
|
|
|
#ifndef TPM_RC_SUCCESS
|
|
|
#define TPM_RC_SUCCESS 0
|
|
|
#endif
|
|
|
|
|
|
unsigned int GetTimeStamp(void)
|
|
|
{
|
|
|
FILETIME now = { 0 };
|
|
|
LARGE_INTEGER convert = { 0 };
|
|
|
|
|
|
// Get the current timestamp
|
|
|
GetSystemTimeAsFileTime(&now);
|
|
|
convert.LowPart = now.dwLowDateTime;
|
|
|
convert.HighPart = now.dwHighDateTime;
|
|
|
convert.QuadPart = (convert.QuadPart - (UINT64)(11644473600000 * 10000)) / 10000000;
|
|
|
return convert.LowPart;
|
|
|
}
|
|
|
|
|
|
unsigned int SetTpmResponseTimeout(unsigned int timeout)
|
|
|
{
|
|
|
COMMTIMEOUTS to = { 0 };
|
|
|
to.ReadIntervalTimeout = 0;
|
|
|
to.ReadTotalTimeoutMultiplier = 0;
|
|
|
to.ReadTotalTimeoutConstant = timeout;
|
|
|
to.WriteTotalTimeoutMultiplier = 0;
|
|
|
to.WriteTotalTimeoutConstant = 0;
|
|
|
if (!SetCommTimeouts(hVCom, &to))
|
|
|
{
|
|
|
return GetLastError();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
unsigned int SendTpmSignal(signalCode_t signal,
|
|
|
unsigned int timeout,
|
|
|
BYTE* dataIn,
|
|
|
unsigned int dataInSize,
|
|
|
BYTE* dataOut,
|
|
|
unsigned int dataOutSize,
|
|
|
unsigned int* dataOutUsed
|
|
|
)
|
|
|
{
|
|
|
unsigned int result = 0;
|
|
|
DWORD written = 0;
|
|
|
unsigned int signalBufSize = sizeof(signalWrapper_t) + dataInSize;
|
|
|
BYTE* signalBuf = (BYTE*)malloc(signalBufSize);
|
|
|
pSignalWrapper_t sig = (pSignalWrapper_t)signalBuf;
|
|
|
sig->s.magic = SIGNALMAGIC;
|
|
|
sig->s.signal = signal;
|
|
|
sig->s.dataSize = dataInSize;
|
|
|
if (dataInSize > 0)
|
|
|
{
|
|
|
memcpy(&signalBuf[sizeof(signalWrapper_t)], dataIn, dataInSize);
|
|
|
}
|
|
|
|
|
|
PurgeComm(hVCom, PURGE_RXCLEAR | PURGE_TXCLEAR);
|
|
|
if (!WriteFile(hVCom, signalBuf, signalBufSize, &written, NULL))
|
|
|
{
|
|
|
result = GetLastError();
|
|
|
goto Cleanup;
|
|
|
}
|
|
|
|
|
|
if (signal == SignalCommand)
|
|
|
{
|
|
|
DWORD read = 0;
|
|
|
unsigned int rspSize = 0;
|
|
|
|
|
|
SetTpmResponseTimeout(timeout - 1000);
|
|
|
if (!ReadFile(hVCom, &rspSize, sizeof(rspSize), (LPDWORD)&read, NULL))
|
|
|
{
|
|
|
result = GetLastError();
|
|
|
goto Cleanup;
|
|
|
}
|
|
|
if (read == 0)
|
|
|
{
|
|
|
result = GetLastError();
|
|
|
goto Cleanup;
|
|
|
}
|
|
|
|
|
|
read = 0;
|
|
|
SetTpmResponseTimeout(1000);
|
|
|
if ((!ReadFile(hVCom, dataOut, min(rspSize, dataOutSize), (LPDWORD)&read, NULL)) ||
|
|
|
(read != rspSize))
|
|
|
{
|
|
|
result = GetLastError();
|
|
|
goto Cleanup;
|
|
|
}
|
|
|
*dataOutUsed = read;
|
|
|
PurgeComm(hVCom, PURGE_RXCLEAR);
|
|
|
}
|
|
|
|
|
|
Cleanup:
|
|
|
if (signalBuf) free(signalBuf);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
BYTE* GenerateTpmCommandPayload(unsigned int locality,
|
|
|
BYTE* cmd,
|
|
|
UINT32 cmdSize,
|
|
|
unsigned int* dataInSize
|
|
|
)
|
|
|
{
|
|
|
pSignalPayload_t payload = NULL;
|
|
|
*dataInSize = sizeof(payload->SignalCommandPayload) - sizeof(unsigned char) + cmdSize;
|
|
|
BYTE* dataIn = (BYTE*)malloc(*dataInSize);
|
|
|
payload = (pSignalPayload_t)dataIn;
|
|
|
payload->SignalCommandPayload.locality = locality;
|
|
|
payload->SignalCommandPayload.cmdSize = cmdSize;
|
|
|
memcpy(payload->SignalCommandPayload.cmd, cmd, cmdSize);
|
|
|
return dataIn;
|
|
|
}
|
|
|
|
|
|
unsigned int OpenTpmConnection(LPCTSTR comPort)
|
|
|
{
|
|
|
DCB dcb = { 0 };
|
|
|
if (hVCom != INVALID_HANDLE_VALUE)
|
|
|
{
|
|
|
CloseHandle(hVCom);
|
|
|
hVCom = INVALID_HANDLE_VALUE;
|
|
|
}
|
|
|
dcb.DCBlength = sizeof(DCB);
|
|
|
dcb.BaudRate = CBR_115200;
|
|
|
dcb.fBinary = TRUE;
|
|
|
dcb.fParity = FALSE;
|
|
|
dcb.ByteSize = 8;
|
|
|
dcb.Parity = NOPARITY;
|
|
|
dcb.StopBits = ONESTOPBIT;
|
|
|
if (((hVCom = CreateFile(comPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) ||
|
|
|
(!SetCommState(hVCom, &dcb)))
|
|
|
{
|
|
|
return GetLastError();
|
|
|
}
|
|
|
PurgeComm(hVCom, PURGE_RXCLEAR);
|
|
|
unsigned int time = GetTimeStamp();
|
|
|
SendTpmSignal(SignalSetClock, 500, (BYTE*)&time, sizeof(time), NULL, 0, NULL);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
UINT32 TPMVComSubmitCommand(
|
|
|
BOOL CloseContext,
|
|
|
BYTE* pbCommand,
|
|
|
UINT32 cbCommand,
|
|
|
BYTE* pbResponse,
|
|
|
UINT32 cbResponse,
|
|
|
UINT32* pcbResponse
|
|
|
)
|
|
|
{
|
|
|
UINT32 result = TPM_RC_SUCCESS;
|
|
|
BYTE* dataIn = NULL;
|
|
|
unsigned int dataInSize = 0;
|
|
|
if (hVCom == INVALID_HANDLE_VALUE)
|
|
|
{
|
|
|
OpenTpmConnection(vcomPort);
|
|
|
}
|
|
|
|
|
|
dataIn = GenerateTpmCommandPayload(0, pbCommand, cbCommand, &dataInSize);
|
|
|
result = SendTpmSignal(SignalCommand, vcomTimeout, dataIn, dataInSize, pbResponse, cbResponse, pcbResponse);
|
|
|
|
|
|
if (CloseContext)
|
|
|
{
|
|
|
CloseHandle(hVCom);
|
|
|
hVCom = INVALID_HANDLE_VALUE;
|
|
|
}
|
|
|
|
|
|
if (dataIn) free(dataIn);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
void TPMVComTeardown(void)
|
|
|
{
|
|
|
if (hVCom != INVALID_HANDLE_VALUE)
|
|
|
{
|
|
|
CloseHandle(hVCom);
|
|
|
hVCom = INVALID_HANDLE_VALUE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
BOOL TPMStartup()
|
|
|
{
|
|
|
unsigned char startupClear[] = { 0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00 };
|
|
|
unsigned char response[10];
|
|
|
unsigned int responseSize;
|
|
|
|
|
|
return ((TPMVComSubmitCommand(FALSE, startupClear, sizeof(startupClear), response, sizeof(response), &responseSize) == TPM_RC_SUCCESS) &&
|
|
|
(responseSize == sizeof(response)) &&
|
|
|
(*((unsigned int*)&response[sizeof(unsigned short) + sizeof(unsigned int)]) == 0));
|
|
|
}
|
|
|
|
|
|
UINT32 TPMShutdown()
|
|
|
{
|
|
|
unsigned char shutdownClear[] = { 0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00 };
|
|
|
unsigned char response[10];
|
|
|
unsigned int responseSize;
|
|
|
|
|
|
return ((TPMVComSubmitCommand(TRUE, shutdownClear, sizeof(shutdownClear), response, sizeof(response), &responseSize) == TPM_RC_SUCCESS) &&
|
|
|
(responseSize == sizeof(response)) &&
|
|
|
(*((unsigned int*)&response[sizeof(unsigned short) + sizeof(unsigned int)]) == 0));
|
|
|
}
|
|
|
|
|
|
int main()
|
|
|
{
|
|
|
if (!TPMStartup()) goto Cleanup;
|
|
|
|
|
|
if (SendTpmSignal(SignalCancelOn, 1000, NULL, 0, NULL, 0, NULL)) goto Cleanup;
|
|
|
if (SendTpmSignal(SignalCancelOff, 1000, NULL, 0, NULL, 0, NULL)) goto Cleanup;
|
|
|
|
|
|
// if (SendTpmSignal(SignalShutdown, 1000, NULL, 0, NULL, 0, NULL)) goto Cleanup;
|
|
|
// if (SendTpmSignal(SignalReset, 1000, NULL, 0, NULL, 0, NULL)) goto Cleanup;
|
|
|
|
|
|
Cleanup:
|
|
|
TPMShutdown();
|
|
|
return 0;
|
|
|
}
|
|
|
|