1*5c591343SA. Cody Schuffelen
2*5c591343SA. Cody Schuffelen /* Microsoft Reference Implementation for TPM 2.0
3*5c591343SA. Cody Schuffelen *
4*5c591343SA. Cody Schuffelen * The copyright in this software is being made available under the BSD License,
5*5c591343SA. Cody Schuffelen * included below. This software may be subject to other third party and
6*5c591343SA. Cody Schuffelen * contributor rights, including patent rights, and no such rights are granted
7*5c591343SA. Cody Schuffelen * under this license.
8*5c591343SA. Cody Schuffelen *
9*5c591343SA. Cody Schuffelen * Copyright (c) Microsoft Corporation
10*5c591343SA. Cody Schuffelen *
11*5c591343SA. Cody Schuffelen * All rights reserved.
12*5c591343SA. Cody Schuffelen *
13*5c591343SA. Cody Schuffelen * BSD License
14*5c591343SA. Cody Schuffelen *
15*5c591343SA. Cody Schuffelen * Redistribution and use in source and binary forms, with or without modification,
16*5c591343SA. Cody Schuffelen * are permitted provided that the following conditions are met:
17*5c591343SA. Cody Schuffelen *
18*5c591343SA. Cody Schuffelen * Redistributions of source code must retain the above copyright notice, this list
19*5c591343SA. Cody Schuffelen * of conditions and the following disclaimer.
20*5c591343SA. Cody Schuffelen *
21*5c591343SA. Cody Schuffelen * Redistributions in binary form must reproduce the above copyright notice, this
22*5c591343SA. Cody Schuffelen * list of conditions and the following disclaimer in the documentation and/or
23*5c591343SA. Cody Schuffelen * other materials provided with the distribution.
24*5c591343SA. Cody Schuffelen *
25*5c591343SA. Cody Schuffelen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
26*5c591343SA. Cody Schuffelen * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27*5c591343SA. Cody Schuffelen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28*5c591343SA. Cody Schuffelen * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
29*5c591343SA. Cody Schuffelen * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30*5c591343SA. Cody Schuffelen * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31*5c591343SA. Cody Schuffelen * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
32*5c591343SA. Cody Schuffelen * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33*5c591343SA. Cody Schuffelen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34*5c591343SA. Cody Schuffelen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*5c591343SA. Cody Schuffelen */
36*5c591343SA. Cody Schuffelen //** Description
37*5c591343SA. Cody Schuffelen //
38*5c591343SA. Cody Schuffelen // This file contains the socket interface to a TPM simulator.
39*5c591343SA. Cody Schuffelen //
40*5c591343SA. Cody Schuffelen //** Includes, Locals, Defines and Function Prototypes
41*5c591343SA. Cody Schuffelen #include "TpmBuildSwitches.h"
42*5c591343SA. Cody Schuffelen #include <stdio.h>
43*5c591343SA. Cody Schuffelen #include <stdbool.h>
44*5c591343SA. Cody Schuffelen
45*5c591343SA. Cody Schuffelen #ifdef _WIN32
46*5c591343SA. Cody Schuffelen # pragma warning(push, 3)
47*5c591343SA. Cody Schuffelen # include <windows.h>
48*5c591343SA. Cody Schuffelen # include <winsock.h>
49*5c591343SA. Cody Schuffelen # pragma warning(pop)
50*5c591343SA. Cody Schuffelen typedef int socklen_t;
51*5c591343SA. Cody Schuffelen #elif defined(__unix__) || __APPLE__
52*5c591343SA. Cody Schuffelen # include <string.h>
53*5c591343SA. Cody Schuffelen # include <unistd.h>
54*5c591343SA. Cody Schuffelen # include <errno.h>
55*5c591343SA. Cody Schuffelen # include <stdint.h>
56*5c591343SA. Cody Schuffelen # include <netinet/in.h>
57*5c591343SA. Cody Schuffelen # include <sys/socket.h>
58*5c591343SA. Cody Schuffelen # include <pthread.h>
59*5c591343SA. Cody Schuffelen # define ZeroMemory(ptr, sz) (memset((ptr), 0, (sz)))
60*5c591343SA. Cody Schuffelen # define closesocket(x) close(x)
61*5c591343SA. Cody Schuffelen # define INVALID_SOCKET (-1)
62*5c591343SA. Cody Schuffelen # define SOCKET_ERROR (-1)
63*5c591343SA. Cody Schuffelen # define WSAGetLastError() (errno)
64*5c591343SA. Cody Schuffelen # define INT_PTR intptr_t
65*5c591343SA. Cody Schuffelen
66*5c591343SA. Cody Schuffelen typedef int SOCKET;
67*5c591343SA. Cody Schuffelen #else
68*5c591343SA. Cody Schuffelen # error "Unsupported platform."
69*5c591343SA. Cody Schuffelen #endif
70*5c591343SA. Cody Schuffelen
71*5c591343SA. Cody Schuffelen #include "TpmTcpProtocol.h"
72*5c591343SA. Cody Schuffelen #include "Manufacture_fp.h"
73*5c591343SA. Cody Schuffelen #include "TpmProfile.h"
74*5c591343SA. Cody Schuffelen
75*5c591343SA. Cody Schuffelen #include "Simulator_fp.h"
76*5c591343SA. Cody Schuffelen #include "Platform_fp.h"
77*5c591343SA. Cody Schuffelen
78*5c591343SA. Cody Schuffelen // To access key cache control in TPM
79*5c591343SA. Cody Schuffelen void RsaKeyCacheControl(int state);
80*5c591343SA. Cody Schuffelen
81*5c591343SA. Cody Schuffelen #ifndef __IGNORE_STATE__
82*5c591343SA. Cody Schuffelen
83*5c591343SA. Cody Schuffelen static uint32_t ServerVersion = 1;
84*5c591343SA. Cody Schuffelen
85*5c591343SA. Cody Schuffelen #define MAX_BUFFER 1048576
86*5c591343SA. Cody Schuffelen char InputBuffer[MAX_BUFFER]; //The input data buffer for the simulator.
87*5c591343SA. Cody Schuffelen char OutputBuffer[MAX_BUFFER]; //The output data buffer for the simulator.
88*5c591343SA. Cody Schuffelen
89*5c591343SA. Cody Schuffelen struct
90*5c591343SA. Cody Schuffelen {
91*5c591343SA. Cody Schuffelen uint32_t largestCommandSize;
92*5c591343SA. Cody Schuffelen uint32_t largestCommand;
93*5c591343SA. Cody Schuffelen uint32_t largestResponseSize;
94*5c591343SA. Cody Schuffelen uint32_t largestResponse;
95*5c591343SA. Cody Schuffelen } CommandResponseSizes = {0};
96*5c591343SA. Cody Schuffelen
97*5c591343SA. Cody Schuffelen #endif // __IGNORE_STATE___
98*5c591343SA. Cody Schuffelen
99*5c591343SA. Cody Schuffelen //** Functions
100*5c591343SA. Cody Schuffelen
101*5c591343SA. Cody Schuffelen //*** CreateSocket()
102*5c591343SA. Cody Schuffelen // This function creates a socket listening on 'PortNumber'.
103*5c591343SA. Cody Schuffelen static int
CreateSocket(int PortNumber,SOCKET * listenSocket)104*5c591343SA. Cody Schuffelen CreateSocket(
105*5c591343SA. Cody Schuffelen int PortNumber,
106*5c591343SA. Cody Schuffelen SOCKET *listenSocket
107*5c591343SA. Cody Schuffelen )
108*5c591343SA. Cody Schuffelen {
109*5c591343SA. Cody Schuffelen struct sockaddr_in MyAddress;
110*5c591343SA. Cody Schuffelen int res;
111*5c591343SA. Cody Schuffelen //
112*5c591343SA. Cody Schuffelen // Initialize Winsock
113*5c591343SA. Cody Schuffelen #ifdef _WIN32
114*5c591343SA. Cody Schuffelen WSADATA wsaData;
115*5c591343SA. Cody Schuffelen res = WSAStartup(MAKEWORD(2, 2), &wsaData);
116*5c591343SA. Cody Schuffelen if(res != 0)
117*5c591343SA. Cody Schuffelen {
118*5c591343SA. Cody Schuffelen printf("WSAStartup failed with error: %d\n", res);
119*5c591343SA. Cody Schuffelen return -1;
120*5c591343SA. Cody Schuffelen }
121*5c591343SA. Cody Schuffelen #endif
122*5c591343SA. Cody Schuffelen // create listening socket
123*5c591343SA. Cody Schuffelen *listenSocket = socket(PF_INET, SOCK_STREAM, 0);
124*5c591343SA. Cody Schuffelen if(INVALID_SOCKET == *listenSocket)
125*5c591343SA. Cody Schuffelen {
126*5c591343SA. Cody Schuffelen printf("Cannot create server listen socket. Error is 0x%x\n",
127*5c591343SA. Cody Schuffelen WSAGetLastError());
128*5c591343SA. Cody Schuffelen return -1;
129*5c591343SA. Cody Schuffelen }
130*5c591343SA. Cody Schuffelen // bind the listening socket to the specified port
131*5c591343SA. Cody Schuffelen ZeroMemory(&MyAddress, sizeof(MyAddress));
132*5c591343SA. Cody Schuffelen MyAddress.sin_port = htons((short)PortNumber);
133*5c591343SA. Cody Schuffelen MyAddress.sin_family = AF_INET;
134*5c591343SA. Cody Schuffelen
135*5c591343SA. Cody Schuffelen res = bind(*listenSocket, (struct sockaddr*) &MyAddress, sizeof(MyAddress));
136*5c591343SA. Cody Schuffelen if(res == SOCKET_ERROR)
137*5c591343SA. Cody Schuffelen {
138*5c591343SA. Cody Schuffelen printf("Bind error. Error is 0x%x\n", WSAGetLastError());
139*5c591343SA. Cody Schuffelen return -1;
140*5c591343SA. Cody Schuffelen }
141*5c591343SA. Cody Schuffelen // listen/wait for server connections
142*5c591343SA. Cody Schuffelen res = listen(*listenSocket, 3);
143*5c591343SA. Cody Schuffelen if(res == SOCKET_ERROR)
144*5c591343SA. Cody Schuffelen {
145*5c591343SA. Cody Schuffelen printf("Listen error. Error is 0x%x\n", WSAGetLastError());
146*5c591343SA. Cody Schuffelen return -1;
147*5c591343SA. Cody Schuffelen }
148*5c591343SA. Cody Schuffelen return 0;
149*5c591343SA. Cody Schuffelen }
150*5c591343SA. Cody Schuffelen
151*5c591343SA. Cody Schuffelen //*** PlatformServer()
152*5c591343SA. Cody Schuffelen // This function processes incoming platform requests.
153*5c591343SA. Cody Schuffelen bool
PlatformServer(SOCKET s)154*5c591343SA. Cody Schuffelen PlatformServer(
155*5c591343SA. Cody Schuffelen SOCKET s
156*5c591343SA. Cody Schuffelen )
157*5c591343SA. Cody Schuffelen {
158*5c591343SA. Cody Schuffelen bool OK = true;
159*5c591343SA. Cody Schuffelen uint32_t Command;
160*5c591343SA. Cody Schuffelen //
161*5c591343SA. Cody Schuffelen for(;;)
162*5c591343SA. Cody Schuffelen {
163*5c591343SA. Cody Schuffelen OK = ReadBytes(s, (char*)&Command, 4);
164*5c591343SA. Cody Schuffelen // client disconnected (or other error). We stop processing this client
165*5c591343SA. Cody Schuffelen // and return to our caller who can stop the server or listen for another
166*5c591343SA. Cody Schuffelen // connection.
167*5c591343SA. Cody Schuffelen if(!OK)
168*5c591343SA. Cody Schuffelen return true;
169*5c591343SA. Cody Schuffelen Command = ntohl(Command);
170*5c591343SA. Cody Schuffelen switch(Command)
171*5c591343SA. Cody Schuffelen {
172*5c591343SA. Cody Schuffelen case TPM_SIGNAL_POWER_ON:
173*5c591343SA. Cody Schuffelen _rpc__Signal_PowerOn(false);
174*5c591343SA. Cody Schuffelen break;
175*5c591343SA. Cody Schuffelen case TPM_SIGNAL_POWER_OFF:
176*5c591343SA. Cody Schuffelen _rpc__Signal_PowerOff();
177*5c591343SA. Cody Schuffelen break;
178*5c591343SA. Cody Schuffelen case TPM_SIGNAL_RESET:
179*5c591343SA. Cody Schuffelen _rpc__Signal_PowerOn(true);
180*5c591343SA. Cody Schuffelen break;
181*5c591343SA. Cody Schuffelen case TPM_SIGNAL_RESTART:
182*5c591343SA. Cody Schuffelen _rpc__Signal_Restart();
183*5c591343SA. Cody Schuffelen break;
184*5c591343SA. Cody Schuffelen case TPM_SIGNAL_PHYS_PRES_ON:
185*5c591343SA. Cody Schuffelen _rpc__Signal_PhysicalPresenceOn();
186*5c591343SA. Cody Schuffelen break;
187*5c591343SA. Cody Schuffelen case TPM_SIGNAL_PHYS_PRES_OFF:
188*5c591343SA. Cody Schuffelen _rpc__Signal_PhysicalPresenceOff();
189*5c591343SA. Cody Schuffelen break;
190*5c591343SA. Cody Schuffelen case TPM_SIGNAL_CANCEL_ON:
191*5c591343SA. Cody Schuffelen _rpc__Signal_CancelOn();
192*5c591343SA. Cody Schuffelen break;
193*5c591343SA. Cody Schuffelen case TPM_SIGNAL_CANCEL_OFF:
194*5c591343SA. Cody Schuffelen _rpc__Signal_CancelOff();
195*5c591343SA. Cody Schuffelen break;
196*5c591343SA. Cody Schuffelen case TPM_SIGNAL_NV_ON:
197*5c591343SA. Cody Schuffelen _rpc__Signal_NvOn();
198*5c591343SA. Cody Schuffelen break;
199*5c591343SA. Cody Schuffelen case TPM_SIGNAL_NV_OFF:
200*5c591343SA. Cody Schuffelen _rpc__Signal_NvOff();
201*5c591343SA. Cody Schuffelen break;
202*5c591343SA. Cody Schuffelen case TPM_SIGNAL_KEY_CACHE_ON:
203*5c591343SA. Cody Schuffelen _rpc__RsaKeyCacheControl(true);
204*5c591343SA. Cody Schuffelen break;
205*5c591343SA. Cody Schuffelen case TPM_SIGNAL_KEY_CACHE_OFF:
206*5c591343SA. Cody Schuffelen _rpc__RsaKeyCacheControl(false);
207*5c591343SA. Cody Schuffelen break;
208*5c591343SA. Cody Schuffelen case TPM_SESSION_END:
209*5c591343SA. Cody Schuffelen // Client signaled end-of-session
210*5c591343SA. Cody Schuffelen TpmEndSimulation();
211*5c591343SA. Cody Schuffelen return true;
212*5c591343SA. Cody Schuffelen case TPM_STOP:
213*5c591343SA. Cody Schuffelen // Client requested the simulator to exit
214*5c591343SA. Cody Schuffelen return false;
215*5c591343SA. Cody Schuffelen case TPM_TEST_FAILURE_MODE:
216*5c591343SA. Cody Schuffelen _rpc__ForceFailureMode();
217*5c591343SA. Cody Schuffelen break;
218*5c591343SA. Cody Schuffelen case TPM_GET_COMMAND_RESPONSE_SIZES:
219*5c591343SA. Cody Schuffelen OK = WriteVarBytes(s, (char *)&CommandResponseSizes,
220*5c591343SA. Cody Schuffelen sizeof(CommandResponseSizes));
221*5c591343SA. Cody Schuffelen memset(&CommandResponseSizes, 0, sizeof(CommandResponseSizes));
222*5c591343SA. Cody Schuffelen if(!OK)
223*5c591343SA. Cody Schuffelen return true;
224*5c591343SA. Cody Schuffelen break;
225*5c591343SA. Cody Schuffelen case TPM_ACT_GET_SIGNALED:
226*5c591343SA. Cody Schuffelen {
227*5c591343SA. Cody Schuffelen uint32_t actHandle;
228*5c591343SA. Cody Schuffelen OK = ReadUINT32(s, &actHandle);
229*5c591343SA. Cody Schuffelen WriteUINT32(s, _rpc__ACT_GetSignaled(actHandle));
230*5c591343SA. Cody Schuffelen break;
231*5c591343SA. Cody Schuffelen }
232*5c591343SA. Cody Schuffelen default:
233*5c591343SA. Cody Schuffelen printf("Unrecognized platform interface command %d\n",
234*5c591343SA. Cody Schuffelen (int)Command);
235*5c591343SA. Cody Schuffelen WriteUINT32(s, 1);
236*5c591343SA. Cody Schuffelen return true;
237*5c591343SA. Cody Schuffelen }
238*5c591343SA. Cody Schuffelen WriteUINT32(s, 0);
239*5c591343SA. Cody Schuffelen }
240*5c591343SA. Cody Schuffelen }
241*5c591343SA. Cody Schuffelen
242*5c591343SA. Cody Schuffelen //*** PlatformSvcRoutine()
243*5c591343SA. Cody Schuffelen // This function is called to set up the socket interfaces to listen for
244*5c591343SA. Cody Schuffelen // commands.
245*5c591343SA. Cody Schuffelen DWORD WINAPI
PlatformSvcRoutine(LPVOID port)246*5c591343SA. Cody Schuffelen PlatformSvcRoutine(
247*5c591343SA. Cody Schuffelen LPVOID port
248*5c591343SA. Cody Schuffelen )
249*5c591343SA. Cody Schuffelen {
250*5c591343SA. Cody Schuffelen int PortNumber = (int)(INT_PTR)port;
251*5c591343SA. Cody Schuffelen SOCKET listenSocket, serverSocket;
252*5c591343SA. Cody Schuffelen struct sockaddr_in HerAddress;
253*5c591343SA. Cody Schuffelen int res;
254*5c591343SA. Cody Schuffelen socklen_t length;
255*5c591343SA. Cody Schuffelen bool continueServing;
256*5c591343SA. Cody Schuffelen //
257*5c591343SA. Cody Schuffelen res = CreateSocket(PortNumber, &listenSocket);
258*5c591343SA. Cody Schuffelen if(res != 0)
259*5c591343SA. Cody Schuffelen {
260*5c591343SA. Cody Schuffelen printf("Create platform service socket fail\n");
261*5c591343SA. Cody Schuffelen return res;
262*5c591343SA. Cody Schuffelen }
263*5c591343SA. Cody Schuffelen // Loop accepting connections one-by-one until we are killed or asked to stop
264*5c591343SA. Cody Schuffelen // Note the platform service is single-threaded so we don't listen for a new
265*5c591343SA. Cody Schuffelen // connection until the prior connection drops.
266*5c591343SA. Cody Schuffelen do
267*5c591343SA. Cody Schuffelen {
268*5c591343SA. Cody Schuffelen printf("Platform server listening on port %d\n", PortNumber);
269*5c591343SA. Cody Schuffelen
270*5c591343SA. Cody Schuffelen // blocking accept
271*5c591343SA. Cody Schuffelen length = sizeof(HerAddress);
272*5c591343SA. Cody Schuffelen serverSocket = accept(listenSocket,
273*5c591343SA. Cody Schuffelen (struct sockaddr*) &HerAddress,
274*5c591343SA. Cody Schuffelen &length);
275*5c591343SA. Cody Schuffelen if(serverSocket == INVALID_SOCKET)
276*5c591343SA. Cody Schuffelen {
277*5c591343SA. Cody Schuffelen printf("Accept error. Error is 0x%x\n", WSAGetLastError());
278*5c591343SA. Cody Schuffelen return (DWORD)-1;
279*5c591343SA. Cody Schuffelen }
280*5c591343SA. Cody Schuffelen printf("Client accepted\n");
281*5c591343SA. Cody Schuffelen
282*5c591343SA. Cody Schuffelen // normal behavior on client disconnection is to wait for a new client
283*5c591343SA. Cody Schuffelen // to connect
284*5c591343SA. Cody Schuffelen continueServing = PlatformServer(serverSocket);
285*5c591343SA. Cody Schuffelen closesocket(serverSocket);
286*5c591343SA. Cody Schuffelen } while(continueServing);
287*5c591343SA. Cody Schuffelen
288*5c591343SA. Cody Schuffelen return 0;
289*5c591343SA. Cody Schuffelen }
290*5c591343SA. Cody Schuffelen
291*5c591343SA. Cody Schuffelen //*** PlatformSignalService()
292*5c591343SA. Cody Schuffelen // This function starts a new thread waiting for platform signals.
293*5c591343SA. Cody Schuffelen // Platform signals are processed one at a time in the order in which they are
294*5c591343SA. Cody Schuffelen // received.
295*5c591343SA. Cody Schuffelen int
PlatformSignalService(int PortNumber)296*5c591343SA. Cody Schuffelen PlatformSignalService(
297*5c591343SA. Cody Schuffelen int PortNumber
298*5c591343SA. Cody Schuffelen )
299*5c591343SA. Cody Schuffelen {
300*5c591343SA. Cody Schuffelen #if defined(_WIN32)
301*5c591343SA. Cody Schuffelen HANDLE hPlatformSvc;
302*5c591343SA. Cody Schuffelen int ThreadId;
303*5c591343SA. Cody Schuffelen int port = PortNumber;
304*5c591343SA. Cody Schuffelen //
305*5c591343SA. Cody Schuffelen // Create service thread for platform signals
306*5c591343SA. Cody Schuffelen hPlatformSvc = CreateThread(NULL, 0,
307*5c591343SA. Cody Schuffelen (LPTHREAD_START_ROUTINE)PlatformSvcRoutine,
308*5c591343SA. Cody Schuffelen (LPVOID)(INT_PTR)port, 0, (LPDWORD)&ThreadId);
309*5c591343SA. Cody Schuffelen if(hPlatformSvc == NULL)
310*5c591343SA. Cody Schuffelen {
311*5c591343SA. Cody Schuffelen printf("Thread Creation failed\n");
312*5c591343SA. Cody Schuffelen return -1;
313*5c591343SA. Cody Schuffelen }
314*5c591343SA. Cody Schuffelen return 0;
315*5c591343SA. Cody Schuffelen #else
316*5c591343SA. Cody Schuffelen pthread_t thread_id;
317*5c591343SA. Cody Schuffelen int ret;
318*5c591343SA. Cody Schuffelen int port = PortNumber;
319*5c591343SA. Cody Schuffelen
320*5c591343SA. Cody Schuffelen ret = pthread_create(&thread_id, NULL, (void*)PlatformSvcRoutine,
321*5c591343SA. Cody Schuffelen (LPVOID)(INT_PTR)port);
322*5c591343SA. Cody Schuffelen if (ret == -1)
323*5c591343SA. Cody Schuffelen {
324*5c591343SA. Cody Schuffelen printf("pthread_create failed: %s", strerror(ret));
325*5c591343SA. Cody Schuffelen }
326*5c591343SA. Cody Schuffelen return ret;
327*5c591343SA. Cody Schuffelen #endif // _WIN32
328*5c591343SA. Cody Schuffelen }
329*5c591343SA. Cody Schuffelen
330*5c591343SA. Cody Schuffelen //*** RegularCommandService()
331*5c591343SA. Cody Schuffelen // This function services regular commands.
332*5c591343SA. Cody Schuffelen int
RegularCommandService(int PortNumber)333*5c591343SA. Cody Schuffelen RegularCommandService(
334*5c591343SA. Cody Schuffelen int PortNumber
335*5c591343SA. Cody Schuffelen )
336*5c591343SA. Cody Schuffelen {
337*5c591343SA. Cody Schuffelen SOCKET listenSocket;
338*5c591343SA. Cody Schuffelen SOCKET serverSocket;
339*5c591343SA. Cody Schuffelen struct sockaddr_in HerAddress;
340*5c591343SA. Cody Schuffelen int res;
341*5c591343SA. Cody Schuffelen socklen_t length;
342*5c591343SA. Cody Schuffelen bool continueServing;
343*5c591343SA. Cody Schuffelen //
344*5c591343SA. Cody Schuffelen res = CreateSocket(PortNumber, &listenSocket);
345*5c591343SA. Cody Schuffelen if(res != 0)
346*5c591343SA. Cody Schuffelen {
347*5c591343SA. Cody Schuffelen printf("Create platform service socket fail\n");
348*5c591343SA. Cody Schuffelen return res;
349*5c591343SA. Cody Schuffelen }
350*5c591343SA. Cody Schuffelen // Loop accepting connections one-by-one until we are killed or asked to stop
351*5c591343SA. Cody Schuffelen // Note the TPM command service is single-threaded so we don't listen for
352*5c591343SA. Cody Schuffelen // a new connection until the prior connection drops.
353*5c591343SA. Cody Schuffelen do
354*5c591343SA. Cody Schuffelen {
355*5c591343SA. Cody Schuffelen printf("TPM command server listening on port %d\n", PortNumber);
356*5c591343SA. Cody Schuffelen
357*5c591343SA. Cody Schuffelen // blocking accept
358*5c591343SA. Cody Schuffelen length = sizeof(HerAddress);
359*5c591343SA. Cody Schuffelen serverSocket = accept(listenSocket,
360*5c591343SA. Cody Schuffelen (struct sockaddr*) &HerAddress,
361*5c591343SA. Cody Schuffelen &length);
362*5c591343SA. Cody Schuffelen if(serverSocket == INVALID_SOCKET)
363*5c591343SA. Cody Schuffelen {
364*5c591343SA. Cody Schuffelen printf("Accept error. Error is 0x%x\n", WSAGetLastError());
365*5c591343SA. Cody Schuffelen return -1;
366*5c591343SA. Cody Schuffelen }
367*5c591343SA. Cody Schuffelen printf("Client accepted\n");
368*5c591343SA. Cody Schuffelen
369*5c591343SA. Cody Schuffelen // normal behavior on client disconnection is to wait for a new client
370*5c591343SA. Cody Schuffelen // to connect
371*5c591343SA. Cody Schuffelen continueServing = TpmServer(serverSocket);
372*5c591343SA. Cody Schuffelen closesocket(serverSocket);
373*5c591343SA. Cody Schuffelen } while(continueServing);
374*5c591343SA. Cody Schuffelen return 0;
375*5c591343SA. Cody Schuffelen }
376*5c591343SA. Cody Schuffelen
377*5c591343SA. Cody Schuffelen #if RH_ACT_0
378*5c591343SA. Cody Schuffelen
379*5c591343SA. Cody Schuffelen //*** SimulatorTimeServiceRoutine()
380*5c591343SA. Cody Schuffelen // This function is called to service the time 'ticks'.
381*5c591343SA. Cody Schuffelen static unsigned long WINAPI
SimulatorTimeServiceRoutine(LPVOID notUsed)382*5c591343SA. Cody Schuffelen SimulatorTimeServiceRoutine(
383*5c591343SA. Cody Schuffelen LPVOID notUsed
384*5c591343SA. Cody Schuffelen )
385*5c591343SA. Cody Schuffelen {
386*5c591343SA. Cody Schuffelen // All time is in ms
387*5c591343SA. Cody Schuffelen const int64_t tick = 1000;
388*5c591343SA. Cody Schuffelen uint64_t prevTime = _plat__RealTime();
389*5c591343SA. Cody Schuffelen int64_t timeout = tick;
390*5c591343SA. Cody Schuffelen
391*5c591343SA. Cody Schuffelen (void)notUsed;
392*5c591343SA. Cody Schuffelen
393*5c591343SA. Cody Schuffelen while (true)
394*5c591343SA. Cody Schuffelen {
395*5c591343SA. Cody Schuffelen uint64_t curTime;
396*5c591343SA. Cody Schuffelen
397*5c591343SA. Cody Schuffelen #if defined(_WIN32)
398*5c591343SA. Cody Schuffelen Sleep((DWORD)timeout);
399*5c591343SA. Cody Schuffelen #else
400*5c591343SA. Cody Schuffelen struct timespec req = { timeout / 1000, (timeout % 1000) * 1000 };
401*5c591343SA. Cody Schuffelen struct timespec rem;
402*5c591343SA. Cody Schuffelen nanosleep(&req, &rem);
403*5c591343SA. Cody Schuffelen #endif // _WIN32
404*5c591343SA. Cody Schuffelen curTime = _plat__RealTime();
405*5c591343SA. Cody Schuffelen
406*5c591343SA. Cody Schuffelen // May need to issue several ticks if the Sleep() took longer than asked,
407*5c591343SA. Cody Schuffelen // or no ticks at all, it Sleep() was interrupted prematurely.
408*5c591343SA. Cody Schuffelen while (prevTime < curTime - tick / 2)
409*5c591343SA. Cody Schuffelen {
410*5c591343SA. Cody Schuffelen //printf("%05lld | %05lld\n",
411*5c591343SA. Cody Schuffelen // prevTime % 100000, (curTime - tick / 2) % 100000);
412*5c591343SA. Cody Schuffelen _plat__ACT_Tick();
413*5c591343SA. Cody Schuffelen prevTime += (uint64_t)tick;
414*5c591343SA. Cody Schuffelen }
415*5c591343SA. Cody Schuffelen // Adjust the next timeout to keep the average interval of one second
416*5c591343SA. Cody Schuffelen timeout = tick + (prevTime - curTime);
417*5c591343SA. Cody Schuffelen //prevTime = curTime;
418*5c591343SA. Cody Schuffelen //printf("%04lld | c:%05lld | p:%05llu\n",
419*5c591343SA. Cody Schuffelen // timeout, curTime % 100000, prevTime);
420*5c591343SA. Cody Schuffelen }
421*5c591343SA. Cody Schuffelen return 0;
422*5c591343SA. Cody Schuffelen }
423*5c591343SA. Cody Schuffelen
424*5c591343SA. Cody Schuffelen //*** ActTimeService()
425*5c591343SA. Cody Schuffelen // This function starts a new thread waiting to wait for time ticks.
426*5c591343SA. Cody Schuffelen // Return Type: int
427*5c591343SA. Cody Schuffelen // ==0 success
428*5c591343SA. Cody Schuffelen // !=0 failure
429*5c591343SA. Cody Schuffelen static int
ActTimeService(void)430*5c591343SA. Cody Schuffelen ActTimeService(
431*5c591343SA. Cody Schuffelen void
432*5c591343SA. Cody Schuffelen )
433*5c591343SA. Cody Schuffelen {
434*5c591343SA. Cody Schuffelen static bool running = false;
435*5c591343SA. Cody Schuffelen int ret = 0;
436*5c591343SA. Cody Schuffelen if(!running)
437*5c591343SA. Cody Schuffelen {
438*5c591343SA. Cody Schuffelen #if defined(_WIN32)
439*5c591343SA. Cody Schuffelen HANDLE hThr;
440*5c591343SA. Cody Schuffelen int ThreadId;
441*5c591343SA. Cody Schuffelen //
442*5c591343SA. Cody Schuffelen printf("Starting ACT thread...\n");
443*5c591343SA. Cody Schuffelen // Don't allow ticks to be processed before TPM is manufactured.
444*5c591343SA. Cody Schuffelen _plat__ACT_EnableTicks(false);
445*5c591343SA. Cody Schuffelen
446*5c591343SA. Cody Schuffelen // Create service thread for ACT internal timer
447*5c591343SA. Cody Schuffelen hThr = CreateThread(NULL, 0,
448*5c591343SA. Cody Schuffelen (LPTHREAD_START_ROUTINE)SimulatorTimeServiceRoutine,
449*5c591343SA. Cody Schuffelen (LPVOID)(INT_PTR)NULL, 0, (LPDWORD)&ThreadId);
450*5c591343SA. Cody Schuffelen if(hThr != NULL)
451*5c591343SA. Cody Schuffelen CloseHandle(hThr);
452*5c591343SA. Cody Schuffelen else
453*5c591343SA. Cody Schuffelen ret = -1;
454*5c591343SA. Cody Schuffelen #else
455*5c591343SA. Cody Schuffelen pthread_t thread_id;
456*5c591343SA. Cody Schuffelen //
457*5c591343SA. Cody Schuffelen ret = pthread_create(&thread_id, NULL, (void*)SimulatorTimeServiceRoutine,
458*5c591343SA. Cody Schuffelen (LPVOID)(INT_PTR)NULL);
459*5c591343SA. Cody Schuffelen #endif // _WIN32
460*5c591343SA. Cody Schuffelen
461*5c591343SA. Cody Schuffelen if(ret != 0)
462*5c591343SA. Cody Schuffelen printf("ACT thread Creation failed\n");
463*5c591343SA. Cody Schuffelen else
464*5c591343SA. Cody Schuffelen running = true;
465*5c591343SA. Cody Schuffelen }
466*5c591343SA. Cody Schuffelen return ret;
467*5c591343SA. Cody Schuffelen }
468*5c591343SA. Cody Schuffelen
469*5c591343SA. Cody Schuffelen #endif // RH_ACT_0
470*5c591343SA. Cody Schuffelen
471*5c591343SA. Cody Schuffelen //*** StartTcpServer()
472*5c591343SA. Cody Schuffelen // This is the main entry-point to the TCP server. The server listens on port
473*5c591343SA. Cody Schuffelen // specified.
474*5c591343SA. Cody Schuffelen //
475*5c591343SA. Cody Schuffelen // Note that there is no way to specify the network interface in this implementation.
476*5c591343SA. Cody Schuffelen int
StartTcpServer(int PortNumber)477*5c591343SA. Cody Schuffelen StartTcpServer(
478*5c591343SA. Cody Schuffelen int PortNumber
479*5c591343SA. Cody Schuffelen )
480*5c591343SA. Cody Schuffelen {
481*5c591343SA. Cody Schuffelen int res;
482*5c591343SA. Cody Schuffelen //
483*5c591343SA. Cody Schuffelen #ifdef RH_ACT_0
484*5c591343SA. Cody Schuffelen // Start the Time Service routine
485*5c591343SA. Cody Schuffelen res = ActTimeService();
486*5c591343SA. Cody Schuffelen if(res != 0)
487*5c591343SA. Cody Schuffelen {
488*5c591343SA. Cody Schuffelen printf("TimeService failed\n");
489*5c591343SA. Cody Schuffelen return res;
490*5c591343SA. Cody Schuffelen }
491*5c591343SA. Cody Schuffelen #endif
492*5c591343SA. Cody Schuffelen
493*5c591343SA. Cody Schuffelen // Start Platform Signal Processing Service
494*5c591343SA. Cody Schuffelen res = PlatformSignalService(PortNumber + 1);
495*5c591343SA. Cody Schuffelen if(res != 0)
496*5c591343SA. Cody Schuffelen {
497*5c591343SA. Cody Schuffelen printf("PlatformSignalService failed\n");
498*5c591343SA. Cody Schuffelen return res;
499*5c591343SA. Cody Schuffelen }
500*5c591343SA. Cody Schuffelen // Start Regular/DRTM TPM command service
501*5c591343SA. Cody Schuffelen res = RegularCommandService(PortNumber);
502*5c591343SA. Cody Schuffelen if(res != 0)
503*5c591343SA. Cody Schuffelen {
504*5c591343SA. Cody Schuffelen printf("RegularCommandService failed\n");
505*5c591343SA. Cody Schuffelen return res;
506*5c591343SA. Cody Schuffelen }
507*5c591343SA. Cody Schuffelen return 0;
508*5c591343SA. Cody Schuffelen }
509*5c591343SA. Cody Schuffelen
510*5c591343SA. Cody Schuffelen //*** ReadBytes()
511*5c591343SA. Cody Schuffelen // This function reads the indicated number of bytes ('NumBytes') into buffer
512*5c591343SA. Cody Schuffelen // from the indicated socket.
513*5c591343SA. Cody Schuffelen bool
ReadBytes(SOCKET s,char * buffer,int NumBytes)514*5c591343SA. Cody Schuffelen ReadBytes(
515*5c591343SA. Cody Schuffelen SOCKET s,
516*5c591343SA. Cody Schuffelen char *buffer,
517*5c591343SA. Cody Schuffelen int NumBytes
518*5c591343SA. Cody Schuffelen )
519*5c591343SA. Cody Schuffelen {
520*5c591343SA. Cody Schuffelen int res;
521*5c591343SA. Cody Schuffelen int numGot = 0;
522*5c591343SA. Cody Schuffelen //
523*5c591343SA. Cody Schuffelen while(numGot < NumBytes)
524*5c591343SA. Cody Schuffelen {
525*5c591343SA. Cody Schuffelen res = recv(s, buffer + numGot, NumBytes - numGot, 0);
526*5c591343SA. Cody Schuffelen if(res == -1)
527*5c591343SA. Cody Schuffelen {
528*5c591343SA. Cody Schuffelen printf("Receive error. Error is 0x%x\n", WSAGetLastError());
529*5c591343SA. Cody Schuffelen return false;
530*5c591343SA. Cody Schuffelen }
531*5c591343SA. Cody Schuffelen if(res == 0)
532*5c591343SA. Cody Schuffelen {
533*5c591343SA. Cody Schuffelen return false;
534*5c591343SA. Cody Schuffelen }
535*5c591343SA. Cody Schuffelen numGot += res;
536*5c591343SA. Cody Schuffelen }
537*5c591343SA. Cody Schuffelen return true;
538*5c591343SA. Cody Schuffelen }
539*5c591343SA. Cody Schuffelen
540*5c591343SA. Cody Schuffelen //*** WriteBytes()
541*5c591343SA. Cody Schuffelen // This function will send the indicated number of bytes ('NumBytes') to the
542*5c591343SA. Cody Schuffelen // indicated socket
543*5c591343SA. Cody Schuffelen bool
WriteBytes(SOCKET s,char * buffer,int NumBytes)544*5c591343SA. Cody Schuffelen WriteBytes(
545*5c591343SA. Cody Schuffelen SOCKET s,
546*5c591343SA. Cody Schuffelen char *buffer,
547*5c591343SA. Cody Schuffelen int NumBytes
548*5c591343SA. Cody Schuffelen )
549*5c591343SA. Cody Schuffelen {
550*5c591343SA. Cody Schuffelen int res;
551*5c591343SA. Cody Schuffelen int numSent = 0;
552*5c591343SA. Cody Schuffelen //
553*5c591343SA. Cody Schuffelen while(numSent < NumBytes)
554*5c591343SA. Cody Schuffelen {
555*5c591343SA. Cody Schuffelen res = send(s, buffer + numSent, NumBytes - numSent, 0);
556*5c591343SA. Cody Schuffelen if(res == -1)
557*5c591343SA. Cody Schuffelen {
558*5c591343SA. Cody Schuffelen if(WSAGetLastError() == 0x2745)
559*5c591343SA. Cody Schuffelen {
560*5c591343SA. Cody Schuffelen printf("Client disconnected\n");
561*5c591343SA. Cody Schuffelen }
562*5c591343SA. Cody Schuffelen else
563*5c591343SA. Cody Schuffelen {
564*5c591343SA. Cody Schuffelen printf("Send error. Error is 0x%x\n", WSAGetLastError());
565*5c591343SA. Cody Schuffelen }
566*5c591343SA. Cody Schuffelen return false;
567*5c591343SA. Cody Schuffelen }
568*5c591343SA. Cody Schuffelen numSent += res;
569*5c591343SA. Cody Schuffelen }
570*5c591343SA. Cody Schuffelen return true;
571*5c591343SA. Cody Schuffelen }
572*5c591343SA. Cody Schuffelen
573*5c591343SA. Cody Schuffelen //*** WriteUINT32()
574*5c591343SA. Cody Schuffelen // Send 4 byte integer
575*5c591343SA. Cody Schuffelen bool
WriteUINT32(SOCKET s,uint32_t val)576*5c591343SA. Cody Schuffelen WriteUINT32(
577*5c591343SA. Cody Schuffelen SOCKET s,
578*5c591343SA. Cody Schuffelen uint32_t val
579*5c591343SA. Cody Schuffelen )
580*5c591343SA. Cody Schuffelen {
581*5c591343SA. Cody Schuffelen uint32_t netVal = htonl(val);
582*5c591343SA. Cody Schuffelen //
583*5c591343SA. Cody Schuffelen return WriteBytes(s, (char*)&netVal, 4);
584*5c591343SA. Cody Schuffelen }
585*5c591343SA. Cody Schuffelen
586*5c591343SA. Cody Schuffelen //*** ReadUINT32()
587*5c591343SA. Cody Schuffelen // Function to read 4 byte integer from socket.
588*5c591343SA. Cody Schuffelen bool
ReadUINT32(SOCKET s,uint32_t * val)589*5c591343SA. Cody Schuffelen ReadUINT32(
590*5c591343SA. Cody Schuffelen SOCKET s,
591*5c591343SA. Cody Schuffelen uint32_t *val
592*5c591343SA. Cody Schuffelen )
593*5c591343SA. Cody Schuffelen {
594*5c591343SA. Cody Schuffelen uint32_t netVal;
595*5c591343SA. Cody Schuffelen //
596*5c591343SA. Cody Schuffelen if (!ReadBytes(s, (char*)&netVal, 4))
597*5c591343SA. Cody Schuffelen return false;
598*5c591343SA. Cody Schuffelen *val = ntohl(netVal);
599*5c591343SA. Cody Schuffelen return true;
600*5c591343SA. Cody Schuffelen }
601*5c591343SA. Cody Schuffelen
602*5c591343SA. Cody Schuffelen
603*5c591343SA. Cody Schuffelen //*** ReadVarBytes()
604*5c591343SA. Cody Schuffelen // Get a uint32-length-prepended binary array. Note that the 4-byte length is
605*5c591343SA. Cody Schuffelen // in network byte order (big-endian).
606*5c591343SA. Cody Schuffelen bool
ReadVarBytes(SOCKET s,char * buffer,uint32_t * BytesReceived,int MaxLen)607*5c591343SA. Cody Schuffelen ReadVarBytes(
608*5c591343SA. Cody Schuffelen SOCKET s,
609*5c591343SA. Cody Schuffelen char *buffer,
610*5c591343SA. Cody Schuffelen uint32_t *BytesReceived,
611*5c591343SA. Cody Schuffelen int MaxLen
612*5c591343SA. Cody Schuffelen )
613*5c591343SA. Cody Schuffelen {
614*5c591343SA. Cody Schuffelen int length;
615*5c591343SA. Cody Schuffelen bool res;
616*5c591343SA. Cody Schuffelen //
617*5c591343SA. Cody Schuffelen res = ReadBytes(s, (char*)&length, 4);
618*5c591343SA. Cody Schuffelen if(!res) return res;
619*5c591343SA. Cody Schuffelen length = ntohl(length);
620*5c591343SA. Cody Schuffelen *BytesReceived = length;
621*5c591343SA. Cody Schuffelen if(length > MaxLen)
622*5c591343SA. Cody Schuffelen {
623*5c591343SA. Cody Schuffelen printf("Buffer too big. Client says %d\n", length);
624*5c591343SA. Cody Schuffelen return false;
625*5c591343SA. Cody Schuffelen }
626*5c591343SA. Cody Schuffelen if(length == 0) return true;
627*5c591343SA. Cody Schuffelen res = ReadBytes(s, buffer, length);
628*5c591343SA. Cody Schuffelen if(!res) return res;
629*5c591343SA. Cody Schuffelen return true;
630*5c591343SA. Cody Schuffelen }
631*5c591343SA. Cody Schuffelen
632*5c591343SA. Cody Schuffelen //*** WriteVarBytes()
633*5c591343SA. Cody Schuffelen // Send a uint32-length-prepended binary array. Note that the 4-byte length is
634*5c591343SA. Cody Schuffelen // in network byte order (big-endian).
635*5c591343SA. Cody Schuffelen bool
WriteVarBytes(SOCKET s,char * buffer,int BytesToSend)636*5c591343SA. Cody Schuffelen WriteVarBytes(
637*5c591343SA. Cody Schuffelen SOCKET s,
638*5c591343SA. Cody Schuffelen char *buffer,
639*5c591343SA. Cody Schuffelen int BytesToSend
640*5c591343SA. Cody Schuffelen )
641*5c591343SA. Cody Schuffelen {
642*5c591343SA. Cody Schuffelen uint32_t netLength = htonl(BytesToSend);
643*5c591343SA. Cody Schuffelen bool res;
644*5c591343SA. Cody Schuffelen //
645*5c591343SA. Cody Schuffelen res = WriteBytes(s, (char*)&netLength, 4);
646*5c591343SA. Cody Schuffelen if(!res)
647*5c591343SA. Cody Schuffelen return res;
648*5c591343SA. Cody Schuffelen res = WriteBytes(s, buffer, BytesToSend);
649*5c591343SA. Cody Schuffelen if(!res)
650*5c591343SA. Cody Schuffelen return res;
651*5c591343SA. Cody Schuffelen return true;
652*5c591343SA. Cody Schuffelen }
653*5c591343SA. Cody Schuffelen
654*5c591343SA. Cody Schuffelen //*** TpmServer()
655*5c591343SA. Cody Schuffelen // Processing incoming TPM command requests using the protocol / interface
656*5c591343SA. Cody Schuffelen // defined above.
657*5c591343SA. Cody Schuffelen bool
TpmServer(SOCKET s)658*5c591343SA. Cody Schuffelen TpmServer(
659*5c591343SA. Cody Schuffelen SOCKET s
660*5c591343SA. Cody Schuffelen )
661*5c591343SA. Cody Schuffelen {
662*5c591343SA. Cody Schuffelen uint32_t length;
663*5c591343SA. Cody Schuffelen uint32_t Command;
664*5c591343SA. Cody Schuffelen uint8_t locality;
665*5c591343SA. Cody Schuffelen bool OK;
666*5c591343SA. Cody Schuffelen int result;
667*5c591343SA. Cody Schuffelen int clientVersion;
668*5c591343SA. Cody Schuffelen _IN_BUFFER InBuffer;
669*5c591343SA. Cody Schuffelen _OUT_BUFFER OutBuffer;
670*5c591343SA. Cody Schuffelen //
671*5c591343SA. Cody Schuffelen for(;;)
672*5c591343SA. Cody Schuffelen {
673*5c591343SA. Cody Schuffelen OK = ReadBytes(s, (char*)&Command, 4);
674*5c591343SA. Cody Schuffelen // client disconnected (or other error). We stop processing this client
675*5c591343SA. Cody Schuffelen // and return to our caller who can stop the server or listen for another
676*5c591343SA. Cody Schuffelen // connection.
677*5c591343SA. Cody Schuffelen if(!OK)
678*5c591343SA. Cody Schuffelen return true;
679*5c591343SA. Cody Schuffelen Command = ntohl(Command);
680*5c591343SA. Cody Schuffelen switch(Command)
681*5c591343SA. Cody Schuffelen {
682*5c591343SA. Cody Schuffelen case TPM_SIGNAL_HASH_START:
683*5c591343SA. Cody Schuffelen _rpc__Signal_Hash_Start();
684*5c591343SA. Cody Schuffelen break;
685*5c591343SA. Cody Schuffelen case TPM_SIGNAL_HASH_END:
686*5c591343SA. Cody Schuffelen _rpc__Signal_HashEnd();
687*5c591343SA. Cody Schuffelen break;
688*5c591343SA. Cody Schuffelen case TPM_SIGNAL_HASH_DATA:
689*5c591343SA. Cody Schuffelen OK = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER);
690*5c591343SA. Cody Schuffelen if(!OK) return true;
691*5c591343SA. Cody Schuffelen InBuffer.Buffer = (uint8_t*)InputBuffer;
692*5c591343SA. Cody Schuffelen InBuffer.BufferSize = length;
693*5c591343SA. Cody Schuffelen _rpc__Signal_Hash_Data(InBuffer);
694*5c591343SA. Cody Schuffelen break;
695*5c591343SA. Cody Schuffelen case TPM_SEND_COMMAND:
696*5c591343SA. Cody Schuffelen OK = ReadBytes(s, (char*)&locality, 1);
697*5c591343SA. Cody Schuffelen if(!OK)
698*5c591343SA. Cody Schuffelen return true;
699*5c591343SA. Cody Schuffelen OK = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER);
700*5c591343SA. Cody Schuffelen if(!OK)
701*5c591343SA. Cody Schuffelen return true;
702*5c591343SA. Cody Schuffelen InBuffer.Buffer = (uint8_t*)InputBuffer;
703*5c591343SA. Cody Schuffelen InBuffer.BufferSize = length;
704*5c591343SA. Cody Schuffelen OutBuffer.BufferSize = MAX_BUFFER;
705*5c591343SA. Cody Schuffelen OutBuffer.Buffer = (_OUTPUT_BUFFER)OutputBuffer;
706*5c591343SA. Cody Schuffelen // record the number of bytes in the command if it is the largest
707*5c591343SA. Cody Schuffelen // we have seen so far.
708*5c591343SA. Cody Schuffelen if(InBuffer.BufferSize > CommandResponseSizes.largestCommandSize)
709*5c591343SA. Cody Schuffelen {
710*5c591343SA. Cody Schuffelen CommandResponseSizes.largestCommandSize = InBuffer.BufferSize;
711*5c591343SA. Cody Schuffelen memcpy(&CommandResponseSizes.largestCommand,
712*5c591343SA. Cody Schuffelen &InputBuffer[6], sizeof(uint32_t));
713*5c591343SA. Cody Schuffelen }
714*5c591343SA. Cody Schuffelen _rpc__Send_Command(locality, InBuffer, &OutBuffer);
715*5c591343SA. Cody Schuffelen // record the number of bytes in the response if it is the largest
716*5c591343SA. Cody Schuffelen // we have seen so far.
717*5c591343SA. Cody Schuffelen if(OutBuffer.BufferSize > CommandResponseSizes.largestResponseSize)
718*5c591343SA. Cody Schuffelen {
719*5c591343SA. Cody Schuffelen CommandResponseSizes.largestResponseSize
720*5c591343SA. Cody Schuffelen = OutBuffer.BufferSize;
721*5c591343SA. Cody Schuffelen memcpy(&CommandResponseSizes.largestResponse,
722*5c591343SA. Cody Schuffelen &OutputBuffer[6], sizeof(uint32_t));
723*5c591343SA. Cody Schuffelen }
724*5c591343SA. Cody Schuffelen OK = WriteVarBytes(s,
725*5c591343SA. Cody Schuffelen (char*)OutBuffer.Buffer,
726*5c591343SA. Cody Schuffelen OutBuffer.BufferSize);
727*5c591343SA. Cody Schuffelen if(!OK)
728*5c591343SA. Cody Schuffelen return true;
729*5c591343SA. Cody Schuffelen break;
730*5c591343SA. Cody Schuffelen case TPM_REMOTE_HANDSHAKE:
731*5c591343SA. Cody Schuffelen OK = ReadBytes(s, (char*)&clientVersion, 4);
732*5c591343SA. Cody Schuffelen if(!OK)
733*5c591343SA. Cody Schuffelen return true;
734*5c591343SA. Cody Schuffelen if(clientVersion == 0)
735*5c591343SA. Cody Schuffelen {
736*5c591343SA. Cody Schuffelen printf("Unsupported client version (0).\n");
737*5c591343SA. Cody Schuffelen return true;
738*5c591343SA. Cody Schuffelen }
739*5c591343SA. Cody Schuffelen OK &= WriteUINT32(s, ServerVersion);
740*5c591343SA. Cody Schuffelen OK &= WriteUINT32(s, tpmInRawMode
741*5c591343SA. Cody Schuffelen | tpmPlatformAvailable | tpmSupportsPP);
742*5c591343SA. Cody Schuffelen break;
743*5c591343SA. Cody Schuffelen case TPM_SET_ALTERNATIVE_RESULT:
744*5c591343SA. Cody Schuffelen OK = ReadBytes(s, (char*)&result, 4);
745*5c591343SA. Cody Schuffelen if(!OK)
746*5c591343SA. Cody Schuffelen return true;
747*5c591343SA. Cody Schuffelen // Alternative result is not applicable to the simulator.
748*5c591343SA. Cody Schuffelen break;
749*5c591343SA. Cody Schuffelen case TPM_SESSION_END:
750*5c591343SA. Cody Schuffelen // Client signaled end-of-session
751*5c591343SA. Cody Schuffelen return true;
752*5c591343SA. Cody Schuffelen case TPM_STOP:
753*5c591343SA. Cody Schuffelen // Client requested the simulator to exit
754*5c591343SA. Cody Schuffelen return false;
755*5c591343SA. Cody Schuffelen default:
756*5c591343SA. Cody Schuffelen printf("Unrecognized TPM interface command %d\n", (int)Command);
757*5c591343SA. Cody Schuffelen return true;
758*5c591343SA. Cody Schuffelen }
759*5c591343SA. Cody Schuffelen OK = WriteUINT32(s, 0);
760*5c591343SA. Cody Schuffelen if(!OK)
761*5c591343SA. Cody Schuffelen return true;
762*5c591343SA. Cody Schuffelen }
763*5c591343SA. Cody Schuffelen }
764