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