diff --git a/MdeModulePkg/Include/Protocol/LogTcg2EventProtocol.h b/MdeModulePkg/Include/Protocol/LogTcg2EventProtocol.h new file mode 100644 index 0000000000..aa596ae53b --- /dev/null +++ b/MdeModulePkg/Include/Protocol/LogTcg2EventProtocol.h @@ -0,0 +1,87 @@ +/** @file + EDKII Log TCG2 Event Protocol definition. + + This protocol provides a service to add an entry to the TCG2 event log from + a caller-supplied digest list, without measuring (hashing and extending) the + event into a PCR. It is intended for callers that have already performed, or + intentionally skipped, the PCR extend and only need the event recorded in the + log. + + See the TCG PC Client Platform Firmware Profile Specification for the event + log format. Refer to http://trustedcomputinggroup.org for the latest + specifications. + +Copyright (c) Qualcomm Technologies, Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#pragma once + +extern EFI_GUID gEdkiiLogTcg2EventProtocolGuid; + +// +// Protocol GUID. +// +#define EDKII_LOG_TCG2_EVENT_PROTOCOL_GUID \ + {0xf82300be, 0x6568, 0x46fa, { 0x96, 0xf2, 0xd5, 0xe5, 0x8d, 0x82, 0x07, 0xcd }} + +// +// Protocol revision. +// +#define EDKII_LOG_TCG2_EVENT_PROTOCOL_REVISION 0x0000000000010000 + +// +// Forward declaration of the protocol structure. +// +typedef struct _EDKII_LOG_TCG2_EVENT_PROTOCOL EDKII_LOG_TCG2_EVENT_PROTOCOL; + +/** + Add an event to the TCG2 event log using the supplied digest list. + + This logs the event described by Tcg2Event together with the digests in + DigestList. Unlike EFI_TCG2_PROTOCOL.HashLogExtendEvent, this service only + records the event in the log; it does not compute any digest and does not + extend a PCR. The caller is responsible for providing digests that are + consistent with the platform's active PCR banks. + + @param[in] This Pointer to the EDKII_LOG_TCG2_EVENT_PROTOCOL + instance. + @param[in] DigestList Pointer to a TPML_DIGEST_VALUES structure + containing the digests to record for the event. + @param[in] DigestListSize Size, in bytes, of the buffer pointed to by + DigestList. + @param[in] Tcg2Event Pointer to an EFI_TCG2_EVENT structure that + describes the event to log. + @param[in] Tcg2EventSize Size, in bytes, of the buffer pointed to by + Tcg2Event. + + @retval EFI_SUCCESS The event was added to the event log. + @retval EFI_INVALID_PARAMETER A parameter is NULL, zero, or otherwise + inconsistent (for example, DigestListSize does + not match the described digests). + @retval EFI_BUFFER_TOO_SMALL Tcg2EventSize is too small for the described + event. + @retval EFI_DEVICE_ERROR The TPM is not present or the event could not + be logged. +**/ +typedef +EFI_STATUS +(EFIAPI *LOG_TCG2_EVENT)( + IN EDKII_LOG_TCG2_EVENT_PROTOCOL *This, + IN VOID *DigestList, + IN UINTN DigestListSize, + IN VOID *Tcg2Event, + IN UINTN Tcg2EventSize + ); + +struct _EDKII_LOG_TCG2_EVENT_PROTOCOL { + // + // Protocol revision, EDKII_LOG_TCG2_EVENT_PROTOCOL_REVISION. + // + UINT64 Revision; + // + // Adds an event to the TCG2 event log from a caller-supplied digest list. + // + LOG_TCG2_EVENT LogEvent; +}; diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index f6b1a73d70..5857e48e1d 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -762,6 +762,9 @@ ## Include/Protocol/CxlIo.h gEdkiiCxlIoProtocolGuid = { 0x8FAC60B2, 0xBBC1, 0x41DE, {0xA7, 0x97, 0x98, 0x75, 0xCD, 0xD3, 0xA8, 0xF8 } } + ## Include/Protocol/LogTcg2EventProtocol.h + gEdkiiLogTcg2EventProtocolGuid = { 0xf82300be, 0x6568, 0x46fa, { 0x96, 0xf2, 0xd5, 0xe5, 0x8d, 0x82, 0x07, 0xcd } } + [PcdsFeatureFlag] ## Indicates if the platform can support update capsule across a system reset.

# TRUE - Supports update capsule across a system reset.
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c index b0383fac47..ffb8d1224a 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c @@ -3,6 +3,7 @@ Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
+Copyright (c) Qualcomm Technologies, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -27,6 +28,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include @@ -1885,6 +1887,180 @@ EFI_TCG2_PROTOCOL mTcg2Protocol = { Tcg2GetResultOfSetActivePcrBanks, }; +/** + Add an event to the TCG2 event log using the supplied digest list. + + This is the EDKII_LOG_TCG2_EVENT_PROTOCOL.LogEvent implementation. It logs + the event described by Tcg2Event together with the caller-supplied digests in + DigestList, mirroring the logging portion of Tcg2HashLogExtendEvent but + without computing any digest or extending a PCR. It is intended for callers + that have already performed, or intentionally skipped, the PCR extend and + only need the event recorded in the log. + + The caller is responsible for providing digests that are consistent with the + platform's active PCR banks; DigestList and Tcg2Event are validated for + self-consistency before anything is written to the log. + + @param[in] This Pointer to the EDKII_LOG_TCG2_EVENT_PROTOCOL + instance. + @param[in] DigestList Pointer to a TPML_DIGEST_VALUES structure + containing the digests to record for the event. + @param[in] DigestListSize Size, in bytes, of the buffer pointed to by + DigestList. + @param[in] Tcg2Event Pointer to an EFI_TCG2_EVENT structure that + describes the event to log. + @param[in] Tcg2EventSize Size, in bytes, of the buffer pointed to by + Tcg2Event. + + @retval EFI_SUCCESS The event was added to the event log. + @retval EFI_INVALID_PARAMETER A parameter is NULL, zero, or otherwise + inconsistent (for example, DigestListSize does + not match the described digests). + @retval EFI_BUFFER_TOO_SMALL Tcg2EventSize is too small for the described + event. + @retval EFI_DEVICE_ERROR The TPM is not present or the event could not + be logged. +**/ +EFI_STATUS +EFIAPI +Tcg2LogEvent ( + IN EDKII_LOG_TCG2_EVENT_PROTOCOL *This, + IN VOID *DigestList, + IN UINTN DigestListSize, + IN VOID *Tcg2Event, + IN UINTN Tcg2EventSize + ) +{ + EFI_STATUS Status; + TCG_PCR_EVENT_HDR NewEventHdr; + EFI_TCG2_EVENT *Event; + TPML_DIGEST_VALUES *DigestValues; + UINT32 DigestCount; + UINT32 DigestIndex; + UINT16 DigestSize; + UINTN ExpectedSize; + + DEBUG ((DEBUG_INFO, "Tcg2LogEvent ...\n")); + + // + // Reject NULL pointers and zero-length buffers up front. + // + if ((This == NULL) || (DigestList == NULL) || (DigestListSize == 0) || + (Tcg2Event == NULL) || (Tcg2EventSize == 0)) + { + return EFI_INVALID_PARAMETER; + } + + DigestValues = (TPML_DIGEST_VALUES *)DigestList; + + // + // The buffer must be large enough to hold the fixed TPML_DIGEST_VALUES + // header before its digest count can be trusted. + // + if (DigestListSize < OFFSET_OF (TPML_DIGEST_VALUES, digests)) { + return EFI_INVALID_PARAMETER; + } + + DigestCount = DigestValues->count; + if ((DigestCount == 0) || (DigestCount > HASH_COUNT)) { + return EFI_INVALID_PARAMETER; + } + + // + // Walk the variable-length digest array, accumulating the exact size implied + // by each digest's hash algorithm. This both validates every algorithm and + // guards against a digest that would run past the end of the buffer. + // + ExpectedSize = OFFSET_OF (TPML_DIGEST_VALUES, digests); + for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) { + DigestSize = GetHashSizeFromAlgo (DigestValues->digests[DigestIndex].hashAlg); + + if (DigestSize == 0) { + return EFI_INVALID_PARAMETER; + } + + ExpectedSize += sizeof (TPMI_ALG_HASH) + DigestSize; + if (ExpectedSize > DigestListSize) { + return EFI_INVALID_PARAMETER; + } + } + + // + // The accumulated size must match DigestListSize exactly; a larger buffer + // implies trailing or malformed data. + // + if (ExpectedSize != DigestListSize) { + return EFI_INVALID_PARAMETER; + } + + // + // Logging requires a present TPM. + // + if (!mTcgDxeData.BsCap.TPMPresentFlag) { + return EFI_DEVICE_ERROR; + } + + Event = (EFI_TCG2_EVENT *)Tcg2Event; + + // + // Validate the EFI_TCG2_EVENT: it must be large enough for the fixed fields, + // carry the expected header size and version, and declare a self-consistent + // Size that fits within the caller-supplied buffer. + // + if (Tcg2EventSize < OFFSET_OF (EFI_TCG2_EVENT, Event)) { + return EFI_BUFFER_TOO_SMALL; + } + + if (Event->Header.HeaderSize != sizeof (EFI_TCG2_EVENT_HEADER)) { + return EFI_INVALID_PARAMETER; + } + + if (Event->Header.HeaderVersion != EFI_TCG2_EVENT_HEADER_VERSION) { + return EFI_INVALID_PARAMETER; + } + + if (Event->Size < Event->Header.HeaderSize + sizeof (Event->Size)) { + return EFI_INVALID_PARAMETER; + } + + if (Event->Size > Tcg2EventSize) { + return EFI_BUFFER_TOO_SMALL; + } + + // + // Every event except EV_NO_ACTION must target a valid PCR index. + // + if ((Event->Header.EventType != EV_NO_ACTION) && (Event->Header.PCRIndex > MAX_PCR_INDEX)) { + return EFI_INVALID_PARAMETER; + } + + // + // Build the internal event header and hand it to the shared log routine. + // EventSize is the payload length: total Size minus the leading UINT32 Size + // field and the event header. + // + NewEventHdr.PCRIndex = Event->Header.PCRIndex; + NewEventHdr.EventType = Event->Header.EventType; + NewEventHdr.EventSize = Event->Size - sizeof (UINT32) - Event->Header.HeaderSize; + + Status = TcgDxeLogHashEvent ( + DigestValues, + &NewEventHdr, + Event->Event + ); + + DEBUG ((DEBUG_VERBOSE, "Tcg2LogEvent - %r\n", Status)); + return Status; +} + +// +// Instance of the EDKII Log TCG2 Event Protocol produced by this driver. +// +EDKII_LOG_TCG2_EVENT_PROTOCOL mLogTcg2EventProtocol = { + EDKII_LOG_TCG2_EVENT_PROTOCOL_REVISION, + Tcg2LogEvent +}; + /** Initialize the Event Log and log events passed from the PEI phase. @@ -3094,6 +3270,8 @@ InstallTcg2 ( &Handle, &gEfiTcg2ProtocolGuid, &mTcg2Protocol, + &gEdkiiLogTcg2EventProtocolGuid, + &mLogTcg2EventProtocol, NULL ); return Status; diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf index dc367e6301..aaee676f85 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf @@ -17,6 +17,7 @@ # buffer overflow, integer overflow. # # Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
+# Copyright (c) Qualcomm Technologies, Inc. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -92,6 +93,7 @@ [Protocols] gEfiTcg2ProtocolGuid ## PRODUCES + gEdkiiLogTcg2EventProtocolGuid ## PRODUCES gEfiTcg2FinalEventsTableGuid ## PRODUCES gEfiMpServiceProtocolGuid ## SOMETIMES_CONSUMES gEfiVariableWriteArchProtocolGuid ## NOTIFY