Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions efi/fw_load_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,12 @@ func (h *fwLoadHandler) measureSecureBootPolicyPreOS(ctx pcrBranchContext) error
e := events[0]
events = events[1:]

if e.PCRIndex == internal_efi.SecureBootPolicyPCR && e.EventType == tcglog.EventTypeEFIVariableDriverConfig {
if e.PCRIndex != internal_efi.SecureBootPolicyPCR {
// we don't care about this event.
continue
}

if e.EventType == tcglog.EventTypeEFIVariableDriverConfig {
// This is the first secure boot configuration measurement. In most
// circumstances, this will be the first measurement to PCR7. Only
// in the case where the first event is a EV_EFI_ACTION "DMA Protection
Expand All @@ -159,7 +164,7 @@ func (h *fwLoadHandler) measureSecureBootPolicyPreOS(ctx pcrBranchContext) error
}

switch {
case e.PCRIndex == internal_efi.SecureBootPolicyPCR && e.EventType == tcglog.EventTypeEFIAction &&
case e.EventType == tcglog.EventTypeEFIAction &&
(bytes.Equal(e.Data.Bytes(), []byte(dmaProtectionDisabled)) || bytes.Equal(e.Data.Bytes(), []byte(dmaProtectionDisabledNul))) &&
allowInsufficientDMAProtection:
// This is a EV_EFI_ACTION "DMA Protection Disabled" measurement and is
Expand All @@ -175,10 +180,10 @@ func (h *fwLoadHandler) measureSecureBootPolicyPreOS(ctx pcrBranchContext) error
ctx.ExtendPCR(internal_efi.SecureBootPolicyPCR, e.Digests[ctx.PCRAlg()])
}
allowInsufficientDMAProtection = false // Only allow this event to appear once
case e.PCRIndex == internal_efi.SecureBootPolicyPCR && e.EventType != tcglog.EventTypeEFIVariableDriverConfig:
return fmt.Errorf("unexpected event type (%v) found in log, before config", e.EventType)
case internal_efi.IsVendorEventType(e.EventType):
ctx.ExtendPCR(internal_efi.SecureBootPolicyPCR, e.Digests[ctx.PCRAlg()])
default:
// we don't care about this event.
return fmt.Errorf("unexpected event type (%v) found in log, before config", e.EventType)
}
}

Expand Down Expand Up @@ -297,6 +302,8 @@ func (h *fwLoadHandler) measureSecureBootPolicyPreOS(ctx pcrBranchContext) error
ctx.ExtendPCR(internal_efi.SecureBootPolicyPCR, e.Digests[ctx.PCRAlg()])
}
allowInsufficientDMAProtection = false // Only allow this event to appear once
case e.PCRIndex == internal_efi.SecureBootPolicyPCR && internal_efi.IsVendorEventType(e.EventType):
ctx.ExtendPCR(internal_efi.SecureBootPolicyPCR, e.Digests[ctx.PCRAlg()])
case e.PCRIndex == internal_efi.SecureBootPolicyPCR:
return fmt.Errorf("unexpected event type (%v) found in log", e.EventType)
default:
Expand All @@ -315,6 +322,29 @@ func (h *fwLoadHandler) measureSecureBootPolicyPreOS(ctx pcrBranchContext) error
if !measuredSecureBootSeparator {
return errors.New("missing separator in log")
}

// Retain any other vendor defined events that occur before the first EV_EFI_VARIABLE_AUTHORITY
// event.
for len(events) > 0 {
e := events[0]
events = events[1:]

if e.PCRIndex != internal_efi.SecureBootPolicyPCR {
continue
}

if e.EventType == tcglog.EventTypeEFIVariableAuthority {
break
}

switch {
case internal_efi.IsVendorEventType(e.EventType):
ctx.ExtendPCR(internal_efi.SecureBootPolicyPCR, e.Digests[ctx.PCRAlg()])
default:
return fmt.Errorf("unexpected event type (%v) found in log", e.EventType)
}
}

return nil
}

Expand Down
143 changes: 142 additions & 1 deletion efi/fw_load_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ var _ = Suite(&fwLoadHandlerSuite{})
type testFwMeasureImageStartData struct {
vars efitest.MockVars
logOptions *efitest.LogOptions
log *tcglog.Log
alg tpm2.HashAlgorithmId
pcrs PcrFlags
expectedEvents []*mockPcrBranchEvent
Expand All @@ -61,7 +62,15 @@ func (s *fwLoadHandlerSuite) testMeasureImageStart(c *C, data *testFwMeasureImag
alg: data.alg,
pcrs: data.pcrs}, data.loadParams, collector.Next())

handler := NewFwLoadHandler(efitest.NewLog(c, data.logOptions))
log := data.log
switch {
case log != nil:
c.Assert(data.logOptions, IsNil)
default:
log = efitest.NewLog(c, data.logOptions)
}

handler := NewFwLoadHandler(log)
c.Check(handler.MeasureImageStart(ctx), IsNil)
c.Check(ctx.events, DeepEquals, data.expectedEvents)
for _, event := range ctx.events {
Expand Down Expand Up @@ -512,6 +521,138 @@ func (s *fwLoadHandlerSuite) TestMeasureImageStartSecureBootPolicyProfileInclude
})
}

func (s *fwLoadHandlerSuite) TestMeasureImageStartSecureBootPolicyProfileWithVendorEventBeforeConfig(c *C) {
log := efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})
var eventsCopy []*tcglog.Event
added := false
events := log.Events
for len(events) > 0 {
ev := events[0]
events = events[1:]

if ev.PCRIndex == internal_efi.SecureBootPolicyPCR && !added {
eventsCopy = append(eventsCopy, &tcglog.Event{
PCRIndex: internal_efi.SecureBootPolicyPCR,
EventType: 0x8041,
Digests: tcglog.DigestMap{
tpm2.HashAlgorithmSHA256: testutil.DecodeHexString(c, "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"),
},
Data: tcglog.OpaqueEventData{0},
})
added = true
}

eventsCopy = append(eventsCopy, ev)
}
log.Events = eventsCopy

vars := makeMockVars(c, withMsSecureBootConfig())
s.testMeasureImageStart(c, &testFwMeasureImageStartData{
vars: vars,
log: log,
alg: tpm2.HashAlgorithmSHA256,
pcrs: MakePcrFlags(internal_efi.SecureBootPolicyPCR),
expectedEvents: []*mockPcrBranchEvent{
{pcr: 7, eventType: mockPcrBranchResetEvent},
{pcr: 7, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d")}, // vendor event
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: efi.VariableDescriptor{Name: "SecureBoot", GUID: efi.GlobalVariable}, varData: []byte{0x01}},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: PK, varData: vars[PK].Payload},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: KEK, varData: vars[KEK].Payload},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: Db, varData: vars[Db].Payload},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: Dbx, varData: vars[Dbx].Payload},
{pcr: 7, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119")}, // EV_SEPARATOR
},
})
}

func (s *fwLoadHandlerSuite) TestMeasureImageStartSecureBootPolicyProfileWithVendorEventWithConfig(c *C) {
log := efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})
var eventsCopy []*tcglog.Event
added := false
events := log.Events
for len(events) > 0 {
ev := events[0]
events = events[1:]

if ev.PCRIndex == internal_efi.SecureBootPolicyPCR && ev.EventType == tcglog.EventTypeSeparator && !added {
eventsCopy = append(eventsCopy, &tcglog.Event{
PCRIndex: internal_efi.SecureBootPolicyPCR,
EventType: 0x8041,
Digests: tcglog.DigestMap{
tpm2.HashAlgorithmSHA256: testutil.DecodeHexString(c, "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"),
},
Data: tcglog.OpaqueEventData{0},
})
added = true
}

eventsCopy = append(eventsCopy, ev)
}
log.Events = eventsCopy

vars := makeMockVars(c, withMsSecureBootConfig())
s.testMeasureImageStart(c, &testFwMeasureImageStartData{
vars: vars,
log: log,
alg: tpm2.HashAlgorithmSHA256,
pcrs: MakePcrFlags(internal_efi.SecureBootPolicyPCR),
expectedEvents: []*mockPcrBranchEvent{
{pcr: 7, eventType: mockPcrBranchResetEvent},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: efi.VariableDescriptor{Name: "SecureBoot", GUID: efi.GlobalVariable}, varData: []byte{0x01}},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: PK, varData: vars[PK].Payload},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: KEK, varData: vars[KEK].Payload},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: Db, varData: vars[Db].Payload},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: Dbx, varData: vars[Dbx].Payload},
{pcr: 7, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d")}, // vendor event
{pcr: 7, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119")}, // EV_SEPARATOR
},
})
}

func (s *fwLoadHandlerSuite) TestMeasureImageStartSecureBootPolicyProfileWithVendorEventWithVerification(c *C) {
log := efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})
var eventsCopy []*tcglog.Event
added := false
events := log.Events
for len(events) > 0 {
ev := events[0]
events = events[1:]

eventsCopy = append(eventsCopy, ev)

if ev.PCRIndex == internal_efi.SecureBootPolicyPCR && ev.EventType == tcglog.EventTypeSeparator && !added {
eventsCopy = append(eventsCopy, &tcglog.Event{
PCRIndex: internal_efi.SecureBootPolicyPCR,
EventType: 0x8041,
Digests: tcglog.DigestMap{
tpm2.HashAlgorithmSHA256: testutil.DecodeHexString(c, "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"),
},
Data: tcglog.OpaqueEventData{0},
})
added = true
}
}
log.Events = eventsCopy

vars := makeMockVars(c, withMsSecureBootConfig())
s.testMeasureImageStart(c, &testFwMeasureImageStartData{
vars: vars,
log: log,
alg: tpm2.HashAlgorithmSHA256,
pcrs: MakePcrFlags(internal_efi.SecureBootPolicyPCR),
expectedEvents: []*mockPcrBranchEvent{
{pcr: 7, eventType: mockPcrBranchResetEvent},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: efi.VariableDescriptor{Name: "SecureBoot", GUID: efi.GlobalVariable}, varData: []byte{0x01}},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: PK, varData: vars[PK].Payload},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: KEK, varData: vars[KEK].Payload},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: Db, varData: vars[Db].Payload},
{pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: Dbx, varData: vars[Dbx].Payload},
{pcr: 7, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119")}, // EV_SEPARATOR
{pcr: 7, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d")}, // vendor event
},
})
}

func (s *fwLoadHandlerSuite) TestMeasureImageStartBootManagerCodeProfile(c *C) {
vars := makeMockVars(c, withMsSecureBootConfig())
s.testMeasureImageStart(c, &testFwMeasureImageStartData{
Expand Down
39 changes: 30 additions & 9 deletions efi/preinstall/check_pcr7.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,12 @@ NextEvent:
fallthrough
default:
// Anything that isn't EV_EFI_ACTION ends up here.
return nil, fmt.Errorf("unexpected %v event %q before config", ev.EventType, ev.Data)
switch {
case internal_efi.IsVendorEventType(ev.EventType):
// ok
default:
return nil, fmt.Errorf("unexpected %v event %q before config", ev.EventType, ev.Data)
}
}
case tcglogPhaseMeasuringSecureBootConfig:
// ev.PCRIndex is always SecureBootPolicyPCR in this phase.
Expand Down Expand Up @@ -560,8 +565,9 @@ NextEvent:
// See the doc notes for this event type in the tcglogPhaseFirmwareLaunch
// phase. This leg is here to accommodate a "DMA Protection Disabled" event
// as part of the secure boot configuration, just at the end of the signature
// database measurements.
if permitDMAProtectionDisabledEvent && (bytes.Equal(ev.Data.Bytes(), []byte(tcglog.DMAProtectionDisabled)) ||
// database measurements. We only permit this if there are no signature database
// measurements remaining.
if permitDMAProtectionDisabledEvent && len(configs) == 0 && (bytes.Equal(ev.Data.Bytes(), []byte(tcglog.DMAProtectionDisabled)) ||
bytes.Equal(ev.Data.Bytes(), append([]byte(tcglog.DMAProtectionDisabled), 0x00))) {
// This event is detected by the host security checks which will result in a flag
// being added to the results so that it can be picked up by the code in
Expand All @@ -572,8 +578,13 @@ NextEvent:
}
fallthrough
default:
// Anything that isn't EV_EFI_VARIABLE_DRIVER_CONFIG ends up here.
return nil, fmt.Errorf("unexpected %v event %q whilst measuring config", ev.EventType, ev.Data)
// Anything that isn't EV_EFI_VARIABLE_DRIVER_CONFIG or EV_EFI_ACTION ends up here.
switch {
case internal_efi.IsVendorEventType(ev.EventType) && len(configs) == 0:
// ok
default:
return nil, fmt.Errorf("unexpected %v event %q whilst measuring config", ev.EventType, ev.Data)
}
}
case tcglogPhasePreOSThirdPartyDispatch:
if len(configs) > 0 {
Expand Down Expand Up @@ -637,8 +648,13 @@ NextEvent:
}
fallthrough
default:
// Anything that isn't EV_EFI_VARIABLE_AUTHORITY ends up here.
return nil, fmt.Errorf("unexpected %v event %q whilst measuring verification", ev.EventType, ev.Data)
// Anything that isn't EV_EFI_VARIABLE_AUTHORITY, EV_SEPARATOR or EV_EFI_ACTION ends up here.
switch {
case internal_efi.IsVendorEventType(ev.EventType):
// ok
default:
return nil, fmt.Errorf("unexpected %v event %q whilst measuring verification", ev.EventType, ev.Data)
}
}
case tcglogPhaseOSPresent:
if len(configs) > 0 {
Expand Down Expand Up @@ -741,8 +757,13 @@ NextEvent:
case tcglog.EventTypeSeparator:
// ok
default:
// Anything that isn't EV_EFI_VARIABLE_AUTHORITY ends up here.
return nil, fmt.Errorf("unexpected %v event %q whilst measuring verification", ev.EventType, ev.Data)
// Anything that isn't EV_EFI_VARIABLE_AUTHORITY or EV_SEPARATOR ends up here.
switch {
case internal_efi.IsVendorEventType(ev.EventType):
// ok
default:
return nil, fmt.Errorf("unexpected %v event %q whilst measuring verification", ev.EventType, ev.Data)
}
}
}
}
Expand Down
Loading
Loading