Skip to content

Commit

Permalink
Add an initial implementation of parsing event types
Browse files Browse the repository at this point in the history
Raw events aren't enormously helpful. Add an initial implementation of
some of the basic event types - this is largely a scratch proposal so we
can figure out API design.
  • Loading branch information
Matthew Garrett committed Sep 20, 2019
1 parent b60a7cc commit 394f627
Showing 1 changed file with 281 additions and 0 deletions.
281 changes: 281 additions & 0 deletions attest/eventlog_events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
// Copyright 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

package attest

import (
"bytes"
"encoding/binary"
"errors"
"unicode/utf16"
"unicode/utf8"
)

const (
// BIOS Events (TCG PC Client Specific Implementation Specification for Conventional BIOS 1.21)
prebootCert EventType = 0x00000000
postCode EventType = 0x00000001
unused EventType = 0x00000002
noAction EventType = 0x00000003
separator EventType = 0x00000004
action EventType = 0x00000005
eventTag EventType = 0x00000006
sCRTMContents EventType = 0x00000007
sCRTMVersion EventType = 0x00000008
cpuMicrocode EventType = 0x00000009
platformConfigFlags EventType = 0x0000000A
tableOfDevices EventType = 0x0000000B
compactHash EventType = 0x0000000C
ipl EventType = 0x0000000D
iplPartitionData EventType = 0x0000000E
nonhostCode EventType = 0x0000000F
nonhostConfig EventType = 0x00000010
nonhostInfo EventType = 0x00000011
omitBootDeviceEvents EventType = 0x00000012

// EFI Events (TCG EFI Platform Specification Version 1.22)
efiEventBase EventType = 0x80000000
efiVariableDriverConfig EventType = 0x80000001
efiVariableBoot EventType = 0x80000002
efiBootServicesApplication EventType = 0x80000003
efiBootServicesDriver EventType = 0x80000004
efiRuntimeServicesDriver EventType = 0x80000005
efiGPTEvent EventType = 0x80000006
efiAction EventType = 0x80000007
efiPlatformFirmwareBlob EventType = 0x80000008
efiHandoffTables EventType = 0x80000009
efiHCRTMEvent EventType = 0x80000010
efiVariableAuthority EventType = 0x800000e0
)

type eventID uint32

const (
smbios eventID = 0x00
bisCertificate eventID = 0x01
postBIOSROM eventID = 0x02
escdeventID eventID = 0x03
cmos eventID = 0x04
nvram eventID = 0x05
optionROMExecute eventID = 0x06
optionROMConfiguration eventID = 0x07
)

type TPMEvent interface {
eventType() EventType
base() rawEvent
}

type stringEvent struct {
rawEvent
Message string
}

type PrebootCertEvent struct {
rawEvent
}

type PostEvent struct {
stringEvent
}

type NoActionEvent struct {
rawEvent
}

type SeparatorEvent struct {
rawEvent
}

type ActionEvent struct {
stringEvent
}

type EventTagEvent struct {
rawEvent
EventID eventID
EventData []byte
}

type CRTMContentEvent struct {
stringEvent
}

type CRTMEvent struct {
stringEvent
}

type MicrocodeEvent struct {
stringEvent
}

type PlatformConfigFlagsEvent struct {
rawEvent
}

type TableOfDevicesEvent struct {
rawEvent
}

type CompactHashEvent struct {
rawEvent
}

type IPLEvent struct {
stringEvent
}

type IPLPartitionEvent struct {
rawEvent
}

type NonHostCodeEvent struct {
rawEvent
}

type NonHostConfigEvent struct {
rawEvent
}

type NonHostInfoEvent struct {
rawEvent
}

type OmitBootDeviceEventsEvent struct {
stringEvent
}

func (event rawEvent) base() rawEvent {
return event
}

func (event rawEvent) eventType() EventType {
return event.typ
}

func parseStringData(b []byte) (string, error) {
var buf []uint16
for i := 0; i < len(b); i += 2 {
if b[i+1] != 0x00 {
buf = nil
break
}
buf = append(buf, binary.LittleEndian.Uint16(b[i:]))
}

if buf != nil {
return string(utf16.Decode(buf)), nil
}

if !utf8.Valid(b) {
return "", errors.New("invalid UTF-8 string")
}

return string(b), nil
}

func ParseEvents(events *EventLog) ([]TPMEvent, error) {
var parsedEvents []TPMEvent

for _, event := range events.rawEvents {
buf := bytes.NewBuffer(event.data)
switch event.typ {
case prebootCert: // 0x00
var parsedEvent PrebootCertEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case postCode: // 0x01
var parsedEvent PostEvent
parsedEvent.rawEvent = event
parsedEvent.Message, _ = parseStringData(event.data)
parsedEvents = append(parsedEvents, parsedEvent)
case noAction: // 0x03
var parsedEvent NoActionEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case separator: // 0x04
var parsedEvent SeparatorEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case action: // 0x05
var parsedEvent ActionEvent
parsedEvent.rawEvent = event
parsedEvent.Message, _ = parseStringData(event.data)
parsedEvents = append(parsedEvents, parsedEvent)
case eventTag: // 0x06
var parsedEvent EventTagEvent
parsedEvent.rawEvent = event
if err := binary.Read(buf, binary.LittleEndian, &parsedEvent.EventID); err != nil {
continue
}
parsedEvent.EventData = event.data[4:]
parsedEvents = append(parsedEvents, parsedEvent)
case sCRTMContents: // 0x07
var parsedEvent CRTMContentEvent
parsedEvent.rawEvent = event
parsedEvent.Message, _ = parseStringData(event.data)
parsedEvents = append(parsedEvents, parsedEvent)
case sCRTMVersion: // 0x08
var parsedEvent CRTMEvent
parsedEvent.rawEvent = event
parsedEvent.Message, _ = parseStringData(event.data)
parsedEvents = append(parsedEvents, parsedEvent)
case cpuMicrocode: // 0x09
var parsedEvent MicrocodeEvent
parsedEvent.rawEvent = event
parsedEvent.Message, _ = parseStringData(event.data)
parsedEvents = append(parsedEvents, parsedEvent)
case platformConfigFlags: // 0x0a
var parsedEvent PlatformConfigFlagsEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case tableOfDevices: // 0x0b
var parsedEvent TableOfDevicesEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case compactHash: // 0x0c
var parsedEvent CompactHashEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case ipl: // 0x0d
var parsedEvent IPLEvent
parsedEvent.rawEvent = event
parsedEvent.Message, _ = parseStringData(event.data)
parsedEvents = append(parsedEvents, parsedEvent)
case iplPartitionData: // 0x0e
var parsedEvent IPLPartitionEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case nonhostCode: // 0x0f
var parsedEvent NonHostCodeEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case nonhostConfig: // 0x10
var parsedEvent NonHostConfigEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case nonhostInfo: // 0x11
var parsedEvent NonHostInfoEvent
parsedEvent.rawEvent = event
parsedEvents = append(parsedEvents, parsedEvent)
case omitBootDeviceEvents: // 0x0f
var parsedEvent OmitBootDeviceEventsEvent
parsedEvent.rawEvent = event
parsedEvent.Message, _ = parseStringData(event.data)
parsedEvents = append(parsedEvents, parsedEvent)
}
}

return parsedEvents, nil
}

0 comments on commit 394f627

Please sign in to comment.