15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published
25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library
35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 4: Supporting Routines
45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0"
55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16
65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014
75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include <stdio.h>
95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include <windows.h>
105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include <winsock.h>
115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "string.h"
125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include <stdlib.h>
135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include <stdint.h>
145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "TpmTcpProtocol.h"
155679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL ReadBytes(SOCKET s, char* buffer, int NumBytes);
165679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL ReadVarBytes(SOCKET s, char* buffer, UINT32* BytesReceived, int MaxLen);
175679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL WriteVarBytes(SOCKET s, char *buffer, int BytesToSend);
185679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL WriteBytes(SOCKET s, char* buffer, int NumBytes);
195679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL WriteUINT32(SOCKET s, UINT32 val);
205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifndef __IGNORE_STATE__
215679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32 ServerVersion = 1;
225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#define MAX_BUFFER 1048576
235679752bf24c21135884e987c4077e2f7184897Vadim Bendeburychar InputBuffer[MAX_BUFFER];        //The input data buffer for the simulator.
245679752bf24c21135884e987c4077e2f7184897Vadim Bendeburychar OutputBuffer[MAX_BUFFER];       //The output data buffer for the simulator.
255679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystruct {
265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32      largestCommandSize;
275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32      largestCommand;
285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32      largestResponseSize;
295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32      largestResponse;
305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} CommandResponseSizes = {0};
315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif // __IGNORE_STATE___
325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          Functions
355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          CreateSocket()
375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function creates a socket listening on PortNumber.
395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
405679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic int
415679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCreateSocket(
425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     int                      PortNumber,
435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     SOCKET                  *listenSocket
445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     WSADATA                  wsaData;
475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     struct                   sockaddr_in MyAddress;
485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     int res;
495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Initialize Winsock
505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     res = WSAStartup(MAKEWORD(2,2), &wsaData);
515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     if (res != 0)
525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     {
535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         printf("WSAStartup failed with error: %d\n", res);
545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         return -1;
555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     }
565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // create listening socket
575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     *listenSocket = socket(PF_INET, SOCK_STREAM, 0);
585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(INVALID_SOCKET == *listenSocket)
605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("Cannot create server listen socket.         Error is 0x%x\n",
625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               WSAGetLastError());
635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return -1;
645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // bind the listening socket to the specified port
665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   ZeroMemory(&MyAddress, sizeof(MyAddress));
675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   MyAddress.sin_port=htons((short) PortNumber);
685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   MyAddress.sin_family=AF_INET;
695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res= bind(*listenSocket,(struct sockaddr*) &MyAddress,sizeof(MyAddress));
705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(res==SOCKET_ERROR)
715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("Bind error. Error is 0x%x\n", WSAGetLastError());
735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return -1;
745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   };
755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // listen/wait for server connections
765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res= listen(*listenSocket,3);
775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(res==SOCKET_ERROR)
785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("Listen error. Error is 0x%x\n", WSAGetLastError());
805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return -1;
815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   };
825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return 0;
835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//         PlatformServer()
875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function processes incoming platform requests.
895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
905679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
915679752bf24c21135884e987c4077e2f7184897Vadim BendeburyPlatformServer(
925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET               s
935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                      ok = TRUE;
965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                    length = 0;
975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                    Command;
985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(;;)
995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
1005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       ok = ReadBytes(s, (char*) &Command, 4);
1015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // client disconnected (or other error). We stop processing this client
1025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // and return to our caller who can stop the server or listen for another
1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // connection.
1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(!ok) return TRUE;
1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       Command = ntohl(Command);
1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       switch(Command)
1075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
1085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           case TPM_SIGNAL_POWER_ON:
1095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               _rpc__Signal_PowerOn(FALSE);
1105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               break;
1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             case TPM_SIGNAL_POWER_OFF:
1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 _rpc__Signal_PowerOff();
1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 break;
1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             case TPM_SIGNAL_RESET:
1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 _rpc__Signal_PowerOn(TRUE);
1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 break;
1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SIGNAL_PHYS_PRES_ON:
1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__Signal_PhysicalPresenceOn();
1205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
1215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SIGNAL_PHYS_PRES_OFF:
1225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__Signal_PhysicalPresenceOff();
1235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
1245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SIGNAL_CANCEL_ON:
1255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__Signal_CancelOn();
1265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
1275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SIGNAL_CANCEL_OFF:
1285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__Signal_CancelOff();
1295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
1305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SIGNAL_NV_ON:
1315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__Signal_NvOn();
1325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
1335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SIGNAL_NV_OFF:
1345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__Signal_NvOff();
1355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
1365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SESSION_END:
1375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // Client signaled end-of-session
1385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  return TRUE;
1395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_STOP:
1405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // Client requested the simulator to exit
1415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  return FALSE;
1425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_TEST_FAILURE_MODE:
1435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__ForceFailureMode();
1445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
1455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_GET_COMMAND_RESPONSE_SIZES:
1465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  ok = WriteVarBytes(s, (char *)&CommandResponseSizes,
1475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     sizeof(CommandResponseSizes));
1485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  memset(&CommandResponseSizes, 0, sizeof(CommandResponseSizes));
1495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(!ok)
1505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      return TRUE;
1515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
1525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              default:
1535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  printf("Unrecognized platform interface command %d\n", Command);
1545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  WriteUINT32(s, 1);
1555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  return TRUE;
1565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
1575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          WriteUINT32(s,0);
1585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
1595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return FALSE;
1605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          PlatformSvcRoutine()
1645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is called to set up the socket interfaces to listen for commands.
1665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1675679752bf24c21135884e987c4077e2f7184897Vadim BendeburyDWORD WINAPI
1685679752bf24c21135884e987c4077e2f7184897Vadim BendeburyPlatformSvcRoutine(
1695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    LPVOID               port
1705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
1715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                      PortNumber = (int)(INT_PTR) port;
1745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET                   listenSocket, serverSocket;
1755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   struct                   sockaddr_in HerAddress;
1765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                      res;
1775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                      length;
1785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                     continueServing;
1795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res = CreateSocket(PortNumber, &listenSocket);
1805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(res != 0)
1815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
1825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("Create platform service socket fail\n");
1835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return res;
1845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
1855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Loop accepting connections one-by-one until we are killed or asked to stop
1865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Note the platform service is single-threaded so we don't listen for a new
1875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // connection until the prior connection drops.
1885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   do
1895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
1905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("Platform server listening on port %d\n", PortNumber);
1915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // blocking accept
1925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          length = sizeof(HerAddress);
1935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          serverSocket = accept(listenSocket,
1945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                (struct sockaddr*) &HerAddress,
1955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                &length);
1965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(serverSocket == SOCKET_ERROR)
1975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
1985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              printf("Accept error. Error is 0x%x\n", WSAGetLastError());
1995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              return -1;
2005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          };
2015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          printf("Client accepted\n");
2025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // normal behavior on client disconnection is to wait for a new client
2035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // to connect
2045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          continueServing = PlatformServer(serverSocket);
2055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          closesocket(serverSocket);
2065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
2075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while(continueServing);
2085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return 0;
2095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          PlatformSignalService()
2135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function starts a new thread waiting for platform signals. Platform signals are processed one at a
2155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      time in the order in which they are received.
2165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2175679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyint
2185679752bf24c21135884e987c4077e2f7184897Vadim BendeburyPlatformSignalService(
2195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                 PortNumber
2205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
2215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   HANDLE                   hPlatformSvc;
2235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                      ThreadId;
2245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                      port = PortNumber;
2255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Create service thread for platform signals
2265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   hPlatformSvc = CreateThread(NULL, 0,
2275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                               (LPTHREAD_START_ROUTINE)PlatformSvcRoutine,
2285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                               (LPVOID) (INT_PTR) port, 0, (LPDWORD)&ThreadId);
2295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(hPlatformSvc == NULL)
2305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
2315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("Thread Creation failed\n");
2325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return -1;
2335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
2345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return 0;
2355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          RegularCommandService()
2395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This funciton services regular commands.
2415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2425679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyint
2435679752bf24c21135884e987c4077e2f7184897Vadim BendeburyRegularCommandService(
2445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                 PortNumber
2455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
2465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET                     listenSocket;
2485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET                     serverSocket;
2495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   struct                     sockaddr_in HerAddress;
2505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int res, length;
2515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL continueServing;
2525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res = CreateSocket(PortNumber, &listenSocket);
2535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(res != 0)
2545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
2555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("Create platform service socket fail\n");
2565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return res;
2575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
2585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Loop accepting connections one-by-one until we are killed or asked to stop
2595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Note the TPM command service is single-threaded so we don't listen for
2605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // a new connection until the prior connection drops.
2615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   do
2625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
2635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("TPM command server listening on port %d\n", PortNumber);
2645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // blocking accept
2655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          length = sizeof(HerAddress);
2665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          serverSocket = accept(listenSocket,
2675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                (struct sockaddr*) &HerAddress,
2685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                &length);
2695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(serverSocket ==SOCKET_ERROR)
2705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
2715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              printf("Accept error. Error is 0x%x\n", WSAGetLastError());
2725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              return -1;
2735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          };
2745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          printf("Client accepted\n");
2755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // normal behavior on client disconnection is to wait for a new client
2765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // to connect
2775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          continueServing = TpmServer(serverSocket);
2785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          closesocket(serverSocket);
2795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
2805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while(continueServing);
2815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return 0;
2825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          StartTcpServer()
2865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Main entry-point to the TCP server. The server listens on port specified. Note that there is no way to
2885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      specify the network interface in this implementation.
2895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2905679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyint
2915679752bf24c21135884e987c4077e2f7184897Vadim BendeburyStartTcpServer(
2925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                  PortNumber
2935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
2945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                       res;
2965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Start Platform Signal Processing Service
2975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res = PlatformSignalService(PortNumber+1);
2985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if (res != 0)
2995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("PlatformSignalService failed\n");
3015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return res;
3025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
3035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Start Regular/DRTM TPM command service
3045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res = RegularCommandService(PortNumber);
3055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if (res != 0)
3065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       printf("RegularCommandService failed\n");
3085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return res;
3095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
3105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return 0;
3115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//         ReadBytes()
3155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function reads the indicated number of bytes (NumBytes) into buffer from the indicated socket.
3175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3185679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
3195679752bf24c21135884e987c4077e2f7184897Vadim BendeburyReadBytes(
3205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET               s,
3215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   char                *buffer,
3225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                  NumBytes
3235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
3245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                       res;
3265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                       numGot = 0;
3275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while(numGot<NumBytes)
3285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       res = recv(s, buffer+numGot, NumBytes-numGot, 0);
3305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(res == -1)
3315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
3325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           printf("Receive error. Error is 0x%x\n", WSAGetLastError());
3335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return FALSE;
3345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
3355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(res==0)
3365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
3375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return FALSE;
3385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
3395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       numGot+=res;
3405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
3415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TRUE;
3425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//         WriteBytes()
3465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function will send the indicated number of bytes (NumBytes) to the indicated socket
3485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3495679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
3505679752bf24c21135884e987c4077e2f7184897Vadim BendeburyWriteBytes(
3515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET              s,
3525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   char               *buffer,
3535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                 NumBytes
3545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
3555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                   res;
3575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                   numSent = 0;
3585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while(numSent<NumBytes)
3595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       res = send(s, buffer+numSent, NumBytes-numSent, 0);
3615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(res == -1)
3625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
3635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           if(WSAGetLastError() == 0x2745)
3645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           {
3655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               printf("Client disconnected\n");
3665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           }
3675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           else
3685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           {
3695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               printf("Send error. Error is 0x%x\n", WSAGetLastError());
3705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           }
3715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return FALSE;
3725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
3735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       numSent+=res;
3745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
3755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TRUE;
3765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//         WriteUINT32()
3805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Send 4 bytes containing hton(1)
3825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3835679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
3845679752bf24c21135884e987c4077e2f7184897Vadim BendeburyWriteUINT32(
3855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET              s,
3865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              val
3875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
3885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32 netVal = htonl(val);
3905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return WriteBytes(s, (char*) &netVal, 4);
3915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       ReadVarBytes()
3955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Get a UINT32-length-prepended binary array. Note that the 4-byte length is in network byte order (big-
3975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      endian).
3985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3995679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
4005679752bf24c21135884e987c4077e2f7184897Vadim BendeburyReadVarBytes(
4015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET              s,
4025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   char               *buffer,
4035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32             *BytesReceived,
4045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                 MaxLen
4055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
4065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                       length;
4085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                      res;
4095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res = ReadBytes(s, (char*) &length, 4);
4105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(!res) return res;
4115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   length = ntohl(length);
4125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   *BytesReceived = length;
4135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(length>MaxLen)
4145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
4155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        printf("Buffer too big.       Client says %d\n", length);
4165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        return FALSE;
4175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
4185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(length==0) return TRUE;
4195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res = ReadBytes(s, buffer, length);
4205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(!res) return res;
4215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TRUE;
4225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       WriteVarBytes()
4265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Send a UINT32-length-prepended binary array. Note that the 4-byte length is in network byte order (big-
4285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      endian).
4295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4305679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
4315679752bf24c21135884e987c4077e2f7184897Vadim BendeburyWriteVarBytes(
4325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET              s,
4335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   char               *buffer,
4345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                 BytesToSend
4355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
4365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                   netLength = htonl(BytesToSend);
4385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL res;
4395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res = WriteBytes(s, (char*) &netLength, 4);
4405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(!res) return res;
4415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   res = WriteBytes(s, buffer, BytesToSend);
4425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(!res) return res;
4435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TRUE;
4445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TpmServer()
4485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Processing incoming TPM command requests using the protocol / interface defined above.
4505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4515679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
4525679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTpmServer(
4535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SOCKET              s
4545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
4555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                   length;
4575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                   Command;
4585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                     locality;
4595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                     ok;
4605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                      result;
4615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   int                      clientVersion;
4625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _IN_BUFFER               InBuffer;
4635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _OUT_BUFFER              OutBuffer;
4645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(;;)
4655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
4665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       ok = ReadBytes(s, (char*) &Command, 4);
4675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // client disconnected (or other error). We stop processing this client
4685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // and return to our caller who can stop the server or listen for another
4695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // connection.
4705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(!ok)
4715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TRUE;
4725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       Command = ntohl(Command);
4735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       switch(Command)
4745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
4755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           case TPM_SIGNAL_HASH_START:
4765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               _rpc__Signal_Hash_Start();
4775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               break;
4785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SIGNAL_HASH_END:
4795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__Signal_HashEnd();
4805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
4815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SIGNAL_HASH_DATA:
4825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  ok = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER);
4835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(!ok) return TRUE;
4845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  InBuffer.Buffer = (BYTE*) InputBuffer;
4855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  InBuffer.BufferSize = length;
4865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__Signal_Hash_Data(InBuffer);
4875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
4885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SEND_COMMAND:
4895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  ok = ReadBytes(s, (char*) &locality, 1);
4905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(!ok)
4915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      return TRUE;
4925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  ok = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER);
4935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(!ok)
4945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      return TRUE;
4955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  InBuffer.Buffer = (BYTE*) InputBuffer;
4965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  InBuffer.BufferSize = length;
4975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  OutBuffer.BufferSize = MAX_BUFFER;
4985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  OutBuffer.Buffer = (_OUTPUT_BUFFER) OutputBuffer;
4995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // record the number of bytes in the command if it is the largest
5005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // we have seen so far.
5015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(InBuffer.BufferSize > CommandResponseSizes.largestCommandSize)
5025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  {
5035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      CommandResponseSizes.largestCommandSize = InBuffer.BufferSize;
5045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      memcpy(&CommandResponseSizes.largestCommand,
5055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             &InputBuffer[6], sizeof(UINT32));
5065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  }
5075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  _rpc__Send_Command(locality, InBuffer, &OutBuffer);
5085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // record the number of bytes in the response if it is the largest
5095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // we have seen so far.
5105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(OutBuffer.BufferSize > CommandResponseSizes.largestResponseSize)
5115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  {
5125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      CommandResponseSizes.largestResponseSize
5135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          = OutBuffer.BufferSize;
5145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      memcpy(&CommandResponseSizes.largestResponse,
5155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             &OutputBuffer[6], sizeof(UINT32));
5165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  }
5175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  ok = WriteVarBytes(s,
5185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     (char*) OutBuffer.Buffer,
5195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     OutBuffer.BufferSize);
5205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(!ok)
5215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      return TRUE;
5225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
5235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_REMOTE_HANDSHAKE:
5245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  ok = ReadBytes(s, (char*)&clientVersion, 4);
5255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(!ok)
5265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      return TRUE;
5275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if( clientVersion == 0 )
5285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  {
5295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      printf("Unsupported client version (0).\n");
5305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      return TRUE;
5315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  }
5325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  ok &= WriteUINT32(s, ServerVersion);
5335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  ok &= WriteUINT32(s,
5345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                 tpmInRawMode | tpmPlatformAvailable | tpmSupportsPP);
5355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
5365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              case TPM_SET_ALTERNATIVE_RESULT:
5375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  ok = ReadBytes(s, (char*)&result, 4);
5385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(!ok)
5395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      return TRUE;
5405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // Alternative result is not applicable to the simulator.
5415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  break;
5425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             case TPM_SESSION_END:
5435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 // Client signaled end-of-session
5445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 return TRUE;
5455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             case TPM_STOP:
5465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 // Client requested the simulator to exit
5475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 return FALSE;
5485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             default:
5495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 printf("Unrecognized TPM interface command %d\n", Command);
5505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 return TRUE;
5515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
5525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        ok = WriteUINT32(s,0);
5535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(!ok)
5545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            return TRUE;
5555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
5565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return FALSE;
5575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
558