-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an initial implementation of parsing event types
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.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |