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
3 changed files with 34 additions and 14 deletions

View File

@ -506,7 +506,7 @@ func ParseEventLog(measurementLog []byte) (*EventLog, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("parse first event: %v", err) 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) specID, err = parseSpecIDEvent(e.data)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse spec ID event: %v", err) return nil, fmt.Errorf("failed to parse spec ID event: %v", err)
@ -568,12 +568,7 @@ const (
wantErrata = 0 wantErrata = 0
) )
// parseSpecIDEvent parses a TCG_EfiSpecIDEventStruct structure from the reader. type specIDEventHeader struct {
//
// 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 Signature [16]byte
PlatformClass uint32 PlatformClass uint32
VersionMinor uint8 VersionMinor uint8
@ -581,9 +576,16 @@ func parseSpecIDEvent(b []byte) (*specIDEvent, error) {
Errata uint8 Errata uint8
UintnSize uint8 UintnSize uint8
NumAlgs uint32 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 specIDEventHeader
if err := binary.Read(r, binary.LittleEndian, &header); err != nil { 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 { if header.Signature != wantSignature {
return nil, fmt.Errorf("invalid spec id signature: %x", header.Signature) 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) { func parseRawEvent(r *bytes.Buffer, specID *specIDEvent) (event rawEvent, err error) {
var h rawEventHeader var h rawEventHeader
if err = binary.Read(r, binary.LittleEndian, &h); err != nil { 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 { if h.EventSize == 0 {
return event, errors.New("event data size is 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)) data := make([]byte, int(h.EventSize))
if _, err := io.ReadFull(r, data); err != nil { 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[:]}} 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) { func TestParseSpecIDEvent(t *testing.T) {
tests := []struct { tests := []struct {
name string name string

BIN
attest/testdata/short_no_action_eventlog vendored Normal file

Binary file not shown.