diff --git a/extract/extract.go b/extract/extract.go index d2ebf21..513759e 100644 --- a/extract/extract.go +++ b/extract/extract.go @@ -558,69 +558,49 @@ func GMESState(hash crypto.Hash, events []tcg.Event) (*pb.GMESState, error) { } if seen, ok := seenSeparators[event.MRIndex()]; ok && seen { - // Don't trust any events for the index after separator. - continue - } - - if eventType != tcg.EventTag { - // Ignore non-Tag events since GMES events are expected to be in Tag format. - continue - } - - // Verify event digest matches event data. - if err := DigestEquals(event, event.RawData()); err != nil { - return nil, fmt.Errorf("invalid digest at event %d: %v", event.Num(), err) - } - - // Parse PCCClient Tagged Event from event data. - taggedEvent, err := tcg.ParseTaggedEventData(event.RawData()) - if err != nil { - return nil, fmt.Errorf("failed to parse PCCClient Tagged Event at event %d: %v", event.Num(), err) - } - - if taggedEvent.ID != gmes.EventID { - return nil, fmt.Errorf("unexpected event ID at event %d: %v", event.Num(), taggedEvent.ID) - } - - // Parse Google Measurement Event Structure. - gmesEvent, err := gmes.ParseEvent(taggedEvent.Data) - if err != nil { - return nil, err + return nil, fmt.Errorf("found event after separator for MR%d at event %d", event.MRIndex(), event.Num()) } registerCfg := gmes.PCRConfig - // TODO: switch to real measurement tag config once we have a suitable event log. - tagCfg := gmes.MeasurementTagConfig - switch event.MRIndex() { case registerCfg.BMCFirmwareIdx: - if gmesEvent.Tag != tagCfg.BMCFirmware { - return nil, fmt.Errorf("unexpected measurement tag at event %d: %v", event.Num(), gmesEvent.Tag) + if eventType != tcg.EFIHCRTMEvent { + return nil, fmt.Errorf("unexpected event type for BMC firmware event: %d", eventType) } - state.BmcFirmware = string(gmesEvent.Content) - - case registerCfg.MBMIdx: - if gmesEvent.Tag != tagCfg.MBM { - return nil, fmt.Errorf("unexpected measurement tag at event %d: %v", event.Num(), gmesEvent.Tag) - } - state.Mbm = string(gmesEvent.Content) + state.BmcFirmwareDigest = event.ReplayedDigest() case registerCfg.BIOSIdx: - if gmesEvent.Tag != tagCfg.BIOS { - return nil, fmt.Errorf("unexpected measurement tag at event %d: %v", event.Num(), gmesEvent.Tag) + if eventType != tcg.GoogleDRTMEvent { + return nil, fmt.Errorf("unexpected event type for BIOS event: %d", eventType) } - state.Bios = string(gmesEvent.Content) + state.BiosDigest = event.ReplayedDigest() case registerCfg.HostKernelIdx: - if gmesEvent.Tag != tagCfg.HostKernel { - return nil, fmt.Errorf("unexpected measurement tag at event %d: %v", event.Num(), gmesEvent.Tag) + if eventType != tcg.EFIBootServicesApplication { + return nil, fmt.Errorf("unexpected event type for host kernel event: %d", eventType) + } + state.HostKernelDigest = event.ReplayedDigest() + + // Parse & populate image load event. + _, err := tcg.ParseEFIImageLoad(bytes.NewReader(event.RawData())) + if err != nil { + return nil, fmt.Errorf("failed parsing EFI image load at host kernel event %d: %v", event.Num(), err) } - state.HostKernel = string(gmesEvent.Content) + + case registerCfg.MBMIdx: + continue default: return nil, fmt.Errorf("unknown MR index: %d", event.MRIndex()) } } + // Confirm separators were found. + for mrIndex, seen := range seenSeparators { + if !seen { + return nil, fmt.Errorf("missing separator event for MR%d", mrIndex) + } + } + return state, nil } diff --git a/extract/extract_test.go b/extract/extract_test.go index 11ac8b8..435f8fb 100644 --- a/extract/extract_test.go +++ b/extract/extract_test.go @@ -27,13 +27,13 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" gmes "github.com/google/go-eventlog/extract/gmes" "github.com/google/go-eventlog/internal/testutil" "github.com/google/go-eventlog/register" "github.com/google/go-eventlog/tcg" "github.com/google/go-eventlog/testdata" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/testing/protocmp" pb "github.com/google/go-eventlog/proto/state" ) @@ -678,95 +678,137 @@ func decodeHex(hexStr string) []byte { } func TestGMESState(t *testing.T) { + separatorEvents := []tcg.Event{ + newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx), + newSeparatorEvent(t, gmes.PCRConfig.BIOSIdx), + newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), + newSeparatorEvent(t, gmes.PCRConfig.MBMIdx), + } + + bmcEvent := newEvent(t, gmes.PCRConfig.BMCFirmwareIdx, tcg.EFIHCRTMEvent, []byte(gmes.BMCData)) + biosEvent := newEvent(t, gmes.PCRConfig.BIOSIdx, tcg.GoogleDRTMEvent, []byte(gmes.BIOSData)) + kernelEvent := newEFIImageLoadEvent(t, gmes.PCRConfig.HostKernelIdx, 0x1000, 0x2000, 0x3000, []byte("test-dev-path")) + + validEvents := append([]tcg.Event{ + bmcEvent, + biosEvent, + kernelEvent, + // MBM data is not captured in GMESState but we should ensure it's handled correctly. + newEvent(t, gmes.PCRConfig.MBMIdx, tcg.EventTag, []byte("please ignore me!")), + }, separatorEvents...) + + // We need to ensure events are replayed correctly. + events := getEventsFromLog(t, validEvents) + + gotState, err := GMESState(crypto.SHA256, events) + if err != nil { + t.Fatalf("GMESState() error = %v", err) + } + expectedState := &pb.GMESState{ - Bios: "TestBIOS", - Mbm: "TestMBM", - BmcFirmware: "TestBMC", - HostKernel: "TestKernel", + BmcFirmwareDigest: bmcEvent.Digest, + BiosDigest: biosEvent.Digest, + HostKernelDigest: kernelEvent.Digest, } - validEvents := []tcg.Event{ - newGMESEvent(t, gmes.PCRConfig.BIOSIdx, gmes.MeasurementTagConfig.BIOS, expectedState.Bios), - newSeparatorEvent(t, gmes.PCRConfig.BIOSIdx), - newGMESEvent(t, gmes.PCRConfig.MBMIdx, gmes.MeasurementTagConfig.MBM, expectedState.Mbm), - newSeparatorEvent(t, gmes.PCRConfig.MBMIdx), - newGMESEvent(t, gmes.PCRConfig.BMCFirmwareIdx, gmes.MeasurementTagConfig.BMCFirmware, expectedState.BmcFirmware), + if diff := cmp.Diff(gotState, expectedState, protocmp.Transform()); diff != "" { + t.Errorf("GMESState() mismatch (-want +got):\n%s", diff) + } +} + +func TestGMESStateErrors(t *testing.T) { + separatorEvents := []tcg.Event{ newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx), - newGMESEvent(t, gmes.PCRConfig.HostKernelIdx, gmes.MeasurementTagConfig.HostKernel, expectedState.HostKernel), + newSeparatorEvent(t, gmes.PCRConfig.BIOSIdx), newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), + newSeparatorEvent(t, gmes.PCRConfig.MBMIdx), } + validEvents := append([]tcg.Event{ + newEvent(t, gmes.PCRConfig.BMCFirmwareIdx, tcg.EFIHCRTMEvent, []byte(gmes.BMCData)), + newEvent(t, gmes.PCRConfig.BIOSIdx, tcg.GoogleDRTMEvent, []byte(gmes.BIOSData)), + newEFIImageLoadEvent(t, gmes.PCRConfig.HostKernelIdx, 0x1000, 0x2000, 0x3000, []byte("test-dev-path")), + // MBM data is not captured in GMESState but we should ensure it's handled correctly. + newEvent(t, gmes.PCRConfig.MBMIdx, tcg.EventTag, []byte("please ignore me!")), + }, separatorEvents...) + testcases := []struct { - name string - events []tcg.Event - expectedState *pb.GMESState + name string + events []tcg.Event + expectedErrStr string }{ { - name: "valid events", - events: validEvents, - expectedState: expectedState, + name: "duplicate separator", + events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx)), + expectedErrStr: "duplicate separator event", }, { - name: "duplicate separator", - events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx)), - expectedState: nil, // Expect failure. + name: "event after separator", + events: append(validEvents, + newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.EFIBootServicesApplication, []byte("ModifiedKernel")), + ), + expectedErrStr: "found event after separator", }, { - name: "invalid tag", - events: []tcg.Event{newGMESEvent(t, gmes.PCRConfig.BIOSIdx, 9999, "InvalidTag")}, - expectedState: nil, // Expect failure. + name: "invalid BMC event type", + events: append([]tcg.Event{ + newEvent(t, gmes.PCRConfig.BMCFirmwareIdx, tcg.GoogleDRTMEvent, []byte(gmes.BMCData)), + }, separatorEvents...), + expectedErrStr: "unexpected event type for BMC firmware", }, { - name: "event after separator ignored", - events: append(validEvents, newGMESEvent(t, gmes.PCRConfig.HostKernelIdx, gmes.MeasurementTagConfig.HostKernel, "ModifiedKernel")), - expectedState: expectedState, // Should ignore the modified event after the separator. + name: "invalid BIOS event type", + events: append([]tcg.Event{ + newEvent(t, gmes.PCRConfig.BIOSIdx, tcg.EFIHCRTMEvent, []byte(gmes.BIOSData)), + }, separatorEvents...), + expectedErrStr: "unexpected event type for BIOS", + }, + { + name: "invalid Host Kernel event type", + events: append([]tcg.Event{ + newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.GoogleDRTMEvent, []byte("testhostkernel")), + newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), + }, separatorEvents...), + expectedErrStr: "unexpected event type for host kernel", + }, + { + name: "unknown MR index", + events: append([]tcg.Event{ + newEvent(t, 999, tcg.EFIHCRTMEvent, []byte("unknown data")), + }, separatorEvents...), + expectedErrStr: "unknown MR index", + }, + { + name: "missing separators", + events: []tcg.Event{ + newEvent(t, gmes.PCRConfig.BMCFirmwareIdx, tcg.EFIHCRTMEvent, []byte(gmes.BMCData)), + newEvent(t, gmes.PCRConfig.BIOSIdx, tcg.GoogleDRTMEvent, []byte(gmes.BIOSData)), + }, + expectedErrStr: "missing separator event", }, } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - gotState, err := GMESState(crypto.SHA256, getEventsFromLog(t, tc.events)) - - if (err != nil) != (tc.expectedState == nil) { - t.Fatalf("GMESState() error = %v, wantErr: %v", err, tc.expectedState == nil) + _, err := GMESState(crypto.SHA256, getEventsFromLog(t, tc.events)) + if err == nil { + t.Fatalf("GMESState() expected error containing %q, but got nil", tc.expectedErrStr) } - if tc.expectedState != nil && !cmp.Equal(gotState, tc.expectedState, cmpopts.IgnoreUnexported(pb.GMESState{})) { - t.Errorf("GMESState() = got %+v, want %+v", gotState, tc.expectedState) + if !strings.Contains(err.Error(), tc.expectedErrStr) { + t.Errorf("GMESState() expected error containing %q, but got %v", tc.expectedErrStr, err) } }) } } -// encodeGMESEventData packages content into the Google Measurement Event Structure -// and wraps it in a TCG Tagged Event structure. -func encodeGMESEventData(t *testing.T, tag uint32, content []byte) []byte { - t.Helper() - // Create GMES MeasurementEvent data - gmesBuf := new(bytes.Buffer) - binary.Write(gmesBuf, binary.LittleEndian, uint32(1)) // Version - binary.Write(gmesBuf, binary.LittleEndian, tag) // Tag - binary.Write(gmesBuf, binary.LittleEndian, uint32(len(content))) // Size - gmesBuf.Write(content) - gmesData := gmesBuf.Bytes() - - // Wrap in TCG_PCClientTaggedEventStruct - taggedBuf := new(bytes.Buffer) - binary.Write(taggedBuf, binary.LittleEndian, gmes.EventID) // ID - binary.Write(taggedBuf, binary.LittleEndian, uint32(len(gmesData))) // DataLen - taggedBuf.Write(gmesData) - - return taggedBuf.Bytes() -} - -// newGMESEvent creates a tcg.Event containing a GMES measurement. -func newGMESEvent(t *testing.T, mrIndex uint32, tag uint32, content string) tcg.Event { +// newEvent creates a tcg.Event containing a GMES measurement. +func newEvent(t *testing.T, mrIndex uint32, eventType tcg.EventType, data []byte) tcg.Event { t.Helper() - data := encodeGMESEventData(t, tag, []byte(content)) digest := sha256.Sum256(data) return tcg.Event{ Index: int(mrIndex), - Type: tcg.EventTag, + Type: eventType, Data: data, Digest: digest[:], } @@ -785,6 +827,25 @@ func newSeparatorEvent(t *testing.T, mrIndex uint32) tcg.Event { } } +// newEFIImageLoadEvent creates a tcg.Event containing an EFI image load event. +func newEFIImageLoadEvent(t *testing.T, mrIndex uint32, loadAddr, length, linkAddr uint64, devPathData []byte) tcg.Event { + t.Helper() + header := tcg.EFIImageLoadHeader{ + LoadAddr: loadAddr, + Length: length, + LinkAddr: linkAddr, + DevicePathLen: uint64(len(devPathData)), + } + buf := new(bytes.Buffer) + if err := binary.Write(buf, binary.LittleEndian, header); err != nil { + t.Fatal(err) + } + if _, err := buf.Write(devPathData); err != nil { + t.Fatal(err) + } + return newEvent(t, mrIndex, tcg.EFIBootServicesApplication, buf.Bytes()) +} + // getEventsFromLog takes a slice of events and returns a slice of verified events // by building a synthetic raw event log and replaying it. func getEventsFromLog(t *testing.T, events []tcg.Event) []tcg.Event { @@ -834,7 +895,13 @@ func getEventsFromLog(t *testing.T, events []tcg.Event) []tcg.Event { h.Write(current) } else { // First event for this PCR - initialize with zeros. + // Note this is a simplification for some PCRs. PCRs 17-23 are initialized with 0xFF but + // the DRTM event clears the index to 0x00 before extending. Starting with 0x00 is functionally + // the same because DRTM is always the first event, but this is subtly different from the spec. initial := make([]byte, h.Size()) + if e.Type == tcg.EFIHCRTMEvent { + initial[len(initial)-1] = 0x04 + } h.Write(initial) } h.Write(e.Digest) diff --git a/extract/gmes/gmes.go b/extract/gmes/gmes.go index e30ff54..a391aa2 100644 --- a/extract/gmes/gmes.go +++ b/extract/gmes/gmes.go @@ -15,19 +15,13 @@ // Package gmes has configs for extracting information from Google measurements. package gmes -import ( - "bytes" - "encoding/binary" - "fmt" -) +const ( + // BMCData is the expected content of the BMC Firmware event. + BMCData = "HCRTM" -// MeasurementEvent represents the structure of a Google measurement event. -type MeasurementEvent struct { - Version uint32 - Tag uint32 - Size uint32 - Content []byte -} + // BIOSData is the expected content of the BIOS event. + BIOSData = "DRTM" +) type registerConfig struct { BMCFirmwareIdx uint32 @@ -36,13 +30,6 @@ type registerConfig struct { HostKernelIdx uint32 } -type measurementTagConfig struct { - BMCFirmware uint32 - MBM uint32 - HostKernel uint32 - BIOS uint32 -} - // PCRConfig configures the expected PCR indexes for GMES event logs. var PCRConfig = registerConfig{ BMCFirmwareIdx: 0, @@ -50,40 +37,3 @@ var PCRConfig = registerConfig{ BIOSIdx: 17, HostKernelIdx: 21, } - -// MeasurementTagConfig configures the expected measurement tags for GMES events. -var MeasurementTagConfig = measurementTagConfig{ - BMCFirmware: 1, - BIOS: 2, - HostKernel: 3, - MBM: 4, -} - -// EventID is the expected event ID for GMES events. -var EventID uint32 = 0x474D4553 - -// ParseEvent parses a GMES event from the given data. -func ParseEvent(eventdata []byte) (*MeasurementEvent, error) { - r := bytes.NewReader(eventdata) - - measurement := &MeasurementEvent{} - - if err := binary.Read(r, binary.LittleEndian, &measurement.Version); err != nil { - return nil, fmt.Errorf("failed to parse measurement version: %v", err) - } - - if err := binary.Read(r, binary.LittleEndian, &measurement.Tag); err != nil { - return nil, fmt.Errorf("failed to parse measurement tag: %v", err) - } - - if err := binary.Read(r, binary.LittleEndian, &measurement.Size); err != nil { - return nil, fmt.Errorf("failed to parse measurement size: %v", err) - } - - measurement.Content = make([]byte, measurement.Size) - if _, err := r.Read(measurement.Content); err != nil { - return nil, fmt.Errorf("failed to parse measurement content: %v", err) - } - - return measurement, nil -} diff --git a/proto/state.proto b/proto/state.proto index 742d64e..6b5444c 100644 --- a/proto/state.proto +++ b/proto/state.proto @@ -222,8 +222,9 @@ message FirmwareLogState { // The verified state of Google measurements on the machine. message GMESState { - string bmc_firmware = 1; - string bios = 2; - string host_kernel = 3; - string mbm = 4; + bytes bmc_firmware_digest = 1; + + bytes bios_digest = 2; + + bytes host_kernel_digest = 3; } diff --git a/proto/state/state.pb.go b/proto/state/state.pb.go index 84ebd75..9dfdea7 100644 --- a/proto/state/state.pb.go +++ b/proto/state/state.pb.go @@ -1183,10 +1183,9 @@ type GMESState struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - BmcFirmware string `protobuf:"bytes,1,opt,name=bmc_firmware,json=bmcFirmware,proto3" json:"bmc_firmware,omitempty"` - Bios string `protobuf:"bytes,2,opt,name=bios,proto3" json:"bios,omitempty"` - HostKernel string `protobuf:"bytes,3,opt,name=host_kernel,json=hostKernel,proto3" json:"host_kernel,omitempty"` - Mbm string `protobuf:"bytes,4,opt,name=mbm,proto3" json:"mbm,omitempty"` + BmcFirmwareDigest []byte `protobuf:"bytes,1,opt,name=bmc_firmware_digest,json=bmcFirmwareDigest,proto3" json:"bmc_firmware_digest,omitempty"` + BiosDigest []byte `protobuf:"bytes,2,opt,name=bios_digest,json=biosDigest,proto3" json:"bios_digest,omitempty"` + HostKernelDigest []byte `protobuf:"bytes,3,opt,name=host_kernel_digest,json=hostKernelDigest,proto3" json:"host_kernel_digest,omitempty"` } func (x *GMESState) Reset() { @@ -1221,32 +1220,25 @@ func (*GMESState) Descriptor() ([]byte, []int) { return file_state_proto_rawDescGZIP(), []int{12} } -func (x *GMESState) GetBmcFirmware() string { +func (x *GMESState) GetBmcFirmwareDigest() []byte { if x != nil { - return x.BmcFirmware + return x.BmcFirmwareDigest } - return "" -} - -func (x *GMESState) GetBios() string { - if x != nil { - return x.Bios - } - return "" + return nil } -func (x *GMESState) GetHostKernel() string { +func (x *GMESState) GetBiosDigest() []byte { if x != nil { - return x.HostKernel + return x.BiosDigest } - return "" + return nil } -func (x *GMESState) GetMbm() string { +func (x *GMESState) GetHostKernelDigest() []byte { if x != nil { - return x.Mbm + return x.HostKernelDigest } - return "" + return nil } var File_state_proto protoreflect.FileDescriptor @@ -1367,43 +1359,44 @@ var file_state_proto_rawDesc = []byte{ 0x66, 0x69, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x03, 0x65, 0x66, 0x69, 0x12, 0x29, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, - 0x6c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x22, 0x75, 0x0a, - 0x09, 0x47, 0x4d, 0x45, 0x53, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6d, - 0x63, 0x5f, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x62, 0x6d, 0x63, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x62, 0x69, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x69, 0x6f, - 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x68, 0x6f, 0x73, 0x74, 0x4b, 0x65, 0x72, 0x6e, - 0x65, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x62, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6d, 0x62, 0x6d, 0x2a, 0x45, 0x0a, 0x07, 0x4c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, - 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x47, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x54, 0x43, 0x47, 0x32, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x4f, - 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x43, 0x10, 0x02, 0x2a, 0x62, 0x0a, 0x19, 0x47, - 0x43, 0x45, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x54, 0x65, - 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, - 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x56, 0x10, 0x01, 0x12, - 0x0e, 0x0a, 0x0a, 0x41, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x56, 0x5f, 0x45, 0x53, 0x10, 0x02, 0x12, - 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x54, 0x45, 0x4c, 0x5f, 0x54, 0x44, 0x58, 0x10, 0x03, 0x12, 0x0f, - 0x0a, 0x0b, 0x41, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x56, 0x5f, 0x53, 0x4e, 0x50, 0x10, 0x04, 0x2a, - 0x96, 0x01, 0x0a, 0x14, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, - 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x53, 0x5f, 0x57, 0x49, 0x4e, 0x44, - 0x4f, 0x57, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x44, 0x5f, 0x50, 0x43, 0x41, 0x5f, 0x32, 0x30, 0x31, - 0x31, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x53, 0x5f, 0x54, 0x48, 0x49, 0x52, 0x44, 0x5f, - 0x50, 0x41, 0x52, 0x54, 0x59, 0x5f, 0x55, 0x45, 0x46, 0x49, 0x5f, 0x43, 0x41, 0x5f, 0x32, 0x30, - 0x31, 0x31, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x53, 0x5f, 0x54, 0x48, 0x49, 0x52, 0x44, - 0x5f, 0x50, 0x41, 0x52, 0x54, 0x59, 0x5f, 0x4b, 0x45, 0x4b, 0x5f, 0x43, 0x41, 0x5f, 0x32, 0x30, - 0x31, 0x31, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x47, 0x43, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, - 0x55, 0x4c, 0x54, 0x5f, 0x50, 0x4b, 0x10, 0x04, 0x2a, 0x4a, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, - 0x41, 0x6c, 0x67, 0x6f, 0x12, 0x10, 0x0a, 0x0c, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x48, 0x41, 0x31, 0x10, 0x04, - 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x0b, 0x12, 0x0a, 0x0a, 0x06, - 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x0c, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x35, - 0x31, 0x32, 0x10, 0x0d, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x6c, 0x6f, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x22, 0x8a, 0x01, + 0x0a, 0x09, 0x47, 0x4d, 0x45, 0x53, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x62, + 0x6d, 0x63, 0x5f, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x64, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x62, 0x6d, 0x63, 0x46, 0x69, 0x72, + 0x6d, 0x77, 0x61, 0x72, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, + 0x69, 0x6f, 0x73, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0a, 0x62, 0x69, 0x6f, 0x73, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x12, + 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x64, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x68, 0x6f, 0x73, 0x74, 0x4b, 0x65, + 0x72, 0x6e, 0x65, 0x6c, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x2a, 0x45, 0x0a, 0x07, 0x4c, 0x6f, + 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x47, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, + 0x0d, 0x4c, 0x4f, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x43, 0x47, 0x32, 0x10, 0x01, + 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x4f, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x43, 0x10, + 0x02, 0x2a, 0x62, 0x0a, 0x19, 0x47, 0x43, 0x45, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x08, + 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x4d, 0x44, 0x5f, + 0x53, 0x45, 0x56, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x56, + 0x5f, 0x45, 0x53, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x54, 0x45, 0x4c, 0x5f, 0x54, + 0x44, 0x58, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x56, 0x5f, + 0x53, 0x4e, 0x50, 0x10, 0x04, 0x2a, 0x96, 0x01, 0x0a, 0x14, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, + 0x6f, 0x77, 0x6e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x0b, + 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x4d, + 0x53, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x44, 0x5f, 0x50, + 0x43, 0x41, 0x5f, 0x32, 0x30, 0x31, 0x31, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x53, 0x5f, + 0x54, 0x48, 0x49, 0x52, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x59, 0x5f, 0x55, 0x45, 0x46, 0x49, + 0x5f, 0x43, 0x41, 0x5f, 0x32, 0x30, 0x31, 0x31, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x53, + 0x5f, 0x54, 0x48, 0x49, 0x52, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x59, 0x5f, 0x4b, 0x45, 0x4b, + 0x5f, 0x43, 0x41, 0x5f, 0x32, 0x30, 0x31, 0x31, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x47, 0x43, + 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x50, 0x4b, 0x10, 0x04, 0x2a, 0x4a, + 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x41, 0x6c, 0x67, 0x6f, 0x12, 0x10, 0x0a, 0x0c, 0x48, 0x41, + 0x53, 0x48, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, + 0x53, 0x48, 0x41, 0x31, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, + 0x10, 0x0b, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x0c, 0x12, 0x0a, + 0x0a, 0x06, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0x0d, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x67, 0x6f, 0x2d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6c, 0x6f, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/tcg/events.go b/tcg/events.go index f7fd1e5..01458e0 100644 --- a/tcg/events.go +++ b/tcg/events.go @@ -105,6 +105,9 @@ const ( EFIVariableAuthority EventType = 0x800000E0 ) +// GoogleDRTMEvent is a custom DRTM event type for Google measurements. +const GoogleDRTMEvent EventType = 0x10000000 + // EventTypeNames maps an EventType to its name. var EventTypeNames = map[EventType]string{ PrebootCert: "Preboot Cert", @@ -142,6 +145,9 @@ var EventTypeNames = map[EventType]string{ EFIVariableBoot2: "EFI Variable Boot2", EFIHCRTMEvent: "EFI H-CRTM Event", EFIVariableAuthority: "EFI Variable Authority", + + // Custom event type, not in TCG spec. + GoogleDRTMEvent: "Google DRTM Event", } var eventTypeStrings = map[uint32]string{ @@ -179,6 +185,9 @@ var eventTypeStrings = map[uint32]string{ 0x8000000C: "EV_EFI_VARIABLE_BOOT2", 0x80000010: "EV_EFI_HCRTM_EVENT", 0x800000E0: "EV_EFI_VARIABLE_AUTHORITY", + + // Custom event type, not in TCG spec. + 0x10000000: "EV_GOOGLE_DRTM_EVENT", } // KnownName returns an event type's readable name if it exists. diff --git a/testdata/eventlog_data.go b/testdata/eventlog_data.go index fd8ce92..8cbe52d 100644 --- a/testdata/eventlog_data.go +++ b/testdata/eventlog_data.go @@ -49,6 +49,8 @@ var ( Ubuntu2404IntelTdxA4HighGpu8GEventLog []byte //go:embed eventlogs/tpm/cos-125-intel-tdx-secure-boot.bin Cos125IntelTdxSecureBootA4HighGpu8GEventLog []byte + //go:embed eventlogs/tpm/host-gmes.bin + HostGMESEventLog []byte ) // Kernel command lines from event logs. diff --git a/testdata/eventlogs/tpm/host-gmes.bin b/testdata/eventlogs/tpm/host-gmes.bin new file mode 100644 index 0000000..1ba2ce8 Binary files /dev/null and b/testdata/eventlogs/tpm/host-gmes.bin differ