/src/ibmswtpm2/src/TPMCmdp.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************************/ |
2 | | /* */ |
3 | | /* Process the commands */ |
4 | | /* Written by Ken Goldman */ |
5 | | /* IBM Thomas J. Watson Research Center */ |
6 | | /* $Id: TPMCmdp.c 1262 2018-07-11 21:03:43Z kgoldman $ */ |
7 | | /* */ |
8 | | /* Licenses and Notices */ |
9 | | /* */ |
10 | | /* 1. Copyright Licenses: */ |
11 | | /* */ |
12 | | /* - Trusted Computing Group (TCG) grants to the user of the source code in */ |
13 | | /* this specification (the "Source Code") a worldwide, irrevocable, */ |
14 | | /* nonexclusive, royalty free, copyright license to reproduce, create */ |
15 | | /* derivative works, distribute, display and perform the Source Code and */ |
16 | | /* derivative works thereof, and to grant others the rights granted herein. */ |
17 | | /* */ |
18 | | /* - The TCG grants to the user of the other parts of the specification */ |
19 | | /* (other than the Source Code) the rights to reproduce, distribute, */ |
20 | | /* display, and perform the specification solely for the purpose of */ |
21 | | /* developing products based on such documents. */ |
22 | | /* */ |
23 | | /* 2. Source Code Distribution Conditions: */ |
24 | | /* */ |
25 | | /* - Redistributions of Source Code must retain the above copyright licenses, */ |
26 | | /* this list of conditions and the following disclaimers. */ |
27 | | /* */ |
28 | | /* - Redistributions in binary form must reproduce the above copyright */ |
29 | | /* licenses, this list of conditions and the following disclaimers in the */ |
30 | | /* documentation and/or other materials provided with the distribution. */ |
31 | | /* */ |
32 | | /* 3. Disclaimers: */ |
33 | | /* */ |
34 | | /* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ |
35 | | /* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ |
36 | | /* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ |
37 | | /* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ |
38 | | /* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ |
39 | | /* information on specification licensing rights available through TCG */ |
40 | | /* membership agreements. */ |
41 | | /* */ |
42 | | /* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ |
43 | | /* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ |
44 | | /* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ |
45 | | /* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ |
46 | | /* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ |
47 | | /* */ |
48 | | /* - Without limitation, TCG and its members and licensors disclaim all */ |
49 | | /* liability, including liability for infringement of any proprietary */ |
50 | | /* rights, relating to use of information in this specification and to the */ |
51 | | /* implementation of this specification, and TCG disclaims all liability for */ |
52 | | /* cost of procurement of substitute goods or services, lost profits, loss */ |
53 | | /* of use, loss of data or any incidental, consequential, direct, indirect, */ |
54 | | /* or special damages, whether under contract, tort, warranty or otherwise, */ |
55 | | /* arising in any way out of use or reliance upon this specification or any */ |
56 | | /* information herein. */ |
57 | | /* */ |
58 | | /* (c) Copyright IBM Corp. and others, 2016 - 2018 */ |
59 | | /* */ |
60 | | /********************************************************************************/ |
61 | | |
62 | | /* D.5 TPMCmdp.c */ |
63 | | /* D.5.1. Description */ |
64 | | /* This file contains the functions that process the commands received on the control port or the |
65 | | command port of the simulator. The control port is used to allow simulation of hardware events |
66 | | (such as, _TPM_Hash_Start()) to test the simulated TPM's reaction to those events. This improves |
67 | | code coverage of the testing. */ |
68 | | /* D.5.2. Includes and Data Definitions */ |
69 | | #include <stdlib.h> |
70 | | #include <stdio.h> |
71 | | #include <setjmp.h> |
72 | | #include "Implementation.h" |
73 | | #include "TpmBuildSwitches.h" |
74 | | #ifdef TPM_WINDOWS |
75 | | #include <windows.h> |
76 | | #include <winsock.h> |
77 | | #endif |
78 | | #include "Platform_fp.h" |
79 | | #include "ExecCommand_fp.h" |
80 | | #include "Manufacture_fp.h" |
81 | | #include "_TPM_Init_fp.h" |
82 | | #include "_TPM_Hash_Start_fp.h" |
83 | | #include "_TPM_Hash_Data_fp.h" |
84 | | #include "_TPM_Hash_End_fp.h" |
85 | | #include "TpmFail_fp.h" |
86 | | #include "TpmTcpProtocol.h" |
87 | | #include "Simulator_fp.h" |
88 | | #ifdef TPM_WINDOWS |
89 | | #include "TcpServer_fp.h" |
90 | | #endif |
91 | | #ifdef TPM_POSIX |
92 | | #include "TcpServerPosix_fp.h" |
93 | | #endif |
94 | | |
95 | | static BOOL s_isPowerOn = FALSE; |
96 | | /* D.5.3. Functions */ |
97 | | /* D.5.3.1. Signal_PowerOn() */ |
98 | | /* This function processes a power-on indication. Among other things, it calls the _TPM_Init() |
99 | | handler. */ |
100 | | void |
101 | | _rpc__Signal_PowerOn( |
102 | | BOOL isReset |
103 | | ) |
104 | 656 | { |
105 | | // if power is on and this is not a call to do TPM reset then return |
106 | 656 | if(s_isPowerOn && !isReset) |
107 | 655 | return; |
108 | | // If this is a reset but power is not on, then return |
109 | 1 | if(isReset && !s_isPowerOn) |
110 | 0 | return; |
111 | | // Unless this is just a reset, pass power on signal to platform |
112 | 1 | if(!isReset) |
113 | 1 | _plat__Signal_PowerOn(); |
114 | | // Power on and reset both lead to _TPM_Init() |
115 | 1 | _plat__Signal_Reset(); |
116 | | // Set state as power on |
117 | 1 | s_isPowerOn = TRUE; |
118 | 1 | } |
119 | | /* D.5.3.2. Signal_Restart() */ |
120 | | /* This function processes the clock restart indication. All it does is call the platform |
121 | | function. */ |
122 | | void |
123 | | _rpc__Signal_Restart( |
124 | | void |
125 | | ) |
126 | 0 | { |
127 | 0 | _plat__TimerRestart(); |
128 | 0 | } |
129 | | /* D.5.3.3. Signal_PowerOff() */ |
130 | | /* This function processes the power off indication. Its primary function is to set a flag |
131 | | indicating that the next power on indication should cause _TPM_Init() to be called. */ |
132 | | void |
133 | | _rpc__Signal_PowerOff( |
134 | | void |
135 | | ) |
136 | 0 | { |
137 | 0 | if(!s_isPowerOn) return; |
138 | | // Pass power off signal to platform |
139 | 0 | _plat__Signal_PowerOff(); |
140 | 0 | s_isPowerOn = FALSE; |
141 | 0 | return; |
142 | 0 | } |
143 | | /* D.5.3.4. _rpc__ForceFailureMode() */ |
144 | | /* This function is used to debug the Failure Mode logic of the TPM. It will set a flag in the TPM |
145 | | code such that the next call to TPM2_SelfTest() will result in a failure, putting the TPM into |
146 | | Failure Mode. */ |
147 | | void |
148 | | _rpc__ForceFailureMode( |
149 | | void |
150 | | ) |
151 | 0 | { |
152 | 0 | SetForceFailureMode(); |
153 | 0 | } |
154 | | /* D.5.3.5. _rpc__Signal_PhysicalPresenceOn() */ |
155 | | /* This function is called to simulate activation of the physical presence pin. */ |
156 | | void |
157 | | _rpc__Signal_PhysicalPresenceOn( |
158 | | void |
159 | | ) |
160 | 0 | { |
161 | | // If TPM is power off, reject this signal |
162 | 0 | if(!s_isPowerOn) return; |
163 | | // Pass physical presence on to platform |
164 | 0 | _plat__Signal_PhysicalPresenceOn(); |
165 | 0 | return; |
166 | 0 | } |
167 | | /* D.5.3.6. _rpc__Signal_PhysicalPresenceOff() */ |
168 | | /* This function is called to simulate deactivation of the physical presence pin. */ |
169 | | void |
170 | | _rpc__Signal_PhysicalPresenceOff( |
171 | | void |
172 | | ) |
173 | 0 | { |
174 | | // If TPM is power off, reject this signal |
175 | 0 | if(!s_isPowerOn) return; |
176 | | // Pass physical presence off to platform |
177 | 0 | _plat__Signal_PhysicalPresenceOff(); |
178 | 0 | return; |
179 | 0 | } |
180 | | /* D.5.3.7. _rpc__Signal_Hash_Start() */ |
181 | | /* This function is called to simulate a _TPM_Hash_Start() event. It will call */ |
182 | | void |
183 | | _rpc__Signal_Hash_Start( |
184 | | void |
185 | | ) |
186 | 4.03k | { |
187 | | // If TPM is power off, reject this signal |
188 | 4.03k | if(!s_isPowerOn) return; |
189 | | // Pass _TPM_Hash_Start signal to TPM |
190 | 4.03k | _TPM_Hash_Start(); |
191 | 4.03k | return; |
192 | 4.03k | } |
193 | | /* D.5.3.8. _rpc__Signal_Hash_Data() */ |
194 | | /* This function is called to simulate a _TPM_Hash_Data() event. */ |
195 | | void |
196 | | _rpc__Signal_Hash_Data( |
197 | | _IN_BUFFER input |
198 | | ) |
199 | 687 | { |
200 | | // If TPM is power off, reject this signal |
201 | 687 | if(!s_isPowerOn) return; |
202 | | // Pass _TPM_Hash_Data signal to TPM |
203 | 687 | _TPM_Hash_Data(input.BufferSize, input.Buffer); |
204 | 687 | return; |
205 | 687 | } |
206 | | /* D.5.3.9. _rpc__Signal_HashEnd() */ |
207 | | /* This function is called to simulate a _TPM_Hash_End() event. */ |
208 | | void |
209 | | _rpc__Signal_HashEnd( |
210 | | void |
211 | | ) |
212 | 3.25k | { |
213 | | // If TPM is power off, reject this signal |
214 | 3.25k | if(!s_isPowerOn) return; |
215 | | // Pass _TPM_HashEnd signal to TPM |
216 | 3.25k | _TPM_Hash_End(); |
217 | 3.25k | return; |
218 | 3.25k | } |
219 | | /* D.5.3.10. rpc_Send_Command() */ |
220 | | /* This is the interface to the TPM code. */ |
221 | | void |
222 | | _rpc__Send_Command( |
223 | | unsigned char locality, |
224 | | _IN_BUFFER request, |
225 | | _OUT_BUFFER *response |
226 | | ) |
227 | 9.66k | { |
228 | | // If TPM is power off, reject any commands. |
229 | 9.66k | if(!s_isPowerOn) |
230 | 0 | { |
231 | 0 | response->BufferSize = 0; |
232 | 0 | return; |
233 | 0 | } |
234 | | // Set the locality of the command so that it doesn't change during the command |
235 | 9.66k | _plat__LocalitySet(locality); |
236 | | // Do implementation-specific command dispatch |
237 | 9.66k | _plat__RunCommand(request.BufferSize, request.Buffer, |
238 | 9.66k | &response->BufferSize, &response->Buffer); |
239 | 9.66k | return; |
240 | 9.66k | } |
241 | | /* D.5.3.10. _rpc__Signal_CancelOn() */ |
242 | | /* This function is used to turn on the indication to cancel a command in process. An executing |
243 | | command is not interrupted. The command code may periodically check this indication to see if it |
244 | | should abort the current command processing and returned TPM_RC_CANCELLED. */ |
245 | | void |
246 | | _rpc__Signal_CancelOn( |
247 | | void |
248 | | ) |
249 | 0 | { |
250 | | // If TPM is power off, reject this signal |
251 | 0 | if(!s_isPowerOn) return; |
252 | | // Set the platform canceling flag. |
253 | 0 | _plat__SetCancel(); |
254 | 0 | return; |
255 | 0 | } |
256 | | /* D.5.3.11. _rpc__Signal_CancelOff() */ |
257 | | /* This function is used to turn off the indication to cancel a command in process. */ |
258 | | void |
259 | | _rpc__Signal_CancelOff( |
260 | | void |
261 | | ) |
262 | 0 | { |
263 | | // If TPM is power off, reject this signal |
264 | 0 | if(!s_isPowerOn) return; |
265 | | // Set the platform canceling flag. |
266 | 0 | _plat__ClearCancel(); |
267 | 0 | return; |
268 | 0 | } |
269 | | /* D.5.3.12. _rpc__Signal_NvOn() */ |
270 | | /* In a system where the NV memory used by the TPM is not within the TPM, the NV may not always be |
271 | | available. This function turns on the indicator that indicates that NV is available. */ |
272 | | void |
273 | | _rpc__Signal_NvOn( |
274 | | void |
275 | | ) |
276 | 656 | { |
277 | | // If TPM is power off, reject this signal |
278 | 656 | if(!s_isPowerOn) return; |
279 | 656 | _plat__SetNvAvail(); |
280 | 656 | return; |
281 | 656 | } |
282 | | /* D.5.3.13. _rpc__Signal_NvOff() */ |
283 | | /* This function is used to set the indication that NV memory is no longer available. */ |
284 | | void |
285 | | _rpc__Signal_NvOff( |
286 | | void |
287 | | ) |
288 | 0 | { |
289 | | // If TPM is power off, reject this signal |
290 | 0 | if(!s_isPowerOn) return; |
291 | 0 | _plat__ClearNvAvail(); |
292 | 0 | return; |
293 | 0 | } |
294 | | void RsaKeyCacheControl(int state); |
295 | | /* D.5.3.14. _rpc__RsaKeyCacheControl() */ |
296 | | /* This function is used to enable/disable the use of the RSA key cache during simulation. */ |
297 | | void |
298 | | _rpc__RsaKeyCacheControl( |
299 | | int state |
300 | | ) |
301 | 0 | { |
302 | | #if USE_RSA_KEY_CACHE |
303 | | RsaKeyCacheControl(state); |
304 | | #else |
305 | 0 | NOT_REFERENCED(state); |
306 | 0 | #endif |
307 | 0 | } |
308 | | /* D.5.3.15. _rpc__Shutdown() */ |
309 | | /* This function is used to stop the TPM simulator. */ |
310 | | void |
311 | | _rpc__Shutdown( |
312 | | void |
313 | | ) |
314 | 0 | { |
315 | | #if 0 /* kgold bypass for now */ |
316 | | RPC_STATUS status; |
317 | | // Stop TPM |
318 | | TPM_TearDown(); |
319 | | status = RpcMgmtStopServerListening(NULL); |
320 | | if(status != RPC_S_OK) |
321 | | { |
322 | | printf("RpcMgmtStopServerListening returned: 0x%x\n", status); |
323 | | exit(status); |
324 | | } |
325 | | status = RpcServerUnregisterIf(NULL, NULL, FALSE); |
326 | | if(status != RPC_S_OK) |
327 | | { |
328 | | printf("RpcServerUnregisterIf returned 0x%x\n", status); |
329 | | exit(status); |
330 | | } |
331 | | #endif |
332 | 0 | return; |
333 | 0 | } |