2 Implement TPM2 Hierarchy related command.
4 Copyright (c) 2013, 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
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.
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>
25 TPM2_COMMAND_HEADER Header
;
26 TPMI_RH_CLEAR AuthHandle
;
27 UINT32 AuthorizationSize
;
28 TPMS_AUTH_COMMAND AuthSession
;
32 TPM2_RESPONSE_HEADER Header
;
34 TPMS_AUTH_RESPONSE AuthSession
;
35 } TPM2_CLEAR_RESPONSE
;
38 TPM2_COMMAND_HEADER Header
;
39 TPMI_RH_CLEAR AuthHandle
;
40 UINT32 AuthorizationSize
;
41 TPMS_AUTH_COMMAND AuthSession
;
43 } TPM2_CLEAR_CONTROL_COMMAND
;
46 TPM2_RESPONSE_HEADER Header
;
48 TPMS_AUTH_RESPONSE AuthSession
;
49 } TPM2_CLEAR_CONTROL_RESPONSE
;
52 TPM2_COMMAND_HEADER Header
;
53 TPMI_RH_HIERARCHY_AUTH AuthHandle
;
54 UINT32 AuthorizationSize
;
55 TPMS_AUTH_COMMAND AuthSession
;
57 } TPM2_HIERARCHY_CHANGE_AUTH_COMMAND
;
60 TPM2_RESPONSE_HEADER Header
;
62 TPMS_AUTH_RESPONSE AuthSession
;
63 } TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE
;
66 TPM2_COMMAND_HEADER Header
;
67 TPMI_RH_PLATFORM AuthHandle
;
68 UINT32 AuthorizationSize
;
69 TPMS_AUTH_COMMAND AuthSession
;
70 } TPM2_CHANGE_EPS_COMMAND
;
73 TPM2_RESPONSE_HEADER Header
;
75 TPMS_AUTH_RESPONSE AuthSession
;
76 } TPM2_CHANGE_EPS_RESPONSE
;
79 TPM2_COMMAND_HEADER Header
;
80 TPMI_RH_PLATFORM AuthHandle
;
81 UINT32 AuthorizationSize
;
82 TPMS_AUTH_COMMAND AuthSession
;
83 } TPM2_CHANGE_PPS_COMMAND
;
86 TPM2_RESPONSE_HEADER Header
;
88 TPMS_AUTH_RESPONSE AuthSession
;
89 } TPM2_CHANGE_PPS_RESPONSE
;
92 TPM2_COMMAND_HEADER Header
;
93 TPMI_RH_HIERARCHY AuthHandle
;
94 UINT32 AuthorizationSize
;
95 TPMS_AUTH_COMMAND AuthSession
;
96 TPMI_RH_HIERARCHY Hierarchy
;
98 } TPM2_HIERARCHY_CONTROL_COMMAND
;
101 TPM2_RESPONSE_HEADER Header
;
102 UINT32 ParameterSize
;
103 TPMS_AUTH_RESPONSE AuthSession
;
104 } TPM2_HIERARCHY_CONTROL_RESPONSE
;
109 This command removes all TPM context associated with a specific Owner.
111 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
112 @param[in] AuthSession Auth Session context
114 @retval EFI_SUCCESS Operation completed successfully.
115 @retval EFI_DEVICE_ERROR Unexpected device behavior.
120 IN TPMI_RH_CLEAR AuthHandle
,
121 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
125 TPM2_CLEAR_COMMAND Cmd
;
126 TPM2_CLEAR_RESPONSE Res
;
127 UINT32 ResultBufSize
;
131 UINT32 SessionInfoSize
;
133 Cmd
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
134 Cmd
.Header
.commandCode
= SwapBytes32(TPM_CC_Clear
);
135 Cmd
.AuthHandle
= SwapBytes32(AuthHandle
);
138 // Add in Auth session
140 Buffer
= (UINT8
*)&Cmd
.AuthSession
;
143 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
144 Buffer
+= SessionInfoSize
;
145 Cmd
.AuthorizationSize
= SwapBytes32(SessionInfoSize
);
147 CmdSize
= (UINT32
)(Buffer
- (UINT8
*)&Cmd
);
148 Cmd
.Header
.paramSize
= SwapBytes32(CmdSize
);
150 ResultBufSize
= sizeof(Res
);
151 Status
= Tpm2SubmitCommand (CmdSize
, (UINT8
*)&Cmd
, &ResultBufSize
, (UINT8
*)&Res
);
152 if (EFI_ERROR(Status
)) {
156 if (ResultBufSize
> sizeof(Res
)) {
157 DEBUG ((EFI_D_ERROR
, "Clear: Failed ExecuteCommand: Buffer Too Small\r\n"));
158 return EFI_BUFFER_TOO_SMALL
;
162 // Validate response headers
164 RespSize
= SwapBytes32(Res
.Header
.paramSize
);
165 if (RespSize
> sizeof(Res
)) {
166 DEBUG ((EFI_D_ERROR
, "Clear: Response size too large! %d\r\n", RespSize
));
167 return EFI_BUFFER_TOO_SMALL
;
171 // Fail if command failed
173 if (SwapBytes32(Res
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
174 DEBUG ((EFI_D_ERROR
, "Clear: Response Code error! 0x%08x\r\n", SwapBytes32(Res
.Header
.responseCode
)));
175 return EFI_DEVICE_ERROR
;
179 // Unmarshal the response
188 Disables and enables the execution of TPM2_Clear().
190 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
191 @param[in] AuthSession Auth Session context
192 @param[in] Disable YES if the disableOwnerClear flag is to be SET,
193 NO if the flag is to be CLEAR.
195 @retval EFI_SUCCESS Operation completed successfully.
196 @retval EFI_DEVICE_ERROR Unexpected device behavior.
201 IN TPMI_RH_CLEAR AuthHandle
,
202 IN TPMS_AUTH_COMMAND
*AuthSession
, OPTIONAL
203 IN TPMI_YES_NO Disable
207 TPM2_CLEAR_CONTROL_COMMAND Cmd
;
208 TPM2_CLEAR_CONTROL_RESPONSE Res
;
209 UINT32 ResultBufSize
;
213 UINT32 SessionInfoSize
;
215 Cmd
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
216 Cmd
.Header
.commandCode
= SwapBytes32(TPM_CC_ClearControl
);
217 Cmd
.AuthHandle
= SwapBytes32(AuthHandle
);
220 // Add in Auth session
222 Buffer
= (UINT8
*)&Cmd
.AuthSession
;
225 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
226 Buffer
+= SessionInfoSize
;
227 Cmd
.AuthorizationSize
= SwapBytes32(SessionInfoSize
);
230 *(UINT8
*)Buffer
= Disable
;
231 Buffer
+= sizeof(UINT8
);
233 CmdSize
= (UINT32
)(Buffer
- (UINT8
*)&Cmd
);
234 Cmd
.Header
.paramSize
= SwapBytes32(CmdSize
);
236 ResultBufSize
= sizeof(Res
);
237 Status
= Tpm2SubmitCommand (CmdSize
, (UINT8
*)&Cmd
, &ResultBufSize
, (UINT8
*)&Res
);
238 if (EFI_ERROR(Status
)) {
242 if (ResultBufSize
> sizeof(Res
)) {
243 DEBUG ((EFI_D_ERROR
, "ClearControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
244 return EFI_BUFFER_TOO_SMALL
;
248 // Validate response headers
250 RespSize
= SwapBytes32(Res
.Header
.paramSize
);
251 if (RespSize
> sizeof(Res
)) {
252 DEBUG ((EFI_D_ERROR
, "ClearControl: Response size too large! %d\r\n", RespSize
));
253 return EFI_BUFFER_TOO_SMALL
;
257 // Fail if command failed
259 if (SwapBytes32(Res
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
260 DEBUG ((EFI_D_ERROR
, "ClearControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res
.Header
.responseCode
)));
261 return EFI_DEVICE_ERROR
;
265 // Unmarshal the response
274 This command allows the authorization secret for a hierarchy or lockout to be changed using the current
275 authorization value as the command authorization.
277 @param[in] AuthHandle TPM_RH_LOCKOUT, TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
278 @param[in] AuthSession Auth Session context
279 @param[in] NewAuth New authorization secret
281 @retval EFI_SUCCESS Operation completed successfully.
282 @retval EFI_DEVICE_ERROR Unexpected device behavior.
286 Tpm2HierarchyChangeAuth (
287 IN TPMI_RH_HIERARCHY_AUTH AuthHandle
,
288 IN TPMS_AUTH_COMMAND
*AuthSession
,
289 IN TPM2B_AUTH
*NewAuth
293 TPM2_HIERARCHY_CHANGE_AUTH_COMMAND Cmd
;
294 TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE Res
;
298 UINT32 SessionInfoSize
;
300 UINT32 ResultBufSize
;
305 Cmd
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
306 Cmd
.Header
.paramSize
= SwapBytes32(sizeof(Cmd
));
307 Cmd
.Header
.commandCode
= SwapBytes32(TPM_CC_HierarchyChangeAuth
);
308 Cmd
.AuthHandle
= SwapBytes32(AuthHandle
);
311 // Add in Auth session
313 Buffer
= (UINT8
*)&Cmd
.AuthSession
;
316 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
317 Buffer
+= SessionInfoSize
;
318 Cmd
.AuthorizationSize
= SwapBytes32(SessionInfoSize
);
320 // New Authorization size
321 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16(NewAuth
->size
));
322 Buffer
+= sizeof(UINT16
);
324 // New Authorizeation
325 CopyMem(Buffer
, NewAuth
->buffer
, NewAuth
->size
);
326 Buffer
+= NewAuth
->size
;
328 CmdSize
= (UINT32
)(Buffer
- (UINT8
*)&Cmd
);
329 Cmd
.Header
.paramSize
= SwapBytes32(CmdSize
);
331 ResultBuf
= (UINT8
*) &Res
;
332 ResultBufSize
= sizeof(Res
);
337 Status
= Tpm2SubmitCommand (
344 if (ResultBufSize
> sizeof(Res
)) {
345 DEBUG ((EFI_D_ERROR
, "HierarchyChangeAuth: Failed ExecuteCommand: Buffer Too Small\r\n"));
346 return EFI_BUFFER_TOO_SMALL
;
350 // Validate response headers
352 RespSize
= SwapBytes32(Res
.Header
.paramSize
);
353 if (RespSize
> sizeof(Res
)) {
354 DEBUG ((EFI_D_ERROR
, "HierarchyChangeAuth: Response size too large! %d\r\n", RespSize
));
355 return EFI_BUFFER_TOO_SMALL
;
359 // Fail if command failed
361 if (SwapBytes32(Res
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
362 DEBUG((EFI_D_ERROR
,"HierarchyChangeAuth: Response Code error! 0x%08x\r\n", SwapBytes32(Res
.Header
.responseCode
)));
363 return EFI_DEVICE_ERROR
;
370 This replaces the current EPS with a value from the RNG and sets the Endorsement hierarchy controls to
371 their default initialization values.
373 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
374 @param[in] AuthSession Auth Session context
376 @retval EFI_SUCCESS Operation completed successfully.
377 @retval EFI_DEVICE_ERROR Unexpected device behavior.
382 IN TPMI_RH_PLATFORM AuthHandle
,
383 IN TPMS_AUTH_COMMAND
*AuthSession
387 TPM2_CHANGE_EPS_COMMAND Cmd
;
388 TPM2_CHANGE_EPS_RESPONSE Res
;
392 UINT32 SessionInfoSize
;
394 UINT32 ResultBufSize
;
399 Cmd
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
400 Cmd
.Header
.paramSize
= SwapBytes32(sizeof(Cmd
));
401 Cmd
.Header
.commandCode
= SwapBytes32(TPM_CC_ChangeEPS
);
402 Cmd
.AuthHandle
= SwapBytes32(AuthHandle
);
405 // Add in Auth session
407 Buffer
= (UINT8
*)&Cmd
.AuthSession
;
410 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
411 Buffer
+= SessionInfoSize
;
412 Cmd
.AuthorizationSize
= SwapBytes32(SessionInfoSize
);
414 CmdSize
= (UINT32
)(Buffer
- (UINT8
*)&Cmd
);
415 Cmd
.Header
.paramSize
= SwapBytes32(CmdSize
);
417 ResultBuf
= (UINT8
*) &Res
;
418 ResultBufSize
= sizeof(Res
);
423 Status
= Tpm2SubmitCommand (
430 if (ResultBufSize
> sizeof(Res
)) {
431 DEBUG ((EFI_D_ERROR
, "ChangeEPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
432 return EFI_BUFFER_TOO_SMALL
;
436 // Validate response headers
438 RespSize
= SwapBytes32(Res
.Header
.paramSize
);
439 if (RespSize
> sizeof(Res
)) {
440 DEBUG ((EFI_D_ERROR
, "ChangeEPS: Response size too large! %d\r\n", RespSize
));
441 return EFI_BUFFER_TOO_SMALL
;
445 // Fail if command failed
447 if (SwapBytes32(Res
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
448 DEBUG((EFI_D_ERROR
,"ChangeEPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res
.Header
.responseCode
)));
449 return EFI_DEVICE_ERROR
;
456 This replaces the current PPS with a value from the RNG and sets platformPolicy to the default
457 initialization value (the Empty Buffer).
459 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
460 @param[in] AuthSession Auth Session context
462 @retval EFI_SUCCESS Operation completed successfully.
463 @retval EFI_DEVICE_ERROR Unexpected device behavior.
468 IN TPMI_RH_PLATFORM AuthHandle
,
469 IN TPMS_AUTH_COMMAND
*AuthSession
473 TPM2_CHANGE_PPS_COMMAND Cmd
;
474 TPM2_CHANGE_PPS_RESPONSE Res
;
478 UINT32 SessionInfoSize
;
480 UINT32 ResultBufSize
;
485 Cmd
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
486 Cmd
.Header
.paramSize
= SwapBytes32(sizeof(Cmd
));
487 Cmd
.Header
.commandCode
= SwapBytes32(TPM_CC_ChangePPS
);
488 Cmd
.AuthHandle
= SwapBytes32(AuthHandle
);
491 // Add in Auth session
493 Buffer
= (UINT8
*)&Cmd
.AuthSession
;
496 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
497 Buffer
+= SessionInfoSize
;
498 Cmd
.AuthorizationSize
= SwapBytes32(SessionInfoSize
);
500 CmdSize
= (UINT32
)(Buffer
- (UINT8
*)&Cmd
);
501 Cmd
.Header
.paramSize
= SwapBytes32(CmdSize
);
503 ResultBuf
= (UINT8
*) &Res
;
504 ResultBufSize
= sizeof(Res
);
509 Status
= Tpm2SubmitCommand (
516 if (ResultBufSize
> sizeof(Res
)) {
517 DEBUG ((EFI_D_ERROR
, "ChangePPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
518 return EFI_BUFFER_TOO_SMALL
;
522 // Validate response headers
524 RespSize
= SwapBytes32(Res
.Header
.paramSize
);
525 if (RespSize
> sizeof(Res
)) {
526 DEBUG ((EFI_D_ERROR
, "ChangePPS: Response size too large! %d\r\n", RespSize
));
527 return EFI_BUFFER_TOO_SMALL
;
531 // Fail if command failed
533 if (SwapBytes32(Res
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
534 DEBUG((EFI_D_ERROR
,"ChangePPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res
.Header
.responseCode
)));
535 return EFI_DEVICE_ERROR
;
542 This command enables and disables use of a hierarchy.
544 @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
545 @param[in] AuthSession Auth Session context
546 @param[in] Hierarchy Hierarchy of the enable being modified
547 @param[in] State YES if the enable should be SET,
548 NO if the enable should be CLEAR
550 @retval EFI_SUCCESS Operation completed successfully.
551 @retval EFI_DEVICE_ERROR Unexpected device behavior.
555 Tpm2HierarchyControl (
556 IN TPMI_RH_HIERARCHY AuthHandle
,
557 IN TPMS_AUTH_COMMAND
*AuthSession
,
558 IN TPMI_RH_HIERARCHY Hierarchy
,
563 TPM2_HIERARCHY_CONTROL_COMMAND Cmd
;
564 TPM2_HIERARCHY_CONTROL_RESPONSE Res
;
568 UINT32 SessionInfoSize
;
570 UINT32 ResultBufSize
;
575 Cmd
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
576 Cmd
.Header
.paramSize
= SwapBytes32(sizeof(Cmd
));
577 Cmd
.Header
.commandCode
= SwapBytes32(TPM_CC_HierarchyControl
);
578 Cmd
.AuthHandle
= SwapBytes32(AuthHandle
);
581 // Add in Auth session
583 Buffer
= (UINT8
*)&Cmd
.AuthSession
;
586 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
587 Buffer
+= SessionInfoSize
;
588 Cmd
.AuthorizationSize
= SwapBytes32(SessionInfoSize
);
590 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32(Hierarchy
));
591 Buffer
+= sizeof(UINT32
);
593 *(UINT8
*)Buffer
= State
;
594 Buffer
+= sizeof(UINT8
);
596 CmdSize
= (UINT32
)(Buffer
- (UINT8
*)&Cmd
);
597 Cmd
.Header
.paramSize
= SwapBytes32(CmdSize
);
599 ResultBuf
= (UINT8
*) &Res
;
600 ResultBufSize
= sizeof(Res
);
605 Status
= Tpm2SubmitCommand (
612 if (ResultBufSize
> sizeof(Res
)) {
613 DEBUG ((EFI_D_ERROR
, "HierarchyControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
614 return EFI_BUFFER_TOO_SMALL
;
618 // Validate response headers
620 RespSize
= SwapBytes32(Res
.Header
.paramSize
);
621 if (RespSize
> sizeof(Res
)) {
622 DEBUG ((EFI_D_ERROR
, "HierarchyControl: Response size too large! %d\r\n", RespSize
));
623 return EFI_BUFFER_TOO_SMALL
;
627 // Fail if command failed
629 if (SwapBytes32(Res
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
630 DEBUG((EFI_D_ERROR
,"HierarchyControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res
.Header
.responseCode
)));
631 return EFI_DEVICE_ERROR
;