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"
21 static 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 //
30 void
_rpc__Signal_PowerOn(BOOL isReset)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 //
58 void
_rpc__Signal_PowerOff(void)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 //
76 void
_rpc__ForceFailureMode(void)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 //
89 void
_rpc__Signal_PhysicalPresenceOn(void)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 //
106 void
_rpc__Signal_PhysicalPresenceOff(void)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 //
123 void
_rpc__Signal_Hash_Start(void)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 //
140 void
_rpc__Signal_Hash_Data(_IN_BUFFER input)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 //
157 void
_rpc__Signal_HashEnd(void)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
170 void
_rpc__Send_Command(unsigned char locality,_IN_BUFFER request,_OUT_BUFFER * response)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 //
197 void
_rpc__Signal_CancelOn(void)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 //
214 void
_rpc__Signal_CancelOff(void)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 //
233 void
_rpc__Signal_NvOn(void)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 //
249 void
_rpc__Signal_NvOff(void)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 //
265 void
_rpc__Shutdown(void)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