1 // VCOM-TPM.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 6 HANDLE hVCom = INVALID_HANDLE_VALUE; 7 LPCTSTR vcomPort = TEXT("COM6"); 8 unsigned int vcomTimeout = 5 * 60 * 1000; 9 10 #ifndef TPM_RC_SUCCESS 11 #define TPM_RC_SUCCESS 0 12 #endif 13 14 unsigned int GetTimeStamp(void) 15 { 16 FILETIME now = { 0 }; 17 LARGE_INTEGER convert = { 0 }; 18 19 // Get the current timestamp 20 GetSystemTimeAsFileTime(&now); 21 convert.LowPart = now.dwLowDateTime; 22 convert.HighPart = now.dwHighDateTime; 23 convert.QuadPart = (convert.QuadPart - (UINT64)(11644473600000 * 10000)) / 10000000; 24 return convert.LowPart; 25 } 26 27 unsigned int SetTpmResponseTimeout(unsigned int timeout) 28 { 29 COMMTIMEOUTS to = { 0 }; 30 to.ReadIntervalTimeout = 0; 31 to.ReadTotalTimeoutMultiplier = 0; 32 to.ReadTotalTimeoutConstant = timeout; 33 to.WriteTotalTimeoutMultiplier = 0; 34 to.WriteTotalTimeoutConstant = 0; 35 if (!SetCommTimeouts(hVCom, &to)) 36 { 37 return GetLastError(); 38 } 39 else 40 { 41 return 0; 42 } 43 } 44 45 unsigned int SendTpmSignal(signalCode_t signal, 46 unsigned int timeout, 47 BYTE* dataIn, 48 unsigned int dataInSize, 49 BYTE* dataOut, 50 unsigned int dataOutSize, 51 unsigned int* dataOutUsed 52 ) 53 { 54 unsigned int result = 0; 55 DWORD written = 0; 56 unsigned int signalBufSize = sizeof(signalWrapper_t) + dataInSize; 57 BYTE* signalBuf = (BYTE*)malloc(signalBufSize); 58 pSignalWrapper_t sig = (pSignalWrapper_t)signalBuf; 59 sig->s.magic = SIGNALMAGIC; 60 sig->s.signal = signal; 61 sig->s.dataSize = dataInSize; 62 if (dataInSize > 0) 63 { 64 memcpy(&signalBuf[sizeof(signalWrapper_t)], dataIn, dataInSize); 65 } 66 67 PurgeComm(hVCom, PURGE_RXCLEAR | PURGE_TXCLEAR); 68 if (!WriteFile(hVCom, signalBuf, signalBufSize, &written, NULL)) 69 { 70 result = GetLastError(); 71 goto Cleanup; 72 } 73 74 if (signal == SignalCommand) 75 { 76 DWORD read = 0; 77 unsigned int rspSize = 0; 78 79 SetTpmResponseTimeout(timeout - 1000); 80 if (!ReadFile(hVCom, &rspSize, sizeof(rspSize), (LPDWORD)&read, NULL)) 81 { 82 result = GetLastError(); 83 goto Cleanup; 84 } 85 if (read == 0) 86 { 87 result = GetLastError(); 88 goto Cleanup; 89 } 90 91 read = 0; 92 SetTpmResponseTimeout(1000); 93 if ((!ReadFile(hVCom, dataOut, min(rspSize, dataOutSize), (LPDWORD)&read, NULL)) || 94 (read != rspSize)) 95 { 96 result = GetLastError(); 97 goto Cleanup; 98 } 99 *dataOutUsed = read; 100 PurgeComm(hVCom, PURGE_RXCLEAR); 101 } 102 103 Cleanup: 104 if (signalBuf) free(signalBuf); 105 return result; 106 } 107 108 BYTE* GenerateTpmCommandPayload(unsigned int locality, 109 BYTE* cmd, 110 UINT32 cmdSize, 111 unsigned int* dataInSize 112 ) 113 { 114 pSignalPayload_t payload = NULL; 115 *dataInSize = sizeof(payload->SignalCommandPayload) - sizeof(unsigned char) + cmdSize; 116 BYTE* dataIn = (BYTE*)malloc(*dataInSize); 117 payload = (pSignalPayload_t)dataIn; 118 payload->SignalCommandPayload.locality = locality; 119 payload->SignalCommandPayload.cmdSize = cmdSize; 120 memcpy(payload->SignalCommandPayload.cmd, cmd, cmdSize); 121 return dataIn; 122 } 123 124 unsigned int OpenTpmConnection(LPCTSTR comPort) 125 { 126 DCB dcb = { 0 }; 127 if (hVCom != INVALID_HANDLE_VALUE) 128 { 129 CloseHandle(hVCom); 130 hVCom = INVALID_HANDLE_VALUE; 131 } 132 dcb.DCBlength = sizeof(DCB); 133 dcb.BaudRate = CBR_115200; 134 dcb.fBinary = TRUE; 135 dcb.fParity = FALSE; 136 dcb.ByteSize = 8; 137 dcb.Parity = NOPARITY; 138 dcb.StopBits = ONESTOPBIT; 139 if (((hVCom = CreateFile(comPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) || 140 (!SetCommState(hVCom, &dcb))) 141 { 142 return GetLastError(); 143 } 144 PurgeComm(hVCom, PURGE_RXCLEAR); 145 unsigned int time = GetTimeStamp(); 146 SendTpmSignal(SignalSetClock, 500, (BYTE*)&time, sizeof(time), NULL, 0, NULL); 147 148 return 0; 149 } 150 151 UINT32 TPMVComSubmitCommand( 152 BOOL CloseContext, 153 BYTE* pbCommand, 154 UINT32 cbCommand, 155 BYTE* pbResponse, 156 UINT32 cbResponse, 157 UINT32* pcbResponse 158 ) 159 { 160 UINT32 result = TPM_RC_SUCCESS; 161 BYTE* dataIn = NULL; 162 unsigned int dataInSize = 0; 163 if (hVCom == INVALID_HANDLE_VALUE) 164 { 165 OpenTpmConnection(vcomPort); 166 } 167 168 dataIn = GenerateTpmCommandPayload(0, pbCommand, cbCommand, &dataInSize); 169 result = SendTpmSignal(SignalCommand, vcomTimeout, dataIn, dataInSize, pbResponse, cbResponse, pcbResponse); 170 171 if (CloseContext) 172 { 173 CloseHandle(hVCom); 174 hVCom = INVALID_HANDLE_VALUE; 175 } 176 177 if (dataIn) free(dataIn); 178 return result; 179 } 180 181 void TPMVComTeardown(void) 182 { 183 if (hVCom != INVALID_HANDLE_VALUE) 184 { 185 CloseHandle(hVCom); 186 hVCom = INVALID_HANDLE_VALUE; 187 } 188 } 189 190 BOOL TPMStartup() 191 { 192 unsigned char startupClear[] = { 0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00 }; 193 unsigned char response[10]; 194 unsigned int responseSize; 195 196 return ((TPMVComSubmitCommand(FALSE, startupClear, sizeof(startupClear), response, sizeof(response), &responseSize) == TPM_RC_SUCCESS) && 197 (responseSize == sizeof(response)) && 198 (*((unsigned int*)&response[sizeof(unsigned short) + sizeof(unsigned int)]) == 0)); 199 } 200 201 UINT32 TPMShutdown() 202 { 203 unsigned char shutdownClear[] = { 0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00 }; 204 unsigned char response[10]; 205 unsigned int responseSize; 206 207 return ((TPMVComSubmitCommand(TRUE, shutdownClear, sizeof(shutdownClear), response, sizeof(response), &responseSize) == TPM_RC_SUCCESS) && 208 (responseSize == sizeof(response)) && 209 (*((unsigned int*)&response[sizeof(unsigned short) + sizeof(unsigned int)]) == 0)); 210 } 211 212 int main() 213 { 214 if (!TPMStartup()) goto Cleanup; 215 216 if (SendTpmSignal(SignalCancelOn, 1000, NULL, 0, NULL, 0, NULL)) goto Cleanup; 217 if (SendTpmSignal(SignalCancelOff, 1000, NULL, 0, NULL, 0, NULL)) goto Cleanup; 218 219 // if (SendTpmSignal(SignalShutdown, 1000, NULL, 0, NULL, 0, NULL)) goto Cleanup; 220 // if (SendTpmSignal(SignalReset, 1000, NULL, 0, NULL, 0, NULL)) goto Cleanup; 221 222 Cleanup: 223 TPMShutdown(); 224 return 0; 225 } 226 227