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