]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
SecurityPkg: Apply uncrustify changes
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Hierarchy.c
1 /** @file
2 Implement TPM2 Hierarchy related command.
3
4 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <IndustryStandard/UefiTcgPlatform.h>
10 #include <Library/Tpm2CommandLib.h>
11 #include <Library/Tpm2DeviceLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/BaseLib.h>
14 #include <Library/DebugLib.h>
15
16 #pragma pack(1)
17
18 typedef struct {
19 TPM2_COMMAND_HEADER Header;
20 TPMI_RH_HIERARCHY_AUTH AuthHandle;
21 UINT32 AuthSessionSize;
22 TPMS_AUTH_COMMAND AuthSession;
23 TPM2B_DIGEST AuthPolicy;
24 TPMI_ALG_HASH HashAlg;
25 } TPM2_SET_PRIMARY_POLICY_COMMAND;
26
27 typedef struct {
28 TPM2_RESPONSE_HEADER Header;
29 UINT32 AuthSessionSize;
30 TPMS_AUTH_RESPONSE AuthSession;
31 } TPM2_SET_PRIMARY_POLICY_RESPONSE;
32
33 typedef struct {
34 TPM2_COMMAND_HEADER Header;
35 TPMI_RH_CLEAR AuthHandle;
36 UINT32 AuthorizationSize;
37 TPMS_AUTH_COMMAND AuthSession;
38 } TPM2_CLEAR_COMMAND;
39
40 typedef struct {
41 TPM2_RESPONSE_HEADER Header;
42 UINT32 ParameterSize;
43 TPMS_AUTH_RESPONSE AuthSession;
44 } TPM2_CLEAR_RESPONSE;
45
46 typedef struct {
47 TPM2_COMMAND_HEADER Header;
48 TPMI_RH_CLEAR AuthHandle;
49 UINT32 AuthorizationSize;
50 TPMS_AUTH_COMMAND AuthSession;
51 TPMI_YES_NO Disable;
52 } TPM2_CLEAR_CONTROL_COMMAND;
53
54 typedef struct {
55 TPM2_RESPONSE_HEADER Header;
56 UINT32 ParameterSize;
57 TPMS_AUTH_RESPONSE AuthSession;
58 } TPM2_CLEAR_CONTROL_RESPONSE;
59
60 typedef struct {
61 TPM2_COMMAND_HEADER Header;
62 TPMI_RH_HIERARCHY_AUTH AuthHandle;
63 UINT32 AuthorizationSize;
64 TPMS_AUTH_COMMAND AuthSession;
65 TPM2B_AUTH NewAuth;
66 } TPM2_HIERARCHY_CHANGE_AUTH_COMMAND;
67
68 typedef struct {
69 TPM2_RESPONSE_HEADER Header;
70 UINT32 ParameterSize;
71 TPMS_AUTH_RESPONSE AuthSession;
72 } TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE;
73
74 typedef struct {
75 TPM2_COMMAND_HEADER Header;
76 TPMI_RH_PLATFORM AuthHandle;
77 UINT32 AuthorizationSize;
78 TPMS_AUTH_COMMAND AuthSession;
79 } TPM2_CHANGE_EPS_COMMAND;
80
81 typedef struct {
82 TPM2_RESPONSE_HEADER Header;
83 UINT32 ParameterSize;
84 TPMS_AUTH_RESPONSE AuthSession;
85 } TPM2_CHANGE_EPS_RESPONSE;
86
87 typedef struct {
88 TPM2_COMMAND_HEADER Header;
89 TPMI_RH_PLATFORM AuthHandle;
90 UINT32 AuthorizationSize;
91 TPMS_AUTH_COMMAND AuthSession;
92 } TPM2_CHANGE_PPS_COMMAND;
93
94 typedef struct {
95 TPM2_RESPONSE_HEADER Header;
96 UINT32 ParameterSize;
97 TPMS_AUTH_RESPONSE AuthSession;
98 } TPM2_CHANGE_PPS_RESPONSE;
99
100 typedef struct {
101 TPM2_COMMAND_HEADER Header;
102 TPMI_RH_HIERARCHY AuthHandle;
103 UINT32 AuthorizationSize;
104 TPMS_AUTH_COMMAND AuthSession;
105 TPMI_RH_HIERARCHY Hierarchy;
106 TPMI_YES_NO State;
107 } TPM2_HIERARCHY_CONTROL_COMMAND;
108
109 typedef struct {
110 TPM2_RESPONSE_HEADER Header;
111 UINT32 ParameterSize;
112 TPMS_AUTH_RESPONSE AuthSession;
113 } TPM2_HIERARCHY_CONTROL_RESPONSE;
114
115 #pragma pack()
116
117 /**
118 This command allows setting of the authorization policy for the platform hierarchy (platformPolicy), the
119 storage hierarchy (ownerPolicy), and and the endorsement hierarchy (endorsementPolicy).
120
121 @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} parameters to be validated
122 @param[in] AuthSession Auth Session context
123 @param[in] AuthPolicy An authorization policy hash
124 @param[in] HashAlg The hash algorithm to use for the policy
125
126 @retval EFI_SUCCESS Operation completed successfully.
127 @retval EFI_DEVICE_ERROR Unexpected device behavior.
128 **/
129 EFI_STATUS
130 EFIAPI
131 Tpm2SetPrimaryPolicy (
132 IN TPMI_RH_HIERARCHY_AUTH AuthHandle,
133 IN TPMS_AUTH_COMMAND *AuthSession,
134 IN TPM2B_DIGEST *AuthPolicy,
135 IN TPMI_ALG_HASH HashAlg
136 )
137 {
138 EFI_STATUS Status;
139 TPM2_SET_PRIMARY_POLICY_COMMAND SendBuffer;
140 TPM2_SET_PRIMARY_POLICY_RESPONSE RecvBuffer;
141 UINT32 SendBufferSize;
142 UINT32 RecvBufferSize;
143 UINT8 *Buffer;
144 UINT32 SessionInfoSize;
145
146 //
147 // Construct command
148 //
149 SendBuffer.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
150 SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_SetPrimaryPolicy);
151
152 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
153
154 //
155 // Add in Auth session
156 //
157 Buffer = (UINT8 *)&SendBuffer.AuthSession;
158
159 // sessionInfoSize
160 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
161 Buffer += SessionInfoSize;
162 SendBuffer.AuthSessionSize = SwapBytes32 (SessionInfoSize);
163
164 //
165 // Real data
166 //
167 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthPolicy->size));
168 Buffer += sizeof (UINT16);
169 CopyMem (Buffer, AuthPolicy->buffer, AuthPolicy->size);
170 Buffer += AuthPolicy->size;
171 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (HashAlg));
172 Buffer += sizeof (UINT16);
173
174 SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
175 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
176
177 //
178 // send Tpm command
179 //
180 RecvBufferSize = sizeof (RecvBuffer);
181 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
182 if (EFI_ERROR (Status)) {
183 goto Done;
184 }
185
186 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
187 DEBUG ((DEBUG_ERROR, "Tpm2SetPrimaryPolicy - RecvBufferSize Error - %x\n", RecvBufferSize));
188 Status = EFI_DEVICE_ERROR;
189 goto Done;
190 }
191
192 if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
193 DEBUG ((DEBUG_ERROR, "Tpm2SetPrimaryPolicy - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));
194 Status = EFI_DEVICE_ERROR;
195 goto Done;
196 }
197
198 Done:
199 //
200 // Clear AuthSession Content
201 //
202 ZeroMem (&SendBuffer, sizeof (SendBuffer));
203 ZeroMem (&RecvBuffer, sizeof (RecvBuffer));
204 return Status;
205 }
206
207 /**
208 This command removes all TPM context associated with a specific Owner.
209
210 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
211 @param[in] AuthSession Auth Session context
212
213 @retval EFI_SUCCESS Operation completed successfully.
214 @retval EFI_DEVICE_ERROR Unexpected device behavior.
215 **/
216 EFI_STATUS
217 EFIAPI
218 Tpm2Clear (
219 IN TPMI_RH_CLEAR AuthHandle,
220 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
221 )
222 {
223 EFI_STATUS Status;
224 TPM2_CLEAR_COMMAND Cmd;
225 TPM2_CLEAR_RESPONSE Res;
226 UINT32 ResultBufSize;
227 UINT32 CmdSize;
228 UINT32 RespSize;
229 UINT8 *Buffer;
230 UINT32 SessionInfoSize;
231
232 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
233 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_Clear);
234 Cmd.AuthHandle = SwapBytes32 (AuthHandle);
235
236 //
237 // Add in Auth session
238 //
239 Buffer = (UINT8 *)&Cmd.AuthSession;
240
241 // sessionInfoSize
242 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
243 Buffer += SessionInfoSize;
244 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
245
246 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
247 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
248
249 ResultBufSize = sizeof (Res);
250 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
251 if (EFI_ERROR (Status)) {
252 goto Done;
253 }
254
255 if (ResultBufSize > sizeof (Res)) {
256 DEBUG ((DEBUG_ERROR, "Clear: Failed ExecuteCommand: Buffer Too Small\r\n"));
257 Status = EFI_BUFFER_TOO_SMALL;
258 goto Done;
259 }
260
261 //
262 // Validate response headers
263 //
264 RespSize = SwapBytes32 (Res.Header.paramSize);
265 if (RespSize > sizeof (Res)) {
266 DEBUG ((DEBUG_ERROR, "Clear: Response size too large! %d\r\n", RespSize));
267 Status = EFI_BUFFER_TOO_SMALL;
268 goto Done;
269 }
270
271 //
272 // Fail if command failed
273 //
274 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
275 DEBUG ((DEBUG_ERROR, "Clear: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
276 Status = EFI_DEVICE_ERROR;
277 goto Done;
278 }
279
280 //
281 // Unmarshal the response
282 //
283
284 // None
285 Done:
286 //
287 // Clear AuthSession Content
288 //
289 ZeroMem (&Cmd, sizeof (Cmd));
290 ZeroMem (&Res, sizeof (Res));
291 return Status;
292 }
293
294 /**
295 Disables and enables the execution of TPM2_Clear().
296
297 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
298 @param[in] AuthSession Auth Session context
299 @param[in] Disable YES if the disableOwnerClear flag is to be SET,
300 NO if the flag is to be CLEAR.
301
302 @retval EFI_SUCCESS Operation completed successfully.
303 @retval EFI_DEVICE_ERROR Unexpected device behavior.
304 **/
305 EFI_STATUS
306 EFIAPI
307 Tpm2ClearControl (
308 IN TPMI_RH_CLEAR AuthHandle,
309 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL,
310 IN TPMI_YES_NO Disable
311 )
312 {
313 EFI_STATUS Status;
314 TPM2_CLEAR_CONTROL_COMMAND Cmd;
315 TPM2_CLEAR_CONTROL_RESPONSE Res;
316 UINT32 ResultBufSize;
317 UINT32 CmdSize;
318 UINT32 RespSize;
319 UINT8 *Buffer;
320 UINT32 SessionInfoSize;
321
322 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
323 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_ClearControl);
324 Cmd.AuthHandle = SwapBytes32 (AuthHandle);
325
326 //
327 // Add in Auth session
328 //
329 Buffer = (UINT8 *)&Cmd.AuthSession;
330
331 // sessionInfoSize
332 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
333 Buffer += SessionInfoSize;
334 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
335
336 // disable
337 *(UINT8 *)Buffer = Disable;
338 Buffer++;
339
340 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
341 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
342
343 ResultBufSize = sizeof (Res);
344 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
345 if (EFI_ERROR (Status)) {
346 goto Done;
347 }
348
349 if (ResultBufSize > sizeof (Res)) {
350 DEBUG ((DEBUG_ERROR, "ClearControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
351 Status = EFI_BUFFER_TOO_SMALL;
352 goto Done;
353 }
354
355 //
356 // Validate response headers
357 //
358 RespSize = SwapBytes32 (Res.Header.paramSize);
359 if (RespSize > sizeof (Res)) {
360 DEBUG ((DEBUG_ERROR, "ClearControl: Response size too large! %d\r\n", RespSize));
361 Status = EFI_BUFFER_TOO_SMALL;
362 goto Done;
363 }
364
365 //
366 // Fail if command failed
367 //
368 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
369 DEBUG ((DEBUG_ERROR, "ClearControl: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
370 Status = EFI_DEVICE_ERROR;
371 goto Done;
372 }
373
374 //
375 // Unmarshal the response
376 //
377
378 // None
379 Done:
380 //
381 // Clear AuthSession Content
382 //
383 ZeroMem (&Cmd, sizeof (Cmd));
384 ZeroMem (&Res, sizeof (Res));
385 return Status;
386 }
387
388 /**
389 This command allows the authorization secret for a hierarchy or lockout to be changed using the current
390 authorization value as the command authorization.
391
392 @param[in] AuthHandle TPM_RH_LOCKOUT, TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
393 @param[in] AuthSession Auth Session context
394 @param[in] NewAuth New authorization secret
395
396 @retval EFI_SUCCESS Operation completed successfully.
397 @retval EFI_DEVICE_ERROR Unexpected device behavior.
398 **/
399 EFI_STATUS
400 EFIAPI
401 Tpm2HierarchyChangeAuth (
402 IN TPMI_RH_HIERARCHY_AUTH AuthHandle,
403 IN TPMS_AUTH_COMMAND *AuthSession,
404 IN TPM2B_AUTH *NewAuth
405 )
406 {
407 EFI_STATUS Status;
408 TPM2_HIERARCHY_CHANGE_AUTH_COMMAND Cmd;
409 TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE Res;
410 UINT32 CmdSize;
411 UINT32 RespSize;
412 UINT8 *Buffer;
413 UINT32 SessionInfoSize;
414 UINT8 *ResultBuf;
415 UINT32 ResultBufSize;
416
417 //
418 // Construct command
419 //
420 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
421 Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));
422 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_HierarchyChangeAuth);
423 Cmd.AuthHandle = SwapBytes32 (AuthHandle);
424
425 //
426 // Add in Auth session
427 //
428 Buffer = (UINT8 *)&Cmd.AuthSession;
429
430 // sessionInfoSize
431 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
432 Buffer += SessionInfoSize;
433 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
434
435 // New Authorization size
436 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NewAuth->size));
437 Buffer += sizeof (UINT16);
438
439 // New Authorization
440 CopyMem (Buffer, NewAuth->buffer, NewAuth->size);
441 Buffer += NewAuth->size;
442
443 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
444 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
445
446 ResultBuf = (UINT8 *)&Res;
447 ResultBufSize = sizeof (Res);
448
449 //
450 // Call the TPM
451 //
452 Status = Tpm2SubmitCommand (
453 CmdSize,
454 (UINT8 *)&Cmd,
455 &ResultBufSize,
456 ResultBuf
457 );
458 if (EFI_ERROR (Status)) {
459 goto Done;
460 }
461
462 if (ResultBufSize > sizeof (Res)) {
463 DEBUG ((DEBUG_ERROR, "HierarchyChangeAuth: Failed ExecuteCommand: Buffer Too Small\r\n"));
464 Status = EFI_BUFFER_TOO_SMALL;
465 goto Done;
466 }
467
468 //
469 // Validate response headers
470 //
471 RespSize = SwapBytes32 (Res.Header.paramSize);
472 if (RespSize > sizeof (Res)) {
473 DEBUG ((DEBUG_ERROR, "HierarchyChangeAuth: Response size too large! %d\r\n", RespSize));
474 Status = EFI_BUFFER_TOO_SMALL;
475 goto Done;
476 }
477
478 //
479 // Fail if command failed
480 //
481 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
482 DEBUG ((DEBUG_ERROR, "HierarchyChangeAuth: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
483 Status = EFI_DEVICE_ERROR;
484 goto Done;
485 }
486
487 Done:
488 //
489 // Clear AuthSession Content
490 //
491 ZeroMem (&Cmd, sizeof (Cmd));
492 ZeroMem (&Res, sizeof (Res));
493 return Status;
494 }
495
496 /**
497 This replaces the current EPS with a value from the RNG and sets the Endorsement hierarchy controls to
498 their default initialization values.
499
500 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
501 @param[in] AuthSession Auth Session context
502
503 @retval EFI_SUCCESS Operation completed successfully.
504 @retval EFI_DEVICE_ERROR Unexpected device behavior.
505 **/
506 EFI_STATUS
507 EFIAPI
508 Tpm2ChangeEPS (
509 IN TPMI_RH_PLATFORM AuthHandle,
510 IN TPMS_AUTH_COMMAND *AuthSession
511 )
512 {
513 EFI_STATUS Status;
514 TPM2_CHANGE_EPS_COMMAND Cmd;
515 TPM2_CHANGE_EPS_RESPONSE Res;
516 UINT32 CmdSize;
517 UINT32 RespSize;
518 UINT8 *Buffer;
519 UINT32 SessionInfoSize;
520 UINT8 *ResultBuf;
521 UINT32 ResultBufSize;
522
523 //
524 // Construct command
525 //
526 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
527 Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));
528 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_ChangeEPS);
529 Cmd.AuthHandle = SwapBytes32 (AuthHandle);
530
531 //
532 // Add in Auth session
533 //
534 Buffer = (UINT8 *)&Cmd.AuthSession;
535
536 // sessionInfoSize
537 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
538 Buffer += SessionInfoSize;
539 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
540
541 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
542 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
543
544 ResultBuf = (UINT8 *)&Res;
545 ResultBufSize = sizeof (Res);
546
547 //
548 // Call the TPM
549 //
550 Status = Tpm2SubmitCommand (
551 CmdSize,
552 (UINT8 *)&Cmd,
553 &ResultBufSize,
554 ResultBuf
555 );
556 if (EFI_ERROR (Status)) {
557 goto Done;
558 }
559
560 if (ResultBufSize > sizeof (Res)) {
561 DEBUG ((DEBUG_ERROR, "ChangeEPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
562 Status = EFI_BUFFER_TOO_SMALL;
563 goto Done;
564 }
565
566 //
567 // Validate response headers
568 //
569 RespSize = SwapBytes32 (Res.Header.paramSize);
570 if (RespSize > sizeof (Res)) {
571 DEBUG ((DEBUG_ERROR, "ChangeEPS: Response size too large! %d\r\n", RespSize));
572 Status = EFI_BUFFER_TOO_SMALL;
573 goto Done;
574 }
575
576 //
577 // Fail if command failed
578 //
579 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
580 DEBUG ((DEBUG_ERROR, "ChangeEPS: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
581 Status = EFI_DEVICE_ERROR;
582 goto Done;
583 }
584
585 Done:
586 //
587 // Clear AuthSession Content
588 //
589 ZeroMem (&Cmd, sizeof (Cmd));
590 ZeroMem (&Res, sizeof (Res));
591 return Status;
592 }
593
594 /**
595 This replaces the current PPS with a value from the RNG and sets platformPolicy to the default
596 initialization value (the Empty Buffer).
597
598 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
599 @param[in] AuthSession Auth Session context
600
601 @retval EFI_SUCCESS Operation completed successfully.
602 @retval EFI_DEVICE_ERROR Unexpected device behavior.
603 **/
604 EFI_STATUS
605 EFIAPI
606 Tpm2ChangePPS (
607 IN TPMI_RH_PLATFORM AuthHandle,
608 IN TPMS_AUTH_COMMAND *AuthSession
609 )
610 {
611 EFI_STATUS Status;
612 TPM2_CHANGE_PPS_COMMAND Cmd;
613 TPM2_CHANGE_PPS_RESPONSE Res;
614 UINT32 CmdSize;
615 UINT32 RespSize;
616 UINT8 *Buffer;
617 UINT32 SessionInfoSize;
618 UINT8 *ResultBuf;
619 UINT32 ResultBufSize;
620
621 //
622 // Construct command
623 //
624 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
625 Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));
626 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_ChangePPS);
627 Cmd.AuthHandle = SwapBytes32 (AuthHandle);
628
629 //
630 // Add in Auth session
631 //
632 Buffer = (UINT8 *)&Cmd.AuthSession;
633
634 // sessionInfoSize
635 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
636 Buffer += SessionInfoSize;
637 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
638
639 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
640 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
641
642 ResultBuf = (UINT8 *)&Res;
643 ResultBufSize = sizeof (Res);
644
645 //
646 // Call the TPM
647 //
648 Status = Tpm2SubmitCommand (
649 CmdSize,
650 (UINT8 *)&Cmd,
651 &ResultBufSize,
652 ResultBuf
653 );
654 if (EFI_ERROR (Status)) {
655 goto Done;
656 }
657
658 if (ResultBufSize > sizeof (Res)) {
659 DEBUG ((DEBUG_ERROR, "ChangePPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
660 Status = EFI_BUFFER_TOO_SMALL;
661 goto Done;
662 }
663
664 //
665 // Validate response headers
666 //
667 RespSize = SwapBytes32 (Res.Header.paramSize);
668 if (RespSize > sizeof (Res)) {
669 DEBUG ((DEBUG_ERROR, "ChangePPS: Response size too large! %d\r\n", RespSize));
670 Status = EFI_BUFFER_TOO_SMALL;
671 goto Done;
672 }
673
674 //
675 // Fail if command failed
676 //
677 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
678 DEBUG ((DEBUG_ERROR, "ChangePPS: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
679 Status = EFI_DEVICE_ERROR;
680 goto Done;
681 }
682
683 Done:
684 //
685 // Clear AuthSession Content
686 //
687 ZeroMem (&Cmd, sizeof (Cmd));
688 ZeroMem (&Res, sizeof (Res));
689 return Status;
690 }
691
692 /**
693 This command enables and disables use of a hierarchy.
694
695 @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
696 @param[in] AuthSession Auth Session context
697 @param[in] Hierarchy Hierarchy of the enable being modified
698 @param[in] State YES if the enable should be SET,
699 NO if the enable should be CLEAR
700
701 @retval EFI_SUCCESS Operation completed successfully.
702 @retval EFI_DEVICE_ERROR Unexpected device behavior.
703 **/
704 EFI_STATUS
705 EFIAPI
706 Tpm2HierarchyControl (
707 IN TPMI_RH_HIERARCHY AuthHandle,
708 IN TPMS_AUTH_COMMAND *AuthSession,
709 IN TPMI_RH_HIERARCHY Hierarchy,
710 IN TPMI_YES_NO State
711 )
712 {
713 EFI_STATUS Status;
714 TPM2_HIERARCHY_CONTROL_COMMAND Cmd;
715 TPM2_HIERARCHY_CONTROL_RESPONSE Res;
716 UINT32 CmdSize;
717 UINT32 RespSize;
718 UINT8 *Buffer;
719 UINT32 SessionInfoSize;
720 UINT8 *ResultBuf;
721 UINT32 ResultBufSize;
722
723 //
724 // Construct command
725 //
726 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
727 Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));
728 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_HierarchyControl);
729 Cmd.AuthHandle = SwapBytes32 (AuthHandle);
730
731 //
732 // Add in Auth session
733 //
734 Buffer = (UINT8 *)&Cmd.AuthSession;
735
736 // sessionInfoSize
737 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
738 Buffer += SessionInfoSize;
739 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
740
741 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Hierarchy));
742 Buffer += sizeof (UINT32);
743
744 *(UINT8 *)Buffer = State;
745 Buffer++;
746
747 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
748 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
749
750 ResultBuf = (UINT8 *)&Res;
751 ResultBufSize = sizeof (Res);
752
753 //
754 // Call the TPM
755 //
756 Status = Tpm2SubmitCommand (
757 CmdSize,
758 (UINT8 *)&Cmd,
759 &ResultBufSize,
760 ResultBuf
761 );
762 if (EFI_ERROR (Status)) {
763 goto Done;
764 }
765
766 if (ResultBufSize > sizeof (Res)) {
767 DEBUG ((DEBUG_ERROR, "HierarchyControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
768 Status = EFI_BUFFER_TOO_SMALL;
769 goto Done;
770 }
771
772 //
773 // Validate response headers
774 //
775 RespSize = SwapBytes32 (Res.Header.paramSize);
776 if (RespSize > sizeof (Res)) {
777 DEBUG ((DEBUG_ERROR, "HierarchyControl: Response size too large! %d\r\n", RespSize));
778 Status = EFI_BUFFER_TOO_SMALL;
779 goto Done;
780 }
781
782 //
783 // Fail if command failed
784 //
785 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
786 DEBUG ((DEBUG_ERROR, "HierarchyControl: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
787 Status = EFI_DEVICE_ERROR;
788 goto Done;
789 }
790
791 Done:
792 //
793 // Clear AuthSession Content
794 //
795 ZeroMem (&Cmd, sizeof (Cmd));
796 ZeroMem (&Res, sizeof (Res));
797 return Status;
798 }