diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h b/SecurityPkg/Include/Library/Tpm2CommandLib.h
index a2fb97f18d..70eec84c90 100644
--- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
+++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
@@ -1,7 +1,7 @@
/** @file
This library is used by other modules to send TPM2 command.
-Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -467,6 +467,27 @@ Tpm2NvGlobalWriteLock (
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.
The digests parameter contains one or more tagged digest value identified by an algorithm ID.
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
index ee8fe6e06e..2169c5e185 100644
--- a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
+++ b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
@@ -3,7 +3,7 @@
hash handler registered, such as SHA1, SHA256.
Platform can use PcdTpm2HashMask to mask some hash engines.
-Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -16,6 +16,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include
#include
#include
+#include
#include "HashLibBaseCryptoRouterCommon.h"
@@ -128,6 +129,49 @@ HashUpdate (
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.
@@ -149,11 +193,16 @@ HashCompleteAndExtend (
OUT TPML_DIGEST_VALUES *DigestList
)
{
- TPML_DIGEST_VALUES Digest;
- HASH_HANDLE *HashCtx;
- UINTN Index;
- EFI_STATUS Status;
- UINT32 HashMask;
+ TPML_DIGEST_VALUES Digest;
+ HASH_HANDLE *HashCtx;
+ UINTN Index;
+ EFI_STATUS Status;
+ UINT32 HashMask;
+ TPML_DIGEST_VALUES TcgPcrEvent2Digest;
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;
+ UINT32 ActivePcrBanks;
+ UINT32 *BufferPtr;
+ UINT32 DigestListBinSize;
if (mHashInterfaceCount == 0) {
return EFI_UNSUPPORTED;
@@ -175,10 +224,29 @@ HashCompleteAndExtend (
FreePool (HashCtx);
- Status = Tpm2PcrExtend (
- PcrIndex,
- DigestList
- );
+ if (PcrIndex <= MAX_PCR_INDEX) {
+ Status = Tpm2PcrExtend (
+ 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;
}
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
index 5077ace7c2..f11f7696b1 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
@@ -1,7 +1,7 @@
/** @file
Implement TPM2 NVStorage related command.
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -148,6 +148,22 @@ typedef struct {
TPMS_AUTH_RESPONSE AuthSession;
} 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()
/**
@@ -1052,3 +1068,107 @@ Done:
ZeroMem (&RecvBuffer, sizeof (RecvBuffer));
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;
+}
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
index f6ea8b2bbf..b8f50e25df 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
@@ -1,7 +1,7 @@
/** @file
This module implements Tcg2 Protocol.
-Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include
#include
#include
+#include
#include
#include
@@ -1230,10 +1231,25 @@ TcgDxeHashLogExtendEvent (
//
// Do not do TPM extend for EV_NO_ACTION
//
- Status = EFI_SUCCESS;
- InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
- if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
- Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);
+ if (NewEventHdr->PCRIndex <= MAX_PCR_INDEX) {
+ Status = EFI_SUCCESS;
+ InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
+ 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;
@@ -1317,7 +1333,7 @@ Tcg2HashLogExtendEvent (
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;
}
@@ -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)
//
@@ -2319,6 +2335,37 @@ MeasureAllSecureVariables (
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;
}
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
index 7dc7a2683d..a645474bf3 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
@@ -16,7 +16,7 @@
# This external input must be validated carefully to avoid security issue like
# buffer overflow, integer overflow.
#
-# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -86,6 +86,7 @@
gTcgEvent2EntryHobGuid ## SOMETIMES_CONSUMES ## HOB
gTpm2StartupLocalityHobGuid ## SOMETIMES_CONSUMES ## HOB
gTcg800155PlatformIdEventHobGuid ## SOMETIMES_CONSUMES ## HOB
+ gEfiDeviceSignatureDatabaseGuid
[Protocols]
gEfiTcg2ProtocolGuid ## PRODUCES
@@ -107,6 +108,7 @@
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLaml ## PRODUCES
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLasa ## PRODUCES
gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication ## CONSUMES
[Depex]
# According to PcdTpm2AcpiTableRev definition in SecurityPkg.dec