summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c797
1 files changed, 797 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
new file mode 100644
index 00000000..039bc503
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
@@ -0,0 +1,797 @@
+/** @file
+ Implement TPM2 Hierarchy related command.
+
+Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#pragma pack(1)
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_RH_HIERARCHY_AUTH AuthHandle;
+ UINT32 AuthSessionSize;
+ TPMS_AUTH_COMMAND AuthSession;
+ TPM2B_DIGEST AuthPolicy;
+ TPMI_ALG_HASH HashAlg;
+} TPM2_SET_PRIMARY_POLICY_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 AuthSessionSize;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_SET_PRIMARY_POLICY_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_RH_CLEAR AuthHandle;
+ UINT32 AuthorizationSize;
+ TPMS_AUTH_COMMAND AuthSession;
+} TPM2_CLEAR_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 ParameterSize;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_CLEAR_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_RH_CLEAR AuthHandle;
+ UINT32 AuthorizationSize;
+ TPMS_AUTH_COMMAND AuthSession;
+ TPMI_YES_NO Disable;
+} TPM2_CLEAR_CONTROL_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 ParameterSize;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_CLEAR_CONTROL_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_RH_HIERARCHY_AUTH AuthHandle;
+ UINT32 AuthorizationSize;
+ TPMS_AUTH_COMMAND AuthSession;
+ TPM2B_AUTH NewAuth;
+} TPM2_HIERARCHY_CHANGE_AUTH_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 ParameterSize;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_RH_PLATFORM AuthHandle;
+ UINT32 AuthorizationSize;
+ TPMS_AUTH_COMMAND AuthSession;
+} TPM2_CHANGE_EPS_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 ParameterSize;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_CHANGE_EPS_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_RH_PLATFORM AuthHandle;
+ UINT32 AuthorizationSize;
+ TPMS_AUTH_COMMAND AuthSession;
+} TPM2_CHANGE_PPS_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 ParameterSize;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_CHANGE_PPS_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_RH_HIERARCHY AuthHandle;
+ UINT32 AuthorizationSize;
+ TPMS_AUTH_COMMAND AuthSession;
+ TPMI_RH_HIERARCHY Hierarchy;
+ TPMI_YES_NO State;
+} TPM2_HIERARCHY_CONTROL_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 ParameterSize;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_HIERARCHY_CONTROL_RESPONSE;
+
+#pragma pack()
+
+/**
+ This command allows setting of the authorization policy for the platform hierarchy (platformPolicy), the
+ storage hierarchy (ownerPolicy), and and the endorsement hierarchy (endorsementPolicy).
+
+ @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} parameters to be validated
+ @param[in] AuthSession Auth Session context
+ @param[in] AuthPolicy An authorization policy hash
+ @param[in] HashAlg The hash algorithm to use for the policy
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2SetPrimaryPolicy (
+ IN TPMI_RH_HIERARCHY_AUTH AuthHandle,
+ IN TPMS_AUTH_COMMAND *AuthSession,
+ IN TPM2B_DIGEST *AuthPolicy,
+ IN TPMI_ALG_HASH HashAlg
+ )
+{
+ EFI_STATUS Status;
+ TPM2_SET_PRIMARY_POLICY_COMMAND SendBuffer;
+ TPM2_SET_PRIMARY_POLICY_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+ UINT8 *Buffer;
+ UINT32 SessionInfoSize;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_SetPrimaryPolicy);
+
+ SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
+
+ //
+ // Add in Auth session
+ //
+ Buffer = (UINT8 *)&SendBuffer.AuthSession;
+
+ // sessionInfoSize
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
+ Buffer += SessionInfoSize;
+ SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
+
+ //
+ // Real data
+ //
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(AuthPolicy->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, AuthPolicy->buffer, AuthPolicy->size);
+ Buffer += AuthPolicy->size;
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(HashAlg));
+ Buffer += sizeof(UINT16);
+
+ SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - RecvBufferSize Error - %x\n", RecvBufferSize));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+Done:
+ //
+ // Clear AuthSession Content
+ //
+ ZeroMem (&SendBuffer, sizeof(SendBuffer));
+ ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
+ return Status;
+}
+
+/**
+ This command removes all TPM context associated with a specific Owner.
+
+ @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
+ @param[in] AuthSession Auth Session context
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2Clear (
+ IN TPMI_RH_CLEAR AuthHandle,
+ IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ TPM2_CLEAR_COMMAND Cmd;
+ TPM2_CLEAR_RESPONSE Res;
+ UINT32 ResultBufSize;
+ UINT32 CmdSize;
+ UINT32 RespSize;
+ UINT8 *Buffer;
+ UINT32 SessionInfoSize;
+
+ Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
+ Cmd.Header.commandCode = SwapBytes32(TPM_CC_Clear);
+ Cmd.AuthHandle = SwapBytes32(AuthHandle);
+
+ //
+ // Add in Auth session
+ //
+ Buffer = (UINT8 *)&Cmd.AuthSession;
+
+ // sessionInfoSize
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
+ Buffer += SessionInfoSize;
+ Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.Header.paramSize = SwapBytes32(CmdSize);
+
+ ResultBufSize = sizeof(Res);
+ Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
+ if (EFI_ERROR(Status)) {
+ goto Done;
+ }
+
+ if (ResultBufSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "Clear: Failed ExecuteCommand: Buffer Too Small\r\n"));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Validate response headers
+ //
+ RespSize = SwapBytes32(Res.Header.paramSize);
+ if (RespSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "Clear: Response size too large! %d\r\n", RespSize));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Fail if command failed
+ //
+ if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Clear: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ //
+ // Unmarshal the response
+ //
+
+ // None
+Done:
+ //
+ // Clear AuthSession Content
+ //
+ ZeroMem (&Cmd, sizeof(Cmd));
+ ZeroMem (&Res, sizeof(Res));
+ return Status;
+}
+
+/**
+ Disables and enables the execution of TPM2_Clear().
+
+ @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
+ @param[in] AuthSession Auth Session context
+ @param[in] Disable YES if the disableOwnerClear flag is to be SET,
+ NO if the flag is to be CLEAR.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2ClearControl (
+ IN TPMI_RH_CLEAR AuthHandle,
+ IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
+ IN TPMI_YES_NO Disable
+ )
+{
+ EFI_STATUS Status;
+ TPM2_CLEAR_CONTROL_COMMAND Cmd;
+ TPM2_CLEAR_CONTROL_RESPONSE Res;
+ UINT32 ResultBufSize;
+ UINT32 CmdSize;
+ UINT32 RespSize;
+ UINT8 *Buffer;
+ UINT32 SessionInfoSize;
+
+ Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
+ Cmd.Header.commandCode = SwapBytes32(TPM_CC_ClearControl);
+ Cmd.AuthHandle = SwapBytes32(AuthHandle);
+
+ //
+ // Add in Auth session
+ //
+ Buffer = (UINT8 *)&Cmd.AuthSession;
+
+ // sessionInfoSize
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
+ Buffer += SessionInfoSize;
+ Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
+
+ // disable
+ *(UINT8 *)Buffer = Disable;
+ Buffer++;
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.Header.paramSize = SwapBytes32(CmdSize);
+
+ ResultBufSize = sizeof(Res);
+ Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
+ if (EFI_ERROR(Status)) {
+ goto Done;
+ }
+
+ if (ResultBufSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "ClearControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Validate response headers
+ //
+ RespSize = SwapBytes32(Res.Header.paramSize);
+ if (RespSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "ClearControl: Response size too large! %d\r\n", RespSize));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Fail if command failed
+ //
+ if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "ClearControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ //
+ // Unmarshal the response
+ //
+
+ // None
+Done:
+ //
+ // Clear AuthSession Content
+ //
+ ZeroMem (&Cmd, sizeof(Cmd));
+ ZeroMem (&Res, sizeof(Res));
+ return Status;
+}
+
+/**
+ This command allows the authorization secret for a hierarchy or lockout to be changed using the current
+ authorization value as the command authorization.
+
+ @param[in] AuthHandle TPM_RH_LOCKOUT, TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
+ @param[in] AuthSession Auth Session context
+ @param[in] NewAuth New authorization secret
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2HierarchyChangeAuth (
+ IN TPMI_RH_HIERARCHY_AUTH AuthHandle,
+ IN TPMS_AUTH_COMMAND *AuthSession,
+ IN TPM2B_AUTH *NewAuth
+ )
+{
+ EFI_STATUS Status;
+ TPM2_HIERARCHY_CHANGE_AUTH_COMMAND Cmd;
+ TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE Res;
+ UINT32 CmdSize;
+ UINT32 RespSize;
+ UINT8 *Buffer;
+ UINT32 SessionInfoSize;
+ UINT8 *ResultBuf;
+ UINT32 ResultBufSize;
+
+ //
+ // Construct command
+ //
+ Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
+ Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
+ Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyChangeAuth);
+ Cmd.AuthHandle = SwapBytes32(AuthHandle);
+
+ //
+ // Add in Auth session
+ //
+ Buffer = (UINT8 *)&Cmd.AuthSession;
+
+ // sessionInfoSize
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
+ Buffer += SessionInfoSize;
+ Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
+
+ // New Authorization size
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NewAuth->size));
+ Buffer += sizeof(UINT16);
+
+ // New Authorization
+ CopyMem(Buffer, NewAuth->buffer, NewAuth->size);
+ Buffer += NewAuth->size;
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.Header.paramSize = SwapBytes32(CmdSize);
+
+ ResultBuf = (UINT8 *) &Res;
+ ResultBufSize = sizeof(Res);
+
+ //
+ // Call the TPM
+ //
+ Status = Tpm2SubmitCommand (
+ CmdSize,
+ (UINT8 *)&Cmd,
+ &ResultBufSize,
+ ResultBuf
+ );
+ if (EFI_ERROR(Status)) {
+ goto Done;
+ }
+
+ if (ResultBufSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Failed ExecuteCommand: Buffer Too Small\r\n"));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Validate response headers
+ //
+ RespSize = SwapBytes32(Res.Header.paramSize);
+ if (RespSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Response size too large! %d\r\n", RespSize));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Fail if command failed
+ //
+ if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG((EFI_D_ERROR,"HierarchyChangeAuth: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+Done:
+ //
+ // Clear AuthSession Content
+ //
+ ZeroMem (&Cmd, sizeof(Cmd));
+ ZeroMem (&Res, sizeof(Res));
+ return Status;
+}
+
+/**
+ This replaces the current EPS with a value from the RNG and sets the Endorsement hierarchy controls to
+ their default initialization values.
+
+ @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
+ @param[in] AuthSession Auth Session context
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2ChangeEPS (
+ IN TPMI_RH_PLATFORM AuthHandle,
+ IN TPMS_AUTH_COMMAND *AuthSession
+ )
+{
+ EFI_STATUS Status;
+ TPM2_CHANGE_EPS_COMMAND Cmd;
+ TPM2_CHANGE_EPS_RESPONSE Res;
+ UINT32 CmdSize;
+ UINT32 RespSize;
+ UINT8 *Buffer;
+ UINT32 SessionInfoSize;
+ UINT8 *ResultBuf;
+ UINT32 ResultBufSize;
+
+ //
+ // Construct command
+ //
+ Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
+ Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
+ Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangeEPS);
+ Cmd.AuthHandle = SwapBytes32(AuthHandle);
+
+ //
+ // Add in Auth session
+ //
+ Buffer = (UINT8 *)&Cmd.AuthSession;
+
+ // sessionInfoSize
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
+ Buffer += SessionInfoSize;
+ Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.Header.paramSize = SwapBytes32(CmdSize);
+
+ ResultBuf = (UINT8 *) &Res;
+ ResultBufSize = sizeof(Res);
+
+ //
+ // Call the TPM
+ //
+ Status = Tpm2SubmitCommand (
+ CmdSize,
+ (UINT8 *)&Cmd,
+ &ResultBufSize,
+ ResultBuf
+ );
+ if (EFI_ERROR(Status)) {
+ goto Done;
+ }
+
+ if (ResultBufSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "ChangeEPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Validate response headers
+ //
+ RespSize = SwapBytes32(Res.Header.paramSize);
+ if (RespSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "ChangeEPS: Response size too large! %d\r\n", RespSize));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Fail if command failed
+ //
+ if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG((EFI_D_ERROR,"ChangeEPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+Done:
+ //
+ // Clear AuthSession Content
+ //
+ ZeroMem (&Cmd, sizeof(Cmd));
+ ZeroMem (&Res, sizeof(Res));
+ return Status;
+}
+
+/**
+ This replaces the current PPS with a value from the RNG and sets platformPolicy to the default
+ initialization value (the Empty Buffer).
+
+ @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
+ @param[in] AuthSession Auth Session context
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2ChangePPS (
+ IN TPMI_RH_PLATFORM AuthHandle,
+ IN TPMS_AUTH_COMMAND *AuthSession
+ )
+{
+ EFI_STATUS Status;
+ TPM2_CHANGE_PPS_COMMAND Cmd;
+ TPM2_CHANGE_PPS_RESPONSE Res;
+ UINT32 CmdSize;
+ UINT32 RespSize;
+ UINT8 *Buffer;
+ UINT32 SessionInfoSize;
+ UINT8 *ResultBuf;
+ UINT32 ResultBufSize;
+
+ //
+ // Construct command
+ //
+ Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
+ Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
+ Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangePPS);
+ Cmd.AuthHandle = SwapBytes32(AuthHandle);
+
+ //
+ // Add in Auth session
+ //
+ Buffer = (UINT8 *)&Cmd.AuthSession;
+
+ // sessionInfoSize
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
+ Buffer += SessionInfoSize;
+ Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.Header.paramSize = SwapBytes32(CmdSize);
+
+ ResultBuf = (UINT8 *) &Res;
+ ResultBufSize = sizeof(Res);
+
+ //
+ // Call the TPM
+ //
+ Status = Tpm2SubmitCommand (
+ CmdSize,
+ (UINT8 *)&Cmd,
+ &ResultBufSize,
+ ResultBuf
+ );
+ if (EFI_ERROR(Status)) {
+ goto Done;
+ }
+
+ if (ResultBufSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "ChangePPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Validate response headers
+ //
+ RespSize = SwapBytes32(Res.Header.paramSize);
+ if (RespSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "ChangePPS: Response size too large! %d\r\n", RespSize));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Fail if command failed
+ //
+ if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG((EFI_D_ERROR,"ChangePPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+Done:
+ //
+ // Clear AuthSession Content
+ //
+ ZeroMem (&Cmd, sizeof(Cmd));
+ ZeroMem (&Res, sizeof(Res));
+ return Status;
+}
+
+/**
+ This command enables and disables use of a hierarchy.
+
+ @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
+ @param[in] AuthSession Auth Session context
+ @param[in] Hierarchy Hierarchy of the enable being modified
+ @param[in] State YES if the enable should be SET,
+ NO if the enable should be CLEAR
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2HierarchyControl (
+ IN TPMI_RH_HIERARCHY AuthHandle,
+ IN TPMS_AUTH_COMMAND *AuthSession,
+ IN TPMI_RH_HIERARCHY Hierarchy,
+ IN TPMI_YES_NO State
+ )
+{
+ EFI_STATUS Status;
+ TPM2_HIERARCHY_CONTROL_COMMAND Cmd;
+ TPM2_HIERARCHY_CONTROL_RESPONSE Res;
+ UINT32 CmdSize;
+ UINT32 RespSize;
+ UINT8 *Buffer;
+ UINT32 SessionInfoSize;
+ UINT8 *ResultBuf;
+ UINT32 ResultBufSize;
+
+ //
+ // Construct command
+ //
+ Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
+ Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
+ Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyControl);
+ Cmd.AuthHandle = SwapBytes32(AuthHandle);
+
+ //
+ // Add in Auth session
+ //
+ Buffer = (UINT8 *)&Cmd.AuthSession;
+
+ // sessionInfoSize
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
+ Buffer += SessionInfoSize;
+ Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
+
+ WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Hierarchy));
+ Buffer += sizeof(UINT32);
+
+ *(UINT8 *)Buffer = State;
+ Buffer++;
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.Header.paramSize = SwapBytes32(CmdSize);
+
+ ResultBuf = (UINT8 *) &Res;
+ ResultBufSize = sizeof(Res);
+
+ //
+ // Call the TPM
+ //
+ Status = Tpm2SubmitCommand (
+ CmdSize,
+ (UINT8 *)&Cmd,
+ &ResultBufSize,
+ ResultBuf
+ );
+ if (EFI_ERROR(Status)) {
+ goto Done;
+ }
+
+ if (ResultBufSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "HierarchyControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Validate response headers
+ //
+ RespSize = SwapBytes32(Res.Header.paramSize);
+ if (RespSize > sizeof(Res)) {
+ DEBUG ((EFI_D_ERROR, "HierarchyControl: Response size too large! %d\r\n", RespSize));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ //
+ // Fail if command failed
+ //
+ if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG((EFI_D_ERROR,"HierarchyControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+Done:
+ //
+ // Clear AuthSession Content
+ //
+ ZeroMem (&Cmd, sizeof(Cmd));
+ ZeroMem (&Res, sizeof(Res));
+ return Status;
+}