• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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