audk/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c

672 lines
24 KiB
C

/** @file
This driver measures SMBIOS table to TPM.
Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
#include <Protocol/Smbios.h>
#include <IndustryStandard/SmBios.h>
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Guid/EventGroup.h>
#include <Guid/SmBios.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/PcdLib.h>
#include <Library/TpmMeasurementLib.h>
#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;
}