You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
13 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

// 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;
}