From c00a0c8761584b0eb204c63a0c270e396f43007c Mon Sep 17 00:00:00 2001 From: "Yao, Jiewen" Date: Tue, 27 Oct 2015 04:46:50 +0000 Subject: [PATCH] Move Smbios measurement from TCG driver to Smbios driver. This is patch to add smbios measurement. The problem of current SMBIOS measurement is: 1) TCG drivers do not support SMBIOS3.0 table. 2) TCG drivers do not follow TCG platform spec on: "Platform configuration information that is automatically updated, such as clock registers, and system unique information, such as asset numbers or serial numbers, MUST NOT be measured into PCR [1], or any other PCR." So we decide to move Smbios measurement from TCG drivers to Smbios driver. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" Reviewed-by: "Zeng, Star" git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18680 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/MdeModulePkg.dsc | 1 + .../SmbiosMeasurementDxe.c | 617 ++++++++++++++++++ .../SmbiosMeasurementDxe.inf | 68 ++ .../SmbiosMeasurementDxe.uni | Bin 0 -> 1988 bytes .../SmbiosMeasurementDxeExtra.uni | Bin 0 -> 1358 bytes 5 files changed, 686 insertions(+) create mode 100644 MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c create mode 100644 MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.inf create mode 100644 MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.uni create mode 100644 MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxeExtra.uni diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 2dddc41b79..62f596db73 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -310,6 +310,7 @@ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.inf MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf diff --git a/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c b/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c new file mode 100644 index 0000000000..21528276c1 --- /dev/null +++ b/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c @@ -0,0 +1,617 @@ +/** @file + This driver measures SMBIOS table to TPM. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#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}, +}; +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 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])}, + {0x1F, NULL, 0}, + {0x21, NULL, 0}, + {0x27, mSmbiosFilterType39BlackList, sizeof(mSmbiosFilterType39BlackList)/sizeof(mSmbiosFilterType39BlackList[0])}, +}; + +EFI_SMBIOS_PROTOCOL *mSmbios; +UINTN mMaxLen; + +/** + + 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_INFO, "%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_INFO, "%04x: ", Index * COLUME_SIZE)); + InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE); + DEBUG ((EFI_D_INFO, "\n")); + } + + if (Left != 0) { + DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE)); + InternalDumpData (Data + Index * COLUME_SIZE, Left); + DEBUG ((EFI_D_INFO, "\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)); + InternalDumpHex (TableEntry, TableEntrySize); + + FilterStruct = GetFilterStructByType (((SMBIOS_STRUCTURE *)TableEntry)->Type); + if (FilterStruct != NULL) { + if (FilterStruct->Filter == NULL || FilterStruct->FilterCount == 0) { + // zero all table entries, except header + ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE)); + } else { + Filter = FilterStruct->Filter; + for (Index = 0; Index < FilterStruct->FilterCount; Index++) { + 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); + //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)); + 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] +**/ +VOID +EFIAPI +MeasureSmbiosTable ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_HANDOFF_TABLE_POINTERS HandoffTables; + 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)); + } + } + 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", + Smbios3Table->AnchorString[0], + Smbios3Table->AnchorString[1], + Smbios3Table->AnchorString[2], + Smbios3Table->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)); + 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)); + InternalDumpHex (TableAddress, TableLength); + + HandoffTables.NumberOfTables = 1; + HandoffTables.TableEntry[0].VendorGuid = gEfiSmbiosTableGuid; + HandoffTables.TableEntry[0].VendorTable = SmbiosTable; + Status = TpmMeasureAndLogData ( + 1, // PCRIndex + EV_EFI_HANDOFF_TABLES, // EventType + &HandoffTables, // EventLog + sizeof (HandoffTables), // LogLen + TableAddress, // HashData + TableLength // HashDataLen + ); + if (EFI_ERROR (Status)) { + return ; + } + } + + return ; +} + +/** + + Driver to produce Smbios measurement. + + @param ImageHandle Module's image handle + @param SystemTable Pointer of EFI_SYSTEM_TABLE + + @retval EFI_SUCCESS Smbios protocol installed + @retval Other No protocol installed, unload driver. + +**/ +EFI_STATUS +EFIAPI +SmbiosMeasurementDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + + Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &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; +} diff --git a/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.inf b/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.inf new file mode 100644 index 0000000000..6f894476e4 --- /dev/null +++ b/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.inf @@ -0,0 +1,68 @@ +## @file +# This driver measures SMBIOS table to TPM. +# +# This driver is a sample driver to follow TCG platform specification to +# filter some fields in SMBIOS table. +# - Platform configuration information that is automatically updated, +# such as clock registers, and system unique information, such as +# asset numbers or serial numbers, MUST NOT be measured into PCR [1], +# or any other PCR. +# +# A platform may use its own policy to filter some fields in SMBIOS table. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmbiosMeasurementDxe + MODULE_UNI_FILE = SmbiosMeasurementDxe.uni + FILE_GUID = D27FED59-ABB4-4FED-BEAD-2A878C7E4A7E + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = SmbiosMeasurementDriverEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64 +# + +[Sources] + SmbiosMeasurementDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + BaseLib + UefiLib + UefiDriverEntryPoint + DebugLib + TpmMeasurementLib + +[Protocols] + gEfiSmbiosProtocolGuid ## PRODUCES + +[Guids] + gEfiSmbiosTableGuid ## SOMETIMES_PRODUCES ## SystemTable + gEfiSmbios3TableGuid ## SOMETIMES_PRODUCES ## SystemTable + +[Depex] + gEfiSmbiosProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + SmbiosMeasurementDxeExtra.uni diff --git a/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.uni b/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.uni new file mode 100644 index 0000000000000000000000000000000000000000..98b0f52a6a3968b18b637d33b0f3cb2f24a18e55 GIT binary patch literal 1988 zcmds&U60aW5QXR3#Q#9p8#TM2Cf*oh1gYAnTLLAkR|d*wQa(~(b^pBjoGGP3Sl1Y@ z3~AqwnfJ^&GxL@o-|JSl3eO{c6?!J?=1WIv<5AmV-yI_XBejGWDYMO;aR$z41k(x;7rcj@8M7;d z4eJ&ADJl}XVb#Y+zImL~Rm3Ki6?_&RG4t~YIE9Ww<=UOPbqo4%$5W`c<>OQaUc+kz zCuMj7p13}M*F(mq_Sl}-GdpJob8F{R z;_I}kr=4pa^<~*nTTaNTPAr(HKQf|9Yr#^? z@9JKZT-7-nD)HQJuX-xiBmd0R)li>N&-zjB*X#^nKD3J?OAVAMPZ=e)cNV~=P4`6h zmUqMNOz1biMVEHb+F@*3k6GaP?b#(`z`in(Bb2!h>E{5Ct|Ldx)W>>P8M}-^tui)! zt=0K2oUX77HS&lRyTYsE%r4mvK@~>i(L1cfU3-cd<0~IU&Ar~>tLUE@-(wMT-M?TL zC07yHr#()I9+HbT-K3bUlixdiZR^fmIn{Hv@0kU)(YHhS`vOt~Mh~=rRRit0r9rl0 z{BHZ5`E3!_mY$t>*QgUNz!K9cr^}B0H{bQ@UeTYaQ7?4Sp+0Hv^M6Xw->dmw|3S)J F{{*hWIG+Fj literal 0 HcmV?d00001 diff --git a/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxeExtra.uni b/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxeExtra.uni new file mode 100644 index 0000000000000000000000000000000000000000..4e081c44b8ab12ffaa6b76a2b7976925d8720162 GIT binary patch literal 1358 zcmZvcTW`}q5QXO%iT|)lUjVfUAn}3_q9Fz%nu~H#%TwhfG_{mV<%H7k)JNf;U;DOVL7KI&&sye zvIkDVF7TOhzrgz!mYGLy@y+m?6BoE$x&0%)ij4?mwsH@q`#alt?A&hg4E7B4=j^ZT zrMch5i8}(I4wY{@KdacmUdH4D`zGJOMFGo ziVXLh)u)uss9S-KNLOJ8azrLE*V0*+C}JkhY_E@$Skw0^u1U{Zyk9)xQgQw1T1;90 ztu}*$5XB+trCb}{RrLg(hkcQ%Vt<1@c1WBb@Hyu6SeK~f4zEcOzb+IIqwRsNnw%}2 zcSOS|q)6=uhtmph!G@V1% zmhU61ZRTriBYdUr*t+Zq_JA!SRNA+h=LCu<)f_8>l41p{*C=BH)5{;Us7a=RU~$`$EncU zXwheyl(WVEvDB^HgMWP*ZkO$3KQH=f=nEw6t_yYhpbYjET!Y;Mbqs!jPZyRQPQlSm u=$s~hPPbE5&6@guhQIhJTa8l(4OOjd|Nq9Ri&u`@@=4YgBPUh}