From e08eef3abb16ebcaec4df8a67ca610b8fb353f72 Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Tue, 12 May 2026 00:36:51 +0000 Subject: [PATCH 01/10] Update GMESState --- extract/extract.go | 55 +++------- extract/extract_test.go | 65 +++++------ extract/gmes/gmes.go | 62 ++--------- proto/state.proto | 23 +++- proto/state/state.pb.go | 232 +++++++++++++++++++++++++++++----------- tcg/events.go | 6 ++ 6 files changed, 239 insertions(+), 204 deletions(-) diff --git a/extract/extract.go b/extract/extract.go index d2ebf21..eceff23 100644 --- a/extract/extract.go +++ b/extract/extract.go @@ -562,60 +562,29 @@ func GMESState(hash crypto.Hash, events []tcg.Event) (*pb.GMESState, error) { 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 - } - 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) - } - 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) + if eventType != tcg.EFIHCRTMEvent { + continue } - 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 { + continue } - 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 { + continue } - state.HostKernel = string(gmesEvent.Content) + state.HostKernelDigest = event.ReplayedDigest() + + case registerCfg.MBMIdx: + continue default: return nil, fmt.Errorf("unknown MR index: %d", event.MRIndex()) diff --git a/extract/extract_test.go b/extract/extract_test.go index 11ac8b8..413bba9 100644 --- a/extract/extract_test.go +++ b/extract/extract_test.go @@ -678,22 +678,29 @@ func decodeHex(hexStr string) []byte { } func TestGMESState(t *testing.T) { + // In this library version, ReplayedDigest() returns the event digest (H(data)). + calcReplayed := func(data []byte) []byte { + h := sha256.New() + h.Write(data) + return h.Sum(nil) + } + expectedState := &pb.GMESState{ - Bios: "TestBIOS", - Mbm: "TestMBM", - BmcFirmware: "TestBMC", - HostKernel: "TestKernel", + BmcFirmwareDigest: calcReplayed([]byte(gmes.BMCData)), + BiosDigest: calcReplayed([]byte(gmes.BIOSData)), + HostKernelDigest: calcReplayed([]byte("KernelData")), } 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), + newEvent(t, gmes.PCRConfig.BMCFirmwareIdx, tcg.EFIHCRTMEvent, []byte(gmes.BMCData)), newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx), - newGMESEvent(t, gmes.PCRConfig.HostKernelIdx, gmes.MeasurementTagConfig.HostKernel, expectedState.HostKernel), + newEvent(t, gmes.PCRConfig.BIOSIdx, tcg.GoogleDRTMEvent, []byte(gmes.BIOSData)), + newSeparatorEvent(t, gmes.PCRConfig.BIOSIdx), + newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.EFIBootServicesApplication, []byte("KernelData")), newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), + // 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!")), + newSeparatorEvent(t, gmes.PCRConfig.MBMIdx), } testcases := []struct { @@ -711,14 +718,9 @@ func TestGMESState(t *testing.T) { events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx)), expectedState: nil, // Expect failure. }, - { - name: "invalid tag", - events: []tcg.Event{newGMESEvent(t, gmes.PCRConfig.BIOSIdx, 9999, "InvalidTag")}, - expectedState: nil, // Expect failure. - }, { name: "event after separator ignored", - events: append(validEvents, newGMESEvent(t, gmes.PCRConfig.HostKernelIdx, gmes.MeasurementTagConfig.HostKernel, "ModifiedKernel")), + events: append(validEvents, newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.EFIBootServicesApplication, []byte("ModifiedKernel"))), expectedState: expectedState, // Should ignore the modified event after the separator. }, } @@ -738,35 +740,13 @@ func TestGMESState(t *testing.T) { } } -// 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 { +// 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() - // 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 { - 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[:], } @@ -835,6 +815,9 @@ func getEventsFromLog(t *testing.T, events []tcg.Event) []tcg.Event { } else { // First event for this PCR - initialize with zeros. 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..57e4b75 100644 --- a/proto/state.proto +++ b/proto/state.proto @@ -222,8 +222,23 @@ 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; + message ImageLoad { + uint64 load_address = 1; + + uint64 image_length = 2; + + uint64 link_address = 3; + + uint64 device_path_length = 4; + + bytes device_path = 5; + } + + bytes bmc_firmware_digest = 1; + + bytes bios_digest = 2; + + bytes host_kernel_digest = 3; + + ImageLoad host_kernel_image_load = 4; } diff --git a/proto/state/state.pb.go b/proto/state/state.pb.go index 84ebd75..00d3176 100644 --- a/proto/state/state.pb.go +++ b/proto/state/state.pb.go @@ -1183,10 +1183,10 @@ 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"` + HostKernelImageLoad *GMESState_ImageLoad `protobuf:"bytes,4,opt,name=host_kernel_image_load,json=hostKernelImageLoad,proto3" json:"host_kernel_image_load,omitempty"` } func (x *GMESState) Reset() { @@ -1221,32 +1221,111 @@ 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 "" + return nil } -func (x *GMESState) GetBios() string { +func (x *GMESState) GetBiosDigest() []byte { if x != nil { - return x.Bios + return x.BiosDigest } - return "" + return nil } -func (x *GMESState) GetHostKernel() string { +func (x *GMESState) GetHostKernelDigest() []byte { if x != nil { - return x.HostKernel + return x.HostKernelDigest } - return "" + return nil } -func (x *GMESState) GetMbm() string { +func (x *GMESState) GetHostKernelImageLoad() *GMESState_ImageLoad { if x != nil { - return x.Mbm + return x.HostKernelImageLoad } - return "" + return nil +} + +type GMESState_ImageLoad struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LoadAddress uint64 `protobuf:"varint,1,opt,name=load_address,json=loadAddress,proto3" json:"load_address,omitempty"` + ImageLength uint64 `protobuf:"varint,2,opt,name=image_length,json=imageLength,proto3" json:"image_length,omitempty"` + LinkAddress uint64 `protobuf:"varint,3,opt,name=link_address,json=linkAddress,proto3" json:"link_address,omitempty"` + DevicePathLength uint64 `protobuf:"varint,4,opt,name=device_path_length,json=devicePathLength,proto3" json:"device_path_length,omitempty"` + DevicePath []byte `protobuf:"bytes,5,opt,name=device_path,json=devicePath,proto3" json:"device_path,omitempty"` +} + +func (x *GMESState_ImageLoad) Reset() { + *x = GMESState_ImageLoad{} + if protoimpl.UnsafeEnabled { + mi := &file_state_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GMESState_ImageLoad) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GMESState_ImageLoad) ProtoMessage() {} + +func (x *GMESState_ImageLoad) ProtoReflect() protoreflect.Message { + mi := &file_state_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GMESState_ImageLoad.ProtoReflect.Descriptor instead. +func (*GMESState_ImageLoad) Descriptor() ([]byte, []int) { + return file_state_proto_rawDescGZIP(), []int{12, 0} +} + +func (x *GMESState_ImageLoad) GetLoadAddress() uint64 { + if x != nil { + return x.LoadAddress + } + return 0 +} + +func (x *GMESState_ImageLoad) GetImageLength() uint64 { + if x != nil { + return x.ImageLength + } + return 0 +} + +func (x *GMESState_ImageLoad) GetLinkAddress() uint64 { + if x != nil { + return x.LinkAddress + } + return 0 +} + +func (x *GMESState_ImageLoad) GetDevicePathLength() uint64 { + if x != nil { + return x.DevicePathLength + } + return 0 +} + +func (x *GMESState_ImageLoad) GetDevicePath() []byte { + if x != nil { + return x.DevicePath + } + return nil } var File_state_proto protoreflect.FileDescriptor @@ -1367,43 +1446,62 @@ 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, 0xa1, 0x03, + 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, 0x12, 0x4f, 0x0a, 0x16, 0x68, 0x6f, + 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, + 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x2e, 0x47, 0x4d, 0x45, 0x53, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x13, 0x68, 0x6f, 0x73, 0x74, 0x4b, 0x65, 0x72, 0x6e, + 0x65, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x1a, 0xc3, 0x01, 0x0a, 0x09, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6c, 0x6f, 0x61, + 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, + 0x21, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x61, 0x74, + 0x68, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x61, 0x74, + 0x68, 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 ( @@ -1419,7 +1517,7 @@ func file_state_proto_rawDescGZIP() []byte { } var file_state_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_state_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_state_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_state_proto_goTypes = []any{ (LogType)(0), // 0: state.LogType (GCEConfidentialTechnology)(0), // 1: state.GCEConfidentialTechnology @@ -1438,6 +1536,7 @@ var file_state_proto_goTypes = []any{ (*EfiState)(nil), // 14: state.EfiState (*FirmwareLogState)(nil), // 15: state.FirmwareLogState (*GMESState)(nil), // 16: state.GMESState + (*GMESState_ImageLoad)(nil), // 17: state.GMESState.ImageLoad } var file_state_proto_depIdxs = []int32{ 1, // 0: state.PlatformState.technology:type_name -> state.GCEConfidentialTechnology @@ -1461,11 +1560,12 @@ var file_state_proto_depIdxs = []int32{ 8, // 18: state.FirmwareLogState.linux_kernel:type_name -> state.LinuxKernelState 14, // 19: state.FirmwareLogState.efi:type_name -> state.EfiState 0, // 20: state.FirmwareLogState.log_type:type_name -> state.LogType - 21, // [21:21] is the sub-list for method output_type - 21, // [21:21] is the sub-list for method input_type - 21, // [21:21] is the sub-list for extension type_name - 21, // [21:21] is the sub-list for extension extendee - 0, // [0:21] is the sub-list for field type_name + 17, // 21: state.GMESState.host_kernel_image_load:type_name -> state.GMESState.ImageLoad + 22, // [22:22] is the sub-list for method output_type + 22, // [22:22] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name } func init() { file_state_proto_init() } @@ -1630,6 +1730,18 @@ func file_state_proto_init() { return nil } } + file_state_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*GMESState_ImageLoad); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_state_proto_msgTypes[1].OneofWrappers = []any{ (*PlatformState_ScrtmVersionId)(nil), @@ -1645,7 +1757,7 @@ func file_state_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_state_proto_rawDesc, NumEnums: 4, - NumMessages: 13, + NumMessages: 14, NumExtensions: 0, NumServices: 0, }, diff --git a/tcg/events.go b/tcg/events.go index f7fd1e5..bd042e5 100644 --- a/tcg/events.go +++ b/tcg/events.go @@ -105,6 +105,9 @@ const ( EFIVariableAuthority EventType = 0x800000E0 ) +// Custom DRTM event type for GMES. +const GoogleDRTMEvent EventType = 0x10000000 + // EventTypeNames maps an EventType to its name. var EventTypeNames = map[EventType]string{ PrebootCert: "Preboot Cert", @@ -142,6 +145,8 @@ var EventTypeNames = map[EventType]string{ EFIVariableBoot2: "EFI Variable Boot2", EFIHCRTMEvent: "EFI H-CRTM Event", EFIVariableAuthority: "EFI Variable Authority", + + GoogleDRTMEvent: "Google DRTM Event", } var eventTypeStrings = map[uint32]string{ @@ -179,6 +184,7 @@ var eventTypeStrings = map[uint32]string{ 0x8000000C: "EV_EFI_VARIABLE_BOOT2", 0x80000010: "EV_EFI_HCRTM_EVENT", 0x800000E0: "EV_EFI_VARIABLE_AUTHORITY", + 0x10000000: "EV_GOOGLE_DRTM_EVENT", } // KnownName returns an event type's readable name if it exists. From 1a286092b583dc06888316e9335e3af7ac36bad6 Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Tue, 12 May 2026 00:45:37 +0000 Subject: [PATCH 02/10] fix formatting and lint errors --- tcg/events.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tcg/events.go b/tcg/events.go index bd042e5..f13543a 100644 --- a/tcg/events.go +++ b/tcg/events.go @@ -105,7 +105,7 @@ const ( EFIVariableAuthority EventType = 0x800000E0 ) -// Custom DRTM event type for GMES. +// GoogleDRTMEvent is a custom DRTM event type for Google measurements. const GoogleDRTMEvent EventType = 0x10000000 // EventTypeNames maps an EventType to its name. @@ -145,8 +145,8 @@ var EventTypeNames = map[EventType]string{ EFIVariableBoot2: "EFI Variable Boot2", EFIHCRTMEvent: "EFI H-CRTM Event", EFIVariableAuthority: "EFI Variable Authority", - - GoogleDRTMEvent: "Google DRTM Event", + + GoogleDRTMEvent: "Google DRTM Event", } var eventTypeStrings = map[uint32]string{ From ba0c9d59ddbfb03404c118ca4665fa5c20deb6e2 Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Tue, 12 May 2026 18:22:08 +0000 Subject: [PATCH 03/10] add gmes eventlog to testdata --- extract/extract.go | 14 +++++++ extract/extract_test.go | 58 +++++++++++++++++++++------ testdata/eventlog_data.go | 2 + testdata/eventlogs/tpm/host-gmes.bin | Bin 0 -> 959 bytes 4 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 testdata/eventlogs/tpm/host-gmes.bin diff --git a/extract/extract.go b/extract/extract.go index eceff23..1549195 100644 --- a/extract/extract.go +++ b/extract/extract.go @@ -583,6 +583,20 @@ func GMESState(hash crypto.Hash, events []tcg.Event) (*pb.GMESState, error) { } state.HostKernelDigest = event.ReplayedDigest() + // Parse & populate image load event. + imageLoadEvent, 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.HostKernelImageLoad = &pb.GMESState_ImageLoad{ + LoadAddress: imageLoadEvent.Header.LoadAddr, + ImageLength: imageLoadEvent.Header.Length, + LinkAddress: imageLoadEvent.Header.LinkAddr, + DevicePathLength: imageLoadEvent.Header.DevicePathLen, + DevicePath: imageLoadEvent.DevPathData, + } + case registerCfg.MBMIdx: continue diff --git a/extract/extract_test.go b/extract/extract_test.go index 413bba9..f947576 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,6 +678,43 @@ func decodeHex(hexStr string) []byte { } func TestGMESState(t *testing.T) { + log := testdata.HostGMESEventLog + expectedState := &pb.GMESState{ + BmcFirmwareDigest: decodeHex("c02bb61127ae90e3fcf2601702805592f5ee0952ee3a8bc518ac0171a75e1342"), + BiosDigest: decodeHex("44b389a3de1020401e9dc7adbb8b1515e5cade4a9bdfa9cce412f3e7ba9c1650"), + HostKernelDigest: decodeHex("825473358df6447f49eaaea583ab0d424fe9ba3aeeb13d0f739f3e942398701c"), + HostKernelImageLoad: &pb.GMESState_ImageLoad{ + LoadAddress: 0x63407018, + ImageLength: 15613408, + LinkAddress: 0x0, + DevicePathLength: 136, + DevicePath: decodeHex("02010c00d041030a200000000101060000010101060001000317100001000000000000000000000004012a000c00000000d0030000000000000002000000000056f5e6005eae42c9a0e1cd8fb5a1c6100202040432004500460049005c005c0042004f004f0054005c005c0042004f004f0054005800360034002e0065006600690000007fff0400"), + }, + } + + pcrBank := testutil.MakePCRBank(pb.HashAlgo_SHA256, map[uint32][]byte{ + 0: decodeHex("e2edb8749753227b24dd2e6689168da5fa4c148fd4567f697c58e6dd577ae4cd"), + 11: decodeHex("872129205c91e8027680899f6749f6409e204d9c366e40b41fedfeec0728b4c8"), + 17: decodeHex("22edb58db85ff13e1ae8110f90955b21b4d972593c3e07d9301f93ea540fbdfd"), + 21: decodeHex("5f60771aaf02702e3a647cdce310611e83d2669d0b77445e9b200ea3dab7993d"), + }) + + events, err := tcg.ParseAndReplay(log, pcrBank.MRs(), tcg.ParseOpts{}) + if err != nil { + t.Fatalf("Error parsing events: %v", err) + } + + gotState, err := GMESState(crypto.SHA256, events) + if err != nil { + t.Fatalf("GMESState() error = %v", err) + } + + if diff := cmp.Diff(gotState, expectedState, protocmp.Transform()); diff != "" { + t.Errorf("GMESState() mismatch (-want +got):\n%s", diff) + } +} + +func TestGMESStateErrors(t *testing.T) { // In this library version, ReplayedDigest() returns the event digest (H(data)). calcReplayed := func(data []byte) []byte { h := sha256.New() @@ -688,7 +725,6 @@ func TestGMESState(t *testing.T) { expectedState := &pb.GMESState{ BmcFirmwareDigest: calcReplayed([]byte(gmes.BMCData)), BiosDigest: calcReplayed([]byte(gmes.BIOSData)), - HostKernelDigest: calcReplayed([]byte("KernelData")), } validEvents := []tcg.Event{ @@ -696,8 +732,6 @@ func TestGMESState(t *testing.T) { newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx), newEvent(t, gmes.PCRConfig.BIOSIdx, tcg.GoogleDRTMEvent, []byte(gmes.BIOSData)), newSeparatorEvent(t, gmes.PCRConfig.BIOSIdx), - newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.EFIBootServicesApplication, []byte("KernelData")), - newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), // 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!")), newSeparatorEvent(t, gmes.PCRConfig.MBMIdx), @@ -708,20 +742,18 @@ func TestGMESState(t *testing.T) { events []tcg.Event expectedState *pb.GMESState }{ - { - name: "valid events", - events: validEvents, - expectedState: expectedState, - }, { name: "duplicate separator", - events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx)), + events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx)), expectedState: nil, // Expect failure. }, { name: "event after separator ignored", - events: append(validEvents, newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.EFIBootServicesApplication, []byte("ModifiedKernel"))), - expectedState: expectedState, // Should ignore the modified event after the separator. + events: append(validEvents, + newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), + newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.EFIBootServicesApplication, []byte("ModifiedKernel")), + ), + expectedState: expectedState, // Should ignore the event after the separator. }, } @@ -733,7 +765,7 @@ func TestGMESState(t *testing.T) { t.Fatalf("GMESState() error = %v, wantErr: %v", err, tc.expectedState == nil) } - if tc.expectedState != nil && !cmp.Equal(gotState, tc.expectedState, cmpopts.IgnoreUnexported(pb.GMESState{})) { + if tc.expectedState != nil && !cmp.Equal(gotState, tc.expectedState, protocmp.Transform()) { t.Errorf("GMESState() = got %+v, want %+v", gotState, tc.expectedState) } }) 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 0000000000000000000000000000000000000000..1ba2ce825cb812d630aabcda2f862ea26342b458 GIT binary patch literal 959 zcmZQzU|?VdVr)PaC>UIjnyldIqTpJVnpa|A%)kgz$i%<|qPZCq7+Bl`oP$AP0t^fd z5Wxf5+XU6uO?dq0Q-U~CL+GTh?>K|rS#=+kSi@MjJWkk&6{y<7IVi-J8^~Y-Vu-dh zKDGPT`2u~nCZ1Ulw4C*S!Ap&sN1889Z{vSc`+4r}K5?MRU{_yvejp74AeZ|(`3ge# z0uX~-Hg_(*C!pXUH~0A3-QA+1Pfy+RntgxenI}S@pYNI@7Qg~j?En%Bwy3sP0;pP|z#$nFUJq>FfhaiWfU=kvc^ED@GIJ>a`HYOfIAR2mj10`;0^q~~ z)4;;0#lQpNT!1BEPz*3IgnfO+5Vy|hfd$=2X$sRRKrASPWGD0!2v3jiBZ?GFF| literal 0 HcmV?d00001 From 52f325a2e1205124c5e364ba5be77a60662a25da Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Tue, 12 May 2026 18:22:55 +0000 Subject: [PATCH 04/10] gofmt --- extract/extract_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extract/extract_test.go b/extract/extract_test.go index f947576..24703b7 100644 --- a/extract/extract_test.go +++ b/extract/extract_test.go @@ -748,8 +748,8 @@ func TestGMESStateErrors(t *testing.T) { expectedState: nil, // Expect failure. }, { - name: "event after separator ignored", - events: append(validEvents, + name: "event after separator ignored", + events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.EFIBootServicesApplication, []byte("ModifiedKernel")), ), From 69076cd2a634765f6b6beec1ac033683f0acbe11 Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Tue, 12 May 2026 23:43:13 +0000 Subject: [PATCH 05/10] address comments --- extract/extract.go | 20 +--- extract/extract_test.go | 69 ++++++++------ proto/state.proto | 14 --- proto/state/state.pb.go | 199 ++++++++-------------------------------- 4 files changed, 85 insertions(+), 217 deletions(-) diff --git a/extract/extract.go b/extract/extract.go index 1549195..318b263 100644 --- a/extract/extract.go +++ b/extract/extract.go @@ -558,45 +558,35 @@ 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 + return nil, fmt.Errorf("found event after separator for MR%d at event %d", event.MRIndex(), event.Num()) } registerCfg := gmes.PCRConfig - switch event.MRIndex() { case registerCfg.BMCFirmwareIdx: if eventType != tcg.EFIHCRTMEvent { - continue + return nil, fmt.Errorf("unexpected event type for BMC firmware event: %d", eventType) } state.BmcFirmwareDigest = event.ReplayedDigest() case registerCfg.BIOSIdx: if eventType != tcg.GoogleDRTMEvent { - continue + return nil, fmt.Errorf("unexpected event type for BIOS event: %d", eventType) } state.BiosDigest = event.ReplayedDigest() case registerCfg.HostKernelIdx: if eventType != tcg.EFIBootServicesApplication { - continue + return nil, fmt.Errorf("unexpected event type for host kernel event: %d", eventType) } state.HostKernelDigest = event.ReplayedDigest() // Parse & populate image load event. - imageLoadEvent, err := tcg.ParseEFIImageLoad(bytes.NewReader(event.RawData())) + _, 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.HostKernelImageLoad = &pb.GMESState_ImageLoad{ - LoadAddress: imageLoadEvent.Header.LoadAddr, - ImageLength: imageLoadEvent.Header.Length, - LinkAddress: imageLoadEvent.Header.LinkAddr, - DevicePathLength: imageLoadEvent.Header.DevicePathLen, - DevicePath: imageLoadEvent.DevPathData, - } - case registerCfg.MBMIdx: continue diff --git a/extract/extract_test.go b/extract/extract_test.go index 24703b7..34237b4 100644 --- a/extract/extract_test.go +++ b/extract/extract_test.go @@ -683,13 +683,6 @@ func TestGMESState(t *testing.T) { BmcFirmwareDigest: decodeHex("c02bb61127ae90e3fcf2601702805592f5ee0952ee3a8bc518ac0171a75e1342"), BiosDigest: decodeHex("44b389a3de1020401e9dc7adbb8b1515e5cade4a9bdfa9cce412f3e7ba9c1650"), HostKernelDigest: decodeHex("825473358df6447f49eaaea583ab0d424fe9ba3aeeb13d0f739f3e942398701c"), - HostKernelImageLoad: &pb.GMESState_ImageLoad{ - LoadAddress: 0x63407018, - ImageLength: 15613408, - LinkAddress: 0x0, - DevicePathLength: 136, - DevicePath: decodeHex("02010c00d041030a200000000101060000010101060001000317100001000000000000000000000004012a000c00000000d0030000000000000002000000000056f5e6005eae42c9a0e1cd8fb5a1c6100202040432004500460049005c005c0042004f004f0054005c005c0042004f004f0054005800360034002e0065006600690000007fff0400"), - }, } pcrBank := testutil.MakePCRBank(pb.HashAlgo_SHA256, map[uint32][]byte{ @@ -715,18 +708,6 @@ func TestGMESState(t *testing.T) { } func TestGMESStateErrors(t *testing.T) { - // In this library version, ReplayedDigest() returns the event digest (H(data)). - calcReplayed := func(data []byte) []byte { - h := sha256.New() - h.Write(data) - return h.Sum(nil) - } - - expectedState := &pb.GMESState{ - BmcFirmwareDigest: calcReplayed([]byte(gmes.BMCData)), - BiosDigest: calcReplayed([]byte(gmes.BIOSData)), - } - validEvents := []tcg.Event{ newEvent(t, gmes.PCRConfig.BMCFirmwareIdx, tcg.EFIHCRTMEvent, []byte(gmes.BMCData)), newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx), @@ -740,33 +721,63 @@ func TestGMESStateErrors(t *testing.T) { testcases := []struct { name string events []tcg.Event - expectedState *pb.GMESState + expectedErrStr string }{ { name: "duplicate separator", events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx)), - expectedState: nil, // Expect failure. + expectedErrStr: "duplicate separator event", }, { - name: "event after separator ignored", + name: "event after separator", events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.EFIBootServicesApplication, []byte("ModifiedKernel")), ), - expectedState: expectedState, // Should ignore the event after the separator. + expectedErrStr: "found event after separator", + }, + { + name: "invalid BMC event type", + events: []tcg.Event{ + newEvent(t, gmes.PCRConfig.BMCFirmwareIdx, tcg.GoogleDRTMEvent, []byte(gmes.BMCData)), + newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx), + }, + expectedErrStr: "unexpected event type for BMC firmware", + }, + { + name: "invalid BIOS event type", + events: []tcg.Event{ + newEvent(t, gmes.PCRConfig.BIOSIdx, tcg.EFIHCRTMEvent, []byte(gmes.BIOSData)), + newSeparatorEvent(t, gmes.PCRConfig.BIOSIdx), + }, + expectedErrStr: "unexpected event type for BIOS", + }, + { + name: "invalid Host Kernel event type", + events: []tcg.Event{ + newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.GoogleDRTMEvent, []byte("testhostkernel")), + newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), + }, + expectedErrStr: "unexpected event type for host kernel", + }, + { + name: "unknown MR index", + events: []tcg.Event{ + newEvent(t, 999, tcg.EFIHCRTMEvent, []byte("unknown data")), + }, + expectedErrStr: "unknown MR index", }, } 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, protocmp.Transform()) { - 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) } }) } diff --git a/proto/state.proto b/proto/state.proto index 57e4b75..6b5444c 100644 --- a/proto/state.proto +++ b/proto/state.proto @@ -222,23 +222,9 @@ message FirmwareLogState { // The verified state of Google measurements on the machine. message GMESState { - message ImageLoad { - uint64 load_address = 1; - - uint64 image_length = 2; - - uint64 link_address = 3; - - uint64 device_path_length = 4; - - bytes device_path = 5; - } - bytes bmc_firmware_digest = 1; bytes bios_digest = 2; bytes host_kernel_digest = 3; - - ImageLoad host_kernel_image_load = 4; } diff --git a/proto/state/state.pb.go b/proto/state/state.pb.go index 00d3176..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 - 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"` - HostKernelImageLoad *GMESState_ImageLoad `protobuf:"bytes,4,opt,name=host_kernel_image_load,json=hostKernelImageLoad,proto3" json:"host_kernel_image_load,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() { @@ -1242,92 +1241,6 @@ func (x *GMESState) GetHostKernelDigest() []byte { return nil } -func (x *GMESState) GetHostKernelImageLoad() *GMESState_ImageLoad { - if x != nil { - return x.HostKernelImageLoad - } - return nil -} - -type GMESState_ImageLoad struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - LoadAddress uint64 `protobuf:"varint,1,opt,name=load_address,json=loadAddress,proto3" json:"load_address,omitempty"` - ImageLength uint64 `protobuf:"varint,2,opt,name=image_length,json=imageLength,proto3" json:"image_length,omitempty"` - LinkAddress uint64 `protobuf:"varint,3,opt,name=link_address,json=linkAddress,proto3" json:"link_address,omitempty"` - DevicePathLength uint64 `protobuf:"varint,4,opt,name=device_path_length,json=devicePathLength,proto3" json:"device_path_length,omitempty"` - DevicePath []byte `protobuf:"bytes,5,opt,name=device_path,json=devicePath,proto3" json:"device_path,omitempty"` -} - -func (x *GMESState_ImageLoad) Reset() { - *x = GMESState_ImageLoad{} - if protoimpl.UnsafeEnabled { - mi := &file_state_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GMESState_ImageLoad) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GMESState_ImageLoad) ProtoMessage() {} - -func (x *GMESState_ImageLoad) ProtoReflect() protoreflect.Message { - mi := &file_state_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GMESState_ImageLoad.ProtoReflect.Descriptor instead. -func (*GMESState_ImageLoad) Descriptor() ([]byte, []int) { - return file_state_proto_rawDescGZIP(), []int{12, 0} -} - -func (x *GMESState_ImageLoad) GetLoadAddress() uint64 { - if x != nil { - return x.LoadAddress - } - return 0 -} - -func (x *GMESState_ImageLoad) GetImageLength() uint64 { - if x != nil { - return x.ImageLength - } - return 0 -} - -func (x *GMESState_ImageLoad) GetLinkAddress() uint64 { - if x != nil { - return x.LinkAddress - } - return 0 -} - -func (x *GMESState_ImageLoad) GetDevicePathLength() uint64 { - if x != nil { - return x.DevicePathLength - } - return 0 -} - -func (x *GMESState_ImageLoad) GetDevicePath() []byte { - if x != nil { - return x.DevicePath - } - return nil -} - var File_state_proto protoreflect.FileDescriptor var file_state_proto_rawDesc = []byte{ @@ -1446,7 +1359,7 @@ 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, 0xa1, 0x03, + 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, @@ -1455,53 +1368,35 @@ var file_state_proto_rawDesc = []byte{ 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, 0x12, 0x4f, 0x0a, 0x16, 0x68, 0x6f, - 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, - 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x47, 0x4d, 0x45, 0x53, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x13, 0x68, 0x6f, 0x73, 0x74, 0x4b, 0x65, 0x72, 0x6e, - 0x65, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x1a, 0xc3, 0x01, 0x0a, 0x09, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6c, 0x6f, 0x61, - 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x0b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, - 0x21, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x61, 0x74, - 0x68, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x61, 0x74, - 0x68, 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, + 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 ( @@ -1517,7 +1412,7 @@ func file_state_proto_rawDescGZIP() []byte { } var file_state_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_state_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_state_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_state_proto_goTypes = []any{ (LogType)(0), // 0: state.LogType (GCEConfidentialTechnology)(0), // 1: state.GCEConfidentialTechnology @@ -1536,7 +1431,6 @@ var file_state_proto_goTypes = []any{ (*EfiState)(nil), // 14: state.EfiState (*FirmwareLogState)(nil), // 15: state.FirmwareLogState (*GMESState)(nil), // 16: state.GMESState - (*GMESState_ImageLoad)(nil), // 17: state.GMESState.ImageLoad } var file_state_proto_depIdxs = []int32{ 1, // 0: state.PlatformState.technology:type_name -> state.GCEConfidentialTechnology @@ -1560,12 +1454,11 @@ var file_state_proto_depIdxs = []int32{ 8, // 18: state.FirmwareLogState.linux_kernel:type_name -> state.LinuxKernelState 14, // 19: state.FirmwareLogState.efi:type_name -> state.EfiState 0, // 20: state.FirmwareLogState.log_type:type_name -> state.LogType - 17, // 21: state.GMESState.host_kernel_image_load:type_name -> state.GMESState.ImageLoad - 22, // [22:22] is the sub-list for method output_type - 22, // [22:22] is the sub-list for method input_type - 22, // [22:22] is the sub-list for extension type_name - 22, // [22:22] is the sub-list for extension extendee - 0, // [0:22] is the sub-list for field type_name + 21, // [21:21] is the sub-list for method output_type + 21, // [21:21] is the sub-list for method input_type + 21, // [21:21] is the sub-list for extension type_name + 21, // [21:21] is the sub-list for extension extendee + 0, // [0:21] is the sub-list for field type_name } func init() { file_state_proto_init() } @@ -1730,18 +1623,6 @@ func file_state_proto_init() { return nil } } - file_state_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*GMESState_ImageLoad); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } file_state_proto_msgTypes[1].OneofWrappers = []any{ (*PlatformState_ScrtmVersionId)(nil), @@ -1757,7 +1638,7 @@ func file_state_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_state_proto_rawDesc, NumEnums: 4, - NumMessages: 14, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, From 4dbd85bae35d9d706005e27199abc483a5998224 Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Tue, 12 May 2026 23:44:24 +0000 Subject: [PATCH 06/10] gofmt --- extract/extract_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/extract/extract_test.go b/extract/extract_test.go index 34237b4..6923f89 100644 --- a/extract/extract_test.go +++ b/extract/extract_test.go @@ -719,13 +719,13 @@ func TestGMESStateErrors(t *testing.T) { } testcases := []struct { - name string - events []tcg.Event - expectedErrStr string + name string + events []tcg.Event + expectedErrStr string }{ { - name: "duplicate separator", - events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx)), + name: "duplicate separator", + events: append(validEvents, newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx)), expectedErrStr: "duplicate separator event", }, { From ad7307fdda5f7ae9f13cccb5e7fcd76bea295a43 Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Thu, 14 May 2026 00:43:42 +0000 Subject: [PATCH 07/10] enforce separators --- extract/extract.go | 7 +++ extract/extract_test.go | 100 +++++++++++++++++++++++++++------------- 2 files changed, 76 insertions(+), 31 deletions(-) diff --git a/extract/extract.go b/extract/extract.go index 318b263..513759e 100644 --- a/extract/extract.go +++ b/extract/extract.go @@ -595,5 +595,12 @@ func GMESState(hash crypto.Hash, events []tcg.Event) (*pb.GMESState, error) { } } + // 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 6923f89..4f1a368 100644 --- a/extract/extract_test.go +++ b/extract/extract_test.go @@ -678,46 +678,60 @@ func decodeHex(hexStr string) []byte { } func TestGMESState(t *testing.T) { - log := testdata.HostGMESEventLog - expectedState := &pb.GMESState{ - BmcFirmwareDigest: decodeHex("c02bb61127ae90e3fcf2601702805592f5ee0952ee3a8bc518ac0171a75e1342"), - BiosDigest: decodeHex("44b389a3de1020401e9dc7adbb8b1515e5cade4a9bdfa9cce412f3e7ba9c1650"), - HostKernelDigest: decodeHex("825473358df6447f49eaaea583ab0d424fe9ba3aeeb13d0f739f3e942398701c"), + separatorEvents := []tcg.Event{ + newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx), + newSeparatorEvent(t, gmes.PCRConfig.BIOSIdx), + newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), + newSeparatorEvent(t, gmes.PCRConfig.MBMIdx), } - pcrBank := testutil.MakePCRBank(pb.HashAlgo_SHA256, map[uint32][]byte{ - 0: decodeHex("e2edb8749753227b24dd2e6689168da5fa4c148fd4567f697c58e6dd577ae4cd"), - 11: decodeHex("872129205c91e8027680899f6749f6409e204d9c366e40b41fedfeec0728b4c8"), - 17: decodeHex("22edb58db85ff13e1ae8110f90955b21b4d972593c3e07d9301f93ea540fbdfd"), - 21: decodeHex("5f60771aaf02702e3a647cdce310611e83d2669d0b77445e9b200ea3dab7993d"), - }) + 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")) - events, err := tcg.ParseAndReplay(log, pcrBank.MRs(), tcg.ParseOpts{}) - if err != nil { - t.Fatalf("Error parsing events: %v", err) - } + 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{ + BmcFirmwareDigest: bmcEvent.Digest, + BiosDigest: biosEvent.Digest, + HostKernelDigest: kernelEvent.Digest, + } + if diff := cmp.Diff(gotState, expectedState, protocmp.Transform()); diff != "" { t.Errorf("GMESState() mismatch (-want +got):\n%s", diff) } } func TestGMESStateErrors(t *testing.T) { - validEvents := []tcg.Event{ - newEvent(t, gmes.PCRConfig.BMCFirmwareIdx, tcg.EFIHCRTMEvent, []byte(gmes.BMCData)), + separatorEvents := []tcg.Event{ newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx), - newEvent(t, gmes.PCRConfig.BIOSIdx, tcg.GoogleDRTMEvent, []byte(gmes.BIOSData)), newSeparatorEvent(t, gmes.PCRConfig.BIOSIdx), - // 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!")), + 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 @@ -731,42 +745,47 @@ func TestGMESStateErrors(t *testing.T) { { name: "event after separator", events: append(validEvents, - newSeparatorEvent(t, gmes.PCRConfig.HostKernelIdx), newEvent(t, gmes.PCRConfig.HostKernelIdx, tcg.EFIBootServicesApplication, []byte("ModifiedKernel")), ), expectedErrStr: "found event after separator", }, { name: "invalid BMC event type", - events: []tcg.Event{ + events: append([]tcg.Event{ newEvent(t, gmes.PCRConfig.BMCFirmwareIdx, tcg.GoogleDRTMEvent, []byte(gmes.BMCData)), - newSeparatorEvent(t, gmes.PCRConfig.BMCFirmwareIdx), - }, + }, separatorEvents...), expectedErrStr: "unexpected event type for BMC firmware", }, { name: "invalid BIOS event type", - events: []tcg.Event{ + events: append([]tcg.Event{ newEvent(t, gmes.PCRConfig.BIOSIdx, tcg.EFIHCRTMEvent, []byte(gmes.BIOSData)), - newSeparatorEvent(t, gmes.PCRConfig.BIOSIdx), - }, + }, separatorEvents...), expectedErrStr: "unexpected event type for BIOS", }, { name: "invalid Host Kernel event type", - events: []tcg.Event{ + 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: []tcg.Event{ + 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 { @@ -808,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 { From 141400ca6268be33a3998c0e78ddbadc53661666 Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Mon, 18 May 2026 18:03:42 +0000 Subject: [PATCH 08/10] address comments --- extract/extract_test.go | 3 +++ tcg/events.go | 1 + 2 files changed, 4 insertions(+) diff --git a/extract/extract_test.go b/extract/extract_test.go index 4f1a368..4d76054 100644 --- a/extract/extract_test.go +++ b/extract/extract_test.go @@ -895,6 +895,9 @@ 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 diff --git a/tcg/events.go b/tcg/events.go index f13543a..7f981e2 100644 --- a/tcg/events.go +++ b/tcg/events.go @@ -146,6 +146,7 @@ var EventTypeNames = map[EventType]string{ EFIHCRTMEvent: "EFI H-CRTM Event", EFIVariableAuthority: "EFI Variable Authority", + // Custom event type, not in TCG spec. GoogleDRTMEvent: "Google DRTM Event", } From 6c594047da24fe61a38f628224ad527d46df348b Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Mon, 18 May 2026 18:06:09 +0000 Subject: [PATCH 09/10] gofmt --- extract/extract_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract/extract_test.go b/extract/extract_test.go index 4d76054..435f8fb 100644 --- a/extract/extract_test.go +++ b/extract/extract_test.go @@ -896,7 +896,7 @@ func getEventsFromLog(t *testing.T, events []tcg.Event) []tcg.Event { } 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 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 { From 7bce33178b1d688b92142bf31ef4d10e06da5b7b Mon Sep 17 00:00:00 2001 From: Jessie Liu Date: Mon, 18 May 2026 18:10:39 +0000 Subject: [PATCH 10/10] add comment --- tcg/events.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tcg/events.go b/tcg/events.go index 7f981e2..01458e0 100644 --- a/tcg/events.go +++ b/tcg/events.go @@ -185,6 +185,8 @@ 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", }