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