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