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 64b577d
Showing 1 changed file with 308 additions and 0 deletions.
308 changes: 308 additions & 0 deletions events/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
// 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 events

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

"github.com/google/go-attestation/attest"
)

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

// EFI Events (TCG EFI Platform Specification Version 1.22)
efiEventBase attest.EventType = 0x80000000
efiVariableDriverConfig attest.EventType = 0x80000001
efiVariableBoot attest.EventType = 0x80000002
efiBootServicesApplication attest.EventType = 0x80000003
efiBootServicesDriver attest.EventType = 0x80000004
efiRuntimeServicesDriver attest.EventType = 0x80000005
efiGPTEvent attest.EventType = 0x80000006
efiAction attest.EventType = 0x80000007
efiPlatformFirmwareBlob attest.EventType = 0x80000008
efiHandoffTables attest.EventType = 0x80000009
efiHCRTMEvent attest.EventType = 0x80000010
efiVariableAuthority attest.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() attest.EventType
base() attest.Event
}

type baseEvent struct {
attest.Event
Err error
}

type stringEvent struct {
baseEvent
Message string
}

type PrebootCertEvent struct {
baseEvent
}

type PostEvent struct {
stringEvent
}

type NoActionEvent struct {
baseEvent
}

type SeparatorEvent struct {
baseEvent
}

type ActionEvent struct {
stringEvent
}

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

type CRTMContentEvent struct {
stringEvent
}

type CRTMEvent struct {
stringEvent
}

type MicrocodeEvent struct {
stringEvent
}

type PlatformConfigFlagsEvent struct {
baseEvent
}

type TableOfDevicesEvent struct {
baseEvent
}

type CompactHashEvent struct {
baseEvent
}

type IPLEvent struct {
stringEvent
}

type IPLPartitionEvent struct {
baseEvent
}

type NonHostCodeEvent struct {
baseEvent
}

type NonHostConfigEvent struct {
baseEvent
}

type NonHostInfoEvent struct {
baseEvent
}

type OmitBootDeviceEventsEvent struct {
stringEvent
}

func (event baseEvent) base() attest.Event {
return event.Event
}

func (event baseEvent) eventType() attest.EventType {
return event.Type
}

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 []attest.Event) ([]TPMEvent, error) {
var parsedEvents []TPMEvent

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

return parsedEvents, nil
}

0 comments on commit 64b577d

Please sign in to comment.