SecurityPkg: Add TCG PFP 1.06 support.

Add new api Tpm2ExtendNvIndex.
It is uesd in HashCompleteAndExtend when PcrIndex > MAX_PCR_INDEX.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Wenxing Hou 2024-04-18 17:28:14 +08:00 committed by mergify[bot]
parent d8e4c4b000
commit c3f615a1bd
5 changed files with 278 additions and 20 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
This library is used by other modules to send TPM2 command. This library is used by other modules to send TPM2 command.
Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR> Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
**/ **/
@ -467,6 +467,27 @@ Tpm2NvGlobalWriteLock (
IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
); );
/**
This command extends a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().
@param[in] AuthHandle the handle indicating the source of the authorization value.
@param[in] NvIndex The NV Index of the area to extend.
@param[in] AuthSession Auth Session context
@param[in] InData The data to extend.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
**/
EFI_STATUS
EFIAPI
Tpm2NvExtend (
IN TPMI_RH_NV_AUTH AuthHandle,
IN TPMI_RH_NV_INDEX NvIndex,
IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL,
IN TPM2B_MAX_BUFFER *InData
);
/** /**
This command is used to cause an update to the indicated PCR. This command is used to cause an update to the indicated PCR.
The digests parameter contains one or more tagged digest value identified by an algorithm ID. The digests parameter contains one or more tagged digest value identified by an algorithm ID.

View File

@ -3,7 +3,7 @@
hash handler registered, such as SHA1, SHA256. hash handler registered, such as SHA1, SHA256.
Platform can use PcdTpm2HashMask to mask some hash engines. Platform can use PcdTpm2HashMask to mask some hash engines.
Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR> Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
**/ **/
@ -16,6 +16,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h> #include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <Library/HashLib.h> #include <Library/HashLib.h>
#include <Protocol/Tcg2Protocol.h>
#include "HashLibBaseCryptoRouterCommon.h" #include "HashLibBaseCryptoRouterCommon.h"
@ -128,6 +129,49 @@ HashUpdate (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Extend to TPM NvIndex.
@param[in] NvIndex The NV Index of the area to extend.
@param[in] DataSize The data size to extend.
@param[in] Data The data to extend.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
**/
EFI_STATUS
EFIAPI
Tpm2ExtendNvIndex (
TPMI_RH_NV_INDEX NvIndex,
UINT16 DataSize,
BYTE *Data
)
{
EFI_STATUS Status;
TPMI_RH_NV_AUTH AuthHandle;
TPM2B_MAX_BUFFER NvExtendData;
AuthHandle = TPM_RH_PLATFORM;
ZeroMem (&NvExtendData, sizeof (NvExtendData));
CopyMem (NvExtendData.buffer, Data, DataSize);
NvExtendData.size = DataSize;
Status = Tpm2NvExtend (
AuthHandle,
NvIndex,
NULL,
&NvExtendData
);
if (EFI_ERROR (Status)) {
DEBUG (
(DEBUG_ERROR, "Extend TPM NV index failed, Index: 0x%x Status: %d\n",
NvIndex, Status)
);
}
return Status;
}
/** /**
Hash sequence complete and extend to PCR. Hash sequence complete and extend to PCR.
@ -149,11 +193,16 @@ HashCompleteAndExtend (
OUT TPML_DIGEST_VALUES *DigestList OUT TPML_DIGEST_VALUES *DigestList
) )
{ {
TPML_DIGEST_VALUES Digest; TPML_DIGEST_VALUES Digest;
HASH_HANDLE *HashCtx; HASH_HANDLE *HashCtx;
UINTN Index; UINTN Index;
EFI_STATUS Status; EFI_STATUS Status;
UINT32 HashMask; UINT32 HashMask;
TPML_DIGEST_VALUES TcgPcrEvent2Digest;
EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;
UINT32 ActivePcrBanks;
UINT32 *BufferPtr;
UINT32 DigestListBinSize;
if (mHashInterfaceCount == 0) { if (mHashInterfaceCount == 0) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
@ -175,10 +224,29 @@ HashCompleteAndExtend (
FreePool (HashCtx); FreePool (HashCtx);
Status = Tpm2PcrExtend ( if (PcrIndex <= MAX_PCR_INDEX) {
PcrIndex, Status = Tpm2PcrExtend (
DigestList PcrIndex,
); DigestList
);
} else {
Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks);
ASSERT_EFI_ERROR (Status);
ActivePcrBanks = ActivePcrBanks & mSupportedHashMaskCurrent;
ZeroMem (&TcgPcrEvent2Digest, sizeof (TcgPcrEvent2Digest));
BufferPtr = CopyDigestListToBuffer (&TcgPcrEvent2Digest, DigestList, ActivePcrBanks);
DigestListBinSize = (UINT32)((UINT8 *)BufferPtr - (UINT8 *)&TcgPcrEvent2Digest);
//
// Extend to TPM NvIndex
//
Status = Tpm2ExtendNvIndex (
PcrIndex,
(UINT16)DigestListBinSize,
(BYTE *)&TcgPcrEvent2Digest
);
}
return Status; return Status;
} }

View File

@ -1,7 +1,7 @@
/** @file /** @file
Implement TPM2 NVStorage related command. Implement TPM2 NVStorage related command.
Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR> Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
**/ **/
@ -148,6 +148,22 @@ typedef struct {
TPMS_AUTH_RESPONSE AuthSession; TPMS_AUTH_RESPONSE AuthSession;
} TPM2_NV_GLOBALWRITELOCK_RESPONSE; } TPM2_NV_GLOBALWRITELOCK_RESPONSE;
typedef struct {
TPM2_COMMAND_HEADER Header;
TPMI_RH_NV_AUTH AuthHandle;
TPMI_RH_NV_INDEX NvIndex;
UINT32 AuthSessionSize;
TPMS_AUTH_COMMAND AuthSession;
TPM2B_MAX_BUFFER Data;
UINT16 Offset;
} TPM2_NV_EXTEND_COMMAND;
typedef struct {
TPM2_RESPONSE_HEADER Header;
UINT32 AuthSessionSize;
TPMS_AUTH_RESPONSE AuthSession;
} TPM2_NV_EXTEND_RESPONSE;
#pragma pack() #pragma pack()
/** /**
@ -1052,3 +1068,107 @@ Done:
ZeroMem (&RecvBuffer, sizeof (RecvBuffer)); ZeroMem (&RecvBuffer, sizeof (RecvBuffer));
return Status; return Status;
} }
/**
This command extends a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().
@param[in] AuthHandle the handle indicating the source of the authorization value.
@param[in] NvIndex The NV Index of the area to extend.
@param[in] AuthSession Auth Session context
@param[in] InData The data to extend.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
**/
EFI_STATUS
EFIAPI
Tpm2NvExtend (
IN TPMI_RH_NV_AUTH AuthHandle,
IN TPMI_RH_NV_INDEX NvIndex,
IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL,
IN TPM2B_MAX_BUFFER *InData
)
{
EFI_STATUS Status;
TPM2_NV_EXTEND_COMMAND SendBuffer;
TPM2_NV_EXTEND_RESPONSE RecvBuffer;
UINT32 SendBufferSize;
UINT32 RecvBufferSize;
UINT8 *Buffer;
UINT32 SessionInfoSize;
TPM_RC ResponseCode;
//
// Construct command
//
SendBuffer.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_NV_Extend);
SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
SendBuffer.NvIndex = SwapBytes32 (NvIndex);
//
// Add in Auth session
//
Buffer = (UINT8 *)&SendBuffer.AuthSession;
// sessionInfoSize
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
Buffer += SessionInfoSize;
SendBuffer.AuthSessionSize = SwapBytes32 (SessionInfoSize);
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (InData->size));
Buffer += sizeof (UINT16);
CopyMem (Buffer, InData->buffer, InData->size);
Buffer += InData->size;
SendBufferSize = (UINT32)(Buffer - (UINT8 *)&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 ((DEBUG_ERROR, "Tpm2NvExtend - RecvBufferSize Error - %x\n", RecvBufferSize));
Status = EFI_DEVICE_ERROR;
goto Done;
}
ResponseCode = SwapBytes32 (RecvBuffer.Header.responseCode);
if (ResponseCode != TPM_RC_SUCCESS) {
DEBUG ((DEBUG_ERROR, "Tpm2NvExtend - responseCode - %x\n", ResponseCode));
}
switch (ResponseCode) {
case TPM_RC_SUCCESS:
// return data
break;
case TPM_RC_ATTRIBUTES:
Status = EFI_UNSUPPORTED;
break;
case TPM_RC_NV_AUTHORIZATION:
Status = EFI_SECURITY_VIOLATION;
break;
case TPM_RC_NV_LOCKED:
Status = EFI_ACCESS_DENIED;
break;
default:
Status = EFI_DEVICE_ERROR;
break;
}
Done:
//
// Clear AuthSession Content
//
ZeroMem (&SendBuffer, sizeof (SendBuffer));
ZeroMem (&RecvBuffer, sizeof (RecvBuffer));
return Status;
}

View File

@ -1,7 +1,7 @@
/** @file /** @file
This module implements Tcg2 Protocol. This module implements Tcg2 Protocol.
Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR> Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/EventExitBootServiceFailed.h> #include <Guid/EventExitBootServiceFailed.h>
#include <Guid/ImageAuthentication.h> #include <Guid/ImageAuthentication.h>
#include <Guid/TpmInstance.h> #include <Guid/TpmInstance.h>
#include <Guid/DeviceAuthentication.h>
#include <Protocol/DevicePath.h> #include <Protocol/DevicePath.h>
#include <Protocol/MpService.h> #include <Protocol/MpService.h>
@ -1230,10 +1231,25 @@ TcgDxeHashLogExtendEvent (
// //
// Do not do TPM extend for EV_NO_ACTION // Do not do TPM extend for EV_NO_ACTION
// //
Status = EFI_SUCCESS; if (NewEventHdr->PCRIndex <= MAX_PCR_INDEX) {
InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize); Status = EFI_SUCCESS;
if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) { InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData); if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);
}
} else {
//
// Extend to NvIndex
//
Status = HashAndExtend (
NewEventHdr->PCRIndex,
HashData,
(UINTN)HashDataLen,
&DigestList
);
if (!EFI_ERROR (Status)) {
Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
}
} }
return Status; return Status;
@ -1317,7 +1333,7 @@ Tcg2HashLogExtendEvent (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (Event->Header.PCRIndex > MAX_PCR_INDEX) { if ((Event->Header.EventType != EV_NO_ACTION) && (Event->Header.PCRIndex > MAX_PCR_INDEX)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
@ -2063,7 +2079,7 @@ MeasureVariable (
); );
} }
if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) { if ((EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) || (EventType == EV_EFI_SPDM_DEVICE_POLICY)) {
// //
// Digest is the event data (UEFI_VARIABLE_DATA) // Digest is the event data (UEFI_VARIABLE_DATA)
// //
@ -2319,6 +2335,37 @@ MeasureAllSecureVariables (
DEBUG ((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2)); DEBUG ((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));
} }
//
// Meaurement UEFI device signature database
//
if ((PcdGet32 (PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106) &&
(PcdGet8 (PcdEnableSpdmDeviceAuthentication) != 0))
{
Status = GetVariable2 (EFI_DEVICE_SECURITY_DATABASE, &gEfiDeviceSignatureDatabaseGuid, &Data, &DataSize);
if (Status == EFI_SUCCESS) {
Status = MeasureVariable (
PCR_INDEX_FOR_SIGNATURE_DB,
EV_EFI_SPDM_DEVICE_POLICY,
EFI_DEVICE_SECURITY_DATABASE,
&gEfiDeviceSignatureDatabaseGuid,
Data,
DataSize
);
FreePool (Data);
} else if (Status == EFI_NOT_FOUND) {
Data = NULL;
DataSize = 0;
Status = MeasureVariable (
PCR_INDEX_FOR_SIGNATURE_DB,
EV_EFI_SPDM_DEVICE_POLICY,
EFI_DEVICE_SECURITY_DATABASE,
&gEfiDeviceSignatureDatabaseGuid,
Data,
DataSize
);
}
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -16,7 +16,7 @@
# This external input must be validated carefully to avoid security issue like # This external input must be validated carefully to avoid security issue like
# buffer overflow, integer overflow. # buffer overflow, integer overflow.
# #
# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
## ##
@ -86,6 +86,7 @@
gTcgEvent2EntryHobGuid ## SOMETIMES_CONSUMES ## HOB gTcgEvent2EntryHobGuid ## SOMETIMES_CONSUMES ## HOB
gTpm2StartupLocalityHobGuid ## SOMETIMES_CONSUMES ## HOB gTpm2StartupLocalityHobGuid ## SOMETIMES_CONSUMES ## HOB
gTcg800155PlatformIdEventHobGuid ## SOMETIMES_CONSUMES ## HOB gTcg800155PlatformIdEventHobGuid ## SOMETIMES_CONSUMES ## HOB
gEfiDeviceSignatureDatabaseGuid
[Protocols] [Protocols]
gEfiTcg2ProtocolGuid ## PRODUCES gEfiTcg2ProtocolGuid ## PRODUCES
@ -107,6 +108,7 @@
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLaml ## PRODUCES gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLaml ## PRODUCES
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLasa ## PRODUCES gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLasa ## PRODUCES
gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication ## CONSUMES
[Depex] [Depex]
# According to PcdTpm2AcpiTableRev definition in SecurityPkg.dec # According to PcdTpm2AcpiTableRev definition in SecurityPkg.dec