1// This file was extracted from the TCG Published
2// Trusted Platform Module Library
3// Part 4: Supporting Routines
4// Family "2.0"
5// Level 00 Revision 01.16
6// October 30, 2014
7
8#define _SWAP_H         // Preclude inclusion of unnecessary simulator header
9#include <stdlib.h>
10#include <stdio.h>
11#include <stdint.h>
12#include "bool.h"
13#include "Platform.h"
14#include "ExecCommand_fp.h"
15#include "Manufacture_fp.h"
16#include "DRTM_fp.h"
17#include "_TPM_Init_fp.h"
18#include "TpmFail_fp.h"
19#include <windows.h>
20#include "TpmTcpProtocol.h"
21static BOOL     s_isPowerOn = FALSE;
22//
23//
24//          Functions
25//
26//          Signal_PowerOn()
27//
28//     This function processes a power-on indicataion. Amoung other things, it calls the _TPM_Init() hangler.
29//
30void
31_rpc__Signal_PowerOn(
32     BOOL          isReset
33     )
34{
35     // if power is on and this is not a call to do TPM reset then return
36     if(s_isPowerOn && !isReset)
37         return;
38     // If this is a reset but power is not on, then return
39     if(isReset && !s_isPowerOn)
40         return;
41     // Pass power on signal to platform
42     if(isReset)
43         _plat__Signal_Reset();
44     else
45         _plat__Signal_PowerOn();
46     // Pass power on signal to TPM
47     _TPM_Init();
48     // Set state as power on
49     s_isPowerOn = TRUE;
50}
51//
52//
53//         Signal_PowerOff()
54//
55//     This function processes the power off indication. Its primary funtion is to set a flag indicating that the next
56//     power on indication should cause _TPM_Init() to be called.
57//
58void
59_rpc__Signal_PowerOff(
60    void
61    )
62{
63    if(!s_isPowerOn) return;
64    // Pass power off signal to platform
65    _plat__Signal_PowerOff();
66    s_isPowerOn = FALSE;
67    return;
68}
69//
70//
71//         _rpc__ForceFailureMode()
72//
73//     This function is used to debug the Failure Mode logic of the TPM. It will set a flag in the TPM code such
74//     that the next call to TPM2_SelfTest() will result in a failure, putting the TPM into Failure Mode.
75//
76void
77_rpc__ForceFailureMode(
78    void
79    )
80{
81    SetForceFailureMode();
82}
83//
84//
85//         _rpc__Signal_PhysicalPresenceOn()
86//
87//     This function is called to simulate activation of the physical presence pin.
88//
89void
90_rpc__Signal_PhysicalPresenceOn(
91    void
92    )
93{
94    // If TPM is power off, reject this signal
95    if(!s_isPowerOn) return;
96    // Pass physical presence on to platform
97    _plat__Signal_PhysicalPresenceOn();
98    return;
99}
100//
101//
102//         _rpc__Signal_PhysicalPresenceOff()
103//
104//     This function is called to simulate deactivation of the physical presence pin.
105//
106void
107_rpc__Signal_PhysicalPresenceOff(
108    void
109    )
110{
111    // If TPM is power off, reject this signal
112    if(!s_isPowerOn) return;
113    // Pass physical presence off to platform
114    _plat__Signal_PhysicalPresenceOff();
115    return;
116}
117//
118//
119//          _rpc__Signal_Hash_Start()
120//
121//      This function is called to simulate a _TPM_Hash_Start() event. It will call
122//
123void
124_rpc__Signal_Hash_Start(
125    void
126    )
127{
128    // If TPM is power off, reject this signal
129    if(!s_isPowerOn) return;
130    // Pass _TPM_Hash_Start signal to TPM
131    Signal_Hash_Start();
132    return;
133}
134//
135//
136//          _rpc__Signal_Hash_Data()
137//
138//      This function is called to simulate a _TPM_Hash_Data() event.
139//
140void
141_rpc__Signal_Hash_Data(
142    _IN_BUFFER           input
143    )
144{
145    // If TPM is power off, reject this signal
146    if(!s_isPowerOn) return;
147    // Pass _TPM_Hash_Data signal to TPM
148    Signal_Hash_Data(input.BufferSize, input.Buffer);
149    return;
150}
151//
152//
153//          _rpc__Signal_HashEnd()
154//
155//      This function is called to simulate a _TPM_Hash_End() event.
156//
157void
158_rpc__Signal_HashEnd(
159    void
160    )
161{
162    // If TPM is power off, reject this signal
163    if(!s_isPowerOn) return;
164    // Pass _TPM_HashEnd signal to TPM
165    Signal_Hash_End();
166    return;
167}
168//
169//      Command interface Entry of a RPC call
170void
171_rpc__Send_Command(
172   unsigned char        locality,
173   _IN_BUFFER           request,
174   _OUT_BUFFER         *response
175   )
176{
177   // If TPM is power off, reject any commands.
178   if(!s_isPowerOn) {
179       response->BufferSize = 0;
180       return;
181   }
182   // Set the locality of the command so that it doesn't change during the command
183   _plat__LocalitySet(locality);
184   // Do implementation-specific command dispatch
185   ExecuteCommand(request.BufferSize, request.Buffer,
186                          &response->BufferSize, &response->Buffer);
187   return;
188}
189//
190//
191//         _rpc__Signal_CancelOn()
192//
193//      This function is used to turn on the indication to cancel a command in process. An executing command is
194//      not interrupted. The command code may perodically check this indication to see if it should abort the
195//      current command processing and returned TPM_RC_CANCELLED.
196//
197void
198_rpc__Signal_CancelOn(
199   void
200   )
201{
202   // If TPM is power off, reject this signal
203   if(!s_isPowerOn) return;
204   // Set the platform canceling flag.
205   _plat__SetCancel();
206   return;
207}
208//
209//
210//       _rpc__Signal_CancelOff()
211//
212//      This function is used to turn off the indication to cancel a command in process.
213//
214void
215_rpc__Signal_CancelOff(
216   void
217   )
218{
219   // If TPM is power off, reject this signal
220   if(!s_isPowerOn) return;
221   // Set the platform canceling flag.
222   _plat__ClearCancel();
223   return;
224}
225//
226//
227//
228//       _rpc__Signal_NvOn()
229//
230//      In a system where the NV memory used by the TPM is not within the TPM, the NV may not always be
231//      available. This function turns on the indicator that indicates that NV is available.
232//
233void
234_rpc__Signal_NvOn(
235   void
236   )
237{
238   // If TPM is power off, reject this signal
239   if(!s_isPowerOn) return;
240   _plat__SetNvAvail();
241   return;
242}
243//
244//
245//       _rpc__Signal_NvOff()
246//
247//      This function is used to set the indication that NV memory is no longer available.
248//
249void
250_rpc__Signal_NvOff(
251   void
252   )
253{
254   // If TPM is power off, reject this signal
255   if(!s_isPowerOn) return;
256   _plat__ClearNvAvail();
257   return;
258}
259//
260//
261//       _rpc__Shutdown()
262//
263//      This function is used to stop the TPM simulator.
264//
265void
266_rpc__Shutdown(
267   void
268   )
269{
270   RPC_STATUS status;
271   // Stop TPM
272   TPM_TearDown();
273   status = RpcMgmtStopServerListening(NULL);
274   if (status != RPC_S_OK)
275   {
276       printf_s("RpcMgmtStopServerListening returned: 0x%x\n", status);
277       exit(status);
278   }
279   status = RpcServerUnregisterIf(NULL, NULL, FALSE);
280   if (status != RPC_S_OK)
281   {
282       printf_s("RpcServerUnregisterIf returned 0x%x\n", status);
283       exit(status);
284   }
285}
286