mirror of
https://github.com/google/go-attestation.git
synced 2024-12-19 04:57:59 +00:00
attest: improve event log debugging (#190)
Event log verification is terrible and easy to mess up. Even if you replay against the PCRs there are still values that can be tampered with or reordered. PCRs also shouldn't be trusted unless they're attested to have come from the correct TPM. Given this, it seems advantageous to add some ability to consume raw event logs, even if it's just for debugging.
This commit is contained in:
parent
63c5188962
commit
0efaf4b19f
@ -65,17 +65,71 @@ const (
|
||||
)
|
||||
|
||||
// EventType indicates what kind of data an event is reporting.
|
||||
//
|
||||
// https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClientSpecPlat_TPM_2p0_1p04_pub.pdf#page=103
|
||||
type EventType uint32
|
||||
|
||||
var eventTypeStrings = map[uint32]string{
|
||||
0x00000000: "EV_PREBOOT_CERT",
|
||||
0x00000001: "EV_POST_CODE",
|
||||
0x00000002: "EV_UNUSED",
|
||||
0x00000003: "EV_NO_ACTION",
|
||||
0x00000004: "EV_SEPARATOR",
|
||||
0x00000005: "EV_ACTION",
|
||||
0x00000006: "EV_EVENT_TAG",
|
||||
0x00000007: "EV_S_CRTM_CONTENTS",
|
||||
0x00000008: "EV_S_CRTM_VERSION",
|
||||
0x00000009: "EV_CPU_MICROCODE",
|
||||
0x0000000A: "EV_PLATFORM_CONFIG_FLAGS",
|
||||
0x0000000B: "EV_TABLE_OF_DEVICES",
|
||||
0x0000000C: "EV_COMPACT_HASH",
|
||||
0x0000000D: "EV_IPL",
|
||||
0x0000000E: "EV_IPL_PARTITION_DATA",
|
||||
0x0000000F: "EV_NONHOST_CODE",
|
||||
0x00000010: "EV_NONHOST_CONFIG",
|
||||
0x00000011: "EV_NONHOST_INFO",
|
||||
0x00000012: "EV_OMIT_BOOT_DEVICE_EVENTS",
|
||||
0x80000000: "EV_EFI_EVENT_BASE",
|
||||
0x80000001: "EV_EFI_VARIABLE_DRIVER_CONFIG",
|
||||
0x80000002: "EV_EFI_VARIABLE_BOOT",
|
||||
0x80000003: "EV_EFI_BOOT_SERVICES_APPLICATION",
|
||||
0x80000004: "EV_EFI_BOOT_SERVICES_DRIVER",
|
||||
0x80000005: "EV_EFI_RUNTIME_SERVICES_DRIVER",
|
||||
0x80000006: "EV_EFI_GPT_EVENT",
|
||||
0x80000007: "EV_EFI_ACTION",
|
||||
0x80000008: "EV_EFI_PLATFORM_FIRMWARE_BLOB",
|
||||
0x80000009: "EV_EFI_HANDOFF_TABLES",
|
||||
0x80000010: "EV_EFI_HCRTM_EVENT",
|
||||
0x800000E0: "EV_EFI_VARIABLE_AUTHORITY",
|
||||
}
|
||||
|
||||
// String returns the Spec name of the EventType, for example "EV_ACTION". If
|
||||
// unknown, it returns a formatted string of the EventType value.
|
||||
func (e EventType) String() string {
|
||||
if s, ok := eventTypeStrings[uint32(e)]; ok {
|
||||
return s
|
||||
}
|
||||
// NOTE: 0x00000013-0x0000FFFF are reserverd. Should we include that
|
||||
// information in the formatting?
|
||||
return fmt.Sprintf("EventType(0x%08x)", uint32(e))
|
||||
}
|
||||
|
||||
// Event is a single event from a TCG event log. This reports descrete items such
|
||||
// as BIOs measurements or EFI states.
|
||||
//
|
||||
// There are many pitfalls for using event log events correctly to determine the
|
||||
// state of a machine[1]. In general it's must safer to only rely on the raw PCR
|
||||
// values and use the event log for debugging.
|
||||
//
|
||||
// [1] https://github.com/google/go-attestation/blob/master/docs/event-log-disclosure.md
|
||||
type Event struct {
|
||||
// order of the event in the event log.
|
||||
sequence int
|
||||
|
||||
// PCR index of the event.
|
||||
// Index of the PCR that this event was replayed against.
|
||||
Index int
|
||||
// Type of the event.
|
||||
// Untrusted type of the event. This value is not verified by event log replays
|
||||
// and can be tampered with. It should NOT be used without additional context,
|
||||
// and unrecognized event types should result in errors.
|
||||
Type EventType
|
||||
|
||||
// Data of the event. For certain kinds of events, this must match the event
|
||||
@ -132,8 +186,39 @@ func (e *EventLog) clone() *EventLog {
|
||||
return &out
|
||||
}
|
||||
|
||||
// Events returns events that have not been replayed against the PCR values and
|
||||
// are therefore unverified. The returned events contain the digest that matches
|
||||
// the provided hash algorithm, or are empty if that event didn't contain a
|
||||
// digest for that hash.
|
||||
//
|
||||
// This method is insecure and should only be used for debugging.
|
||||
func (e *EventLog) Events(hash HashAlg) []Event {
|
||||
var events []Event
|
||||
for _, re := range e.rawEvents {
|
||||
ev := Event{
|
||||
Index: re.index,
|
||||
Type: re.typ,
|
||||
Data: re.data,
|
||||
}
|
||||
|
||||
for _, digest := range re.digests {
|
||||
if hash.cryptoHash() != digest.hash {
|
||||
continue
|
||||
}
|
||||
ev.Digest = digest.data
|
||||
break
|
||||
}
|
||||
events = append(events, ev)
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
// Verify replays the event log against a TPM's PCR values, returning the
|
||||
// events which could be matched to a provided PCR value.
|
||||
//
|
||||
// PCRs provide no security guarentees unless they're attested to have been
|
||||
// generated by a TPM. Verify does not perform these checks.
|
||||
//
|
||||
// An error is returned if the replayed digest for events with a given PCR
|
||||
// index do not match any provided value for that PCR index.
|
||||
func (e *EventLog) Verify(pcrs []PCR) ([]Event, error) {
|
||||
|
Loading…
Reference in New Issue
Block a user