summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c396
1 files changed, 396 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c
new file mode 100644
index 00000000..f28bd0b6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c
@@ -0,0 +1,396 @@
+/** @file
+ Implement TPM2 EnhancedAuthorization related command.
+
+Copyright (c) 2014 - 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_DH_ENTITY AuthHandle;
+ TPMI_SH_POLICY PolicySession;
+ UINT32 AuthSessionSize;
+ TPMS_AUTH_COMMAND AuthSession;
+ TPM2B_NONCE NonceTPM;
+ TPM2B_DIGEST CpHashA;
+ TPM2B_NONCE PolicyRef;
+ INT32 Expiration;
+} TPM2_POLICY_SECRET_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 AuthSessionSize;
+ TPM2B_TIMEOUT Timeout;
+ TPMT_TK_AUTH PolicyTicket;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_POLICY_SECRET_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_SH_POLICY PolicySession;
+ TPML_DIGEST HashList;
+} TPM2_POLICY_OR_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+} TPM2_POLICY_OR_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_SH_POLICY PolicySession;
+ TPM_CC Code;
+} TPM2_POLICY_COMMAND_CODE_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+} TPM2_POLICY_COMMAND_CODE_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_SH_POLICY PolicySession;
+} TPM2_POLICY_GET_DIGEST_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ TPM2B_DIGEST PolicyHash;
+} TPM2_POLICY_GET_DIGEST_RESPONSE;
+
+#pragma pack()
+
+/**
+ This command includes a secret-based authorization to a policy.
+ The caller proves knowledge of the secret value using an authorization
+ session using the authValue associated with authHandle.
+
+ @param[in] AuthHandle Handle for an entity providing the authorization
+ @param[in] PolicySession Handle for the policy session being extended.
+ @param[in] AuthSession Auth Session context
+ @param[in] NonceTPM The policy nonce for the session.
+ @param[in] CpHashA Digest of the command parameters to which this authorization is limited.
+ @param[in] PolicyRef A reference to a policy relating to the authorization.
+ @param[in] Expiration Time when authorization will expire, measured in seconds from the time that nonceTPM was generated.
+ @param[out] Timeout Time value used to indicate to the TPM when the ticket expires.
+ @param[out] PolicyTicket A ticket that includes a value indicating when the authorization expires.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicySecret (
+ IN TPMI_DH_ENTITY AuthHandle,
+ IN TPMI_SH_POLICY PolicySession,
+ IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
+ IN TPM2B_NONCE *NonceTPM,
+ IN TPM2B_DIGEST *CpHashA,
+ IN TPM2B_NONCE *PolicyRef,
+ IN INT32 Expiration,
+ OUT TPM2B_TIMEOUT *Timeout,
+ OUT TPMT_TK_AUTH *PolicyTicket
+ )
+{
+ EFI_STATUS Status;
+ TPM2_POLICY_SECRET_COMMAND SendBuffer;
+ TPM2_POLICY_SECRET_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_PolicySecret);
+ SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
+ SendBuffer.PolicySession = SwapBytes32 (PolicySession);
+
+ //
+ // 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(NonceTPM->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, NonceTPM->buffer, NonceTPM->size);
+ Buffer += NonceTPM->size;
+
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(CpHashA->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, CpHashA->buffer, CpHashA->size);
+ Buffer += CpHashA->size;
+
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PolicyRef->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, PolicyRef->buffer, PolicyRef->size);
+ Buffer += PolicyRef->size;
+
+ WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32((UINT32)Expiration));
+ Buffer += sizeof(UINT32);
+
+ 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, "Tpm2PolicySecret - RecvBufferSize Error - %x\n", RecvBufferSize));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ //
+ // Return the response
+ //
+ Buffer = (UINT8 *)&RecvBuffer.Timeout;
+ Timeout->size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));
+ if (Timeout->size > sizeof(UINT64)) {
+ DEBUG ((DEBUG_ERROR, "Tpm2PolicySecret - Timeout->size error %x\n", Timeout->size));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ Buffer += sizeof(UINT16);
+ CopyMem (Timeout->buffer, Buffer, Timeout->size);
+
+ PolicyTicket->tag = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));
+ Buffer += sizeof(UINT16);
+ PolicyTicket->hierarchy = SwapBytes32(ReadUnaligned32 ((UINT32 *)Buffer));
+ Buffer += sizeof(UINT32);
+ PolicyTicket->digest.size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));
+ Buffer += sizeof(UINT16);
+ if (PolicyTicket->digest.size > sizeof(TPMU_HA)) {
+ DEBUG ((DEBUG_ERROR, "Tpm2PolicySecret - digest.size error %x\n", PolicyTicket->digest.size));
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ CopyMem (PolicyTicket->digest.buffer, Buffer, PolicyTicket->digest.size);
+
+Done:
+ //
+ // Clear AuthSession Content
+ //
+ ZeroMem (&SendBuffer, sizeof(SendBuffer));
+ ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
+ return Status;
+}
+
+/**
+ This command allows options in authorizations without requiring that the TPM evaluate all of the options.
+ If a policy may be satisfied by different sets of conditions, the TPM need only evaluate one set that
+ satisfies the policy. This command will indicate that one of the required sets of conditions has been
+ satisfied.
+
+ @param[in] PolicySession Handle for the policy session being extended.
+ @param[in] HashList the list of hashes to check for a match.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicyOR (
+ IN TPMI_SH_POLICY PolicySession,
+ IN TPML_DIGEST *HashList
+ )
+{
+ EFI_STATUS Status;
+ TPM2_POLICY_OR_COMMAND SendBuffer;
+ TPM2_POLICY_OR_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+ UINT8 *Buffer;
+ UINTN Index;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyOR);
+
+ SendBuffer.PolicySession = SwapBytes32 (PolicySession);
+ Buffer = (UINT8 *)&SendBuffer.HashList;
+ WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (HashList->count));
+ Buffer += sizeof(UINT32);
+ for (Index = 0; Index < HashList->count; Index++) {
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (HashList->digests[Index].size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, HashList->digests[Index].buffer, HashList->digests[Index].size);
+ Buffer += HashList->digests[Index].size;
+ }
+
+ 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)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyOR - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyOR - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This command indicates that the authorization will be limited to a specific command code.
+
+ @param[in] PolicySession Handle for the policy session being extended.
+ @param[in] Code The allowed commandCode.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicyCommandCode (
+ IN TPMI_SH_POLICY PolicySession,
+ IN TPM_CC Code
+ )
+{
+ EFI_STATUS Status;
+ TPM2_POLICY_COMMAND_CODE_COMMAND SendBuffer;
+ TPM2_POLICY_COMMAND_CODE_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyCommandCode);
+
+ SendBuffer.PolicySession = SwapBytes32 (PolicySession);
+ SendBuffer.Code = SwapBytes32 (Code);
+
+ SendBufferSize = (UINT32) sizeof (SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This command returns the current policyDigest of the session. This command allows the TPM
+ to be used to perform the actions required to precompute the authPolicy for an object.
+
+ @param[in] PolicySession Handle for the policy session.
+ @param[out] PolicyHash the current value of the policyHash of policySession.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicyGetDigest (
+ IN TPMI_SH_POLICY PolicySession,
+ OUT TPM2B_DIGEST *PolicyHash
+ )
+{
+ EFI_STATUS Status;
+ TPM2_POLICY_GET_DIGEST_COMMAND SendBuffer;
+ TPM2_POLICY_GET_DIGEST_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyGetDigest);
+
+ SendBuffer.PolicySession = SwapBytes32 (PolicySession);
+
+ SendBufferSize = (UINT32) sizeof (SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return the response
+ //
+ PolicyHash->size = SwapBytes16 (RecvBuffer.PolicyHash.size);
+ if (PolicyHash->size > sizeof(TPMU_HA)) {
+ DEBUG ((DEBUG_ERROR, "Tpm2PolicyGetDigest - PolicyHash->size error %x\n", PolicyHash->size));
+ return EFI_DEVICE_ERROR;
+ }
+
+ CopyMem (PolicyHash->buffer, &RecvBuffer.PolicyHash.buffer, PolicyHash->size);
+
+ return EFI_SUCCESS;
+}