bugfix(eventlog): Assume TPM1.2 events if NO_ACTION is too short (#208)

This commit is contained in:
Dmitrii Okunev 2021-04-13 18:46:15 +01:00 committed by GitHub
parent 1ceeedc8dc
commit b89180c3eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 14 deletions

View File

@ -37,7 +37,7 @@ import (
// ReplayError describes the parsed events that failed to verify against
// a particular PCR.
type ReplayError struct {
Events []Event
Events []Event
// InvalidPCRs reports the set of PCRs where the event log replay failed.
InvalidPCRs []int
}
@ -506,7 +506,7 @@ func ParseEventLog(measurementLog []byte) (*EventLog, error) {
if err != nil {
return nil, fmt.Errorf("parse first event: %v", err)
}
if e.typ == eventTypeNoAction {
if e.typ == eventTypeNoAction && len(e.data) >= binary.Size(specIDEventHeader{}) {
specID, err = parseSpecIDEvent(e.data)
if err != nil {
return nil, fmt.Errorf("failed to parse spec ID event: %v", err)
@ -568,22 +568,24 @@ const (
wantErrata = 0
)
type specIDEventHeader struct {
Signature [16]byte
PlatformClass uint32
VersionMinor uint8
VersionMajor uint8
Errata uint8
UintnSize uint8
NumAlgs uint32
}
// parseSpecIDEvent parses a TCG_EfiSpecIDEventStruct structure from the reader.
//
// https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf#page=18
func parseSpecIDEvent(b []byte) (*specIDEvent, error) {
r := bytes.NewReader(b)
var header struct {
Signature [16]byte
PlatformClass uint32
VersionMinor uint8
VersionMajor uint8
Errata uint8
UintnSize uint8
NumAlgs uint32
}
var header specIDEventHeader
if err := binary.Read(r, binary.LittleEndian, &header); err != nil {
return nil, fmt.Errorf("reading event header: %v", err)
return nil, fmt.Errorf("reading event header: %w: %X", err, b)
}
if header.Signature != wantSignature {
return nil, fmt.Errorf("invalid spec id signature: %x", header.Signature)
@ -653,7 +655,7 @@ func (e *eventSizeErr) Error() string {
func parseRawEvent(r *bytes.Buffer, specID *specIDEvent) (event rawEvent, err error) {
var h rawEventHeader
if err = binary.Read(r, binary.LittleEndian, &h); err != nil {
return event, err
return event, fmt.Errorf("header deserialization error: %w", err)
}
if h.EventSize == 0 {
return event, errors.New("event data size is 0")
@ -664,7 +666,7 @@ func parseRawEvent(r *bytes.Buffer, specID *specIDEvent) (event rawEvent, err er
data := make([]byte, int(h.EventSize))
if _, err := io.ReadFull(r, data); err != nil {
return event, err
return event, fmt.Errorf("reading data error: %w", err)
}
digests := []digest{{hash: crypto.SHA1, data: h.Digest[:]}}

View File

@ -149,6 +149,24 @@ func TestParseEventLogEventSizeTooLarge(t *testing.T) {
}
}
func TestParseShortNoAction(t *testing.T) {
// https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClientSpecPlat_TPM_2p0_1p04_pub.pdf#page=110
// says: "For EV_NO_ACTION events other than the EFI Specification ID event
// (Section 9.4.5.1) the log will ...". Thus it is concluded other
// than "EFI Specification ID" events are also valid as NO_ACTION events.
//
// Currently we just assume that such events will have Data shorter than
// "EFI Specification ID" field.
data, err := ioutil.ReadFile("testdata/short_no_action_eventlog")
if err != nil {
t.Fatalf("reading test data: %v", err)
}
if _, err := ParseEventLog(data); err != nil {
t.Fatalf("parsing event log: %v", err)
}
}
func TestParseSpecIDEvent(t *testing.T) {
tests := []struct {
name string

BIN
attest/testdata/short_no_action_eventlog vendored Normal file

Binary file not shown.