Merge pull request #305 from 9elements/psp-fake-measurements

Add PSP Table, PSP Headers, BIOS/PSP Entries to Fake Measurements
This commit is contained in:
Trynity Mirell 2021-10-19 11:09:47 +00:00 committed by GitHub
commit 5d277ef296
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 230 additions and 4 deletions

View File

@ -23,6 +23,8 @@ type BIOSDirectoryTableEntryType uint8
const (
// APCBBinaryEntry denotes APCB binary entry in BIOS Directory table
APCBBinaryEntry BIOSDirectoryTableEntryType = 0x60
// APOBBinaryEntry denotes APOB binary in BIOS Directory table
APOBBinaryEntry BIOSDirectoryTableEntryType = 0x61
// BIOSRTMVolumeEntry denotes BIOS RTM Volume entry in BIOS Directory table
BIOSRTMVolumeEntry BIOSDirectoryTableEntryType = 0x62
// BIOSDirectoryTableLevel2Entry denotes an entry that points to BIOS Directory table level 2

View File

@ -222,6 +222,14 @@ func (f Flow) MeasurementIDs() MeasurementIDs {
MeasurementIDBIOSDirectoryLevel1,
MeasurementIDBIOSDirectoryLevel2Header,
MeasurementIDBIOSDirectoryLevel2,
MeasurementIDBIOSDirectoryLevel1Entries, // fake measurement
MeasurementIDBIOSDirectoryLevel2Entries, // fake measurement
MeasurementIDPSPDirectoryLevel1, // fake measurement
MeasurementIDPSPDirectoryLevel1Entries, // fake measurement
MeasurementIDPSPDirectoryLevel1Header, // fake measurement
MeasurementIDPSPDirectoryLevel2, // fake measurement
MeasurementIDPSPDirectoryLevel2Entries, // fake measurement
MeasurementIDPSPDirectoryLevel2Header, // fake measurement
MeasurementIDPCDFirmwareVendorVersionData,
MeasurementIDDXE,
MeasurementIDSeparator,

View File

@ -12,7 +12,7 @@ import (
// MeasureBIOSDirectoryHeader constructs measurements of BIOS Directory table header
func MeasureBIOSDirectoryHeader(table *amd_manifest.BIOSDirectoryTable, biosDirectoryTableRange pkgbytes.Range) (*Measurement, error) {
if table == nil {
return nil, nil
return nil, fmt.Errorf("empty BIOS Directory Table")
}
var id MeasurementID
switch table.BIOSCookie {
@ -30,10 +30,31 @@ func MeasureBIOSDirectoryHeader(table *amd_manifest.BIOSDirectoryTable, biosDire
return NewRangeMeasurement(id, biosDirectoryTableRange.Offset, headerSize), nil
}
// MeasurePSPDirectoryHeader constructs measurements of PSP Directory table header
func MeasurePSPDirectoryHeader(table *amd_manifest.PSPDirectoryTable, pspDirectoryTableRange pkgbytes.Range) (*Measurement, error) {
if table == nil {
return nil, fmt.Errorf("empty PSP Directory Table")
}
var id MeasurementID
switch table.PSPCookie {
case amd_manifest.PSPDirectoryTableCookie:
id = MeasurementIDPSPDirectoryLevel1Header
case amd_manifest.PSPDirectoryTableLevel2Cookie:
id = MeasurementIDPSPDirectoryLevel2Header
default:
return nil, fmt.Errorf("unknown psp table cookie: '%X'", table.PSPCookie)
}
headerSize := uint64(binary.Size(table.PSPDirectoryTableHeader))
if headerSize > pspDirectoryTableRange.Length {
return nil, fmt.Errorf("psp table is too short: '%d'", pspDirectoryTableRange.Length)
}
return NewRangeMeasurement(id, pspDirectoryTableRange.Offset, headerSize), nil
}
// MeasureBIOSDirectoryTable constructs measurements of BIOS Directory table
func MeasureBIOSDirectoryTable(table *amd_manifest.BIOSDirectoryTable, biosDirectoryTableRange pkgbytes.Range) (*Measurement, error) {
if table == nil {
return nil, nil
return nil, fmt.Errorf("empty BIOS Directory Table")
}
var id MeasurementID
@ -56,6 +77,92 @@ func MeasureBIOSDirectoryTable(table *amd_manifest.BIOSDirectoryTable, biosDirec
biosDirectoryTableRange.Length-headerSize), nil
}
// MeasurePSPDirectoryTable constructs measurements of PSP Directory table
func MeasurePSPDirectoryTable(table *amd_manifest.PSPDirectoryTable, pspDirectoryTableRange pkgbytes.Range) (*Measurement, error) {
if table == nil {
return nil, fmt.Errorf("empty PSP Directory Table")
}
var id MeasurementID
switch table.PSPCookie {
case amd_manifest.PSPDirectoryTableCookie:
id = MeasurementIDPSPDirectoryLevel1
case amd_manifest.PSPDirectoryTableLevel2Cookie:
id = MeasurementIDPSPDirectoryLevel2
default:
return nil, fmt.Errorf("unknown psp table cookie: '%X'", table.PSPCookie)
}
headerSize := uint64(binary.Size(table.PSPDirectoryTableHeader))
if headerSize > pspDirectoryTableRange.Length {
return nil, fmt.Errorf("psp table is too short: '%d'", pspDirectoryTableRange.Length)
}
return NewRangeMeasurement(
id,
pspDirectoryTableRange.Offset+headerSize,
pspDirectoryTableRange.Length-headerSize), nil
}
// MeasureBIOSDirectoryTableEntries constructs measurements of AMD's BIOS directory table entries
func MeasureBIOSDirectoryTableEntries(table *amd_manifest.BIOSDirectoryTable) (*Measurement, error) {
if table == nil {
return nil, fmt.Errorf("empty BIOS Directory Table")
}
var id MeasurementID
switch table.BIOSCookie {
case amd_manifest.BIOSDirectoryTableCookie:
id = MeasurementIDBIOSDirectoryLevel1Entries
case amd_manifest.BIOSDirectoryTableLevel2Cookie:
id = MeasurementIDBIOSDirectoryLevel2Entries
default:
return nil, fmt.Errorf("unknown bios table cookie: '%X'", table.BIOSCookie)
}
ranges := []pkgbytes.Range{}
for _, entry := range table.Entries {
switch entry.Type {
case amd_manifest.APCBBinaryEntry: // this can vary
case amd_manifest.APOBBinaryEntry: // this can vary
default:
ranges = append(ranges, pkgbytes.Range{Offset: entry.SourceAddress, Length: uint64(entry.Size)})
}
}
return NewRangesMeasurement(id, ranges), nil
}
// MeasurePSPDirectoryTableEntries constructs measurements of AMD's PSP directory table entries
func MeasurePSPDirectoryTableEntries(table *amd_manifest.PSPDirectoryTable) (*Measurement, error) {
if table == nil {
return nil, fmt.Errorf("empty PSP Directory Table")
}
var id MeasurementID
switch table.PSPCookie {
case amd_manifest.PSPDirectoryTableCookie:
id = MeasurementIDPSPDirectoryLevel1Entries
case amd_manifest.PSPDirectoryTableLevel2Cookie:
id = MeasurementIDPSPDirectoryLevel2Entries
default:
return nil, fmt.Errorf("unknown psp table cookie: '%X'", table.PSPCookie)
}
ranges := []pkgbytes.Range{}
for _, entry := range table.Entries {
switch entry.Type {
case 0x0B: // Skip PSP Soft Fuse Entry
default:
ranges = append(ranges, pkgbytes.Range{Offset: entry.LocationOrValue, Length: uint64(entry.Size)})
}
}
return NewRangesMeasurement(id, ranges), nil
}
// MeasureMP0C2PMsgRegisters constructs measurement of AMD's MPO_CP2_MSG registers
func MeasureMP0C2PMsgRegisters(regs registers.Registers) (*Measurement, error) {
msg37, found := registers.FindMP0C2PMsg37(regs)

View File

@ -52,10 +52,18 @@ const (
MeasurementIDFITHeaders
MeasurementIDDeepAnalysis
MeasurementIDACMDateInPlace
MeasurementIDBIOSDirectoryLevel1Header
MeasurementIDBIOSDirectoryLevel1
MeasurementIDBIOSDirectoryLevel2Header
MeasurementIDBIOSDirectoryLevel1Entries
MeasurementIDBIOSDirectoryLevel1Header
MeasurementIDBIOSDirectoryLevel2
MeasurementIDBIOSDirectoryLevel2Entries
MeasurementIDBIOSDirectoryLevel2Header
MeasurementIDPSPDirectoryLevel1
MeasurementIDPSPDirectoryLevel1Entries
MeasurementIDPSPDirectoryLevel1Header
MeasurementIDPSPDirectoryLevel2
MeasurementIDPSPDirectoryLevel2Entries
MeasurementIDPSPDirectoryLevel2Header
MeasurementIDMP0C2PMsgRegisters
MeasurementIDEmbeddedFirmwareStructure
MeasurementIDPSPVersion
@ -86,6 +94,22 @@ func (id MeasurementID) IsFake() bool {
return true
case MeasurementIDDeepAnalysis:
return true
case MeasurementIDBIOSDirectoryLevel1Entries:
return true
case MeasurementIDBIOSDirectoryLevel2Entries:
return true
case MeasurementIDPSPDirectoryLevel1:
return true
case MeasurementIDPSPDirectoryLevel1Header:
return true
case MeasurementIDPSPDirectoryLevel2:
return true
case MeasurementIDPSPDirectoryLevel2Header:
return true
case MeasurementIDPSPDirectoryLevel1Entries:
return true
case MeasurementIDPSPDirectoryLevel2Entries:
return true
}
return false
@ -152,6 +176,22 @@ func (id MeasurementID) String() string {
return "Header of BIOS directory table level 2"
case MeasurementIDBIOSDirectoryLevel2:
return "BIOS directory table level 2"
case MeasurementIDBIOSDirectoryLevel1Entries:
return "Entries of BIOS directory table level 1"
case MeasurementIDBIOSDirectoryLevel2Entries:
return "Entries of BIOS directory table level 2"
case MeasurementIDPSPDirectoryLevel1Header:
return "Header of PSP directory table level 1"
case MeasurementIDPSPDirectoryLevel1:
return "PSP directory table level 1"
case MeasurementIDPSPDirectoryLevel2Header:
return "Header of PSP directory table level 2"
case MeasurementIDPSPDirectoryLevel2:
return "PSP directory table level 2"
case MeasurementIDPSPDirectoryLevel1Entries:
return "Entries of PSP directory table level 1"
case MeasurementIDPSPDirectoryLevel2Entries:
return "Entries of PSP directory table level 2"
case MeasurementIDMP0C2PMsgRegisters:
return "AMD MP0_CP2MSG registers"
case MeasurementIDEmbeddedFirmwareStructure:
@ -418,6 +458,75 @@ func (id MeasurementID) singleMeasureFunc() singleMeasureFunc {
return MeasureBIOSDirectoryTable(pspFirmware.BIOSDirectoryLevel2, pspFirmware.BIOSDirectoryLevel2Range)
}
case MeasurementIDBIOSDirectoryLevel1Entries:
return func(config MeasurementConfig, provider DataProvider) (*Measurement, error) {
pspFirmware := provider.PSPFirmware()
if err := checkPSPFirmwareFound(pspFirmware); err != nil {
return nil, err
}
return MeasureBIOSDirectoryTableEntries(pspFirmware.BIOSDirectoryLevel1)
}
case MeasurementIDBIOSDirectoryLevel2Entries:
return func(config MeasurementConfig, provider DataProvider) (*Measurement, error) {
pspFirmware := provider.PSPFirmware()
if err := checkPSPFirmwareFound(pspFirmware); err != nil {
return nil, err
}
return MeasureBIOSDirectoryTableEntries(pspFirmware.BIOSDirectoryLevel2)
}
case MeasurementIDPSPDirectoryLevel1Header:
return func(config MeasurementConfig, provider DataProvider) (*Measurement, error) {
pspFirmware := provider.PSPFirmware()
if err := checkPSPFirmwareFound(pspFirmware); err != nil {
return nil, err
}
return MeasurePSPDirectoryHeader(pspFirmware.PSPDirectoryLevel1, pspFirmware.PSPDirectoryLevel1Range)
}
case MeasurementIDPSPDirectoryLevel2Header:
return func(config MeasurementConfig, provider DataProvider) (*Measurement, error) {
pspFirmware := provider.PSPFirmware()
if err := checkPSPFirmwareFound(pspFirmware); err != nil {
return nil, err
}
return MeasurePSPDirectoryHeader(pspFirmware.PSPDirectoryLevel2, pspFirmware.PSPDirectoryLevel2Range)
}
case MeasurementIDPSPDirectoryLevel1:
return func(config MeasurementConfig, provider DataProvider) (*Measurement, error) {
pspFirmware := provider.PSPFirmware()
if err := checkPSPFirmwareFound(pspFirmware); err != nil {
return nil, err
}
return MeasurePSPDirectoryTable(pspFirmware.PSPDirectoryLevel1, pspFirmware.PSPDirectoryLevel1Range)
}
case MeasurementIDPSPDirectoryLevel2:
return func(config MeasurementConfig, provider DataProvider) (*Measurement, error) {
pspFirmware := provider.PSPFirmware()
if err := checkPSPFirmwareFound(pspFirmware); err != nil {
return nil, err
}
return MeasurePSPDirectoryTable(pspFirmware.PSPDirectoryLevel2, pspFirmware.PSPDirectoryLevel2Range)
}
case MeasurementIDPSPDirectoryLevel1Entries:
return func(config MeasurementConfig, provider DataProvider) (*Measurement, error) {
pspFirmware := provider.PSPFirmware()
if err := checkPSPFirmwareFound(pspFirmware); err != nil {
return nil, err
}
return MeasurePSPDirectoryTableEntries(pspFirmware.PSPDirectoryLevel1)
}
case MeasurementIDPSPDirectoryLevel2Entries:
return func(config MeasurementConfig, provider DataProvider) (*Measurement, error) {
pspFirmware := provider.PSPFirmware()
if err := checkPSPFirmwareFound(pspFirmware); err != nil {
return nil, err
}
return MeasurePSPDirectoryTableEntries(pspFirmware.PSPDirectoryLevel2)
}
case MeasurementIDMP0C2PMsgRegisters:
return func(config MeasurementConfig, provider DataProvider) (*Measurement, error) {
return MeasureMP0C2PMsgRegisters(config.Registers)