From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../SmbiosMeasurementDxe/SmbiosMeasurementDxe.c | 671 +++++++++++++++++++++ 1 file changed, 671 insertions(+) create mode 100644 roms/edk2/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c (limited to 'roms/edk2/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c') diff --git a/roms/edk2/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c b/roms/edk2/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c new file mode 100644 index 000000000..1050c9b17 --- /dev/null +++ b/roms/edk2/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c @@ -0,0 +1,671 @@ +/** @file + This driver measures SMBIOS table to TPM. + +Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FIELD_SIZE_OF(TYPE, Field) ((UINTN)sizeof(((TYPE *)0)->Field)) + +typedef struct { + UINT8 Type; + UINTN Offset; + UINTN Size; + UINT32 Flags; +} SMBIOS_FILTER_TABLE; +#define SMBIOS_FILTER_TABLE_FLAG_IS_STRING BIT0 + +typedef struct { + UINT8 Type; + SMBIOS_FILTER_TABLE *Filter; // NULL means all fields + UINTN FilterCount; +} SMBIOS_FILTER_STRUCT; + +// +// Platform Specific Policy +// +SMBIOS_FILTER_TABLE mSmbiosFilterType1BlackList[] = { + {0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, Uuid), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, Uuid), 0}, + {0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, WakeUpType), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, WakeUpType), 0}, +}; +SMBIOS_FILTER_TABLE mSmbiosFilterType2BlackList[] = { + {0x02, OFFSET_OF(SMBIOS_TABLE_TYPE2, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE2, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x02, OFFSET_OF(SMBIOS_TABLE_TYPE2, LocationInChassis), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE2, LocationInChassis), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, +}; +SMBIOS_FILTER_TABLE mSmbiosFilterType3BlackList[] = { + {0x03, OFFSET_OF(SMBIOS_TABLE_TYPE3, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE3, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x03, OFFSET_OF(SMBIOS_TABLE_TYPE3, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE3, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, +}; +SMBIOS_FILTER_TABLE mSmbiosFilterType4BlackList[] = { + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, PartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, PartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, CoreCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, CoreCount), 0}, + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount), 0}, + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, ThreadCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, ThreadCount), 0}, + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, CoreCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, CoreCount2), 0}, + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount2), 0}, + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, ThreadCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, ThreadCount2), 0}, + {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, Voltage), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, Voltage), 0}, +}; +SMBIOS_FILTER_TABLE mSmbiosFilterType17BlackList[] = { + {0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, PartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, PartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, +}; +SMBIOS_FILTER_TABLE mSmbiosFilterType22BlackList[] = { + {0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SBDSSerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SBDSSerialNumber), 0}, + {0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SBDSManufactureDate), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SBDSManufactureDate), 0}, +}; +SMBIOS_FILTER_TABLE mSmbiosFilterType23BlackList[] = { + {0x17, OFFSET_OF(SMBIOS_TABLE_TYPE23, ResetCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE23, ResetCount), 0}, +}; +SMBIOS_FILTER_TABLE mSmbiosFilterType27BlackList[] = { + {0x1B, OFFSET_OF(SMBIOS_TABLE_TYPE27, NominalSpeed), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE27, NominalSpeed), 0}, +}; +SMBIOS_FILTER_TABLE mSmbiosFilterType39BlackList[] = { + {0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, AssetTagNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, AssetTagNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, + {0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, ModelPartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, ModelPartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING}, +}; + +SMBIOS_FILTER_STRUCT mSmbiosFilterStandardTableBlackList[] = { + {0x01, mSmbiosFilterType1BlackList, sizeof(mSmbiosFilterType1BlackList)/sizeof(mSmbiosFilterType1BlackList[0])}, + {0x02, mSmbiosFilterType2BlackList, sizeof(mSmbiosFilterType2BlackList)/sizeof(mSmbiosFilterType2BlackList[0])}, + {0x03, mSmbiosFilterType3BlackList, sizeof(mSmbiosFilterType3BlackList)/sizeof(mSmbiosFilterType3BlackList[0])}, + {0x04, mSmbiosFilterType4BlackList, sizeof(mSmbiosFilterType4BlackList)/sizeof(mSmbiosFilterType4BlackList[0])}, + {0x0B, NULL, 0}, + {0x0F, NULL, 0}, + {0x11, mSmbiosFilterType17BlackList, sizeof(mSmbiosFilterType17BlackList)/sizeof(mSmbiosFilterType17BlackList[0])}, + {0x12, NULL, 0}, + {0x16, mSmbiosFilterType22BlackList, sizeof(mSmbiosFilterType22BlackList)/sizeof(mSmbiosFilterType22BlackList[0])}, + {0x17, mSmbiosFilterType23BlackList, sizeof(mSmbiosFilterType23BlackList)/sizeof(mSmbiosFilterType23BlackList[0])}, + {0x1B, mSmbiosFilterType27BlackList, sizeof(mSmbiosFilterType27BlackList)/sizeof(mSmbiosFilterType27BlackList[0])}, + {0x1F, NULL, 0}, + {0x21, NULL, 0}, + {0x27, mSmbiosFilterType39BlackList, sizeof(mSmbiosFilterType39BlackList)/sizeof(mSmbiosFilterType39BlackList[0])}, +}; + +EFI_SMBIOS_PROTOCOL *mSmbios; +UINTN mMaxLen; + +#pragma pack (1) + +#define SMBIOS_HANDOFF_TABLE_DESC "SmbiosTable" +typedef struct { + UINT8 TableDescriptionSize; + UINT8 TableDescription[sizeof(SMBIOS_HANDOFF_TABLE_DESC)]; + UINT64 NumberOfTables; + EFI_CONFIGURATION_TABLE TableEntry[1]; +} SMBIOS_HANDOFF_TABLE_POINTERS2; + +#pragma pack () + +/** + + This function dump raw data. + + @param Data raw data + @param Size raw data size + +**/ +VOID +InternalDumpData ( + IN UINT8 *Data, + IN UINTN Size + ) +{ + UINTN Index; + for (Index = 0; Index < Size; Index++) { + DEBUG ((EFI_D_VERBOSE, "%02x", (UINTN)Data[Index])); + } +} + +/** + + This function dump raw data with colume format. + + @param Data raw data + @param Size raw data size + +**/ +VOID +InternalDumpHex ( + IN UINT8 *Data, + IN UINTN Size + ) +{ + UINTN Index; + UINTN Count; + UINTN Left; + +#define COLUME_SIZE (16 * 2) + + Count = Size / COLUME_SIZE; + Left = Size % COLUME_SIZE; + for (Index = 0; Index < Count; Index++) { + DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE)); + InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE); + DEBUG ((EFI_D_VERBOSE, "\n")); + } + + if (Left != 0) { + DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE)); + InternalDumpData (Data + Index * COLUME_SIZE, Left); + DEBUG ((EFI_D_VERBOSE, "\n")); + } +} + + +/** + + This function get filter structure by SMBIOS type. + + @param Type SMBIOS type + +**/ +SMBIOS_FILTER_STRUCT * +GetFilterStructByType ( + IN UINT8 Type + ) +{ + UINTN Index; + for (Index = 0; Index < sizeof(mSmbiosFilterStandardTableBlackList)/sizeof(mSmbiosFilterStandardTableBlackList[0]); Index++) { + if (mSmbiosFilterStandardTableBlackList[Index].Type == Type) { + return &mSmbiosFilterStandardTableBlackList[Index]; + } + } + return NULL; +} + +/** + + This function get SMBIOS string in SMBIOS table. + + @param Head SMBIOS table head + @param StringId SMBIOS string ID + @param StringLen length of SMBIOS string + + @return SMBIOS string data +**/ +CHAR8 * +GetSmbiosStringById ( + IN EFI_SMBIOS_TABLE_HEADER *Head, + IN SMBIOS_TABLE_STRING StringId, + OUT UINTN *StringLen + ) +{ + UINTN Size; + UINTN StrLen; + CHAR8 *CharInStr; + UINTN StringsNumber; + CHAR8 *String; + + CharInStr = (CHAR8 *)Head + Head->Length; + Size = Head->Length; + StringsNumber = 0; + StrLen = 0; + // + // look for the two consecutive zeros, check the string limit by the way. + // + String = NULL; + while (*CharInStr != 0 || *(CharInStr+1) != 0) { + if (*CharInStr == 0) { + Size += 1; + CharInStr++; + } + String = CharInStr; + + for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) { + if (*(CharInStr+StrLen) == 0) { + break; + } + } + *StringLen = StrLen; + + if (StrLen == mMaxLen) { + return NULL; + } + + // + // forward the pointer + // + CharInStr += StrLen; + Size += StrLen; + StringsNumber += 1; + if (StringsNumber == StringId) { + break; + } + } + + return String; +} + +/** + + This function update SMBIOS table based on policy. + + @param TableEntry SMBIOS table + @param TableEntrySize SMBIOS table size + +**/ +VOID +FilterSmbiosEntry ( + IN OUT VOID *TableEntry, + IN UINTN TableEntrySize + ) +{ + SMBIOS_FILTER_STRUCT *FilterStruct; + SMBIOS_FILTER_TABLE *Filter; + UINTN Index; + SMBIOS_TABLE_STRING StringId; + CHAR8 *String; + UINTN StringLen; + + DEBUG ((EFI_D_INFO, "Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type)); + DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize);); + + // + // Skip measurement for OEM types. + // + if (((SMBIOS_STRUCTURE *)TableEntry)->Type >= SMBIOS_OEM_BEGIN) { + // zero all table fields, except header + ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE)); + } else { + FilterStruct = GetFilterStructByType (((SMBIOS_STRUCTURE *)TableEntry)->Type); + if (FilterStruct != NULL) { + if (FilterStruct->Filter == NULL || FilterStruct->FilterCount == 0) { + // zero all table fields, except header + ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE)); + } else { + Filter = FilterStruct->Filter; + for (Index = 0; Index < FilterStruct->FilterCount; Index++) { + if (((SMBIOS_STRUCTURE *) TableEntry)->Length >= (Filter[Index].Offset + Filter[Index].Size)) { + // + // The field is present in the SMBIOS entry. + // + if ((Filter[Index].Flags & SMBIOS_FILTER_TABLE_FLAG_IS_STRING) != 0) { + CopyMem (&StringId, (UINT8 *)TableEntry + Filter[Index].Offset, sizeof(StringId)); + if (StringId != 0) { + // set ' ' for string field + String = GetSmbiosStringById (TableEntry, StringId, &StringLen); + ASSERT (String != NULL); + //DEBUG ((EFI_D_INFO,"StrId(0x%x)-%a(%d)\n", StringId, String, StringLen)); + SetMem (String, StringLen, ' '); + } + } + // zero non-string field + ZeroMem ((UINT8 *)TableEntry + Filter[Index].Offset, Filter[Index].Size); + } + } + } + } + } + + DEBUG ((EFI_D_INFO, "Filter Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type)); + DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize);); +} + +/** + + Get the full size of SMBIOS structure including optional strings that follow the formatted structure. + + @param Head Pointer to the beginning of SMBIOS structure. + @param NumberOfStrings The returned number of optional strings that follow the formatted structure. + + @return Size The returned size. +**/ +UINTN +GetSmbiosStructureSize ( + IN EFI_SMBIOS_TABLE_HEADER *Head, + OUT UINTN *NumberOfStrings + ) +{ + UINTN Size; + UINTN StrLen; + CHAR8 *CharInStr; + UINTN StringsNumber; + + CharInStr = (CHAR8 *)Head + Head->Length; + Size = Head->Length; + StringsNumber = 0; + StrLen = 0; + // + // look for the two consecutive zeros, check the string limit by the way. + // + while (*CharInStr != 0 || *(CharInStr+1) != 0) { + if (*CharInStr == 0) { + Size += 1; + CharInStr++; + } + + for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) { + if (*(CharInStr+StrLen) == 0) { + break; + } + } + + if (StrLen == mMaxLen) { + return 0; + } + + // + // forward the pointer + // + CharInStr += StrLen; + Size += StrLen; + StringsNumber += 1; + } + + // + // count ending two zeros. + // + Size += 2; + + if (NumberOfStrings != NULL) { + *NumberOfStrings = StringsNumber; + } + return Size; +} + +/** + + This function returns full SMBIOS table length. + + @param TableAddress SMBIOS table based address + @param TableMaximumSize Maximum size of SMBIOS table + + @return SMBIOS table length + +**/ +UINTN +GetSmbiosTableLength ( + IN VOID *TableAddress, + IN UINTN TableMaximumSize + ) +{ + VOID *TableEntry; + VOID *TableAddressEnd; + UINTN TableEntryLength; + + TableAddressEnd = (VOID *)((UINTN)TableAddress + TableMaximumSize); + TableEntry = TableAddress; + while (TableEntry < TableAddressEnd) { + TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL); + if (TableEntryLength == 0) { + break; + } + if (((SMBIOS_STRUCTURE *)TableEntry)->Type == 127) { + TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength); + break; + } + TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength); + } + + return ((UINTN)TableEntry - (UINTN)TableAddress); +} + +/** + + This function updatess full SMBIOS table length. + + @param TableAddress SMBIOS table based address + @param TableLength SMBIOS table length + +**/ +VOID +FilterSmbiosTable ( + IN OUT VOID *TableAddress, + IN UINTN TableLength + ) +{ + VOID *TableAddressEnd; + VOID *TableEntry; + UINTN TableEntryLength; + + TableEntry = TableAddress; + TableAddressEnd = (VOID *)((UINTN)TableAddress + TableLength); + while ((UINTN)TableEntry < (UINTN)TableAddressEnd) { + TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL); + if (TableEntryLength == 0) { + break; + } + + FilterSmbiosEntry (TableEntry, TableEntryLength); + + TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength); + } +} + +/** + Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +MeasureSmbiosTable ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_HANDOFF_TABLE_POINTERS HandoffTables; + SMBIOS_HANDOFF_TABLE_POINTERS2 SmbiosHandoffTables2; + UINT32 EventType; + VOID *EventLog; + UINT32 EventLogSize; + SMBIOS_TABLE_ENTRY_POINT *SmbiosTable; + SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios3Table; + VOID *SmbiosTableAddress; + VOID *TableAddress; + UINTN TableLength; + + SmbiosTable = NULL; + Smbios3Table = NULL; + SmbiosTableAddress = NULL; + TableLength = 0; + + if (mSmbios->MajorVersion >= 3) { + Status = EfiGetSystemConfigurationTable ( + &gEfiSmbios3TableGuid, + (VOID **) &Smbios3Table + ); + if (!EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "Smbios3Table:\n")); + DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c%c'\n", + Smbios3Table->AnchorString[0], + Smbios3Table->AnchorString[1], + Smbios3Table->AnchorString[2], + Smbios3Table->AnchorString[3], + Smbios3Table->AnchorString[4] + )); + DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", Smbios3Table->EntryPointStructureChecksum)); + DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", Smbios3Table->EntryPointLength)); + DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", Smbios3Table->MajorVersion)); + DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", Smbios3Table->MinorVersion)); + DEBUG ((EFI_D_INFO, " DocRev - 0x%02x\n", Smbios3Table->DocRev)); + DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", Smbios3Table->EntryPointRevision)); + DEBUG ((EFI_D_INFO, " TableMaximumSize - 0x%08x\n", Smbios3Table->TableMaximumSize)); + DEBUG ((EFI_D_INFO, " TableAddress - 0x%016lx\n", Smbios3Table->TableAddress)); + } + } + + if (Smbios3Table == NULL) { + Status = EfiGetSystemConfigurationTable ( + &gEfiSmbiosTableGuid, + (VOID **) &SmbiosTable + ); + if (!EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "SmbiosTable:\n")); + DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c'\n", + SmbiosTable->AnchorString[0], + SmbiosTable->AnchorString[1], + SmbiosTable->AnchorString[2], + SmbiosTable->AnchorString[3] + )); + DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", SmbiosTable->EntryPointStructureChecksum)); + DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", SmbiosTable->EntryPointLength)); + DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", SmbiosTable->MajorVersion)); + DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", SmbiosTable->MinorVersion)); + DEBUG ((EFI_D_INFO, " MaxStructureSize - 0x%08x\n", SmbiosTable->MaxStructureSize)); + DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", SmbiosTable->EntryPointRevision)); + DEBUG ((EFI_D_INFO, " FormattedArea - '%c%c%c%c%c'\n", + SmbiosTable->FormattedArea[0], + SmbiosTable->FormattedArea[1], + SmbiosTable->FormattedArea[2], + SmbiosTable->FormattedArea[3], + SmbiosTable->FormattedArea[4] + )); + DEBUG ((EFI_D_INFO, " IntermediateAnchorString - '%c%c%c%c%c'\n", + SmbiosTable->IntermediateAnchorString[0], + SmbiosTable->IntermediateAnchorString[1], + SmbiosTable->IntermediateAnchorString[2], + SmbiosTable->IntermediateAnchorString[3], + SmbiosTable->IntermediateAnchorString[4] + )); + DEBUG ((EFI_D_INFO, " IntermediateChecksum - 0x%02x\n", SmbiosTable->IntermediateChecksum)); + DEBUG ((EFI_D_INFO, " TableLength - 0x%04x\n", SmbiosTable->TableLength)); + DEBUG ((EFI_D_INFO, " TableAddress - 0x%08x\n", SmbiosTable->TableAddress)); + DEBUG ((EFI_D_INFO, " NumberOfSmbiosStructures - 0x%04x\n", SmbiosTable->NumberOfSmbiosStructures)); + DEBUG ((EFI_D_INFO, " SmbiosBcdRevision - 0x%02x\n", SmbiosTable->SmbiosBcdRevision)); + } + } + + if (Smbios3Table != NULL) { + SmbiosTableAddress = (VOID *)(UINTN)Smbios3Table->TableAddress; + TableLength = GetSmbiosTableLength (SmbiosTableAddress, Smbios3Table->TableMaximumSize); + } else if (SmbiosTable != NULL) { + SmbiosTableAddress = (VOID *)(UINTN)SmbiosTable->TableAddress; + TableLength = SmbiosTable->TableLength; + } + + if (SmbiosTableAddress != NULL) { + DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTableAddress)); + DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", TableLength)); + DEBUG_CODE (InternalDumpHex ((UINT8 *)(UINTN)SmbiosTableAddress, TableLength);); + + TableAddress = AllocateCopyPool ((UINTN)TableLength, (VOID *)(UINTN)SmbiosTableAddress); + if (TableAddress == NULL) { + return ; + } + + FilterSmbiosTable (TableAddress, TableLength); + + DEBUG ((DEBUG_INFO, "The final Smbios Table starts at: 0x%x\n", TableAddress)); + DEBUG ((DEBUG_INFO, "The final Smbios Table size: 0x%x\n", TableLength)); + DEBUG_CODE (InternalDumpHex (TableAddress, TableLength);); + + HandoffTables.NumberOfTables = 1; + if (Smbios3Table != NULL) { + CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbios3TableGuid); + HandoffTables.TableEntry[0].VendorTable = Smbios3Table; + } else { + CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbiosTableGuid); + HandoffTables.TableEntry[0].VendorTable = SmbiosTable; + } + EventType = EV_EFI_HANDOFF_TABLES; + EventLog = &HandoffTables; + EventLogSize = sizeof (HandoffTables); + + if (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105) { + SmbiosHandoffTables2.TableDescriptionSize = sizeof(SmbiosHandoffTables2.TableDescription); + CopyMem (SmbiosHandoffTables2.TableDescription, SMBIOS_HANDOFF_TABLE_DESC, sizeof(SmbiosHandoffTables2.TableDescription)); + SmbiosHandoffTables2.NumberOfTables = HandoffTables.NumberOfTables; + CopyMem (&(SmbiosHandoffTables2.TableEntry[0]), &(HandoffTables.TableEntry[0]), sizeof(SmbiosHandoffTables2.TableEntry[0])); + EventType = EV_EFI_HANDOFF_TABLES2; + EventLog = &SmbiosHandoffTables2; + EventLogSize = sizeof (SmbiosHandoffTables2); + } + Status = TpmMeasureAndLogData ( + 1, // PCRIndex + EventType, // EventType + EventLog, // EventLog + EventLogSize, // LogLen + TableAddress, // HashData + TableLength // HashDataLen + ); + if (!EFI_ERROR (Status)) { + gBS->CloseEvent (Event) ; + } + } + + return ; +} + +/** + + Driver to produce Smbios measurement. + + @param ImageHandle Module's image handle + @param SystemTable Pointer of EFI_SYSTEM_TABLE + + @return Status returned from EfiCreateEventReadyToBootEx(). + +**/ +EFI_STATUS +EFIAPI +SmbiosMeasurementDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + + Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &mSmbios); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "The Smbios Table Version: %x.%x\n", mSmbios->MajorVersion, mSmbios->MinorVersion)); + + if (mSmbios->MajorVersion < 2 || (mSmbios->MajorVersion == 2 && mSmbios->MinorVersion < 7)){ + mMaxLen = SMBIOS_STRING_MAX_LENGTH; + } else if (mSmbios->MajorVersion < 3) { + // + // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string. + // However, the length of the entire structure table (including all strings) must be reported + // in the Structure Table Length field of the SMBIOS Structure Table Entry Point, + // which is a WORD field limited to 65,535 bytes. + // + mMaxLen = SMBIOS_TABLE_MAX_LENGTH; + } else { + // + // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes. + // Locate the end of string as long as possible. + // + mMaxLen = SMBIOS_3_0_TABLE_MAX_LENGTH; + } + + // + // Measure Smbios tables + // + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + MeasureSmbiosTable, + NULL, + &Event + ); + + return Status; +} -- cgit