android13/external/ms-tpm-20-ref/Samples/Nucleo-TPM/VCOM/VCOM-TPM/VCOM-TPM.cpp

227 lines
13 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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