]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
Add TPM2 implementation.
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Hierarchy.c
CommitLineData
c1d93242
JY
1/** @file\r
2 Implement TPM2 Hierarchy related command.\r
3\r
4Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <IndustryStandard/UefiTcgPlatform.h>\r
16#include <Library/Tpm2CommandLib.h>\r
17#include <Library/Tpm2DeviceLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/DebugLib.h>\r
21\r
22#pragma pack(1)\r
23\r
24typedef struct {\r
25 TPM2_COMMAND_HEADER Header;\r
26 TPMI_RH_CLEAR AuthHandle;\r
27 UINT32 AuthorizationSize;\r
28 TPMS_AUTH_COMMAND AuthSession;\r
29} TPM2_CLEAR_COMMAND;\r
30\r
31typedef struct {\r
32 TPM2_RESPONSE_HEADER Header;\r
33 UINT32 ParameterSize;\r
34 TPMS_AUTH_RESPONSE AuthSession;\r
35} TPM2_CLEAR_RESPONSE;\r
36\r
37typedef struct {\r
38 TPM2_COMMAND_HEADER Header;\r
39 TPMI_RH_CLEAR AuthHandle;\r
40 UINT32 AuthorizationSize;\r
41 TPMS_AUTH_COMMAND AuthSession;\r
42 TPMI_YES_NO Disable;\r
43} TPM2_CLEAR_CONTROL_COMMAND;\r
44\r
45typedef struct {\r
46 TPM2_RESPONSE_HEADER Header;\r
47 UINT32 ParameterSize;\r
48 TPMS_AUTH_RESPONSE AuthSession;\r
49} TPM2_CLEAR_CONTROL_RESPONSE;\r
50\r
51typedef struct {\r
52 TPM2_COMMAND_HEADER Header;\r
53 TPMI_RH_HIERARCHY_AUTH AuthHandle;\r
54 UINT32 AuthorizationSize;\r
55 TPMS_AUTH_COMMAND AuthSession;\r
56 TPM2B_AUTH NewAuth;\r
57} TPM2_HIERARCHY_CHANGE_AUTH_COMMAND;\r
58\r
59typedef struct {\r
60 TPM2_RESPONSE_HEADER Header;\r
61 UINT32 ParameterSize;\r
62 TPMS_AUTH_RESPONSE AuthSession;\r
63} TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE;\r
64\r
65typedef struct {\r
66 TPM2_COMMAND_HEADER Header;\r
67 TPMI_RH_PLATFORM AuthHandle;\r
68 UINT32 AuthorizationSize;\r
69 TPMS_AUTH_COMMAND AuthSession;\r
70} TPM2_CHANGE_EPS_COMMAND;\r
71\r
72typedef struct {\r
73 TPM2_RESPONSE_HEADER Header;\r
74 UINT32 ParameterSize;\r
75 TPMS_AUTH_RESPONSE AuthSession;\r
76} TPM2_CHANGE_EPS_RESPONSE;\r
77\r
78typedef struct {\r
79 TPM2_COMMAND_HEADER Header;\r
80 TPMI_RH_PLATFORM AuthHandle;\r
81 UINT32 AuthorizationSize;\r
82 TPMS_AUTH_COMMAND AuthSession;\r
83} TPM2_CHANGE_PPS_COMMAND;\r
84\r
85typedef struct {\r
86 TPM2_RESPONSE_HEADER Header;\r
87 UINT32 ParameterSize;\r
88 TPMS_AUTH_RESPONSE AuthSession;\r
89} TPM2_CHANGE_PPS_RESPONSE;\r
90\r
91typedef struct {\r
92 TPM2_COMMAND_HEADER Header;\r
93 TPMI_RH_HIERARCHY AuthHandle;\r
94 UINT32 AuthorizationSize;\r
95 TPMS_AUTH_COMMAND AuthSession;\r
96 TPMI_RH_HIERARCHY Hierarchy;\r
97 TPMI_YES_NO State;\r
98} TPM2_HIERARCHY_CONTROL_COMMAND;\r
99\r
100typedef struct {\r
101 TPM2_RESPONSE_HEADER Header;\r
102 UINT32 ParameterSize;\r
103 TPMS_AUTH_RESPONSE AuthSession;\r
104} TPM2_HIERARCHY_CONTROL_RESPONSE;\r
105\r
106#pragma pack()\r
107\r
108/**\r
109 This command removes all TPM context associated with a specific Owner.\r
110\r
111 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}\r
112 @param[in] AuthSession Auth Session context\r
113 \r
114 @retval EFI_SUCCESS Operation completed successfully.\r
115 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
116**/\r
117EFI_STATUS\r
118EFIAPI\r
119Tpm2Clear (\r
120 IN TPMI_RH_CLEAR AuthHandle,\r
121 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL\r
122 )\r
123{\r
124 EFI_STATUS Status;\r
125 TPM2_CLEAR_COMMAND Cmd;\r
126 TPM2_CLEAR_RESPONSE Res;\r
127 UINT32 ResultBufSize;\r
128 UINT32 CmdSize;\r
129 UINT32 RespSize;\r
130 UINT8 *Buffer;\r
131 UINT32 SessionInfoSize;\r
132\r
133 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
134 Cmd.Header.commandCode = SwapBytes32(TPM_CC_Clear);\r
135 Cmd.AuthHandle = SwapBytes32(AuthHandle);\r
136\r
137 //\r
138 // Add in Auth session\r
139 //\r
140 Buffer = (UINT8 *)&Cmd.AuthSession;\r
141\r
142 // sessionInfoSize\r
143 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
144 Buffer += SessionInfoSize;\r
145 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
146\r
147 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
148 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
149\r
150 ResultBufSize = sizeof(Res);\r
151 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
152 if (EFI_ERROR(Status)) {\r
153 return Status;\r
154 }\r
155\r
156 if (ResultBufSize > sizeof(Res)) {\r
157 DEBUG ((EFI_D_ERROR, "Clear: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
158 return EFI_BUFFER_TOO_SMALL;\r
159 }\r
160\r
161 //\r
162 // Validate response headers\r
163 //\r
164 RespSize = SwapBytes32(Res.Header.paramSize);\r
165 if (RespSize > sizeof(Res)) {\r
166 DEBUG ((EFI_D_ERROR, "Clear: Response size too large! %d\r\n", RespSize));\r
167 return EFI_BUFFER_TOO_SMALL;\r
168 }\r
169\r
170 //\r
171 // Fail if command failed\r
172 //\r
173 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
174 DEBUG ((EFI_D_ERROR, "Clear: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
175 return EFI_DEVICE_ERROR;\r
176 }\r
177\r
178 //\r
179 // Unmarshal the response\r
180 //\r
181\r
182 // None\r
183\r
184 return EFI_SUCCESS;\r
185}\r
186\r
187/**\r
188 Disables and enables the execution of TPM2_Clear().\r
189\r
190 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}\r
191 @param[in] AuthSession Auth Session context\r
192 @param[in] Disable YES if the disableOwnerClear flag is to be SET,\r
193 NO if the flag is to be CLEAR.\r
194\r
195 @retval EFI_SUCCESS Operation completed successfully.\r
196 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
197**/\r
198EFI_STATUS\r
199EFIAPI\r
200Tpm2ClearControl (\r
201 IN TPMI_RH_CLEAR AuthHandle,\r
202 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL\r
203 IN TPMI_YES_NO Disable\r
204 )\r
205{\r
206 EFI_STATUS Status;\r
207 TPM2_CLEAR_CONTROL_COMMAND Cmd;\r
208 TPM2_CLEAR_CONTROL_RESPONSE Res;\r
209 UINT32 ResultBufSize;\r
210 UINT32 CmdSize;\r
211 UINT32 RespSize;\r
212 UINT8 *Buffer;\r
213 UINT32 SessionInfoSize;\r
214\r
215 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
216 Cmd.Header.commandCode = SwapBytes32(TPM_CC_ClearControl);\r
217 Cmd.AuthHandle = SwapBytes32(AuthHandle);\r
218\r
219 //\r
220 // Add in Auth session\r
221 //\r
222 Buffer = (UINT8 *)&Cmd.AuthSession;\r
223\r
224 // sessionInfoSize\r
225 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
226 Buffer += SessionInfoSize;\r
227 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
228\r
229 // disable\r
230 *(UINT8 *)Buffer = Disable;\r
231 Buffer += sizeof(UINT8);\r
232\r
233 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
234 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
235\r
236 ResultBufSize = sizeof(Res);\r
237 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
238 if (EFI_ERROR(Status)) {\r
239 return Status;\r
240 }\r
241\r
242 if (ResultBufSize > sizeof(Res)) {\r
243 DEBUG ((EFI_D_ERROR, "ClearControl: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
244 return EFI_BUFFER_TOO_SMALL;\r
245 }\r
246\r
247 //\r
248 // Validate response headers\r
249 //\r
250 RespSize = SwapBytes32(Res.Header.paramSize);\r
251 if (RespSize > sizeof(Res)) {\r
252 DEBUG ((EFI_D_ERROR, "ClearControl: Response size too large! %d\r\n", RespSize));\r
253 return EFI_BUFFER_TOO_SMALL;\r
254 }\r
255\r
256 //\r
257 // Fail if command failed\r
258 //\r
259 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
260 DEBUG ((EFI_D_ERROR, "ClearControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
261 return EFI_DEVICE_ERROR;\r
262 }\r
263\r
264 //\r
265 // Unmarshal the response\r
266 //\r
267\r
268 // None\r
269\r
270 return EFI_SUCCESS;\r
271}\r
272\r
273/**\r
274 This command allows the authorization secret for a hierarchy or lockout to be changed using the current\r
275 authorization value as the command authorization.\r
276\r
277 @param[in] AuthHandle TPM_RH_LOCKOUT, TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}\r
278 @param[in] AuthSession Auth Session context\r
279 @param[in] NewAuth New authorization secret\r
280\r
281 @retval EFI_SUCCESS Operation completed successfully.\r
282 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
283**/\r
284EFI_STATUS\r
285EFIAPI\r
286Tpm2HierarchyChangeAuth (\r
287 IN TPMI_RH_HIERARCHY_AUTH AuthHandle,\r
288 IN TPMS_AUTH_COMMAND *AuthSession,\r
289 IN TPM2B_AUTH *NewAuth\r
290 )\r
291{\r
292 EFI_STATUS Status;\r
293 TPM2_HIERARCHY_CHANGE_AUTH_COMMAND Cmd;\r
294 TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE Res;\r
295 UINT32 CmdSize;\r
296 UINT32 RespSize;\r
297 UINT8 *Buffer;\r
298 UINT32 SessionInfoSize;\r
299 UINT8 *ResultBuf;\r
300 UINT32 ResultBufSize;\r
301\r
302 //\r
303 // Construct command\r
304 //\r
305 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
306 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));\r
307 Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyChangeAuth);\r
308 Cmd.AuthHandle = SwapBytes32(AuthHandle);\r
309\r
310 //\r
311 // Add in Auth session\r
312 //\r
313 Buffer = (UINT8 *)&Cmd.AuthSession;\r
314\r
315 // sessionInfoSize\r
316 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
317 Buffer += SessionInfoSize;\r
318 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
319\r
320 // New Authorization size\r
321 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NewAuth->size));\r
322 Buffer += sizeof(UINT16);\r
323\r
324 // New Authorizeation\r
325 CopyMem(Buffer, NewAuth->buffer, NewAuth->size);\r
326 Buffer += NewAuth->size;\r
327\r
328 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
329 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
330\r
331 ResultBuf = (UINT8 *) &Res;\r
332 ResultBufSize = sizeof(Res);\r
333\r
334 //\r
335 // Call the TPM\r
336 //\r
337 Status = Tpm2SubmitCommand (\r
338 CmdSize, \r
339 (UINT8 *)&Cmd, \r
340 &ResultBufSize,\r
341 ResultBuf\r
342 );\r
343\r
344 if (ResultBufSize > sizeof(Res)) {\r
345 DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
346 return EFI_BUFFER_TOO_SMALL;\r
347 }\r
348\r
349 //\r
350 // Validate response headers\r
351 //\r
352 RespSize = SwapBytes32(Res.Header.paramSize);\r
353 if (RespSize > sizeof(Res)) {\r
354 DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Response size too large! %d\r\n", RespSize));\r
355 return EFI_BUFFER_TOO_SMALL;\r
356 }\r
357\r
358 //\r
359 // Fail if command failed\r
360 //\r
361 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
362 DEBUG((EFI_D_ERROR,"HierarchyChangeAuth: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
363 return EFI_DEVICE_ERROR;\r
364 }\r
365\r
366 return EFI_SUCCESS;\r
367}\r
368\r
369/**\r
370 This replaces the current EPS with a value from the RNG and sets the Endorsement hierarchy controls to\r
371 their default initialization values.\r
372\r
373 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}\r
374 @param[in] AuthSession Auth Session context\r
375\r
376 @retval EFI_SUCCESS Operation completed successfully.\r
377 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
378**/\r
379EFI_STATUS\r
380EFIAPI\r
381Tpm2ChangeEPS (\r
382 IN TPMI_RH_PLATFORM AuthHandle,\r
383 IN TPMS_AUTH_COMMAND *AuthSession\r
384 )\r
385{\r
386 EFI_STATUS Status;\r
387 TPM2_CHANGE_EPS_COMMAND Cmd;\r
388 TPM2_CHANGE_EPS_RESPONSE Res;\r
389 UINT32 CmdSize;\r
390 UINT32 RespSize;\r
391 UINT8 *Buffer;\r
392 UINT32 SessionInfoSize;\r
393 UINT8 *ResultBuf;\r
394 UINT32 ResultBufSize;\r
395\r
396 //\r
397 // Construct command\r
398 //\r
399 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
400 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));\r
401 Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangeEPS);\r
402 Cmd.AuthHandle = SwapBytes32(AuthHandle);\r
403\r
404 //\r
405 // Add in Auth session\r
406 //\r
407 Buffer = (UINT8 *)&Cmd.AuthSession;\r
408\r
409 // sessionInfoSize\r
410 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
411 Buffer += SessionInfoSize;\r
412 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
413\r
414 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
415 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
416\r
417 ResultBuf = (UINT8 *) &Res;\r
418 ResultBufSize = sizeof(Res);\r
419\r
420 //\r
421 // Call the TPM\r
422 //\r
423 Status = Tpm2SubmitCommand (\r
424 CmdSize, \r
425 (UINT8 *)&Cmd, \r
426 &ResultBufSize,\r
427 ResultBuf\r
428 );\r
429\r
430 if (ResultBufSize > sizeof(Res)) {\r
431 DEBUG ((EFI_D_ERROR, "ChangeEPS: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
432 return EFI_BUFFER_TOO_SMALL;\r
433 }\r
434\r
435 //\r
436 // Validate response headers\r
437 //\r
438 RespSize = SwapBytes32(Res.Header.paramSize);\r
439 if (RespSize > sizeof(Res)) {\r
440 DEBUG ((EFI_D_ERROR, "ChangeEPS: Response size too large! %d\r\n", RespSize));\r
441 return EFI_BUFFER_TOO_SMALL;\r
442 }\r
443\r
444 //\r
445 // Fail if command failed\r
446 //\r
447 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
448 DEBUG((EFI_D_ERROR,"ChangeEPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
449 return EFI_DEVICE_ERROR;\r
450 }\r
451\r
452 return EFI_SUCCESS;\r
453}\r
454\r
455/**\r
456 This replaces the current PPS with a value from the RNG and sets platformPolicy to the default\r
457 initialization value (the Empty Buffer).\r
458\r
459 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}\r
460 @param[in] AuthSession Auth Session context\r
461\r
462 @retval EFI_SUCCESS Operation completed successfully.\r
463 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
464**/\r
465EFI_STATUS\r
466EFIAPI\r
467Tpm2ChangePPS (\r
468 IN TPMI_RH_PLATFORM AuthHandle,\r
469 IN TPMS_AUTH_COMMAND *AuthSession\r
470 )\r
471{\r
472 EFI_STATUS Status;\r
473 TPM2_CHANGE_PPS_COMMAND Cmd;\r
474 TPM2_CHANGE_PPS_RESPONSE Res;\r
475 UINT32 CmdSize;\r
476 UINT32 RespSize;\r
477 UINT8 *Buffer;\r
478 UINT32 SessionInfoSize;\r
479 UINT8 *ResultBuf;\r
480 UINT32 ResultBufSize;\r
481\r
482 //\r
483 // Construct command\r
484 //\r
485 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
486 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));\r
487 Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangePPS);\r
488 Cmd.AuthHandle = SwapBytes32(AuthHandle);\r
489\r
490 //\r
491 // Add in Auth session\r
492 //\r
493 Buffer = (UINT8 *)&Cmd.AuthSession;\r
494\r
495 // sessionInfoSize\r
496 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
497 Buffer += SessionInfoSize;\r
498 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
499\r
500 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
501 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
502\r
503 ResultBuf = (UINT8 *) &Res;\r
504 ResultBufSize = sizeof(Res);\r
505\r
506 //\r
507 // Call the TPM\r
508 //\r
509 Status = Tpm2SubmitCommand (\r
510 CmdSize, \r
511 (UINT8 *)&Cmd, \r
512 &ResultBufSize,\r
513 ResultBuf\r
514 );\r
515\r
516 if (ResultBufSize > sizeof(Res)) {\r
517 DEBUG ((EFI_D_ERROR, "ChangePPS: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
518 return EFI_BUFFER_TOO_SMALL;\r
519 }\r
520\r
521 //\r
522 // Validate response headers\r
523 //\r
524 RespSize = SwapBytes32(Res.Header.paramSize);\r
525 if (RespSize > sizeof(Res)) {\r
526 DEBUG ((EFI_D_ERROR, "ChangePPS: Response size too large! %d\r\n", RespSize));\r
527 return EFI_BUFFER_TOO_SMALL;\r
528 }\r
529\r
530 //\r
531 // Fail if command failed\r
532 //\r
533 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
534 DEBUG((EFI_D_ERROR,"ChangePPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
535 return EFI_DEVICE_ERROR;\r
536 }\r
537\r
538 return EFI_SUCCESS;\r
539}\r
540\r
541/**\r
542 This command enables and disables use of a hierarchy.\r
543\r
544 @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}\r
545 @param[in] AuthSession Auth Session context\r
546 @param[in] Hierarchy Hierarchy of the enable being modified\r
547 @param[in] State YES if the enable should be SET,\r
548 NO if the enable should be CLEAR\r
549\r
550 @retval EFI_SUCCESS Operation completed successfully.\r
551 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
552**/\r
553EFI_STATUS\r
554EFIAPI\r
555Tpm2HierarchyControl (\r
556 IN TPMI_RH_HIERARCHY AuthHandle,\r
557 IN TPMS_AUTH_COMMAND *AuthSession,\r
558 IN TPMI_RH_HIERARCHY Hierarchy,\r
559 IN TPMI_YES_NO State\r
560 )\r
561{\r
562 EFI_STATUS Status;\r
563 TPM2_HIERARCHY_CONTROL_COMMAND Cmd;\r
564 TPM2_HIERARCHY_CONTROL_RESPONSE Res;\r
565 UINT32 CmdSize;\r
566 UINT32 RespSize;\r
567 UINT8 *Buffer;\r
568 UINT32 SessionInfoSize;\r
569 UINT8 *ResultBuf;\r
570 UINT32 ResultBufSize;\r
571\r
572 //\r
573 // Construct command\r
574 //\r
575 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
576 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));\r
577 Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyControl);\r
578 Cmd.AuthHandle = SwapBytes32(AuthHandle);\r
579\r
580 //\r
581 // Add in Auth session\r
582 //\r
583 Buffer = (UINT8 *)&Cmd.AuthSession;\r
584\r
585 // sessionInfoSize\r
586 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
587 Buffer += SessionInfoSize;\r
588 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
589\r
590 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Hierarchy));\r
591 Buffer += sizeof(UINT32);\r
592\r
593 *(UINT8 *)Buffer = State;\r
594 Buffer += sizeof(UINT8);\r
595\r
596 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
597 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
598\r
599 ResultBuf = (UINT8 *) &Res;\r
600 ResultBufSize = sizeof(Res);\r
601\r
602 //\r
603 // Call the TPM\r
604 //\r
605 Status = Tpm2SubmitCommand (\r
606 CmdSize, \r
607 (UINT8 *)&Cmd, \r
608 &ResultBufSize,\r
609 ResultBuf\r
610 );\r
611\r
612 if (ResultBufSize > sizeof(Res)) {\r
613 DEBUG ((EFI_D_ERROR, "HierarchyControl: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
614 return EFI_BUFFER_TOO_SMALL;\r
615 }\r
616\r
617 //\r
618 // Validate response headers\r
619 //\r
620 RespSize = SwapBytes32(Res.Header.paramSize);\r
621 if (RespSize > sizeof(Res)) {\r
622 DEBUG ((EFI_D_ERROR, "HierarchyControl: Response size too large! %d\r\n", RespSize));\r
623 return EFI_BUFFER_TOO_SMALL;\r
624 }\r
625\r
626 //\r
627 // Fail if command failed\r
628 //\r
629 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
630 DEBUG((EFI_D_ERROR,"HierarchyControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
631 return EFI_DEVICE_ERROR;\r
632 }\r
633\r
634 return EFI_SUCCESS;\r
635}\r