1 /* Microsoft Reference Implementation for TPM 2.0
2 *
3 * The copyright in this software is being made available under the BSD License,
4 * included below. This software may be subject to other third party and
5 * contributor rights, including patent rights, and no such rights are granted
6 * under this license.
7 *
8 * Copyright (c) Microsoft Corporation
9 *
10 * All rights reserved.
11 *
12 * BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this list
18 * of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice, this
21 * list of conditions and the following disclaimer in the documentation and/or
22 * other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 //** Description
36 // This file contains the functions that process the commands received on the
37 // control port or the command port of the simulator. The control port is used
38 // to allow simulation of hardware events (such as, _TPM_Hash_Start) to test
39 // the simulated TPM's reaction to those events. This improves code coverage
40 // of the testing.
41
42 //** Includes and Data Definitions
43 #include <stdbool.h>
44 #include "TpmBuildSwitches.h"
45
46 #ifdef _MSC_VER
47 # pragma warning(push, 3)
48 # include <windows.h>
49 # include <winsock.h>
50 # pragma warning(pop)
51 #elif defined(__unix__)
52 # include "BaseTypes.h" // on behalf of TpmFail_fp.h
53 typedef int SOCKET;
54 #else
55 # error "Unsupported platform."
56 #endif
57
58 #include "Platform_fp.h"
59 #include "ExecCommand_fp.h"
60 #include "Manufacture_fp.h"
61 #include "_TPM_Init_fp.h"
62 #include "_TPM_Hash_Start_fp.h"
63 #include "_TPM_Hash_Data_fp.h"
64 #include "_TPM_Hash_End_fp.h"
65 #include "TpmFail_fp.h"
66
67 #include "TpmTcpProtocol.h"
68 #include "Simulator_fp.h"
69
70 static bool s_isPowerOn = false;
71
72 //** Functions
73
74 //*** Signal_PowerOn()
75 // This function processes a power-on indication. Among other things, it
76 // calls the _TPM_Init() handler.
77 void
_rpc__Signal_PowerOn(bool isReset)78 _rpc__Signal_PowerOn(
79 bool isReset
80 )
81 {
82 // if power is on and this is not a call to do TPM reset then return
83 if(s_isPowerOn && !isReset)
84 return;
85 // If this is a reset but power is not on, then return
86 if(isReset && !s_isPowerOn)
87 return;
88 // Unless this is just a reset, pass power on signal to platform
89 if(!isReset)
90 _plat__Signal_PowerOn();
91 // Power on and reset both lead to _TPM_Init()
92 _plat__Signal_Reset();
93
94 // Set state as power on
95 s_isPowerOn = true;
96 }
97
98 //*** Signal_Restart()
99 // This function processes the clock restart indication. All it does is call
100 // the platform function.
101 void
_rpc__Signal_Restart(void)102 _rpc__Signal_Restart(
103 void
104 )
105 {
106 _plat__TimerRestart();
107 }
108
109 //***Signal_PowerOff()
110 // This function processes the power off indication. Its primary function is
111 // to set a flag indicating that the next power on indication should cause
112 // _TPM_Init() to be called.
113 void
_rpc__Signal_PowerOff(void)114 _rpc__Signal_PowerOff(
115 void
116 )
117 {
118 if(s_isPowerOn)
119 // Pass power off signal to platform
120 _plat__Signal_PowerOff();
121 // This could be redundant, but...
122 s_isPowerOn = false;
123
124 return;
125 }
126
127 //*** _rpc__ForceFailureMode()
128 // This function is used to debug the Failure Mode logic of the TPM. It will set
129 // a flag in the TPM code such that the next call to TPM2_SelfTest() will result
130 // in a failure, putting the TPM into Failure Mode.
131 void
_rpc__ForceFailureMode(void)132 _rpc__ForceFailureMode(
133 void
134 )
135 {
136 SetForceFailureMode();
137 return;
138 }
139
140 //*** _rpc__Signal_PhysicalPresenceOn()
141 // This function is called to simulate activation of the physical presence "pin".
142 void
_rpc__Signal_PhysicalPresenceOn(void)143 _rpc__Signal_PhysicalPresenceOn(
144 void
145 )
146 {
147 // If TPM power is on...
148 if(s_isPowerOn)
149 // ... pass physical presence on to platform
150 _plat__Signal_PhysicalPresenceOn();
151 return;
152 }
153
154 //*** _rpc__Signal_PhysicalPresenceOff()
155 // This function is called to simulate deactivation of the physical presence "pin".
156 void
_rpc__Signal_PhysicalPresenceOff(void)157 _rpc__Signal_PhysicalPresenceOff(
158 void
159 )
160 {
161 // If TPM is power on...
162 if(s_isPowerOn)
163 // ... pass physical presence off to platform
164 _plat__Signal_PhysicalPresenceOff();
165 return;
166 }
167
168 //*** _rpc__Signal_Hash_Start()
169 // This function is called to simulate a _TPM_Hash_Start event. It will call
170 //
171 void
_rpc__Signal_Hash_Start(void)172 _rpc__Signal_Hash_Start(
173 void
174 )
175 {
176 // If TPM power is on...
177 if(s_isPowerOn)
178 // ... pass _TPM_Hash_Start signal to TPM
179 _TPM_Hash_Start();
180 return;
181 }
182
183 //*** _rpc__Signal_Hash_Data()
184 // This function is called to simulate a _TPM_Hash_Data event.
185 void
_rpc__Signal_Hash_Data(_IN_BUFFER input)186 _rpc__Signal_Hash_Data(
187 _IN_BUFFER input
188 )
189 {
190 // If TPM power is on...
191 if(s_isPowerOn)
192 // ... pass _TPM_Hash_Data signal to TPM
193 _TPM_Hash_Data(input.BufferSize, input.Buffer);
194 return;
195 }
196
197 //*** _rpc__Signal_HashEnd()
198 // This function is called to simulate a _TPM_Hash_End event.
199 void
_rpc__Signal_HashEnd(void)200 _rpc__Signal_HashEnd(
201 void
202 )
203 {
204 // If TPM power is on...
205 if(s_isPowerOn)
206 // ... pass _TPM_HashEnd signal to TPM
207 _TPM_Hash_End();
208 return;
209 }
210
211 //*** _rpc__Send_Command()
212 // This is the interface to the TPM code.
213 // Return Type: void
214 void
_rpc__Send_Command(unsigned char locality,_IN_BUFFER request,_OUT_BUFFER * response)215 _rpc__Send_Command(
216 unsigned char locality,
217 _IN_BUFFER request,
218 _OUT_BUFFER *response
219 )
220 {
221 // If TPM is power off, reject any commands.
222 if(!s_isPowerOn)
223 {
224 response->BufferSize = 0;
225 return;
226 }
227 // Set the locality of the command so that it doesn't change during the command
228 _plat__LocalitySet(locality);
229 // Do implementation-specific command dispatch
230 _plat__RunCommand(request.BufferSize, request.Buffer,
231 &response->BufferSize, &response->Buffer);
232 return;
233 }
234
235 //*** _rpc__Signal_CancelOn()
236 // This function is used to turn on the indication to cancel a command in process.
237 // An executing command is not interrupted. The command code may periodically check
238 // this indication to see if it should abort the current command processing and
239 // returned TPM_RC_CANCELLED.
240 void
_rpc__Signal_CancelOn(void)241 _rpc__Signal_CancelOn(
242 void
243 )
244 {
245 // If TPM power is on...
246 if(s_isPowerOn)
247 // ... set the platform canceling flag.
248 _plat__SetCancel();
249 return;
250 }
251
252 //*** _rpc__Signal_CancelOff()
253 // This function is used to turn off the indication to cancel a command in process.
254 void
_rpc__Signal_CancelOff(void)255 _rpc__Signal_CancelOff(
256 void
257 )
258 {
259 // If TPM power is on...
260 if(s_isPowerOn)
261 // ... set the platform canceling flag.
262 _plat__ClearCancel();
263 return;
264 }
265
266 //*** _rpc__Signal_NvOn()
267 // In a system where the NV memory used by the TPM is not within the TPM, the
268 // NV may not always be available. This function turns on the indicator that
269 // indicates that NV is available.
270 void
_rpc__Signal_NvOn(void)271 _rpc__Signal_NvOn(
272 void
273 )
274 {
275 // If TPM power is on...
276 if(s_isPowerOn)
277 // ... make the NV available
278 _plat__SetNvAvail();
279 return;
280 }
281
282 //*** _rpc__Signal_NvOff()
283 // This function is used to set the indication that NV memory is no
284 // longer available.
285 void
_rpc__Signal_NvOff(void)286 _rpc__Signal_NvOff(
287 void
288 )
289 {
290 // If TPM power is on...
291 if(s_isPowerOn)
292 // ... make NV not available
293 _plat__ClearNvAvail();
294 return;
295 }
296
297 void RsaKeyCacheControl(int state);
298
299 //*** _rpc__RsaKeyCacheControl()
300 // This function is used to enable/disable the use of the RSA key cache during
301 // simulation.
302 void
_rpc__RsaKeyCacheControl(int state)303 _rpc__RsaKeyCacheControl(
304 int state
305 )
306 {
307 #if USE_RSA_KEY_CACHE
308 RsaKeyCacheControl(state);
309 #else
310 NOT_REFERENCED(state);
311 #endif
312 return;
313 }
314
315 #define TPM_RH_ACT_0 0x40000110
316
317 //*** _rpc__ACT_GetSignaled()
318 // This function is used to count the ACT second tick.
319 bool
_rpc__ACT_GetSignaled(uint32_t actHandle)320 _rpc__ACT_GetSignaled(
321 uint32_t actHandle
322 )
323 {
324 // If TPM power is on...
325 if (s_isPowerOn)
326 // ... query the platform
327 return _plat__ACT_GetSignaled(actHandle - TPM_RH_ACT_0);
328 return false;
329 }
330
331