From a35a08c5c8d9308ba2b63a15a40e4ddc3e265dbd Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Tue, 13 Feb 2024 16:30:10 -0500 Subject: [PATCH 05/17] SecurityPkg: Support CcMeasurementProtocol in DxeTpmMeasurementLib RH-Author: Jon Maloy RH-MergeRequest: 44: edk2: heap buffer overflow in Tcg2MeasureGptTable() RH-Jira: RHEL-21154 RHEL-21156 RH-Acked-by: Laszlo Ersek RH-Commit: [5/13] fa844740ca589cabb52ae7dfa0dd329315dc168f (jmaloy/jons_fork) JIRA: https://issues.redhat.com/browse/RHEL-21154 CVE: CVE-2022-36763 Upstream: Merged Conflicts: Only cosmetic, due to the uncrustify changes made in the newer version. commit 314ff1dc8c9a9597280b50e44a5c861cb6a58517 (HEAD -> CVE-2022-36763_RHEL-21154_rhel-8.10.0) Author: Min Xu Date: Sat Dec 11 21:08:42 2021 +0800 SecurityPkg: Support CcMeasurementProtocol in DxeTpmMeasurementLib BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3625 DxeTpmMeasurementLib supports TPM based measurement in DXE phase. After CcMeasurementProtocol is introduced, CC based measurement needs to be supported in DxeTpmMeasurementLib as well. A platform should have only one RTS/RTR. Only one of (virtual)TPM1.2, (virtual)TPM2.0 and CC MR exists. Then only one TCG_SERVICE_PROTOCOL, TCG2_PROTOCOL, CC_MEASUREMENT_PROTOCOL is exposed. In this library when do measurement only one of above 3 protocols will be called. Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Jiewen Yao Cc: Jian J Wang Cc: Sami Mujawar Cc: Gerd Hoffmann Reviewed-by: Sami Mujawar Reviewed-by: Jiewen Yao Signed-off-by: Min Xu Signed-off-by: Jon Maloy --- .../DxeTpmMeasurementLib.c | 122 +++++++++++++++--- .../DxeTpmMeasurementLib.inf | 9 +- 2 files changed, 111 insertions(+), 20 deletions(-) diff --git a/SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.c b/SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.c index 061136ee78..802bc3c3cd 100644 --- a/SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.c +++ b/SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.c @@ -1,5 +1,6 @@ /** @file - This library is used by other modules to measure data to TPM. + This library is used by other modules to measure data to TPM and Confidential + Computing (CC) measure registers. Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -19,6 +20,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +#include @@ -37,6 +39,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent @retval EFI_OUT_OF_RESOURCES Out of memory. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ +STATIC EFI_STATUS Tpm12MeasureAndLogData ( IN UINT32 PcrIndex, @@ -103,6 +106,7 @@ Tpm12MeasureAndLogData ( @retval EFI_OUT_OF_RESOURCES Out of memory. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ +STATIC EFI_STATUS Tpm20MeasureAndLogData ( IN UINT32 PcrIndex, @@ -149,6 +153,73 @@ Tpm20MeasureAndLogData ( return Status; } +/** + Cc measure and log data, and extend the measurement result into a + specific CC MR. + + @param[in] CcProtocol Instance of CC measurement protocol + @param[in] PcrIndex PCR Index. + @param[in] EventType Event type. + @param[in] EventLog Measurement event log. + @param[in] LogLen Event log length in bytes. + @param[in] HashData The start of the data buffer to be hashed, extended. + @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_UNSUPPORTED CC guest not available. + @retval EFI_OUT_OF_RESOURCES Out of memory. + @retval EFI_DEVICE_ERROR The operation was unsuccessful. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. +**/ +STATIC +EFI_STATUS +CcMeasureAndLogData ( + IN EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol, + IN UINT32 PcrIndex, + IN UINT32 EventType, + IN VOID *EventLog, + IN UINT32 LogLen, + IN VOID *HashData, + IN UINT64 HashDataLen + ) +{ + EFI_STATUS Status; + EFI_CC_EVENT *EfiCcEvent; + EFI_CC_MR_INDEX MrIndex; + + if (CcProtocol == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = CcProtocol->MapPcrToMrIndex (CcProtocol, PcrIndex, &MrIndex); + if (EFI_ERROR (Status)) { + return Status; + } + + EfiCcEvent = (EFI_CC_EVENT *)AllocateZeroPool (LogLen + sizeof (EFI_CC_EVENT)); + if (EfiCcEvent == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + EfiCcEvent->Size = (UINT32)LogLen + sizeof (EFI_CC_EVENT) - sizeof (EfiCcEvent->Event); + EfiCcEvent->Header.HeaderSize = sizeof (EFI_CC_EVENT_HEADER); + EfiCcEvent->Header.HeaderVersion = EFI_CC_EVENT_HEADER_VERSION; + EfiCcEvent->Header.MrIndex = MrIndex; + EfiCcEvent->Header.EventType = EventType; + CopyMem (&EfiCcEvent->Event[0], EventLog, LogLen); + + Status = CcProtocol->HashLogExtendEvent ( + CcProtocol, + 0, + (EFI_PHYSICAL_ADDRESS)(UINTN)HashData, + HashDataLen, + EfiCcEvent + ); + FreePool (EfiCcEvent); + + return Status; +} + /** Tpm measure and log data, and extend the measurement result into a specific PCR. @@ -175,25 +246,16 @@ TpmMeasureAndLogData ( IN UINT64 HashDataLen ) { - EFI_STATUS Status; - - // - // Try to measure using Tpm20 protocol - // - Status = Tpm20MeasureAndLogData( - PcrIndex, - EventType, - EventLog, - LogLen, - HashData, - HashDataLen - ); + EFI_STATUS Status; + EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol; - if (EFI_ERROR (Status)) { + Status = gBS->LocateProtocol (&gEfiCcMeasurementProtocolGuid, NULL, (VOID **)&CcProtocol); + if (!EFI_ERROR (Status)) { // - // Try to measure using Tpm1.2 protocol + // Try to measure using Cc measurement protocol // - Status = Tpm12MeasureAndLogData( + Status = CcMeasureAndLogData ( + CcProtocol, PcrIndex, EventType, EventLog, @@ -201,6 +263,32 @@ TpmMeasureAndLogData ( HashData, HashDataLen ); + } else { + // + // Try to measure using Tpm20 protocol + // + Status = Tpm20MeasureAndLogData ( + PcrIndex, + EventType, + EventLog, + LogLen, + HashData, + HashDataLen + ); + + if (EFI_ERROR (Status)) { + // + // Try to measure using Tpm1.2 protocol + // + Status = Tpm12MeasureAndLogData ( + PcrIndex, + EventType, + EventLog, + LogLen, + HashData, + HashDataLen + ); + } } return Status; diff --git a/SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf b/SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf index 7d41bc41f9..3af3d4e33b 100644 --- a/SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf +++ b/SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf @@ -1,5 +1,7 @@ ## @file -# Provides TPM measurement functions for TPM1.2 and TPM 2.0 +# Provides below measurement functions: +# 1. TPM measurement functions for TPM1.2 and TPM 2.0 +# 2. Confidential Computing (CC) measurement functions # # This library provides TpmMeasureAndLogData() to measure and log data, and # extend the measurement result into a specific PCR. @@ -40,5 +42,6 @@ UefiBootServicesTableLib [Protocols] - gEfiTcgProtocolGuid ## SOMETIMES_CONSUMES - gEfiTcg2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiTcgProtocolGuid ## SOMETIMES_CONSUMES + gEfiTcg2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiCcMeasurementProtocolGuid ## SOMETIMES_CONSUMES -- 2.41.0