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