Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions MdePkg/Include/IndustryStandard/Tpm2Acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,36 @@ typedef struct {
UINT8 Reserved[8];
} EFI_TPM2_ACPI_START_METHOD_SPECIFIC_PARAMETERS_ARM_FFA;

// MU_CHANGE - [BEGIN]

typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
// Flags field is replaced in version 4 and above
// BIT0~15: PlatformClass This field is only valid for version 4 and above
// BIT16~31: Reserved
UINT32 Flags;
UINT64 AddressOfControlArea;
UINT32 StartMethod;
UINT8 PlatformSpecificParameters[12]; // size up to 12
UINT32 Laml; // Optional
UINT64 Lasa; // Optional
} EFI_TPM2_ACPI_TABLE_V4;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to combine this with EFI_TPM2_ACPI_TABLE


typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
// Flags field is replaced in version 4 and above
// BIT0~15: PlatformClass This field is only valid for version 4 and above
// BIT16~31: Reserved
UINT32 Flags;
UINT64 AddressOfControlArea;
UINT32 StartMethod;
EFI_TPM2_ACPI_START_METHOD_SPECIFIC_PARAMETERS_ARM_FFA FfaParameters;
UINT32 Laml; // Optional
UINT64 Lasa; // Optional
} EFI_TPM2_ACPI_TABLE_V5;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this really a version 5 table and is it really hard coded to FFA? Seems like we should use unions and make a more flexible data structure. What is the guidance for non FFA TPMs. What table version do they use? I also don't see a place for EFI_TPM2_ACPI_START_METHOD_SPECIFIC_PARAMETERS_ARM_SMC in the table. Again, I assume there is a flavor of the table that has this.


// MU_CHANGE - [END]

#define EFI_TPM2_ACPI_TABLE_ARM_FFA_PARAMETER_FLAG_NOTIFICATION_SUPPORT BIT0

#define EFI_TPM2_ACPI_TABLE_ARM_FFA_PARAMETER_ATTR_MEM_TYPE_MASK 0x3
Expand Down
5 changes: 5 additions & 0 deletions MdePkg/Include/IndustryStandard/UefiTcgPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@
#define FIRMWARE_DEBUGGER_EVENT_STRING "UEFI Debug Mode"
#define FIRMWARE_DEBUGGER_EVENT_STRING_LEN (sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1)

// MU_CHANGE
// String logged as a NO_ACTION event to mark the ACPI-visible TCG
// log as truncated when dynamic scaling occurs post ReadyToBoot.
#define TCG_LOG_TRUNCATION_EVENT_STRING "TCG Event Log Truncated"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

follow existing pattern to add len

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment that this is not yet spec defined. do we have plans to take to tcg?

//
// Set structure alignment to 1-byte
//
Expand Down
7 changes: 7 additions & 0 deletions SecurityPkg/SecurityPkg.dec
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,13 @@
# Include/Protocol/MuTcg2Protocol.h
gMuTcg2ProtocolExGuid = {0x227e7984, 0x1a77, 0x4762, { 0x96, 0x69, 0x57, 0x4c, 0xda, 0xd1, 0xa0, 0x1e }}
## MU_CHANGE - END - Add a new protocol to support Log-only events.

## MU_CHANGE - [BEGIN]
## Protocol used to test dynamic TCG log scaling functionality.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a private protocol with visibility only to the test app and test dxe driver.

I could see two options.

  1. just note that here
  2. don't create a package defined global for it and just include the guid define in the header file.

# Tcg/TcgLogTest/TcgLogTest.h
gTcgLogTestProtocolGuid = {0xa3c12f80, 0x7d9e, 0x4b5a, { 0x91, 0xe4, 0x6c, 0xf8, 0x2d, 0xa1, 0xb7, 0x03 }}
## MU_CHANGE - [END]

[Ppis]
## The PPI GUID for that TPM physical presence should be locked.
# Include/Ppi/LockPhysicalPresence.h
Expand Down
10 changes: 10 additions & 0 deletions SecurityPkg/SecurityPkg.dsc
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,16 @@

SecurityPkg/Applications/TpmShellApp/TpmShellApp.inf ## MU_CHANGE

## MU_CHANGE - [BEGIN]
SecurityPkg/Tcg/TcgLogTest/TcgLogTestDxe.inf
SecurityPkg/Tcg/TcgLogTest/TcgLogTestApp.inf {
<LibraryClasses>
UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf
UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these don't look right for a functioning app

UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf
}
## MU_CHANGE - [END]

#
# TCG Storage.
#
Expand Down
12 changes: 10 additions & 2 deletions SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
#define MAX_PRS_INT_BUF_SIZE (15*4)

#pragma pack(1)
// MU_CHANGE - [BEGIN]

#if 0

#pragma pack(1)

typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
Expand All @@ -89,7 +93,11 @@ typedef struct {
UINT64 Lasa; // Optional
} EFI_TPM2_ACPI_TABLE_V4;

#pragma pack()
#pragma pack()

#endif

// MU_CHANGE - [END]

EFI_TPM2_ACPI_TABLE_V4 mTpm2AcpiTemplate = {
{
Expand Down
12 changes: 10 additions & 2 deletions SecurityPkg/Tcg/Tcg2AcpiFfa/Tcg2AcpiFfa.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
#define MAX_PRS_INT_BUF_SIZE (15*4)

#pragma pack(1)
// MU_CHANGE - [BEGIN]

#if 0

#pragma pack(1)

typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
Expand All @@ -81,7 +85,11 @@ typedef struct {
UINT64 Lasa; // Optional
} EFI_TPM2_ACPI_TABLE_V5;

#pragma pack()
#pragma pack()

#endif

// MU_CHANGE - [END]

EFI_TPM2_ACPI_TABLE_V5 mTpm2AcpiTemplate = {
{
Expand Down
83 changes: 83 additions & 0 deletions SecurityPkg/Tcg/Tcg2Dxe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Tcg2Dxe

Tcg2Dxe is a DXE-phase UEFI driver that publishes the TCG2 protocol defined
by the [TCG EFI Protocol Specification](https://trustedcomputinggroup.org/resource/tcg-efi-protocol-specification/).
It's main responsibilites are to expose a standard interface to a TPM device,
measure components and events into PCRs, support measured boot, and enable
secure boot attestation.

## Dynamic Event Log Scaling

The TCG event log is initially allocated with a fixed size defined by a
PCD: PcdTcgLogAreaMinLen. As firmware components log measured boot
events the log fills up. Traditionally, when the log is full, subsequent events
are dropped and the log is marked as truncated.

Tcg2Dxe extends this behavior with **dynamic scaling**: when the log is about
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably important to call out here the different behaviors based on time of execution (pre ready to boot vs post).

to overflow, the driver doubles its allocation, copies the existing log into
the new buffer, and frees the old one. This allows the log to grow as needed
and avoids losing events.

### How It Works

1. **Scaling check** — Before logging a TCG 2.0 event,
`TcgLogDynamicScalingNeeded` calculates whether the new event (plus a
reserved truncation marker) would exceed the current allocation
(`EventLogAreaStruct->Laml`). Space is reserved for the truncation marker
as long as the ACPI log has not yet been marked truncated.

2. **Reallocation** — When scaling is needed, `TcgScaleEventLog` allocates a
new `EfiBootServicesData` region at twice the current size, copies the
existing log, updates the `Lasa`/`Laml` fields in the event log area
struct, and frees the old region.

3. **Logging** — After scaling, the new event is logged into the resized buffer
via `TcgDxeLogEvent` inside a TPL-raised critical section.

### Normal Log vs. ACPI Log vs. Final Events Log

Tcg2Dxe maintains three distinct event log regions:

| Log | Memory Type | Lifetime | Can Scale |
| --- | ----------- | -------- | --------- |
| **Normal log** | `EfiBootServicesData` | Available until `ExitBootServices` | Yes |
| **ACPI log** | `EfiACPIMemoryNVS` | Persistent | No |
| **Final Events log** | `EfiACPIMemoryNVS` | Persistent | No |

- The **Normal log** is the main log copy which is returned via `GetEventLog`.
It can grow dynamically via scaling. Note that previous calls to `GetEventLog`
could contain stale data if the log was scaled after. It is recommended to
call `GetEventLog` each time access is required.
- The **ACPI log** is created at `ReadyToBoot` by `GenerateAcpiLog`. It
allocates an `EfiACPIMemoryNVS` region equal to the **Normal log** size at that
point, copies the log contents, and updates the TPM2 ACPI table's
`LAML`/`LASA` fields so the OS can find it. If the TPM2 table was already
installed via Tcg2Acpi/Tcg2AcpiFfa, `GenerateAcpiLog` will uninstall and
reinstall the ACPI table with the updated LAML and LASA pointing to the
newly allocated NVS region.
- The **Final Events log** (`EFI_TCG2_FINAL_EVENTS_TABLE`) records events
logged after `GetEventLog` has been called. It is installed as a UEFI
configuration table so the OS can discover events that occurred between its
call to `GetEventLog` and `ExitBootServices`. Because the **Final Events log**
does not scale, it can become truncated.

After `ReadyToBoot`, every new event is also appended to the ACPI log. Because
the ACPI log's NVS allocation is fixed (the OS may already be referencing its
address), it cannot be reallocated.

### Post-ReadyToBoot Truncation

When dynamic scaling is triggered after `ReadyToBoot`:

1. A `NO_ACTION` event with the payload `"TCG Event Log Truncated"` is
appended to the **ACPI log** to notify the OS that the ACPI-visible log is
now incomplete.
2. The ACPI log is marked truncated (`EventLogTruncated = TRUE`) so no further
events are written to it and no additional space is reserved for the
truncation marker.
3. The **normal log** is scaled as usual — it continues to grow and accept new
events.

This means the normal log accessed via `GetEventLog` always has the complete
set of events, while the ACPI log visible to the OS may be truncated with a
marker at the end.
Loading
Loading