diff --git a/crypt.go b/crypt.go index 1cdbce1a..8c3699f1 100755 --- a/crypt.go +++ b/crypt.go @@ -28,6 +28,8 @@ import ( "io" "os" "strconv" + "strings" + "unicode" "golang.org/x/sys/unix" "golang.org/x/xerrors" @@ -95,10 +97,11 @@ func ParseRecoveryKey(s string) (out RecoveryKey, err error) { // Move to the next 5 digits s = s[5:] - // Permit each set of 5 digits to be separated by an optional '-', but don't allow the formatted key to end or begin with one. - if len(s) > 1 && s[0] == '-' { - s = s[1:] - } + + // Permit each set of 5 digits to be separated by an arbitrary number of spaces or '-' characters. + s = strings.TrimLeftFunc(s, func(c rune) bool { + return unicode.IsSpace(c) || c == '-' + }) } if len(s) > 0 { diff --git a/crypt_test.go b/crypt_test.go index 9fd9085c..ecb29361 100644 --- a/crypt_test.go +++ b/crypt_test.go @@ -682,6 +682,20 @@ func (s *cryptSuite) TestParseRecoveryKey3(c *C) { }) } +func (s *cryptSuite) TestParseRecoveryKey4(c *C) { + s.testParseRecoveryKey(c, &testParseRecoveryKeyData{ + formatted: "61665 00531 54469 09783 47273 19035 40077 28287", + expected: testutil.DecodeHexString(c, "e1f01302c5d43726a9b85b4a8d9c7f6e"), + }) +} + +func (s *cryptSuite) TestParseRecoveryKey5(c *C) { + s.testParseRecoveryKey(c, &testParseRecoveryKeyData{ + formatted: "61665 00531-54469 09783- 4727319035 -40077 28287 ", + expected: testutil.DecodeHexString(c, "e1f01302c5d43726a9b85b4a8d9c7f6e"), + }) +} + type testParseRecoveryKeyErrorHandlingData struct { formatted string errChecker Checker @@ -725,14 +739,6 @@ func (s *cryptSuite) TestParseRecoveryKeyErrorHandling4(c *C) { }) } -func (s *cryptSuite) TestParseRecoveryKeyErrorHandling5(c *C) { - s.testParseRecoveryKeyErrorHandling(c, &testParseRecoveryKeyErrorHandlingData{ - formatted: "00000-00000-00000-00000-00000-00000-00000-00000-", - errChecker: ErrorMatches, - errCheckerArgs: []interface{}{"incorrectly formatted: too many characters"}, - }) -} - type testRecoveryKeyStringifyData struct { key []byte expected string diff --git a/efi/fw_load_handler.go b/efi/fw_load_handler.go index fbd9d720..3cef06c5 100644 --- a/efi/fw_load_handler.go +++ b/efi/fw_load_handler.go @@ -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 @@ -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 @@ -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) } } @@ -199,6 +204,28 @@ func (h *fwLoadHandler) measureSecureBootPolicyPreOS(ctx pcrBranchContext) error // TODO: Support optional dbt/dbr database + // Include the user mode related measurements if the system is in user mode, it is + // permitted with the WithSecureBootUserMode option and they are being included in this + // branch. + includeUserMode := boolParamOrFalse(ctx.Params(), includeSecureBootUserModeParamKey) + switch deployedMode, _, err := ctx.Vars().ReadVar("DeployedMode", efi.GlobalVariable); { + case errors.Is(err, efi.ErrVarNotExist): + // pre-2.5 UEFI system + case err != nil: + return fmt.Errorf("cannot read DeployedMode variable: %w", err) + case len(deployedMode) != 1: + return fmt.Errorf("invalid DeployedMode value %#x", deployedMode) + case deployedMode[0] == 0 && includeUserMode: + // System is in user mode, the WithSecureBootUserMode option was supplied and + // we are including the user mode related measurements in this branch. + ctx.MeasureVariable(internal_efi.SecureBootPolicyPCR, efi.GlobalVariable, "AuditMode", []byte{0}) + ctx.MeasureVariable(internal_efi.SecureBootPolicyPCR, efi.GlobalVariable, "DeployedMode", []byte{0}) + default: + // Do nothing for the deployed mode case, or where the system is in user mode + // but where the WithSecureBootUserMode option is not supplied or we are creating + // a branch that allows for deployed mode to be enabled. + } + // We don't measure a EV_SEPARATOR here yet because we need to preserve the // device-specific measurement ordering - see the notes above about when the // verification of third-party pre-OS code is measured. We don't know whether @@ -256,24 +283,6 @@ func (h *fwLoadHandler) measureSecureBootPolicyPreOS(ctx pcrBranchContext) error // once we've encountered the first EV_EFI_VARIABLE_AUTHORITY event and // we'll likely generate an invalid profile if we do. The preinstall // checks will catch this. - - // Except... - // Backward compliance: On Ubuntu Core not using preinstall checks, - // the firmware might be UEFI 2.5 compliant but not be in deployed mode. - // In that case we should still expect those measurements due to the mode. - if data, ok := e.Data.(*tcglog.EFIVariableData); ok { - if (data.VariableName == efi.GlobalVariable && data.UnicodeName == "AuditMode") { - if bytes.Equal(data.VariableData, []byte{0}) { - ctx.MeasureVariable(internal_efi.SecureBootPolicyPCR, efi.GlobalVariable, "AuditMode", data.VariableData) - } - } - if (data.VariableName == efi.GlobalVariable && data.UnicodeName == "DeployedMode") { - if bytes.Equal(data.VariableData, []byte{0}) { - ctx.MeasureVariable(internal_efi.SecureBootPolicyPCR, efi.GlobalVariable, "DeployedMode", data.VariableData) - } - } - } - case e.PCRIndex == internal_efi.SecureBootPolicyPCR && e.EventType == tcglog.EventTypeEFIAction && (bytes.Equal(e.Data.Bytes(), []byte(dmaProtectionDisabled)) || bytes.Equal(e.Data.Bytes(), []byte(dmaProtectionDisabledNul))) && allowInsufficientDMAProtection: @@ -293,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: @@ -311,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 } diff --git a/efi/fw_load_handler_test.go b/efi/fw_load_handler_test.go index 9f68cec5..f5afed21 100644 --- a/efi/fw_load_handler_test.go +++ b/efi/fw_load_handler_test.go @@ -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 @@ -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 { @@ -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{ @@ -629,6 +770,73 @@ func (s *fwLoadHandlerSuite) TestMeasureImageStartBootManagerCodeProfileIgnoreUn }) } +func (s *fwLoadHandlerSuite) TestMeasureImageStartBootManagerCodeProfileHP(c *C) { + log := efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}}) + // XXX: It would be good to have this sort of thing in internal/efitest + var eventsCopy []*tcglog.Event + for _, ev := range log.Events { + eventsCopy = append(eventsCopy, ev) + + if ev.PCRIndex == internal_efi.SecureBootPolicyPCR && ev.EventType == tcglog.EventTypeSeparator { + // Add HP events to PCR4 + addEvent := func(guid efi.GUID, digest tpm2.Digest) { + eventsCopy = append(eventsCopy, &tcglog.Event{ + PCRIndex: internal_efi.BootManagerCodePCR, + EventType: tcglog.EventTypeEFIBootServicesApplication, + Digests: tcglog.DigestMap{ + tpm2.HashAlgorithmSHA256: digest, + }, + Data: &tcglog.EFIImageLoadEvent{ + DevicePath: efi.DevicePath{ + efi.MediaFvDevicePathNode(efi.MakeGUID(0xcdbb7b35, 0x6833, 0x4ed6, 0x9ab2, [...]uint8{0x57, 0xd2, 0xac, 0xdd, 0xf6, 0xf0})), + efi.MediaFvFileDevicePathNode(guid), + }, + }, + }) + } + + addEvent(efi.MakeGUID(0xb1dac9bd, 0x132e, 0x4f9f, 0xb2ca, [...]byte{0x14, 0xfd, 0xc6, 0x5b, 0xd6, 0x61}), testutil.DecodeHexString(c, "f407e3fd9a46e946d91522880ab771bce2fe08d1410bd1f10dab99ab2ec3d6c5")) + addEvent(efi.MakeGUID(0x9d8243e8, 0x8381, 0x453d, 0xaceb, [...]byte{0xc3, 0x50, 0xee, 0x77, 0x57, 0xca}), testutil.DecodeHexString(c, "3cfb0e1a22e6e1a203d3382e00db516107cbf948708befe8b1e7c79e5fb0455c")) // StartupMenuApp + addEvent(efi.MakeGUID(0x96d0626b, 0x71d5, 0x4001, 0xac71, [...]byte{0xe0, 0x5B, 0x10, 0x3b, 0xd4, 0x5d}), testutil.DecodeHexString(c, "ae1d24af29d3a27d49da12ad98b64e6072ad3e1786186dfe5e23b1001671b858")) // F10App + addEvent(efi.MakeGUID(0xeb6b71c3, 0x0659, 0x4a8a, 0x8ae1, [...]byte{0xda, 0xd2, 0xf5, 0x19, 0x2c, 0x62}), testutil.DecodeHexString(c, "ccf5d88d928171a2af8d0fec99fe142aa75684a49dda5c5db2feae19085a7a6b")) // BootMenuApp + addEvent(efi.MakeGUID(0xaf8898c9, 0x9b92, 0x4556, 0x8318, [...]byte{0xe4, 0x25, 0xc9, 0xde, 0x0a, 0x65}), testutil.DecodeHexString(c, "43099125543e0647d3918e5e06239e940157c42a881eed8d854f230beb96951b")) // F2App + addEvent(efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), testutil.DecodeHexString(c, "6a8138a15c60aca1bfe06914987e3e2ea9a243b2e055e5c903482cea5b3893bc")) // AbsoluteAbtInstaller + addEvent(efi.MakeGUID(0xc988bded, 0x6977, 0x464d, 0xb714, [...]byte{0xe6, 0x1d, 0xeb, 0xd2, 0xde, 0x97}), testutil.DecodeHexString(c, "953e26aeecfea145f82a2be73674af76e54850387e5bdcb9e540ef01e51b145e")) + addEvent(efi.MakeGUID(0x4ea97c46, 0x7491, 0x4dfd, 0xb542, [...]byte{0x74, 0x70, 0x10, 0xf3, 0xce, 0x7f}), testutil.DecodeHexString(c, "63040d9100b9fdfd849c06d13bbfddc5eb08131a6c18f0e0aef7a46ccfb92630")) // HPNetworkTransferWorker + addEvent(efi.MakeGUID(0x8224846e, 0x6d50, 0x453d, 0xb7c2, [...]byte{0x3e, 0x7e, 0xd7, 0xd0, 0x0d, 0x52}), testutil.DecodeHexString(c, "445a4fe85fa4b48f4eb7a86e92b89a2f4ceb1c9a1a849c3b808226ac45039a17")) + addEvent(efi.MakeGUID(0xf02313f7, 0x581f, 0x4f31, 0xb09c, [...]byte{0xc1, 0xba, 0x2f, 0xc5, 0x87, 0x13}), testutil.DecodeHexString(c, "dd42008bac6b5c4c07919921ec21f39176811b597b3a7553badfa30c4e3dfe8a")) // HPDriveWipe + + // HP systems seem to measure this twice + addEvent(efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), testutil.DecodeHexString(c, "6a8138a15c60aca1bfe06914987e3e2ea9a243b2e055e5c903482cea5b3893bc")) // AbsoluteAbtInstaller + } + } + log.Events = eventsCopy + + vars := makeMockVars(c, withMsSecureBootConfig()) + s.testMeasureImageStart(c, &testFwMeasureImageStartData{ + vars: vars, + log: log, + alg: tpm2.HashAlgorithmSHA256, + pcrs: MakePcrFlags(internal_efi.BootManagerCodePCR), + expectedEvents: []*mockPcrBranchEvent{ + {pcr: 4, eventType: mockPcrBranchResetEvent}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "f407e3fd9a46e946d91522880ab771bce2fe08d1410bd1f10dab99ab2ec3d6c5")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "3cfb0e1a22e6e1a203d3382e00db516107cbf948708befe8b1e7c79e5fb0455c")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "ae1d24af29d3a27d49da12ad98b64e6072ad3e1786186dfe5e23b1001671b858")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "ccf5d88d928171a2af8d0fec99fe142aa75684a49dda5c5db2feae19085a7a6b")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "43099125543e0647d3918e5e06239e940157c42a881eed8d854f230beb96951b")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "6a8138a15c60aca1bfe06914987e3e2ea9a243b2e055e5c903482cea5b3893bc")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "953e26aeecfea145f82a2be73674af76e54850387e5bdcb9e540ef01e51b145e")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "63040d9100b9fdfd849c06d13bbfddc5eb08131a6c18f0e0aef7a46ccfb92630")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "445a4fe85fa4b48f4eb7a86e92b89a2f4ceb1c9a1a849c3b808226ac45039a17")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "dd42008bac6b5c4c07919921ec21f39176811b597b3a7553badfa30c4e3dfe8a")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "6a8138a15c60aca1bfe06914987e3e2ea9a243b2e055e5c903482cea5b3893bc")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "3d6772b4f84ed47595d72a2c4c5ffd15f5bb72c7507fe26f2aaee2c69d5633ba")}, + {pcr: 4, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119")}, // EV_SEPARATOR + }, + }) +} + func (s *fwLoadHandlerSuite) TestMeasureImageStartBootManagerCodeProfileIncludeAbsoluteAbtInstallerPreOS(c *C) { // Verify the events associated with the "AbsoluteAbtInstaller" application contained in the firmware // that loads as part of pre-OS. @@ -1196,7 +1404,7 @@ func (s *fwLoadHandlerSuite) TestMeasureImageLoadSecureBootPolicyAndBootManagerC }) } -func (s *fwLoadHandlerSuite) TestMeasureImageStartSecureBootPolicyProfileDisabledDeployedMode(c *C) { +func (s *fwLoadHandlerSuite) TestMeasureImageStartSecureBootPolicyProfileUserMode(c *C) { vars := makeMockVars(c, withMsSecureBootConfig(), withDeployedModeDisabled()) s.testMeasureImageStart(c, &testFwMeasureImageStartData{ vars: vars, @@ -1206,6 +1414,9 @@ func (s *fwLoadHandlerSuite) TestMeasureImageStartSecureBootPolicyProfileDisable }, alg: tpm2.HashAlgorithmSHA256, pcrs: MakePcrFlags(internal_efi.SecureBootPolicyPCR), + loadParams: &LoadParams{ + "include_secure_boot_user_mode": true, + }, expectedEvents: []*mockPcrBranchEvent{ {pcr: 7, eventType: mockPcrBranchResetEvent}, {pcr: 7, eventType: mockPcrBranchMeasureVariableEvent, varName: efi.VariableDescriptor{Name: "SecureBoot", GUID: efi.GlobalVariable}, varData: []byte{0x01}}, @@ -1219,3 +1430,25 @@ func (s *fwLoadHandlerSuite) TestMeasureImageStartSecureBootPolicyProfileDisable }, }) } + +func (s *fwLoadHandlerSuite) TestMeasureImageStartSecureBootPolicyProfileUserModeNotIncluded(c *C) { + vars := makeMockVars(c, withMsSecureBootConfig(), withDeployedModeDisabled()) + s.testMeasureImageStart(c, &testFwMeasureImageStartData{ + vars: vars, + logOptions: &efitest.LogOptions{ + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256, tpm2.HashAlgorithmSHA1}, + DisableDeployedMode: true, + }, + 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 + }, + }) +} diff --git a/efi/pcr_profile_test.go b/efi/pcr_profile_test.go index e6c5f970..b6848f28 100644 --- a/efi/pcr_profile_test.go +++ b/efi/pcr_profile_test.go @@ -1377,3 +1377,67 @@ func (s *pcrProfileSuite) TestAddPCRProfileUC20WithDbxUpdateWithAllowInsufficien }, WithSecureBootPolicyProfile(), WithBootManagerCodeProfile(), WithKernelConfigProfile(), WithSignatureDBUpdates(&SignatureDBUpdate{Name: Dbx, Data: msDbxUpdate2}), WithAllowInsufficientDmaProtection()) c.Check(err, IsNil) } + +func (s *pcrProfileSuite) TestAddPCRProfileUC20WithAllowSecureBootUserMode(c *C) { + shim := newMockUbuntuShimImage15_7(c) + grub := newMockUbuntuGrubImage3(c) + recoverKernel := newMockUbuntuKernelImage2(c) + runKernel := newMockUbuntuKernelImage3(c) + + err := s.testAddPCRProfile(c, &testAddPCRProfileData{ + vars: makeMockVars(c, withMsSecureBootConfig(), withSbatLevel([]byte("sbat,1,2022052400\ngrub,2\n")), withDeployedModeDisabled()), + log: efitest.NewLog(c, &efitest.LogOptions{ + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256, tpm2.HashAlgorithmSHA1}, + }), + alg: tpm2.HashAlgorithmSHA256, + loadSequences: NewImageLoadSequences( + SnapModelParams(testutil.MakeMockCore20ModelAssertion(c, map[string]interface{}{ + "authority-id": "fake-brand", + "series": "16", + "brand-id": "fake-brand", + "model": "fake-model", + "grade": "secured", + }, "Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij")), + ).Append( + NewImageLoadActivity(shim).Loads( + NewImageLoadActivity(grub, KernelCommandlineParams("console=ttyS0 console=tty1 panic=-1 systemd.gpt_auto=0 snapd_recovery_mode=recover")).Loads( + NewImageLoadActivity(grub, KernelCommandlineParams("console=ttyS0 console=tty1 panic=-1 systemd.gpt_auto=0 snapd_recovery_mode=run")).Loads( + NewImageLoadActivity(runKernel), + ), + NewImageLoadActivity(recoverKernel), + ), + ), + ), + expected: []tpm2.PCRValues{ + { + tpm2.HashAlgorithmSHA256: { + 4: testutil.DecodeHexString(c, "bec6121586508581e08a41244944292ef452879f8e19c7f93d166e912c6aac5e"), + 7: testutil.DecodeHexString(c, "3d65dbe406e9427d402488ea4f87e07e8b584c79c578a735d48d21a6405fc8bb"), + 12: testutil.DecodeHexString(c, "fd1000c6f691c3054e2ff5cfacb39305820c9f3534ba67d7894cb753aa85074b"), + }, + }, + { + tpm2.HashAlgorithmSHA256: { + 4: testutil.DecodeHexString(c, "c731a39b7fc6475c7d8a9264e704902157c7cee40c22f59fa1690ea99ff70c67"), + 7: testutil.DecodeHexString(c, "3d65dbe406e9427d402488ea4f87e07e8b584c79c578a735d48d21a6405fc8bb"), + 12: testutil.DecodeHexString(c, "5b354c57a61bb9f71fcf596d7e9ef9e2e0d6f4ad8151c9f358e6f0aaa7823756"), + }, + }, + { + tpm2.HashAlgorithmSHA256: { + 4: testutil.DecodeHexString(c, "bec6121586508581e08a41244944292ef452879f8e19c7f93d166e912c6aac5e"), + 7: testutil.DecodeHexString(c, "d6a99cb0ea5ac9290b65b8847bb48613fc504a798229fb37e88b7b33337f4c60"), + 12: testutil.DecodeHexString(c, "fd1000c6f691c3054e2ff5cfacb39305820c9f3534ba67d7894cb753aa85074b"), + }, + }, + { + tpm2.HashAlgorithmSHA256: { + 4: testutil.DecodeHexString(c, "c731a39b7fc6475c7d8a9264e704902157c7cee40c22f59fa1690ea99ff70c67"), + 7: testutil.DecodeHexString(c, "d6a99cb0ea5ac9290b65b8847bb48613fc504a798229fb37e88b7b33337f4c60"), + 12: testutil.DecodeHexString(c, "5b354c57a61bb9f71fcf596d7e9ef9e2e0d6f4ad8151c9f358e6f0aaa7823756"), + }, + }, + }, + }, WithSecureBootPolicyProfile(), WithBootManagerCodeProfile(), WithKernelConfigProfile(), WithAllowSecureBootUserMode()) + c.Check(err, IsNil) +} diff --git a/efi/preinstall/check_host_security.go b/efi/preinstall/check_host_security.go index 0bc28383..61c0f9ff 100644 --- a/efi/preinstall/check_host_security.go +++ b/efi/preinstall/check_host_security.go @@ -21,7 +21,6 @@ package preinstall import ( "bytes" - "fmt" "github.com/canonical/tcglog-parser" "github.com/pilebones/go-udev/netlink" @@ -51,6 +50,24 @@ const ( dtpmPartialResetAttackMitigationUnavailable ) +// platformFirmwareIntegrityConfig indicates how the root-of-trust provides +// assurances of the platform firmware integrity. +type platformFirmwareIntegrityConfig int + +const ( + // platformFirmwareIntegrityNone indicates that no firmware integrity assurances + // are provided. + platformFirmwareIntegrityNone platformFirmwareIntegrityConfig = iota + + // platformFirmwareIntegrityMeasured indicates that firmware integrity is provided + // by measured boot. + platformFirmwareIntegrityMeasured + + // platformFirmwareIntegrityVerified indicates that firmware integrity is provided + // by verifying it against a key that is fused into the platform. + platformFirmwareIntegrityVerified +) + // checkForKernelIOMMU checks that the kernel has enabled some sort of DMA protection. // On Intel devices, the domains are defined by the DMAR ACPI table. The check is quite // simple, and based on the fwupd HSI checks. If it is not enabled, a [ErrNoKernelIOMMU] @@ -115,17 +132,9 @@ Loop: // as the TCG PC Client Platform Firmware Profile spec says that the event // data in EV_EFI_ACTION events should not be NULL terminated. errs = append(errs, ErrInsufficientDMAProtection) - default: - // Unexpected data - return fmt.Errorf("unexpected EV_EFI_ACTION event data in PCR7 event: %q", event.Data) } - case tcglog.EventTypeEFIVariableDriverConfig, tcglog.EventTypeSeparator: - // ok case tcglog.EventTypeEFIVariableAuthority: break Loop - default: - // Unexpected event type - return fmt.Errorf("unexpected event type (%v) in PCR7", event.EventType) } } diff --git a/efi/preinstall/check_host_security_amd.go b/efi/preinstall/check_host_security_amd.go index df2d62fb..2e88c2a6 100644 --- a/efi/preinstall/check_host_security_amd.go +++ b/efi/preinstall/check_host_security_amd.go @@ -47,7 +47,7 @@ func readAMDPSPBooleanAttribute(dev internal_efi.SysfsDevice, name string) (bool return strconv.ParseBool(string(bytes.TrimSuffix(data, []byte("\n")))) } -func checkHostSecurityAMDPSP(env internal_efi.HostEnvironment) error { +func checkHostSecurityAMDPSP(env internal_efi.HostEnvironment) (platformFirmwareIntegrityConfig, error) { // Enumerate the PCI devices that are bound to the ccp driver. devices, err := env.EnumerateDevices(&netlink.RuleDefinition{ Env: map[string]string{ @@ -56,7 +56,7 @@ func checkHostSecurityAMDPSP(env internal_efi.HostEnvironment) error { }, }) if err != nil { - return fmt.Errorf("cannot obtain PCI devices that are bound to the ccp driver: %w", err) + return platformFirmwareIntegrityNone, fmt.Errorf("cannot obtain PCI devices that are bound to the ccp driver: %w", err) } if len(devices) == 0 { @@ -70,39 +70,54 @@ func checkHostSecurityAMDPSP(env internal_efi.HostEnvironment) error { }, }) if err != nil { - return fmt.Errorf("cannot enumerate AMD PCI CCP devices: %w", err) + return platformFirmwareIntegrityNone, fmt.Errorf("cannot enumerate AMD PCI CCP devices: %w", err) } if len(devices) == 0 { // We can't find the PSP device, so this platform is unsupported. - return &UnsupportedPlatformError{errors.New("no PSP PCI device")} + return platformFirmwareIntegrityNone, &UnsupportedPlatformError{errors.New("no PSP PCI device")} } // We found the PSP device, so indicate that the ccp module should // be loaded. - return MissingKernelModuleError("ccp") + return platformFirmwareIntegrityNone, MissingKernelModuleError("ccp") } device := devices[0] - debugLock, err := readAMDPSPBooleanAttribute(device, "debug_lock_on") - switch { + amd64Env, err := env.AMD64() + if err != nil { + return platformFirmwareIntegrityNone, fmt.Errorf("cannot obtain AMD64 environment: %w", err) + } + if amd64Env.CPUFamily() < 0x17 { + // Require at least Zen. + return platformFirmwareIntegrityNone, &UnsupportedPlatformError{errors.New("unsupported CPU family")} + } + + switch debugLock, err := readAMDPSPBooleanAttribute(device, "debug_lock_on"); { case errors.Is(err, internal_efi.ErrNoDeviceAttribute): - return &NoHardwareRootOfTrustError{errors.New("PSP security reporting not available")} + return platformFirmwareIntegrityNone, &NoHardwareRootOfTrustError{errors.New("PSP security reporting not available")} case err != nil: - return fmt.Errorf("cannot determine if debug lock is on: %w", err) + return platformFirmwareIntegrityNone, fmt.Errorf("cannot determine if debug lock is on: %w", err) case !debugLock: - return &NoHardwareRootOfTrustError{errors.New("PSP debug lock is not enabled")} + return platformFirmwareIntegrityNone, &NoHardwareRootOfTrustError{errors.New("PSP debug lock is not enabled")} } - fused, err := readAMDPSPBooleanAttribute(device, "fused_part") - switch { - case errors.Is(err, internal_efi.ErrNoDeviceAttribute): - return &NoHardwareRootOfTrustError{errors.New("PSP security reporting not available")} + switch fused, err := readAMDPSPBooleanAttribute(device, "fused_part"); { case err != nil: - return fmt.Errorf("cannot determine if PSB is enabled: %w", err) + return platformFirmwareIntegrityNone, fmt.Errorf("cannot determine if part is fused: %w", err) case !fused: - return &NoHardwareRootOfTrustError{errors.New("Platform Secure Boot is not enabled")} + return platformFirmwareIntegrityMeasured, nil + } + + switch integrity, err := readAMDPSPBooleanAttribute(device, "boot_integrity"); { + case errors.Is(err, internal_efi.ErrNoDeviceAttribute): + // Only exists since https://lore.kernel.org/linux-crypto/20260123033457.645189-1-superm1@kernel.org/ + return platformFirmwareIntegrityMeasured, nil + case err != nil: + return platformFirmwareIntegrityNone, fmt.Errorf("cannot determine if PSB is enabled: %w", err) + case !integrity: + return platformFirmwareIntegrityMeasured, nil } - return nil + return platformFirmwareIntegrityVerified, nil } diff --git a/efi/preinstall/check_host_security_amd64.go b/efi/preinstall/check_host_security_amd64.go index 46088a83..4a5f30df 100644 --- a/efi/preinstall/check_host_security_amd64.go +++ b/efi/preinstall/check_host_security_amd64.go @@ -31,28 +31,31 @@ import ( // is sufficient. Errors that can't be resolved or which should prevent further checks from running // are returned immediately and without any wrapping. Errors that can be resolved and which shouldn't // prevent further checks from running are returned wrapped in [joinError]. -func checkHostSecurity(env internal_efi.HostEnvironment, log *tcglog.Log) error { +func checkHostSecurity(env internal_efi.HostEnvironment, log *tcglog.Log) (platformFirmwareIntegrityConfig, error) { cpuVendor, err := determineCPUVendor(env) if err != nil { - return &UnsupportedPlatformError{fmt.Errorf("cannot determine CPU vendor: %w", err)} + return platformFirmwareIntegrityNone, &UnsupportedPlatformError{fmt.Errorf("cannot determine CPU vendor: %w", err)} } amd64Env, err := env.AMD64() if err != nil { - return fmt.Errorf("cannot obtain AMD64 environment: %w", err) + return platformFirmwareIntegrityNone, fmt.Errorf("cannot obtain AMD64 environment: %w", err) } + var integrity platformFirmwareIntegrityConfig switch cpuVendor { case cpuVendorIntel: if err := checkHostSecurityIntelBootGuard(env); err != nil { - return fmt.Errorf("encountered an error when checking Intel BootGuard configuration: %w", err) + return platformFirmwareIntegrityNone, fmt.Errorf("encountered an error when checking Intel BootGuard configuration: %w", err) } if err := checkHostSecurityIntelCPUDebuggingLocked(amd64Env); err != nil { - return fmt.Errorf("encountered an error when checking Intel CPU debugging configuration: %w", err) + return platformFirmwareIntegrityNone, fmt.Errorf("encountered an error when checking Intel CPU debugging configuration: %w", err) } + integrity = platformFirmwareIntegrityVerified case cpuVendorAMD: - if err := checkHostSecurityAMDPSP(env); err != nil { - return fmt.Errorf("encountered an error when checking the AMD PSP configuration: %w", err) + integrity, err = checkHostSecurityAMDPSP(env) + if err != nil { + return platformFirmwareIntegrityNone, fmt.Errorf("encountered an error when checking the AMD PSP configuration: %w", err) } default: panic("not reached") @@ -63,7 +66,7 @@ func checkHostSecurity(env internal_efi.HostEnvironment, log *tcglog.Log) error if err := checkSecureBootPolicyPCRForDegradedFirmwareSettings(log); err != nil { var ce CompoundError if !errors.As(err, &ce) { - return fmt.Errorf("encountered an error whilst checking the TCG log for degraded firmware settings: %w", err) + return platformFirmwareIntegrityNone, fmt.Errorf("encountered an error whilst checking the TCG log for degraded firmware settings: %w", err) } errs = append(errs, ce.Unwrap()...) } @@ -72,15 +75,15 @@ func checkHostSecurity(env internal_efi.HostEnvironment, log *tcglog.Log) error case errors.Is(err, ErrNoKernelIOMMU): errs = append(errs, err) default: - return fmt.Errorf("encountered an error whilst checking sysfs to determine that kernel IOMMU support is enabled: %w", err) + return platformFirmwareIntegrityNone, fmt.Errorf("encountered an error whilst checking sysfs to determine that kernel IOMMU support is enabled: %w", err) } } if len(errs) > 0 { - return joinErrors(errs...) + return platformFirmwareIntegrityNone, joinErrors(errs...) } - return nil + return integrity, nil } // checkDiscreteTPMPartialResetAttackMitigationStatus determines whether a partial mitigation diff --git a/efi/preinstall/check_host_security_amd64_test.go b/efi/preinstall/check_host_security_amd64_test.go index 166190cd..9ed0f242 100644 --- a/efi/preinstall/check_host_security_amd64_test.go +++ b/efi/preinstall/check_host_security_amd64_test.go @@ -59,25 +59,29 @@ C7E003CB } env := efitest.NewMockHostEnvironmentWithOpts( efitest.WithSysfsDevices(devices...), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000}), ) log := efitest.NewLog(c, &efitest.LogOptions{}) - c.Check(CheckHostSecurity(env, log), IsNil) + integrity, err := CheckHostSecurity(env, log) + c.Check(err, IsNil) + c.Check(integrity, Equals, PlatformFirmwareIntegrityVerified) } func (s *hostSecurityAMD64Suite) TestCheckHostSecurityErrNotAMD64(c *C) { env := efitest.NewMockHostEnvironmentWithOpts() - err := CheckHostSecurity(env, nil) + _, err := CheckHostSecurity(env, nil) c.Check(err, ErrorMatches, `unsupported platform: cannot determine CPU vendor: not a AMD64 host`) var upe *UnsupportedPlatformError c.Check(errors.As(err, &upe), testutil.IsTrue) } -func (s *hostSecurityAMD64Suite) TestCheckHostSecurityAMDGood(c *C) { +func (s *hostSecurityAMD64Suite) TestCheckHostSecurityAMDGoodVerified(c *C) { pspAttrs := map[string][]byte{ + "boot_integrity": []byte(`1 +`), "debug_lock_on": []byte(`1 `), "fused_part": []byte(`1 @@ -90,19 +94,46 @@ func (s *hostSecurityAMD64Suite) TestCheckHostSecurityAMDGood(c *C) { } env := efitest.NewMockHostEnvironmentWithOpts( efitest.WithSysfsDevices(devices...), - efitest.WithAMD64Environment("AuthenticAMD", nil, 0, nil), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), ) log := efitest.NewLog(c, &efitest.LogOptions{}) - c.Check(CheckHostSecurity(env, log), IsNil) + integrity, err := CheckHostSecurity(env, log) + c.Check(err, IsNil) + c.Check(integrity, Equals, PlatformFirmwareIntegrityVerified) +} + +func (s *hostSecurityAMD64Suite) TestCheckHostSecurityAMDGoodMeasured(c *C) { + pspAttrs := map[string][]byte{ + "boot_integrity": []byte(`0 +`), + "debug_lock_on": []byte(`1 +`), + "fused_part": []byte(`1 +`), + } + devices := []internal_efi.SysfsDevice{ + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar0", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar1", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", pspAttrs, nil), + } + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(devices...), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), + ) + log := efitest.NewLog(c, &efitest.LogOptions{}) + + integrity, err := CheckHostSecurity(env, log) + c.Check(err, IsNil) + c.Check(integrity, Equals, PlatformFirmwareIntegrityMeasured) } func (s *hostSecurityAMD64Suite) TestCheckHostSecurityErrUnrecognizedCpuVendor(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineInte", nil, 0, nil), + efitest.WithAMD64Environment("GenuineInte", 0x6, nil, 0, nil), ) - err := CheckHostSecurity(env, nil) + _, err := CheckHostSecurity(env, nil) c.Check(err, ErrorMatches, `unsupported platform: cannot determine CPU vendor: unknown CPU vendor: GenuineInte`) var upe *UnsupportedPlatformError @@ -130,41 +161,35 @@ C7E003CB } env := efitest.NewMockHostEnvironmentWithOpts( efitest.WithSysfsDevices(devices...), - efitest.WithAMD64Environment("GenuineIntel", nil, 0, nil), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 0, nil), ) - err := CheckHostSecurity(env, nil) - c.Check(err, ErrorMatches, `encountered an error when checking Intel BootGuard configuration: no hardware root-of-trust properly configured: ME is in manufacturing mode`) + _, err := CheckHostSecurity(env, nil) + c.Check(err, ErrorMatches, `encountered an error when checking Intel BootGuard configuration: no hardware root-of-trust properly configured: system is in manufacturing mode`) var nhrotErr *NoHardwareRootOfTrustError c.Check(errors.As(err, &nhrotErr), testutil.IsTrue) - c.Check(nhrotErr, ErrorMatches, `no hardware root-of-trust properly configured: ME is in manufacturing mode`) + c.Check(nhrotErr, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) } func (s *hostSecurityAMD64Suite) TestCheckHostSecurityAMDErrPSP(c *C) { - pspAttrs := map[string][]byte{ - "debug_lock_on": []byte(`1 -`), - "fused_part": []byte(`0 -`), - } devices := []internal_efi.SysfsDevice{ efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar0", nil, "iommu", nil, nil), efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar1", nil, "iommu", nil, nil), - efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", pspAttrs, nil), + efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", nil, nil), } env := efitest.NewMockHostEnvironmentWithOpts( efitest.WithSysfsDevices(devices...), - efitest.WithAMD64Environment("AuthenticAMD", nil, 0, nil), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), ) log := efitest.NewLog(c, &efitest.LogOptions{}) - err := CheckHostSecurity(env, log) - c.Check(err, ErrorMatches, `encountered an error when checking the AMD PSP configuration: no hardware root-of-trust properly configured: Platform Secure Boot is not enabled`) + _, err := CheckHostSecurity(env, log) + c.Check(err, ErrorMatches, `encountered an error when checking the AMD PSP configuration: no hardware root-of-trust properly configured: PSP security reporting not available`) var nhrotErr *NoHardwareRootOfTrustError c.Check(errors.As(err, &nhrotErr), testutil.IsTrue) - c.Check(nhrotErr, ErrorMatches, `no hardware root-of-trust properly configured: Platform Secure Boot is not enabled`) + c.Check(nhrotErr, ErrorMatches, `no hardware root-of-trust properly configured: PSP security reporting not available`) } func (s *hostSecurityAMD64Suite) TestCheckHostSecuritySecureBootPolicyFirmwareDebugging(c *C) { @@ -190,11 +215,11 @@ C7E003CB } env := efitest.NewMockHostEnvironmentWithOpts( efitest.WithSysfsDevices(devices...), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000}), ) log := efitest.NewLog(c, &efitest.LogOptions{FirmwareDebugger: true}) - err := CheckHostSecurity(env, log) + _, err := CheckHostSecurity(env, log) c.Check(err, ErrorMatches, `the platform firmware contains a debugging endpoint enabled`) var tmpl CompoundError c.Assert(err, Implements, &tmpl) @@ -222,11 +247,11 @@ C7E003CB } env := efitest.NewMockHostEnvironmentWithOpts( efitest.WithSysfsDevices(devices...), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000}), ) log := efitest.NewLog(c, &efitest.LogOptions{}) - err := CheckHostSecurity(env, log) + _, err := CheckHostSecurity(env, log) c.Check(err, ErrorMatches, `no kernel IOMMU support was detected`) var tmpl CompoundError c.Assert(err, Implements, &tmpl) @@ -254,11 +279,11 @@ C7E003CB } env := efitest.NewMockHostEnvironmentWithOpts( efitest.WithSysfsDevices(devices...), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000}), ) log := efitest.NewLog(c, &efitest.LogOptions{FirmwareDebugger: true}) - err := CheckHostSecurity(env, log) + _, err := CheckHostSecurity(env, log) c.Check(err, ErrorMatches, `2 errors detected: - the platform firmware contains a debugging endpoint enabled - no kernel IOMMU support was detected @@ -291,18 +316,18 @@ C7E003CB } env := efitest.NewMockHostEnvironmentWithOpts( efitest.WithSysfsDevices(devices...), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0x0}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0x0}), ) log := efitest.NewLog(c, &efitest.LogOptions{}) - err := CheckHostSecurity(env, log) + _, err := CheckHostSecurity(env, log) c.Check(err, ErrorMatches, `encountered an error when checking Intel CPU debugging configuration: CPU debugging features are not disabled and locked`) c.Check(errors.Is(err, ErrCPUDebuggingNotLocked), testutil.IsTrue) } func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigationStatusNotRequiredAMD(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("AuthenticAMD", nil, 0, nil), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), ) status, err := CheckDiscreteTPMPartialResetAttackMitigationStatus(env, NewPCRBankResults(tpm2.HashAlgorithmSHA256, 0, [8]PcrResults{ @@ -320,7 +345,7 @@ func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigatio func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigationStatusIntelNotDiscrete(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1)}), ) status, err := CheckDiscreteTPMPartialResetAttackMitigationStatus(env, NewPCRBankResults(tpm2.HashAlgorithmSHA256, 0, [8]PcrResults{ @@ -338,7 +363,7 @@ func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigatio func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigationStatusIntelUnavailableInvalidPCR0(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1)}), ) status, err := CheckDiscreteTPMPartialResetAttackMitigationStatus(env, NewPCRBankResults(tpm2.HashAlgorithmSHA256, 3, [8]PcrResults{ @@ -356,7 +381,7 @@ func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigatio func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigationStatusIntelPreferred(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1)}), ) status, err := CheckDiscreteTPMPartialResetAttackMitigationStatus(env, NewPCRBankResults(tpm2.HashAlgorithmSHA256, 3, [8]PcrResults{ @@ -374,7 +399,7 @@ func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigatio func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigationStatusIntelUnavailableSL0(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1)}), ) status, err := CheckDiscreteTPMPartialResetAttackMitigationStatus(env, NewPCRBankResults(tpm2.HashAlgorithmSHA256, 0, [8]PcrResults{ @@ -392,7 +417,7 @@ func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigatio func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigationStatusIntelUnavailableNoTXT(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 4, map[uint32]uint64{0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 4, map[uint32]uint64{0x13a: (2 << 1)}), ) status, err := CheckDiscreteTPMPartialResetAttackMitigationStatus(env, NewPCRBankResults(tpm2.HashAlgorithmSHA256, 3, [8]PcrResults{ @@ -410,7 +435,7 @@ func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigatio func (s *hostSecurityAMD64Suite) TestCheckDiscreteTPMPartialResetAttackMitigationStatusErrUnsupportedCpuVendor(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineInte", nil, 0, nil), + efitest.WithAMD64Environment("GenuineInte", 0x6, nil, 0, nil), ) _, err := CheckDiscreteTPMPartialResetAttackMitigationStatus(env, NewPCRBankResults(tpm2.HashAlgorithmSHA256, 0, [8]PcrResults{})) diff --git a/efi/preinstall/check_host_security_amd_test.go b/efi/preinstall/check_host_security_amd_test.go index 4be0b71d..8b3c0ddd 100644 --- a/efi/preinstall/check_host_security_amd_test.go +++ b/efi/preinstall/check_host_security_amd_test.go @@ -34,6 +34,8 @@ var _ = Suite(&hostSecurityAMDSuite{}) func (s *hostSecurityAMDSuite) TestCheckHostSecurityAMDPSPGood(c *C) { attrs := map[string][]byte{ + "boot_integrity": []byte(`1 +`), "debug_lock_on": []byte(`1 `), "fused_part": []byte(`1 @@ -41,43 +43,106 @@ func (s *hostSecurityAMDSuite) TestCheckHostSecurityAMDPSPGood(c *C) { } device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", attrs, nil) - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) - err := CheckHostSecurityAMDPSP(env) + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(device), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), + ) + integrity, err := CheckHostSecurityAMDPSP(env) + c.Check(err, IsNil) + c.Check(integrity, Equals, PlatformFirmwareIntegrityVerified) +} + +func (s *hostSecurityAMDSuite) TestCheckHostSecurityAMDPSPGoodBootIntegrityDisabled(c *C) { + attrs := map[string][]byte{ + "boot_integrity": []byte(`0 +`), + "debug_lock_on": []byte(`1 +`), + "fused_part": []byte(`1 +`), + } + + device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", attrs, nil) + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(device), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), + ) + integrity, err := CheckHostSecurityAMDPSP(env) + c.Check(err, IsNil) + c.Check(integrity, Equals, PlatformFirmwareIntegrityMeasured) +} + +func (s *hostSecurityAMDSuite) TestCheckHostSecurityAMDPSPGoodNoBootIntegrityAttr(c *C) { + attrs := map[string][]byte{ + "debug_lock_on": []byte(`1 +`), + "fused_part": []byte(`1 +`), + } + + device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", attrs, nil) + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(device), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), + ) + integrity, err := CheckHostSecurityAMDPSP(env) + c.Check(err, IsNil) + c.Check(integrity, Equals, PlatformFirmwareIntegrityMeasured) +} + +func (s *hostSecurityAMDSuite) TestCheckHostSecurityAMDPSPGoodNotFused(c *C) { + attrs := map[string][]byte{ + "boot_integrity": []byte(`0 +`), + "debug_lock_on": []byte(`1 +`), + "fused_part": []byte(`0 +`), + } + + device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", attrs, nil) + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(device), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), + ) + integrity, err := CheckHostSecurityAMDPSP(env) c.Check(err, IsNil) + c.Check(integrity, Equals, PlatformFirmwareIntegrityMeasured) } func (s *hostSecurityAMDSuite) TestCheckHostSecurityErrNoCCPModule(c *C) { device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"PCI_CLASS": "108000", "PCI_ID": "1022:15C7"}, "pci", nil, nil) env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) - err := CheckHostSecurityAMDPSP(env) + _, err := CheckHostSecurityAMDPSP(env) c.Check(err, ErrorMatches, `the kernel module "ccp" must be loaded`) c.Check(err, Equals, MissingKernelModuleError("ccp")) } func (s *hostSecurityAMDSuite) TestCheckHostSecurityErrNoPSPDevice(c *C) { env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices()) - err := CheckHostSecurityAMDPSP(env) + _, err := CheckHostSecurityAMDPSP(env) c.Check(err, ErrorMatches, `unsupported platform: no PSP PCI device`) c.Check(err, FitsTypeOf, &UnsupportedPlatformError{}) } -func (s *hostSecurityAMDSuite) TestCheckHostSecurityErrNoSecurityReporting1(c *C) { +func (s *hostSecurityAMDSuite) TestCheckHostSecurityErrUnsupportedFamily(c *C) { device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", nil, nil) - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) - err := CheckHostSecurityAMDPSP(env) - c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: PSP security reporting not available`) - c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(device), + efitest.WithAMD64Environment("AuthenticAMD", 0x16, nil, 0, nil), + ) + _, err := CheckHostSecurityAMDPSP(env) + c.Check(err, ErrorMatches, `unsupported platform: unsupported CPU family`) + c.Check(err, FitsTypeOf, &UnsupportedPlatformError{}) } -func (s *hostSecurityAMDSuite) TestCheckHostSecurityErrNoSecurityReporting2(c *C) { - attrs := map[string][]byte{ - "debug_lock_on": []byte(`1 -`), - } - - device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", attrs, nil) - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) - err := CheckHostSecurityAMDPSP(env) +func (s *hostSecurityAMDSuite) TestCheckHostSecurityErrNoSecurityReporting1(c *C) { + device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", nil, nil) + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(device), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), + ) + _, err := CheckHostSecurityAMDPSP(env) c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: PSP security reporting not available`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } @@ -91,23 +156,11 @@ func (s *hostSecurityAMDSuite) TestCheckHostSecurityAMDPSPErrNoDebugLock(c *C) { } device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", attrs, nil) - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) - err := CheckHostSecurityAMDPSP(env) + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(device), + efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil), + ) + _, err := CheckHostSecurityAMDPSP(env) c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: PSP debug lock is not enabled`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } - -func (s *hostSecurityAMDSuite) TestCheckHostSecurityAMDPSPErrNoPSB(c *C) { - attrs := map[string][]byte{ - "debug_lock_on": []byte(`1 -`), - "fused_part": []byte(`0 -`), - } - - device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:08.1/0000:c1:00.2", map[string]string{"DRIVER": "ccp"}, "pci", attrs, nil) - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) - err := CheckHostSecurityAMDPSP(env) - c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: Platform Secure Boot is not enabled`) - c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) -} diff --git a/efi/preinstall/check_host_security_intel.go b/efi/preinstall/check_host_security_intel.go index dd79310a..bedd4f92 100644 --- a/efi/preinstall/check_host_security_intel.go +++ b/efi/preinstall/check_host_security_intel.go @@ -61,19 +61,12 @@ func (reg hfsts1) operationMode() meOperationMode { } const ( - // hfsts1MfgMode indicates that the ME is in manufacturing mode. Fwupd refers to this - // as manufacturing mode for CSME #11 and SPI protection mode for CSME #18. Slimbootloader - // refers to this as the latter for everything other than Comet Lake. - hfsts1MfgMode hfsts1 = 1 << 4 - // hfsts1OperationMode is the ME operation mode bitmask, from fwupd and slimbootloader. hfsts1OperationMode hfsts1 = 0xf0000 hfsts5BtgAcmActive hfsts5 = 1 << 0 hfsts5BtgAcmDone hfsts5 = 1 << 8 - hfsts6FPFSOCLock hfsts6 = 1 << 30 - meOperationModeNormal meOperationMode = 0x0 meOperationModeDebug meOperationMode = 0x2 meOperationModeDisabled meOperationMode = 0x3 @@ -286,9 +279,23 @@ func checkHostSecurityIntelBootGuard(env internal_efi.HostEnvironment) error { return fmt.Errorf("cannot enumerate PCI devices with MEI class: %w", err) } if len(devices) == 0 { - // We didn't find the PCI device, so indicate that this platform - // isn't supported. - return &UnsupportedPlatformError{errors.New("no MEI PCI device")} + // We didn't find the PCI device. This could be an Intel platform that + // is configured in High Assurance mode, so try this fallback using the + // BootGuard status MSR instead. + amd64Env, err := env.AMD64() + if err != nil { + return err + } + status, err := readIntelBootGuardStatus(amd64Env) + switch { + case errors.Is(err, internal_efi.ErrNoKernelMSRSupport): + return MissingKernelModuleError("msr") + case errors.Is(err, internal_efi.ErrNoMSRSupport): + return &UnsupportedPlatformError{errors.New("no MEI PCI device or BootGuard status MSR")} + case err != nil: + return fmt.Errorf("cannot read BootGuard status MSR: %w", err) + } + return checkHostSecurityIntelBootGuardMSR(status) } // We did find the PCI device, so indicate that we need the mei_me module @@ -316,24 +323,14 @@ func checkHostSecurityIntelBootGuard(env internal_efi.HostEnvironment) error { return &NoHardwareRootOfTrustError{errors.New("invalid ME operation mode")} } - // Check manufacturing mode is not enabled. - if regs.Hfsts1&hfsts1MfgMode > 0 { - return &NoHardwareRootOfTrustError{errors.New("ME is in manufacturing mode")} - } - // Check that the BootGuard ACM is active. Fwupd only checks this for CSME #18, but it // appears that the same bits are defined for both versions. if regs.Hfsts5&(hfsts5BtgAcmActive|hfsts5BtgAcmDone) != hfsts5BtgAcmActive|hfsts5BtgAcmDone { return &NoHardwareRootOfTrustError{errors.New("BootGuard ACM is not active")} } - // Check that the FPFs are locked. - if regs.Hfsts6&hfsts6FPFSOCLock == 0 { - return &NoHardwareRootOfTrustError{errors.New("BootGuard OTP fuses are not locked")} - } - if vers.Major < 18 { - return checkHostSecurityIntelBootGuardCSME11(toHfstsRegistersCsme11(regs)) + return checkHostSecurityIntelBootGuardCSME11(vers, toHfstsRegistersCsme11(regs)) } return checkHostSecurityIntelBootGuardCSME18(toHfstsRegistersCsme18(regs)) diff --git a/efi/preinstall/check_host_security_intel_btgmsr.go b/efi/preinstall/check_host_security_intel_btgmsr.go new file mode 100644 index 00000000..d64a65bb --- /dev/null +++ b/efi/preinstall/check_host_security_intel_btgmsr.go @@ -0,0 +1,53 @@ +//go:build amd64 + +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2026 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package preinstall + +import ( + "errors" + "fmt" +) + +// checkHostSecurityIntelBootGuardMSR checks the BootGuard configuration using the BootGuard status +// MSR rather than the HFSTS registers. The MSR is mirrored by the startup ACM - it will contain +// all zeroes if this didn't execute, in which case, BootGuard is not active. +// +// This has some limitations compared with using the HFSTS registers. Eg, it's not possible to +// ensure that the system has properly transitioned out of manufacturing mode. +func checkHostSecurityIntelBootGuardMSR(status bootGuardStatus) error { + if status&bootGuardCapability == 0 { + return &NoHardwareRootOfTrustError{errors.New("BootGuard ACM is not active")} + } + + // Check the BootGuard profile. + profile, err := status.btgProfile() + if err != nil { + return &NoHardwareRootOfTrustError{fmt.Errorf("cannot determine BootGuard profile: %w", err)} + } + switch profile { + case btgProfileFVE, btgProfileFVME: + // We require verified boot, so the 2 profiles with forced + // verification are ok. + return nil + default: + return &NoHardwareRootOfTrustError{errors.New("unsupported BootGuard profile")} + } +} diff --git a/efi/preinstall/check_host_security_intel_btgmsr_test.go b/efi/preinstall/check_host_security_intel_btgmsr_test.go new file mode 100644 index 00000000..0025edf7 --- /dev/null +++ b/efi/preinstall/check_host_security_intel_btgmsr_test.go @@ -0,0 +1,64 @@ +//go:build amd64 + +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2026 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package preinstall_test + +import ( + . "gopkg.in/check.v1" + + . "github.com/snapcore/secboot/efi/preinstall" +) + +type hostSecurityIntelBtgMSRSuite struct{} + +var _ = Suite(&hostSecurityIntelBtgMSRSuite{}) + +func (*hostSecurityIntelBtgMSRSuite) TestCheckHostSecurityIntelBootGuardMSRGoodFVMEProfile(c *C) { + c.Check(CheckHostSecurityIntelBootGuardMSR(0x000000030000007d), IsNil) +} + +func (*hostSecurityIntelBtgMSRSuite) TestCheckHostSecurityIntelBootGuardMSRGoodFVEProfile(c *C) { + c.Check(CheckHostSecurityIntelBootGuardMSR(0x000000030000005d), IsNil) +} + +func (*hostSecurityIntelBtgMSRSuite) TestCheckHostSecurityIntelBootGuardMSRErrInvalidProfile(c *C) { + err := CheckHostSecurityIntelBootGuardMSR(0x000000030000007c) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: cannot determine BootGuard profile: invalid profile`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (*hostSecurityIntelBtgMSRSuite) TestCheckHostSecurityIntelBootGuardMSRErrUnsupportedNoFVMEProfile(c *C) { + err := CheckHostSecurityIntelBootGuardMSR(0x000000030000000c) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (*hostSecurityIntelBtgMSRSuite) TestCheckHostSecurityIntelBootGuardMSRErrUnsupportedVMProfile(c *C) { + err := CheckHostSecurityIntelBootGuardMSR(0x000000030000006d) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (*hostSecurityIntelBtgMSRSuite) TestCheckHostSecurityIntelBootGuardMSRErrNoBtg(c *C) { + err := CheckHostSecurityIntelBootGuardMSR(0) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: BootGuard ACM is not active`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} diff --git a/efi/preinstall/check_host_security_intel_csme11.go b/efi/preinstall/check_host_security_intel_csme11.go index ac23f524..806cd6bb 100644 --- a/efi/preinstall/check_host_security_intel_csme11.go +++ b/efi/preinstall/check_host_security_intel_csme11.go @@ -83,23 +83,56 @@ func toHfstsRegistersCsme11(regs hfstsRegisters) hfstsRegistersCsme11 { } const ( + // hfsts1Csme11MfgMode indicates that the system is in manufacturing mode. Note that + // fwupd and coreboot refer to this bit as manufacturing mode whilst slimbootloader refers + // to this as SPI protection mode. Based on this and the comments in coreboot, this bit + // is set when the SPI flash descriptor is locked. + hfsts1Csme11MfgMode hfsts1Csme11 = 1 << 4 + hfsts6Csme11ForceBootPolicy hfsts6Csme11 = 1 << 0 hfsts6Csme11CpuDebugDisable hfsts6Csme11 = 1 << 1 hfsts6Csme11ProtectBIOSEnv hfsts6Csme11 = 1 << 3 hfsts6Csme11ErrorEnforcementPolicy hfsts6Csme11 = 0xc0 hfsts6Csme11MeasuredBoot hfsts6Csme11 = 1 << 8 hfsts6Csme11VerifiedBoot hfsts6Csme11 = 1 << 9 + hfsts6Csme11MfgLock hfsts6Csme11 = 1 << 21 hfsts6Csme11BootGuardDisable hfsts6Csme11 = 1 << 28 + hfsts6Csme11FPFSOCLock hfsts6Csme11 = 1 << 30 errorEnforcementPolicyCsme11Nothing errorEnforcementPolicyCsme11 = 0 errorEnforcementPolicyCsme11Shutdown30Mins errorEnforcementPolicyCsme11 = 1 // fwupd defines this as 3, which I think is wrong. errorEnforcementPolicyCsme11ShutdownNow errorEnforcementPolicyCsme11 = 3 // fwupd defines this as 2, which I think is wrong. ) -func checkHostSecurityIntelBootGuardCSME11(regs hfstsRegistersCsme11) error { +func isInManufacturingModeCSME11(vers meVersion, regs hfstsRegistersCsme11) bool { + // This is based on the checks from + // https://github.com/coreboot/coreboot/blob/eb5bdf06b92534b6f66f612297a4ccb69008b4ac/src/soc/intel/common/block/cse/cse_spec.c#L15 + if regs.Hfsts1&hfsts1Csme11MfgMode > 0 { + return true + } + if vers.Major > 13 { + if regs.Hfsts6&hfsts6Csme11FPFSOCLock == 0 { + return true + } + } + if vers.Major > 15 { + if regs.Hfsts6&hfsts6Csme11MfgLock == 0 { + return true + } + } + return false +} + +// checkHostSecurityIntelBootGuardCSME11 checks the BootGuard configuration CSME versions 11 to 17. +func checkHostSecurityIntelBootGuardCSME11(vers meVersion, regs hfstsRegistersCsme11) error { // These checks are based on the HSI checks performed in the pci-mei // plugin in fwupd. + // Make sure that the system is not in manufacturing mode. + if isInManufacturingModeCSME11(vers, regs) { + return &NoHardwareRootOfTrustError{errors.New("system is in manufacturing mode")} + } + // Check that BootGuard is enabled. if regs.Hfsts6&hfsts6Csme11BootGuardDisable > 0 { return &NoHardwareRootOfTrustError{errors.New("BootGuard is disabled")} diff --git a/efi/preinstall/check_host_security_intel_csme11_test.go b/efi/preinstall/check_host_security_intel_csme11_test.go index 7176d008..74eea31e 100644 --- a/efi/preinstall/check_host_security_intel_csme11_test.go +++ b/efi/preinstall/check_host_security_intel_csme11_test.go @@ -32,35 +32,96 @@ type hostSecurityIntelCsme11Suite struct{} var _ = Suite(&hostSecurityIntelCsme11Suite{}) func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11GoodFVMEProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E003CB}) + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0xC7E003CB, + }) c.Check(err, IsNil) } func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11GoodFVEProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E002CB}) + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0xC7E002CB, + }) c.Check(err, IsNil) } +func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11Good13(c *C) { + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 13}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0x87C003CB, + }) + c.Check(err, IsNil) +} + +func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11Good15(c *C) { + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 15}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0xC7C003CB, + }) + c.Check(err, IsNil) +} + +func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrMfgMode(c *C) { + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 13}, HfstsRegistersCsme11{ + Hfsts1: 0x94000255, + Hfsts6: 0x87C003CB, + }) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrFPFsNotLocked(c *C) { + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 15}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0x87C003CB, + }) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrNoManufLock(c *C) { + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0x87C003CB, + }) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrBootGuardDisabled(c *C) { - err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xD7E003CB}) + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0xD7E003CB, + }) c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: BootGuard is disabled`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrInvalidProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E0024A}) + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0xC7E0024A, + }) c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: cannot determine BootGuard profile: invalid profile`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrUnsupportedNoFVMEProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E00002}) + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0xC7E00002, + }) c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrUnsupportedVMProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E0030A}) + err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{ + Hfsts1: 0x94000245, + Hfsts6: 0xC7E0030A, + }) c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } diff --git a/efi/preinstall/check_host_security_intel_csme18.go b/efi/preinstall/check_host_security_intel_csme18.go index 04e8996b..4693e4e4 100644 --- a/efi/preinstall/check_host_security_intel_csme18.go +++ b/efi/preinstall/check_host_security_intel_csme18.go @@ -46,8 +46,13 @@ func (reg hfsts5Csme18) btgProfile() btgProfile { } const ( + hfsts1Csme18SPIProtectionMode hfsts1Csme18 = 1 << 4 + hfsts5Csme18BtgProfileValid hfsts5Csme18 = 1 << 1 + hfsts6Csme18MfgLock hfsts6Csme18 = 1 << 21 + hfsts6Csme18FPFSOCLock hfsts6Csme18 = 1 << 30 + // hfsts5Csme18BtgProfile is the bitmask for the BootGuard profile. // fwupd defines this as 0xe0000, but I think this is off by one bit. // I see a profile value of 5 on my XPS16 (which is what I expect) if @@ -68,10 +73,31 @@ func toHfstsRegistersCsme18(regs hfstsRegisters) hfstsRegistersCsme18 { } } +func isInManufacturingModeCSME18(regs hfstsRegistersCsme18) bool { + // This is based on the checks from + // https://github.com/coreboot/coreboot/blob/eb5bdf06b92534b6f66f612297a4ccb69008b4ac/src/soc/intel/common/block/cse/cse_spec.c#L15 + if regs.Hfsts1&hfsts1Csme18SPIProtectionMode > 0 { + return true + } + if regs.Hfsts6&hfsts6Csme18MfgLock == 0 { + return true + } + if regs.Hfsts6&hfsts6Csme18FPFSOCLock == 0 { + return true + } + return false +} + +// checkHostSecurityIntelBootGuardCSME18 checks the BootGuard configuration CSME versions 18 onwards. func checkHostSecurityIntelBootGuardCSME18(regs hfstsRegistersCsme18) error { // These checks are based on the HSI checks performed in the pci-mei // plugin in fwupd. + // Make sure that the system is not in manufacturing mode. + if isInManufacturingModeCSME18(regs) { + return &NoHardwareRootOfTrustError{errors.New("system is in manufacturing mode")} + } + // Check that the BootGuard profile is valid. I think that's what this // is checking - fwupd's definition of this bit is just called "valid". // This bit does exist for CSME #11, but the definition in slimbootloader diff --git a/efi/preinstall/check_host_security_intel_csme18_test.go b/efi/preinstall/check_host_security_intel_csme18_test.go index 6e9cb1d0..56339779 100644 --- a/efi/preinstall/check_host_security_intel_csme18_test.go +++ b/efi/preinstall/check_host_security_intel_csme18_test.go @@ -32,29 +32,79 @@ type hostSecurityIntelCsme18Suite struct{} var _ = Suite(&hostSecurityIntelCsme18Suite{}) func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18GoodFVMEProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02F61F03}) + err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{ + Hfsts1: 0x94000245, + Hfsts5: 0x02F61F03, + Hfsts6: 0x40200000, + }) c.Check(err, IsNil) } func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18GoodFVEProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02F21F03}) + err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{ + Hfsts1: 0x94000245, + Hfsts5: 0x02F21F03, + Hfsts6: 0x40200000, + }) c.Check(err, IsNil) } +func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrNoSPIProtection(c *C) { + err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{ + Hfsts1: 0x94000255, + Hfsts5: 0x02F61F03, + Hfsts6: 0x40200000, + }) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrFPFsNotLocked(c *C) { + err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{ + Hfsts1: 0x94000245, + Hfsts5: 0x02F61F03, + Hfsts6: 0x00200000, + }) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrNoManufLock(c *C) { + err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{ + Hfsts1: 0x94000245, + Hfsts5: 0x02F61F03, + Hfsts6: 0x40000000, + }) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrInvalidProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02F61F01}) + err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{ + Hfsts1: 0x94000245, + Hfsts5: 0x02F61F01, + Hfsts6: 0x40200000, + }) c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: invalid BootGuard profile`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrUnsupportedNoFVMEProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02E21F03}) + err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{ + Hfsts1: 0x94000245, + Hfsts5: 0x02E21F03, + Hfsts6: 0x40200000, + }) c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrUnsupportedVMProfile(c *C) { - err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02EE1F03}) + err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{ + Hfsts1: 0x94000245, + Hfsts5: 0x02EE1F03, + Hfsts6: 0x40200000, + }) c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } diff --git a/efi/preinstall/check_host_security_intel_test.go b/efi/preinstall/check_host_security_intel_test.go index 2f4ff5e3..81eb007e 100644 --- a/efi/preinstall/check_host_security_intel_test.go +++ b/efi/preinstall/check_host_security_intel_test.go @@ -378,6 +378,41 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardGoodFVMECSME c.Check(err, IsNil) } +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardNoMEDevice1(c *C) { + // Test the case where there are no mei devices, but we can + // fallback to using the bootguard status MSR. + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 4, map[uint32]uint64{0x13a: 0x000000030000007d}), + ) + c.Check(CheckHostSecurityIntelBootGuard(env), IsNil) +} + +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardMEDevice2(c *C) { + // Test the case where the only mei device is not the required one. + device := efitest.NewMockSysfsDevice("/sys/devices/platform/intel_vsc/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", nil, efitest.NewMockSysfsDevice( + "/sys/devices/platform", map[string]string{"DRIVER": "intel_vsc"}, "platform", nil, nil, + )) + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(device), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 4, map[uint32]uint64{0x13a: 0x000000030000007d}), + ) + c.Check(CheckHostSecurityIntelBootGuard(env), IsNil) +} + +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardNoMEDevice3(c *C) { + // Test the case where there is a PCI mei device that isn't bound to the mei_me + // module. This probably isn't a realistic test case. + device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", nil, efitest.NewMockSysfsDevice( + "/sys/devices/pci0000:00:16:0", nil, "pci", nil, nil, + )) + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(device), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 4, map[uint32]uint64{0x13a: 0x000000030000007d}), + ) + c.Check(CheckHostSecurityIntelBootGuard(env), IsNil) +} + func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoDevices(c *C) { env := efitest.NewMockHostEnvironmentWithOpts() err := CheckHostSecurityIntelBootGuard(env) @@ -393,36 +428,26 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoMEModul c.Check(err, Equals, MissingKernelModuleError("mei_me")) } -func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoMEDevice1(c *C) { - // Test the case where there are no mei devices. - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices()) +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardNoMEDeviceAndNoMSRModule(c *C) { + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 4, nil), + ) err := CheckHostSecurityIntelBootGuard(env) - c.Check(err, ErrorMatches, `unsupported platform: no MEI PCI device`) - c.Check(err, FitsTypeOf, &UnsupportedPlatformError{}) + c.Check(err, ErrorMatches, `the kernel module "msr" must be loaded`) + c.Check(err, Equals, MissingKernelModuleError("msr")) } -func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoMEDevice2(c *C) { - // Test the case where the only mei device is not the required one. - device := efitest.NewMockSysfsDevice("/sys/devices/platform/intel_vsc/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", nil, efitest.NewMockSysfsDevice( - "/sys/devices/platform", map[string]string{"DRIVER": "intel_vsc"}, "platform", nil, nil, - )) - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardNoMEDeviceAndNoBtgMSR(c *C) { + env := efitest.NewMockHostEnvironmentWithOpts( + efitest.WithSysfsDevices(), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 4, map[uint32]uint64{}), + ) err := CheckHostSecurityIntelBootGuard(env) - c.Check(err, ErrorMatches, `unsupported platform: no MEI PCI device`) + c.Check(err, ErrorMatches, `unsupported platform: no MEI PCI device or BootGuard status MSR`) c.Check(err, FitsTypeOf, &UnsupportedPlatformError{}) } -func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoMEDevice3(c *C) { - // Test the case where there is a PCI mei device that isn't bound to the mei_me - // module. This probably isn't a realistic test case. - device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", nil, efitest.NewMockSysfsDevice( - "/sys/devices/pci0000:00:16:0", nil, "pci", nil, nil, - )) - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) - err := CheckHostSecurityIntelBootGuard(env) - c.Check(err, ErrorMatches, `unsupported platform: no MEI PCI device`) - c.Check(err, FitsTypeOf, &UnsupportedPlatformError{}) -} func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrFwVer(c *C) { attrs := map[string][]byte{ "fw_status": []byte(`94000245 @@ -525,18 +550,18 @@ C7E003CB c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } -func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrMfgMode(c *C) { +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrACMNotActive(c *C) { attrs := map[string][]byte{ - "fw_ver": []byte(`0:16.1.27.2176 -0:16.1.27.2176 -0:16.0.15.1624 + "fw_ver": []byte(`0:18.0.5.2141 +0:18.0.5.2141 +0:18.0.5.2066 `), - "fw_status": []byte(`94000255 -09F10506 + "fw_status": []byte(`A4000245 +09110500 00000020 -00004000 -00041F03 -C7E003CB +00000000 +02F61E02 +40200000 `), } device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", attrs, efitest.NewMockSysfsDevice( @@ -544,11 +569,11 @@ C7E003CB )) env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) err := CheckHostSecurityIntelBootGuard(env) - c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: ME is in manufacturing mode`) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: BootGuard ACM is not active`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } -func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrACMNotActive(c *C) { +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrACMNotDone(c *C) { attrs := map[string][]byte{ "fw_ver": []byte(`0:18.0.5.2141 0:18.0.5.2141 @@ -558,7 +583,7 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrACMNotAct 09110500 00000020 00000000 -02F61E02 +02F61E03 40200000 `), } @@ -571,18 +596,18 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrACMNotAct c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } -func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrACMNotDone(c *C) { +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrBootGuardDisable(c *C) { attrs := map[string][]byte{ - "fw_ver": []byte(`0:18.0.5.2141 -0:18.0.5.2141 -0:18.0.5.2066 + "fw_ver": []byte(`0:16.1.27.2176 +0:16.1.27.2176 +0:16.0.15.1624 `), - "fw_status": []byte(`A4000245 -09110500 + "fw_status": []byte(`94000245 +09F10506 00000020 -00000000 -02F61E03 -40200000 +00004000 +00041F03 +D7E003CB `), } device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", attrs, efitest.NewMockSysfsDevice( @@ -590,11 +615,34 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrACMNotDon )) env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) err := CheckHostSecurityIntelBootGuard(env) - c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: BootGuard ACM is not active`) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: BootGuard is disabled`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } -func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoFPFSOCLock(c *C) { +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrMfgModeCSME11(c *C) { + attrs := map[string][]byte{ + "fw_ver": []byte(`0:16.1.27.2176 +0:16.1.27.2176 +0:16.0.15.1624 +`), + "fw_status": []byte(`94000255 +09F10506 +00000020 +00004000 +00041F03 +C7E003CB +`), + } + device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", attrs, efitest.NewMockSysfsDevice( + "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, + )) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) + err := CheckHostSecurityIntelBootGuard(env) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrFPFsNotLockedCSME11(c *C) { attrs := map[string][]byte{ "fw_ver": []byte(`0:16.1.27.2176 0:16.1.27.2176 @@ -613,11 +661,11 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoFPFSOCL )) env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) err := CheckHostSecurityIntelBootGuard(env) - c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: BootGuard OTP fuses are not locked`) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } -func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrBootGuardDisable(c *C) { +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoManufLockCSME11(c *C) { attrs := map[string][]byte{ "fw_ver": []byte(`0:16.1.27.2176 0:16.1.27.2176 @@ -628,7 +676,7 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrBootGuard 00000020 00004000 00041F03 -D7E003CB +C7C003CB `), } device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", attrs, efitest.NewMockSysfsDevice( @@ -636,7 +684,7 @@ D7E003CB )) env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) err := CheckHostSecurityIntelBootGuard(env) - c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: BootGuard is disabled`) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } @@ -709,6 +757,75 @@ C7E0024A c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) } +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoSPIProtectionCSME18(c *C) { + attrs := map[string][]byte{ + "fw_ver": []byte(`0:18.0.5.2141 +0:18.0.5.2141 +0:18.0.5.2066 +`), + "fw_status": []byte(`A4000255 +09110500 +00000020 +00000000 +02F61F03 +40200000 +`), + } + device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", attrs, efitest.NewMockSysfsDevice( + "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, + )) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) + err := CheckHostSecurityIntelBootGuard(env) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrFPFsNotLockedCSME18(c *C) { + attrs := map[string][]byte{ + "fw_ver": []byte(`0:18.0.5.2141 +0:18.0.5.2141 +0:18.0.5.2066 +`), + "fw_status": []byte(`A4000245 +09110500 +00000020 +00000000 +02F61F03 +00200000 +`), + } + device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", attrs, efitest.NewMockSysfsDevice( + "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, + )) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) + err := CheckHostSecurityIntelBootGuard(env) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + +func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrNoManufLockCSME18(c *C) { + attrs := map[string][]byte{ + "fw_ver": []byte(`0:18.0.5.2141 +0:18.0.5.2141 +0:18.0.5.2066 +`), + "fw_status": []byte(`A4000245 +09110500 +00000020 +00000000 +02F61F03 +40000000 +`), + } + device := efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", attrs, efitest.NewMockSysfsDevice( + "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, + )) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithSysfsDevices(device)) + err := CheckHostSecurityIntelBootGuard(env) + c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`) + c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{}) +} + func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrInvalidProfileCSME18(c *C) { attrs := map[string][]byte{ "fw_ver": []byte(`0:18.0.5.2141 @@ -779,7 +896,7 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelBootGuardErrUnsupport } func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedDisabledCPUID(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", nil, 1, map[uint32]uint64{0xc80: 0})) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 1, map[uint32]uint64{0xc80: 0})) amd64Env, err := env.AMD64() c.Assert(err, IsNil) @@ -787,7 +904,7 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedDis } func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedDisabledMSR(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0x40000000})) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0x40000000})) amd64Env, err := env.AMD64() c.Assert(err, IsNil) @@ -795,7 +912,7 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedDis } func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedDisabledAvailable(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0})) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0})) amd64Env, err := env.AMD64() c.Assert(err, IsNil) @@ -803,7 +920,7 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedDis } func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedEnabled(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 1})) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 1})) amd64Env, err := env.AMD64() c.Assert(err, IsNil) @@ -811,7 +928,7 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedEna } func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedErrMissingMSR(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG}, 4, map[uint32]uint64{})) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG}, 4, map[uint32]uint64{})) amd64Env, err := env.AMD64() c.Assert(err, IsNil) @@ -821,7 +938,7 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedErr } func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedErrNoMSRSupport(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG}, 0, nil)) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG}, 0, nil)) amd64Env, err := env.AMD64() c.Assert(err, IsNil) @@ -832,7 +949,7 @@ func (s *hostSecurityIntelSuite) TestCheckHostSecurityIntelCPUDebuggingLockedErr func (s *hostSecurityIntelSuite) TestRestrictedTPMLocalitiesIntel(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SMX}, 0, nil), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SMX}, 0, nil), ) amd64Env, err := env.AMD64() c.Assert(err, IsNil) @@ -842,7 +959,7 @@ func (s *hostSecurityIntelSuite) TestRestrictedTPMLocalitiesIntel(c *C) { func (s *hostSecurityIntelSuite) TestRestrictedTPMLocalitiesIntelNoTXT(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 0, nil), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 0, nil), ) amd64Env, err := env.AMD64() c.Assert(err, IsNil) diff --git a/efi/preinstall/check_host_security_null.go b/efi/preinstall/check_host_security_null.go index 94d706ab..ecaca284 100644 --- a/efi/preinstall/check_host_security_null.go +++ b/efi/preinstall/check_host_security_null.go @@ -30,8 +30,8 @@ import ( internal_efi "github.com/snapcore/secboot/internal/efi" ) -func checkHostSecurity(env internal_efi.HostEnvironment, log *tcglog.Log) error { - return &UnsupportedPlatformError{fmt.Errorf("checking host security is not implemented on %s", runtime.GOARCH)} +func checkHostSecurity(env internal_efi.HostEnvironment, log *tcglog.Log) (platformFirmwareIntegrityConfig, error) { + return platformFirmwareIntegrityNone, &UnsupportedPlatformError{fmt.Errorf("checking host security is not implemented on %s", runtime.GOARCH)} } func checkDiscreteTPMPartialResetAttackMitigationStatus(env internal_efi.HostEnvironment, logResults *pcrBankResults) (discreteTPMPartialResetAttackMitigationStatus, error) { diff --git a/efi/preinstall/check_host_security_test.go b/efi/preinstall/check_host_security_test.go index d4748b8c..404877db 100644 --- a/efi/preinstall/check_host_security_test.go +++ b/efi/preinstall/check_host_security_test.go @@ -22,9 +22,7 @@ package preinstall_test import ( . "gopkg.in/check.v1" - "github.com/canonical/tcglog-parser" . "github.com/snapcore/secboot/efi/preinstall" - internal_efi "github.com/snapcore/secboot/internal/efi" "github.com/snapcore/secboot/internal/efitest" ) @@ -127,30 +125,3 @@ func (s *hostSecuritySuite) TestCheckSecureBootPolicyPCRForDegradedSettingsFirmw c.Assert(err, Implements, &tmpl) c.Check(err.(CompoundError).Unwrap(), DeepEquals, []error{ErrUEFIDebuggingEnabled, ErrInsufficientDMAProtection}) } - -func (s *hostSecuritySuite) TestCheckSecureBootPolicyPCRForDegradedSettingsErrUnexpectedData(c *C) { - log := efitest.NewLog(c, &efitest.LogOptions{FirmwareDebugger: true}) - for _, ev := range log.Events { - if ev.PCRIndex != internal_efi.SecureBootPolicyPCR { - continue - } - ev.Data = tcglog.EFICallingEFIApplicationEvent - break - } - err := CheckSecureBootPolicyPCRForDegradedFirmwareSettings(log) - c.Check(err, ErrorMatches, `unexpected EV_EFI_ACTION event data in PCR7 event: \"Calling EFI Application from Boot Option\"`) -} - -func (s *hostSecuritySuite) TestCheckSecureBootPolicyPCRForDegradedSettingsErrUnexpectedType(c *C) { - log := efitest.NewLog(c, &efitest.LogOptions{FirmwareDebugger: true}) - for _, ev := range log.Events { - if ev.PCRIndex != internal_efi.SecureBootPolicyPCR { - continue - } - ev.EventType = tcglog.EventTypeAction - break - } - c.Check(CheckSecureBootPolicyPCRForDegradedFirmwareSettings(log), ErrorMatches, `unexpected event type \(EV_ACTION\) in PCR7`) - err := CheckSecureBootPolicyPCRForDegradedFirmwareSettings(log) - c.Check(err, ErrorMatches, `unexpected event type \(EV_ACTION\) in PCR7`) -} diff --git a/efi/preinstall/check_pcr2.go b/efi/preinstall/check_pcr2.go index c90fd565..a62bff89 100644 --- a/efi/preinstall/check_pcr2.go +++ b/efi/preinstall/check_pcr2.go @@ -30,29 +30,6 @@ import ( internal_efi "github.com/snapcore/secboot/internal/efi" ) -// isLaunchedFromFirmwareVolume indicates that the supplied event is associated -// with an image launch from a firmware volume. -func isLaunchedFromFirmwareVolume(ev *tcglog.Event) (yes bool, err error) { - // The caller should check this. - switch ev.EventType { - case tcglog.EventTypeEFIBootServicesDriver, tcglog.EventTypeEFIRuntimeServicesDriver, tcglog.EventTypeEFIBootServicesApplication: - // ok - default: - return false, fmt.Errorf("unexpected event type %v", ev.EventType) - } - - data, ok := ev.Data.(*tcglog.EFIImageLoadEvent) - if !ok { - return false, fmt.Errorf("event has invalid event data: %w", ev.Data.(error)) - } - - if len(data.DevicePath) == 0 { - return false, errors.New("empty device path") - } - - return data.DevicePath[0].CompoundType() == efi.DevicePathNodeFwVolType, nil -} - // checkDriversAndAppsMeasurements performs minimal checks on PCR 2, which is where // addon code from value-added-retailer components such as option ROMs and UEFI // drivers are measured. @@ -119,7 +96,7 @@ func checkDriversAndAppsMeasurements(ctx context.Context, env internal_efi.HostE // volumes (as early firmware code verifies firmware volumes separately) and to require image // verification for everything else. Drivers loaded from firmware volumes are not really addon // drivers in any case. - switch yes, err := isLaunchedFromFirmwareVolume(ev); { + switch yes, err := internal_efi.IsLaunchedFromFirmwareVolume(ev); { case err != nil: return nil, fmt.Errorf("cannot determine if %v event for %v was loaded from an option ROM: %w", ev.EventType, data.DevicePath, err) case yes: diff --git a/efi/preinstall/check_pcr2_test.go b/efi/preinstall/check_pcr2_test.go index aaaea9e8..51320d13 100644 --- a/efi/preinstall/check_pcr2_test.go +++ b/efi/preinstall/check_pcr2_test.go @@ -37,83 +37,6 @@ type pcr2Suite struct{} var _ = Suite(&pcr2Suite{}) -func (s *pcr2Suite) TestIsLaunchedFromFirmwareVolumeYes(c *C) { - yes, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ - EventType: tcglog.EventTypeEFIBootServicesDriver, - Data: &tcglog.EFIImageLoadEvent{ - DevicePath: efi.DevicePath{ - efi.FWVolDevicePathNode(efi.MakeGUID(0xf0d99c58, 0x3e06, 0x430c, 0x8d02, [...]uint8{0x9a, 0xb8, 0x8b, 0xa1, 0x61, 0x20})), - efi.FWFileDevicePathNode(efi.MakeGUID(0x0c2c4003, 0x6551, 0x4eea, 0xb006, [...]uint8{0x0f, 0xec, 0xb4, 0xbb, 0x30, 0x0b})), - }, - }, - }) - c.Check(err, IsNil) - c.Check(yes, testutil.IsTrue) -} - -func (s *pcr2Suite) TestIsLaunchedFromFirmwareVolumeNo(c *C) { - yes, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ - EventType: tcglog.EventTypeEFIBootServicesDriver, - Data: &tcglog.EFIImageLoadEvent{ - DevicePath: efi.DevicePath{ - &efi.ACPIDevicePathNode{ - HID: 0x0a0341d0, - UID: 0x0, - }, - &efi.PCIDevicePathNode{ - Function: 0x1c, - Device: 0x2, - }, - &efi.PCIDevicePathNode{ - Function: 0x0, - Device: 0x0, - }, - &efi.MediaRelOffsetRangeDevicePathNode{ - StartingOffset: 0x38, - EndingOffset: 0x11dff, - }, - }, - }, - }) - c.Check(err, IsNil) - c.Check(yes, testutil.IsFalse) -} - -func (s *pcr2Suite) TestIsLaunchedFromFirmwareVolumeYesRuntimeDriver(c *C) { - yes, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ - EventType: tcglog.EventTypeEFIRuntimeServicesDriver, - Data: &tcglog.EFIImageLoadEvent{ - DevicePath: efi.DevicePath{ - efi.FWVolDevicePathNode(efi.MakeGUID(0xf0d99c58, 0x3e06, 0x430c, 0x8d02, [...]uint8{0x9a, 0xb8, 0x8b, 0xa1, 0x61, 0x20})), - efi.FWFileDevicePathNode(efi.MakeGUID(0x0c2c4003, 0x6551, 0x4eea, 0xb006, [...]uint8{0x0f, 0xec, 0xb4, 0xbb, 0x30, 0x0b})), - }, - }, - }) - c.Check(err, IsNil) - c.Check(yes, testutil.IsTrue) -} - -func (s *pcr2Suite) TestIsLaunchedFromFirmwareVolumeErrInvalidEventType(c *C) { - _, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{EventType: tcglog.EventTypeSeparator}) - c.Check(err, ErrorMatches, `unexpected event type EV_SEPARATOR`) -} - -func (s *pcr2Suite) TestIsLaunchedFromFirmwareVolumeErrInvalidEventData(c *C) { - _, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ - EventType: tcglog.EventTypeEFIBootServicesDriver, - Data: &invalidEventData{errors.New("some error")}, - }) - c.Check(err, ErrorMatches, `event has invalid event data: some error`) -} - -func (s *pcr2Suite) TestIsLaunchedFromFirmwareVolumeErrEmptyPath(c *C) { - _, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ - EventType: tcglog.EventTypeEFIBootServicesDriver, - Data: &tcglog.EFIImageLoadEvent{}, - }) - c.Check(err, ErrorMatches, `empty device path`) -} - type testCheckDriversAndAppsMeasurementsParams struct { env internal_efi.HostEnvironment pcrAlg tpm2.HashAlgorithmId diff --git a/efi/preinstall/check_pcr4.go b/efi/preinstall/check_pcr4.go index 47f8ac72..47e8648c 100644 --- a/efi/preinstall/check_pcr4.go +++ b/efi/preinstall/check_pcr4.go @@ -51,23 +51,25 @@ type bootManagerCodeResult struct { // order in which they are loaded. These images are used to verify the digests of the // EV_EFI_BOOT_SERVICES_APPLICATION events. // -// This function ensures that the pre-OS environment is well formed. Either it contains a single -// EV_OMIT_BOOT_DEVICE_EVENT event or an optional EV_EFI_ACTION "Calling EFI Application from Boot -// Option" event if the EV_OMIT_BOOT_DEVICE_EVENT event is not present. If the EV_EFI_ACTION event -// is present, then the next expected event is the EV_SEPARATOR to signal the transition to OS-present. -// The function considers any EV_EFI_BOOT_SERVICES_APPLICATION events before this to be system -// preparation applications, and it will return information about these in the returned result. If -// the BootOptionSupport EFI variable indicates that sysprep apps are not supported but they are present, -// then an error is returned. If any pre-OS EV_EFI_BOOT_SERVICES_APPLICATION event is associated with -// Absolute, then this is indicated separately in the returned result. +// This function ensures that the pre-OS environment is relatively well formed. Before the secure +// boot configuration is measured, it may contain an optional EV_OMIT_BOOT_DEVICE_EVENT event Whilst +// there should only be one of these, this isn't enforced and generated profiles will still be +// correct. After the secure boot configuration is measured, it may contain an optional +// EV_OMIT_BOOT_DEVICE_EVENT event, EV_EFI_BOOT_SERVICES_APPLICATION events and an optional +// EV_EFI_ACTION "Calling EFI Application from Boot Option" event. Whilst the EV_EFI_ACTION event +// should only be present if there is no EV_OMIT_BOOT_DEVICE_EVENT event, this isn't enforced and +// generated profiles will still be correct. If the EV_EFI_ACTION event is present, the next +// event is expected to be an EV_SEPARATOR to signal the transition to OS-present. This function +// considers any pre-OS EV_EFI_BOOT_SERVICES_APPLICATION events to be system preparation applications +// unless they are loaded from SPI flash, and it will return information about these in the returned +// result. If any pre-OS EV_EFI_BOOT_SERVICES_APPLICATION event is associated with Absolute, then this +// is indicated separately in the returned result. // // The function expects the next event after the EV_SEPARATOR to be a EV_EFI_BOOT_SERVICES_APPLICATION // event, either the one associated with the IBL (initial boot loader) for the OS, or a component of // Absolute. If it is Absolute, then this is indicated in the returned result. It then expects the next -// event to be the one associated with the IBL (based on the value of the BootCurrent EFI variable, -// and the corresponding EFI_LOAD_OPTION in the TCG log). If the event data is inconsistent with the -// EFI_LOAD_OPTION for BootCurrent, it returns an error. It verifies that the digest of the event matches -// the Authenticode digest of the first supplied image, and returns an error if it isn't. +// event to be the one associated with the IBL. It verifies that the digest of the event matches the +// Authenticode digest of the first supplied image, and returns an error if it isn't. // // Once the IBL image digest is verified, then the digests of all other EV_EFI_BOOT_SERVICES_APPLICATION // events in the log are checked, if enough images associated with the current boot are supplied via the @@ -82,40 +84,16 @@ type bootManagerCodeResult struct { func checkBootManagerCodeMeasurements(ctx context.Context, env internal_efi.HostEnvironment, log *tcglog.Log, pcrAlg tpm2.HashAlgorithmId, loadImages []secboot_efi.Image) (result *bootManagerCodeResult, err error) { varCtx := env.VarContext(ctx) - // Obtain the boot option support - opts, err := efi.ReadBootOptionSupportVariable(varCtx) - switch { - case errors.Is(err, efi.ErrVarNotExist): - // We want RunChecks to not return the EFI variable access error in this case. - return nil, errors.New("cannot obtain boot option support: variable doesn't exist") - case err != nil: - return nil, fmt.Errorf("cannot obtain boot option support: %w", err) - } - - // Obtain the load option from the current boot so we can identify which load - // event corresponds to the initial OS boot loader. - bootOpt, err := readCurrentBootLoadOptionFromLog(varCtx, log) - if err != nil { - return nil, err - } - - var ( - sysprepOrder []uint16 - sysprepOpts []*efi.LoadOption - ) - if opts&efi.BootOptionSupportSysPrep > 0 { - sysprepOpts, sysprepOrder, err = readOrderedLoadOptionVariables(varCtx, efi.LoadOptionClassSysPrep) - if err != nil && !errors.Is(err, efi.ErrVarNotExist) { - return nil, fmt.Errorf("cannot read sysprep app load option variables: %w", err) - } + sysprepOpts, sysprepOrder, err := readOrderedLoadOptionVariables(varCtx, efi.LoadOptionClassSysPrep) + if err != nil && !errors.Is(err, efi.ErrVarNotExist) { + return nil, fmt.Errorf("cannot read sysprep app load option variables: %w", err) } result = new(bootManagerCodeResult) var ( - omitBootDeviceEventsSeen = false // a EV_OMIT_BOOT_DEVICE_EVENTS event has been seen expectingTransitionToOSPresent = false // The next events in PCR4 are expected to be the transition to OS-present - seenOSComponentLaunches = 0 // The number of EV_EFI_BOOT_SERVICES_APPLICATION events associated with OS component launches we've seen + seenOSLaunch = false // Whether we've seen the EV_EFI_BOOT_SERVICES_APPLICATION event for the initial OS loader ) phaseTracker := newTcgLogPhaseTracker() @@ -127,15 +105,23 @@ NextEvent: } switch phase { - case tcglogPhaseFirmwareLaunch, tcglogPhasePreOSThirdPartyDispatch, tcglogPhasePreOSThirdPartyDispatchUnterminated: + case tcglogPhaseFirmwareLaunch: if ev.PCRIndex != internal_efi.BootManagerCodePCR { // Not PCR4 continue NextEvent } - - // Make sure the event data is valid - if err, isErr := ev.Data.(error); isErr { - return nil, fmt.Errorf("invalid %v event data: %w", ev.EventType, err) + switch ev.EventType { + case tcglog.EventTypeOmitBootDeviceEvents: + // ok + default: + // We're not expecting any other event types during the pre-OS phase. + // TODO: Permit vendor types here, with changes to efi/fw_load_handler.go + return nil, fmt.Errorf("unexpected pre-OS event type %v", ev.EventType) + } + case tcglogPhasePreOSThirdPartyDispatch: + if ev.PCRIndex != internal_efi.BootManagerCodePCR { + // Not PCR4 + continue NextEvent } if expectingTransitionToOSPresent { @@ -145,12 +131,7 @@ NextEvent: switch ev.EventType { case tcglog.EventTypeOmitBootDeviceEvents: - // The digest is the tagged hash of the event data, but we don't bother verifying - // that because we just copy this event into the profile if it's present. - if omitBootDeviceEventsSeen { - return nil, errors.New("already seen a EV_OMIT_BOOT_DEVICE_EVENTS event") - } - omitBootDeviceEventsSeen = true + // ok case tcglog.EventTypeEFIAction: // ok, although 1.05 of the TCG PFP spec is a bit ambiguous here, section 8.2.4 says // the event associated with the first boot attempt, if it is measured, occurs before @@ -166,13 +147,6 @@ NextEvent: // verifying this because we just copy the events into the profile. if ev.Data == tcglog.EFICallingEFIApplicationEvent { // This is the signal from BDS that we're about to hand over to the OS. - if phase == tcglogPhaseFirmwareLaunch { - return nil, fmt.Errorf("unexpected EV_EFI_ACTION event %q (before secure boot config was measured)", ev.Data) - } - if omitBootDeviceEventsSeen { - return nil, fmt.Errorf("unexpected EV_EFI_ACTION event %q (because of earlier EV_OMIT_BOOT_DEVICE_EVENTS event)", ev.Data) - } - // The next event we're expecting is the pre-OS to OS-present transition. // // TODO(chrisccoulson): The TCG PFP spec 1.06 r49 expects there to be a @@ -200,24 +174,29 @@ NextEvent: // device path, if it's reachable from the OS. Although this also suffers from a similar // variation of the issue described above - that path could have been updated between // booting and now. - data := ev.Data.(*tcglog.EFIImageLoadEvent) // this is safe as we already checked that the data is valid. - if phase == tcglogPhaseFirmwareLaunch { - // Application launches before the secure boot configuration has been measured is a bug. - return nil, fmt.Errorf("encountered pre-OS EV_EFI_BOOT_SERVICES_APPLICATION event for %v before secure boot configuration has been measured", data.DevicePath) + data, ok := ev.Data.(*tcglog.EFIImageLoadEvent) + if !ok { + // The data resulting from decode errors are guaranteed to implement the error interface + return nil, fmt.Errorf("invalid %v event data: %w", ev.EventType, ev.Data.(error)) } - switch isAbsolute, err := internal_efi.IsAbsoluteAgentLaunch(ev); { + switch isFwVol, err := internal_efi.IsLaunchedFromFirmwareVolume(ev); { case err != nil: - return nil, fmt.Errorf("cannot determine if pre-OS EV_EFI_BOOT_SERVICES_APPLICATION event for %v is associated with Absolute: %w", data.DevicePath, err) - case isAbsolute && result.HasAbsolute: - return nil, errors.New("encountered more than one EV_EFI_BOOT_SERVICES_APPLICATION event associated with Absolute") - case isAbsolute: - result.HasAbsolute = true + return nil, fmt.Errorf("cannot determine if pre-OS EV_EFI_BOOT_SERVICES_APPLICATION event for %v is launched from firmware volume: %w", data.DevicePath, err) + case isFwVol: + // Consider anything loaded from SPI flash to not be a sysprep application. Check if it is Absolute. + switch isAbsolute, err := internal_efi.IsAbsoluteAgentLaunch(ev); { + case err != nil: + return nil, fmt.Errorf("cannot determine if pre-OS EV_EFI_BOOT_SERVICES_APPLICATION event for %v is associated with Absolute: %w", data.DevicePath, err) + case isAbsolute: + result.HasAbsolute = true + } case len(sysprepOpts) == 0: - // We are not expecting any sysprep applications. + // Not a launch from SPI flash and we are not expecting any sysprep applications. return nil, fmt.Errorf("encountered pre-OS EV_EFI_BOOT_SERVICES_APPLICATION event for %v when no sysprep applications are expected", data.DevicePath) default: + // This is a sysprep application. for { if len(sysprepOpts) == 0 { return nil, fmt.Errorf("encountered unexpected pre-OS EV_EFI_BOOT_SERVICES_APPLICATION event for %v", data.DevicePath) @@ -246,6 +225,7 @@ NextEvent: } default: // We're not expecting any other event types during the pre-OS phase. + // TODO: Permit vendor types here, with changes to efi/fw_load_handler.go return nil, fmt.Errorf("unexpected pre-OS event type %v", ev.EventType) } case tcglogPhaseOSPresent: @@ -256,7 +236,7 @@ NextEvent: if ev.EventType != tcglog.EventTypeEFIBootServicesApplication { // Only care about EV_EFI_BOOT_SERVICES_APPLICATION events for checking - if seenOSComponentLaunches == 0 { + if !seenOSLaunch { // The only events we're expecting in OS-present for now is EV_EFI_BOOT_SERVICES_APPLICATION. return nil, fmt.Errorf("unexpected OS-present log event type %v (expected EV_EFI_BOOT_SERVICES_APPLICATION)", ev.EventType) } @@ -265,44 +245,27 @@ NextEvent: continue NextEvent } - switch seenOSComponentLaunches { - case 0: - // Check if this launch is associated with the EFI_LOAD_OPTION associated with - // the current boot. This will fail if the data associated with the event is invalid. - isBootOptLaunch, err := isLaunchedFromLoadOption(ev, bootOpt) - if err != nil { - return nil, fmt.Errorf("cannot determine if OS-present EV_EFI_BOOT_SERVICES_APPLICATION event is associated with the current boot load option: %w", err) + if !seenOSLaunch { + // If we haven't seen the EV_EFI_BOOT_SERVICES_APPLICATION event for the OS initial + // loader yet, check whether this event is associated with Absolute and permit it if + // it is. This handles the case where some firmware implementations measure this as + // part of OS-present. As this event is just copied into the profile, we don't need + // to do any other verification of this event. + data, ok := ev.Data.(*tcglog.EFIImageLoadEvent) + if !ok { + // The data resulting from decode errors are guaranteed to implement the error interface + return nil, fmt.Errorf("invalid %v event data: %w", ev.EventType, ev.Data.(error)) } - if isBootOptLaunch { - // We have the EV_EFI_BOOT_SERVICES_APPLICATION event associated with the IBL launch. - seenOSComponentLaunches += 1 - } else { - // We have an EV_EFI_BOOT_SERVICES_APPLICATION that didn't come from the load option - // associated with the current boot. - // Test to see if it's part of Absolute. If it is, that's fine - we copy this into - // the profile, so we don't need to do any other verification of it and we don't have - // anything to verify the Authenticode digest against anyway. We have a device path, - // but not one that we're able to read back from. - // - // If this isn't Absolute, we bail with an error. We don't support anything else being - // loaded here, and ideally Absolute will be turned off as well. - - data := ev.Data.(*tcglog.EFIImageLoadEvent) // this is safe, else the earlier isLaunchedFromLoadOption would have returned an error - switch isAbsolute, err := internal_efi.IsAbsoluteAgentLaunch(ev); { - case err != nil: - return nil, fmt.Errorf("cannot determine if OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for %v is associated with Absolute: %w", data.DevicePath, err) - case !isAbsolute: - return nil, fmt.Errorf("OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for %v is not associated with the current boot load option and is not Absolute", data.DevicePath) - case result.HasAbsolute: - return nil, errors.New("encountered more than one EV_EFI_BOOT_SERVICES_APPLICATION event associated with Absolute") - default: - result.HasAbsolute = true - } + switch isAbsolute, err := internal_efi.IsAbsoluteAgentLaunch(ev); { + case err != nil: + return nil, fmt.Errorf("cannot determine if OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for %v is associated with Absolute: %w", data.DevicePath, err) + case isAbsolute: + result.HasAbsolute = true continue NextEvent // We want to start a new iteration, else we'll consume one of the loadImages below. + default: + seenOSLaunch = true } - default: - seenOSComponentLaunches += 1 } if len(loadImages) == 0 { @@ -340,7 +303,7 @@ NextEvent: } if !bytes.Equal(h.Sum(nil), ev.Digests[pcrAlg]) { // Still no digest match - return fmt.Errorf("log contains unexpected EV_EFI_BOOT_SERVICES_APPLICATION digest for OS-present application %s (calculated PE digest: %#x, log value: %#x) - were the correct boot images supplied?", + return fmt.Errorf("log contains unexpected EV_EFI_BOOT_SERVICES_APPLICATION digest for OS-present application %s (calculated PE digest: %#x, log value: %#x)", image, digest, ev.Digests[pcrAlg]) } // We have a digest match, so something loaded this component outside of the LoadImage API and used the diff --git a/efi/preinstall/check_pcr4_test.go b/efi/preinstall/check_pcr4_test.go index 8ba5cff8..6a380a43 100644 --- a/efi/preinstall/check_pcr4_test.go +++ b/efi/preinstall/check_pcr4_test.go @@ -22,7 +22,6 @@ package preinstall_test import ( "context" "crypto" - "errors" "io" efi "github.com/canonical/go-efilib" @@ -72,10 +71,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodSHA256(c *C) { // Test good result with SHA-256 err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -93,10 +89,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodSHA384(c *C) { // Test good result with SHA-384, when log also contains SHA-256 err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256, tpm2.HashAlgorithmSHA384}})), ), pcrAlg: tpm2.HashAlgorithmSHA384, @@ -115,9 +108,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodWithSysprepApp(c *C) err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - {Name: "SysPrepOrder", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1, 0x0}}, + {Name: "SysPrepOrder", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1, 0x0}}, {Name: "SysPrep0001", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: efitest.MakeVarPayload(c, &efi.LoadOption{ Attributes: efi.LoadOptionActive | efi.LoadOptionCategoryApp, Description: "Mock sysprep app", @@ -183,9 +174,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodWithSysprepAppSHA384 err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - {Name: "SysPrepOrder", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1, 0x0}}, + {Name: "SysPrepOrder", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1, 0x0}}, {Name: "SysPrep0001", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: efitest.MakeVarPayload(c, &efi.LoadOption{ Attributes: efi.LoadOptionActive | efi.LoadOptionCategoryApp, Description: "Mock sysprep app", @@ -250,10 +239,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodWithAbsolutePreOS(c // Test good result with Absolute running as part of pre-OS err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludePreOSFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), @@ -274,10 +260,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodWithAbsoluteOSPresen // Test good result with Absolute running as part of OS-present before shim err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeOSPresentFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), @@ -294,14 +277,71 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodWithAbsoluteOSPresen c.Check(err, IsNil) } +func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodHPSystem(c *C) { + // Test good results with a log that comes from a HP system, which contains + // lots of additional EV_EFI_BOOT_SERVICES_APPLICATION events in PCR4. + log := efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}}) + // XXX: It would be good to have this sort of thing in internal/efitest + var eventsCopy []*tcglog.Event + for _, ev := range log.Events { + eventsCopy = append(eventsCopy, ev) + + if ev.PCRIndex == internal_efi.SecureBootPolicyPCR && ev.EventType == tcglog.EventTypeSeparator { + // Add HP events to PCR4 + addEvent := func(guid efi.GUID) { + eventsCopy = append(eventsCopy, &tcglog.Event{ + PCRIndex: internal_efi.BootManagerCodePCR, + EventType: tcglog.EventTypeEFIBootServicesApplication, + Digests: tcglog.DigestMap{ + tpm2.HashAlgorithmSHA256: make(tpm2.Digest, 32), + }, + Data: &tcglog.EFIImageLoadEvent{ + DevicePath: efi.DevicePath{ + efi.MediaFvDevicePathNode(efi.MakeGUID(0xcdbb7b35, 0x6833, 0x4ed6, 0x9ab2, [...]uint8{0x57, 0xd2, 0xac, 0xdd, 0xf6, 0xf0})), + efi.MediaFvFileDevicePathNode(guid), + }, + }, + }) + } + + addEvent(efi.MakeGUID(0xb1dac9bd, 0x132e, 0x4f9f, 0xb2ca, [...]byte{0x14, 0xfd, 0xc6, 0x5b, 0xd6, 0x61})) + addEvent(efi.MakeGUID(0x9d8243e8, 0x8381, 0x453d, 0xaceb, [...]byte{0xc3, 0x50, 0xee, 0x77, 0x57, 0xca})) // StartupMenuApp + addEvent(efi.MakeGUID(0x96d0626b, 0x71d5, 0x4001, 0xac71, [...]byte{0xe0, 0x5B, 0x10, 0x3b, 0xd4, 0x5d})) // F10App + addEvent(efi.MakeGUID(0xeb6b71c3, 0x0659, 0x4a8a, 0x8ae1, [...]byte{0xda, 0xd2, 0xf5, 0x19, 0x2c, 0x62})) // BootMenuApp + addEvent(efi.MakeGUID(0xaf8898c9, 0x9b92, 0x4556, 0x8318, [...]byte{0xe4, 0x25, 0xc9, 0xde, 0x0a, 0x65})) // F2App + addEvent(efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d})) // AbsoluteAbtInstaller + addEvent(efi.MakeGUID(0xc988bded, 0x6977, 0x464d, 0xb714, [...]byte{0xe6, 0x1d, 0xeb, 0xd2, 0xde, 0x97})) + addEvent(efi.MakeGUID(0x4ea97c46, 0x7491, 0x4dfd, 0xb542, [...]byte{0x74, 0x70, 0x10, 0xf3, 0xce, 0x7f})) // HPNetworkTransferWorker + addEvent(efi.MakeGUID(0x8224846e, 0x6d50, 0x453d, 0xb7c2, [...]byte{0x3e, 0x7e, 0xd7, 0xd0, 0x0d, 0x52})) + addEvent(efi.MakeGUID(0xf02313f7, 0x581f, 0x4f31, 0xb09c, [...]byte{0xc1, 0xba, 0x2f, 0xc5, 0x87, 0x13})) // HPDriveWipe + + // HP systems seem to measure this twice + addEvent(efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d})) // AbsoluteAbtInstaller + } + } + log.Events = eventsCopy + + err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithMockVars(efitest.MockVars{}), + efitest.WithLog(log), + ), + pcrAlg: tpm2.HashAlgorithmSHA256, + images: []secboot_efi.Image{ + &mockImage{contents: []byte("mock shim executable"), digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7")}, + &mockImage{contents: []byte("mock grub executable"), digest: testutil.DecodeHexString(c, "d5a9780e9f6a43c2e53fe9fda547be77f7783f31aea8013783242b040ff21dc0")}, + &mockImage{contents: []byte("mock kernel executable"), digest: testutil.DecodeHexString(c, "2ddfbd91fa1698b0d133c38ba90dbba76c9e08371ff83d03b5fb4c2e56d7e81f")}, + }, + expectedResult: &BootManagerCodeResult{HasAbsolute: true}, + }) + c.Check(err, IsNil) +} + func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodWithoutCallingEFIApplicationEvent(c *C) { // Test good result with log without EV_EFI_ACTION "Calling EFI Application from Boot Option" event err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, NoCallingEFIApplicationEvent: true, @@ -340,10 +380,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodSkipOtherEventTypesI err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(log), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -357,71 +394,12 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsGoodSkipOtherEventTypesI c.Check(err, IsNil) } -func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadBootOptionSupport(c *C) { - // Test error result because of invalid BootOptionSupport - err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Err: efi.ErrVarDeviceError}, - }), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - ), - pcrAlg: tpm2.HashAlgorithmSHA256, - }) - c.Check(err, ErrorMatches, `cannot obtain boot option support: variable access failed because of a hardware error`) - c.Check(errors.Is(err, efi.ErrVarDeviceError), testutil.IsTrue) -} - -func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsMissingBootOptionSupport(c *C) { - // Test error result because of invalid BootOptionSupport - err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{}), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - ), - pcrAlg: tpm2.HashAlgorithmSHA256, - }) - c.Check(err, ErrorMatches, `cannot obtain boot option support: variable doesn't exist`) -} - -func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadBootCurrent(c *C) { - // Test error result because of bad BootCurrent - err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - ), - pcrAlg: tpm2.HashAlgorithmSHA256, - }) - c.Check(err, ErrorMatches, `cannot read BootCurrent variable: BootCurrent variable contents has the wrong size \(1 bytes\)`) -} - -func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadLoadOption(c *C) { - // Test error result because BootCurrent value doesn't match entry in log - err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x5, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - ), - pcrAlg: tpm2.HashAlgorithmSHA256, - }) - c.Check(err, ErrorMatches, `cannot read current Boot0005 load option from log: cannot find specified boot option`) -} - func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadSysPrepVariables(c *C) { // Test error case where there is an invalid SysPrepOrder variable. err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - {Name: "SysPrepOrder", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1, 0x0, 0x2}}, + {Name: "SysPrepOrder", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1, 0x0, 0x2}}, }), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), ), @@ -434,10 +412,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadNoImages(c *C) { // Test error result because no load images were supplied. err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -445,32 +420,11 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadNoImages(c *C) { c.Check(err, ErrorMatches, `cannot verify correctness of EV_EFI_BOOT_SERVICES_APPLICATION event digest for \\PciRoot\(0x0\)\\Pci\(0x1d,0x0\)\\Pci\(0x0,0x0\)\\NVMe\(0x1,00-00-00-00-00-00-00-00\)\\HD\(1,GPT,66de947b-fdb2-4525-b752-30d66bb2b960\)\\\\EFI\\ubuntu\\shimx64.efi: not enough images supplied`) } -func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadUnrecognizedInitialLaunch(c *C) { - // Test error result because IBL launch can't be identified - it doesn't match boot entry in log that BootCurrent points to - err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - ), - pcrAlg: tpm2.HashAlgorithmSHA256, - images: []secboot_efi.Image{ - &mockImage{contents: []byte("mock shim executable"), digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7")}, - }, - }) - c.Check(err, ErrorMatches, `OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for \\PciRoot\(0x0\)\\Pci\(0x1d,0x0\)\\Pci\(0x0,0x0\)\\NVMe\(0x1,00-00-00-00-00-00-00-00\)\\HD\(1,GPT,66de947b-fdb2-4525-b752-30d66bb2b960\)\\\\EFI\\ubuntu\\shimx64\.efi is not associated with the current boot load option and is not Absolute`) -} - func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadMissingImage(c *C) { // Test error result because it wasn't possible to verify Authenticode digest for SBL launch (in our case, grub), as it wasn't supplied err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -486,10 +440,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadSBLMeasuredFlatFileDi // case of shim -> grub, might mean that EFI_TCG2_PROTOCOL is missing from the firmware. err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -508,10 +459,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadProvidedBootImages(c // Test error result because the SBL image (in our case grub) has a digest that doesn't match what's in the log err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -521,49 +469,14 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadProvidedBootImages(c &mockImage{contents: []byte("foo"), digest: testutil.DecodeHexString(c, "80fd5a9364df79953369758a419f7cb167201cf580160b91f837aad455c55bcd")}, }, }) - c.Check(err, ErrorMatches, `log contains unexpected EV_EFI_BOOT_SERVICES_APPLICATION digest for OS-present application mock image \(calculated PE digest: 0x80fd5a9364df79953369758a419f7cb167201cf580160b91f837aad455c55bcd, log value: 0xd5a9780e9f6a43c2e53fe9fda547be77f7783f31aea8013783242b040ff21dc0\) - were the correct boot images supplied\?`) -} - -func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadWithUnsupportedSysprepApp(c *C) { - // Test error result because a sysprep app was detected when BootOptionSupport indicates they aren't supported - err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x03, 0x03, 0x00, 0x00}}, - {Name: "SysPrepOrder", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1, 0x0}}, - {Name: "SysPrep0001", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: efitest.MakeVarPayload(c, &efi.LoadOption{ - Attributes: efi.LoadOptionActive | efi.LoadOptionCategoryApp, - Description: "Mock sysprep app", - FilePath: efi.DevicePath{ - &efi.HardDriveDevicePathNode{ - PartitionNumber: 1, - PartitionStart: 0x800, - PartitionSize: 0x100000, - Signature: efi.GUIDHardDriveSignature(efi.MakeGUID(0x66de947b, 0xfdb2, 0x4525, 0xb752, [...]uint8{0x30, 0xd6, 0x6b, 0xb2, 0xb9, 0x60})), - MBRType: efi.GPT}, - efi.FilePathDevicePathNode("\\EFI\\Dell\\sysprep.efi"), - }, - })}, - }), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ - Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - IncludeSysPrepAppLaunch: true, - })), - ), - pcrAlg: tpm2.HashAlgorithmSHA256, - }) - c.Check(err, ErrorMatches, `encountered pre-OS EV_EFI_BOOT_SERVICES_APPLICATION event for \\PciRoot\(0x0\)\\Pci\(0x1d,0x0\)\\Pci\(0x0,0x0\)\\NVMe\(0x1,00-00-00-00-00-00-00-00\)\\HD\(1,GPT,66de947b-fdb2-4525-b752-30d66bb2b960\)\\\\EFI\\Dell\\sysprep.efi when no sysprep applications are expected`) + c.Check(err, ErrorMatches, `log contains unexpected EV_EFI_BOOT_SERVICES_APPLICATION digest for OS-present application mock image \(calculated PE digest: 0x80fd5a9364df79953369758a419f7cb167201cf580160b91f837aad455c55bcd, log value: 0xd5a9780e9f6a43c2e53fe9fda547be77f7783f31aea8013783242b040ff21dc0\)`) } func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadWithUnexpectedSysprepApp1(c *C) { // Test error result because a sysprep app was detected when there are no corresponding SysPrep variables. err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeSysPrepAppLaunch: true, @@ -579,9 +492,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadWithUnexpectedSysprep err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - {Name: "SysPrepOrder", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1, 0x0}}, + {Name: "SysPrepOrder", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1, 0x0}}, {Name: "SysPrep0001", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: efitest.MakeVarPayload(c, &efi.LoadOption{ Attributes: efi.LoadOptionActive | efi.LoadOptionCategoryApp, Description: "Mock sysprep app", @@ -622,10 +533,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadUnexpectedTransitionT err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(log), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -657,10 +565,7 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadUnexpectedFirstOSPres err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), + efitest.WithMockVars(efitest.MockVars{}), efitest.WithLog(log), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -671,64 +576,6 @@ func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadUnexpectedFirstOSPres c.Check(err, ErrorMatches, `unexpected OS-present log event type EV_IPL \(expected EV_EFI_BOOT_SERVICES_APPLICATION\)`) } -func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadWithMultipleAbsoluteLaunches1(c *C) { - // Test error where there is an Absolute launch in both the pre-OS and OS-present phases. - err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ - Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - IncludePreOSFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), - IncludeOSPresentFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), - })), - ), - pcrAlg: tpm2.HashAlgorithmSHA256, - images: []secboot_efi.Image{ - &mockImage{contents: []byte("mock shim executable"), digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7")}, - }, - }) - c.Check(err, ErrorMatches, `encountered more than one EV_EFI_BOOT_SERVICES_APPLICATION event associated with Absolute`) -} - -func (s *pcr4Suite) TestCheckBootManagerCodeMeasurementsBadWithMultipleAbsoluteLaunches2(c *C) { - // Test error where there are 2 Absolute launches in the pre-OS phase. - log := efitest.NewLog(c, &efitest.LogOptions{ - Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - IncludePreOSFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), - }) - - var ( - copiedAbsolute bool - eventsCopy []*tcglog.Event - ) - for _, ev := range log.Events { - eventsCopy = append(eventsCopy, ev) - if ev.EventType == tcglog.EventTypeEFIBootServicesApplication && !copiedAbsolute { - eventsCopy = append(eventsCopy, ev) - copiedAbsolute = true - } - } - log.Events = eventsCopy - - err := s.testCheckBootManagerCodeMeasurements(c, &testCheckBootManagerCodeMeasurementsParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - }), - efitest.WithLog(log), - ), - pcrAlg: tpm2.HashAlgorithmSHA256, - images: []secboot_efi.Image{ - &mockImage{contents: []byte("mock shim executable"), digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7")}, - }, - }) - c.Check(err, ErrorMatches, `encountered more than one EV_EFI_BOOT_SERVICES_APPLICATION event associated with Absolute`) -} - // TODO (other error cases - some harder, some may require more customizable log generator in internal/efitest/log.go): // - Event data decode errors in pre-OS environment. // - Unexpected event types in log in pre-OS environment. diff --git a/efi/preinstall/check_pcr7.go b/efi/preinstall/check_pcr7.go index 8d64e7fc..1b67ef9c 100644 --- a/efi/preinstall/check_pcr7.go +++ b/efi/preinstall/check_pcr7.go @@ -206,7 +206,7 @@ func handleVariableAuthorityEvent(pcrAlg tpm2.HashAlgorithmId, db efi.SignatureD data, ok := ev.Data.(*tcglog.EFIVariableData) if !ok { // if decoding failed, the resulting data is guaranteed to implement error. - return efi.GUID{}, nil, fmt.Errorf("event has wong data format: %w", ev.Data.(error)) + return efi.GUID{}, nil, fmt.Errorf("event has wrong data format: %w", ev.Data.(error)) } // As we're only checking events up to the launch of the IBL, we don't expect @@ -291,6 +291,7 @@ type secureBootPolicyResultFlags int const ( secureBootIncludesWeakAlg secureBootPolicyResultFlags = 1 << iota // Weak algorithms were used during image verification. secureBootPreOSVerificationIncludesDigest // Authenticode digests were used to authenticate pre-OS components. + secureBootNoDeployedMode // Deployed mode is not enabled. ) // secureBootPolicyResult is the result of a successful call to checkSecureBootPolicyMeasurementsAndObtainAuthorities. @@ -300,49 +301,39 @@ type secureBootPolicyResult struct { } // checkSecureBootPolicyMeasurementsAndObtainAuthorities performs some checks on the secure boot policy PCR (7). - +// // The supplied context is used to attach an EFI variable backend to, for functions that read // from EFI variables. The supplied env and log arguments provide other inputs to this function. // The pcrAlg argument is the PCR bank that is chosen as the best one to use. The iblImage // corresponds to the initial boot loader image for the current boot. This is used to detect the // launch of the OS, at which checks for PCR7 end. There are some limitations of this, ie, we may // not detect LoadImage bugs that happen later on, but once the OS has loaded, it's impossible to -// tell whicj events come from firmware and which are under the control of OS components. - +// tell which events come from firmware and which are under the control of OS components. +// // This ensures that secure boot is enabled, else an error is returned, as WithSecureBootPolicyProfile // only generates profiles compatible with secure boot being enabled. - -// If the version of UEFI is >= 2.5, it also makes sure that the secure boot mode is "deployed mode". -// If the secure boot mode is "user mode", then the "AuditMode" and "DeployedMode" values are measured to PCR7, -// something that WithSecureBootPolicyProfile doesn't support today. Support for "user mode" will be added -// in the future, although the public RunChecks API will probably require a flag to opt in to supporting user -// mode, as it is the less secure mode of the 2 (see the documentation for SecureBootMode in -// github.com/canonical/go-efilib). - +// +// If the version of UEFI is >= 2.5, it also makes sure that the secure boot mode is "deployed mode". If +// not, then the result will indicate that the system is in user mode. +// // It also reads the "OsIndicationsSupported" variable to test for features that are not supported by // WithSecureBootPolicyProfile. These are timestamp revocation (which requires an extra signature database - // "dbt") and OS recovery (which requires an extra signature database -"dbr", used to control access to // OsRecoveryOrder and OsRecover#### variables). Of the 2, it's likely that we might need to add support for // timestamp revocation at some point in the future. - -// It reads the "BootCurrent" EFI variable and matches this to the EFI_LOAD_OPTION associated with the current -// boot from the TCG log - it uses the log as "BootXXXX" EFI variables can be updated at runtime and -// might be out of data when this code runs. It uses this to detect the launch of the initial boot loader, -// which might not necessarily be the first EV_EFI_BOOT_SERVICES_APPLICATION event in the OS-present -// environment in PCR4 (eg, if Absolute is active). - +// // After these checks, it iterates over the secure boot configuration in the log, making sure that the // configuration is measured in the correct order, that the event data is valid, and that the measured digest // is the tagged hash of the event data. It makes sure that the value of "SecureBoot" in the log is consistent // with the "SecureBoot" variable (which is read-only at runtime), and it verifies that all of the signature // databases are formatted correctly and can be decoded. It will return an error if any of these checks fail. - +// // If the pre-OS environment contains events other than EV_EFI_VARIABLE_DRIVER_CONFIG, it will return an error. // This can happen a firmware debugger is enabled, in which case PCR7 will begin with a EV_EFI_ACTION // "UEFI Debug Mode" event. This case is detected by earlier firmware protection checks. - +// // If not all of the expected secure boot configuration is measured, an error is returned. - +// // Once the secure boot configuration has been measured, it looks for EV_EFI_VARIABLE_AUTHORITY events in PCR7, // until it detects the launch of the initial boot loader. It verifies that each of these come from db, and // if the log is in the OS-present environment, it ensures that the measured digest is the tagged hash of the @@ -357,7 +348,7 @@ type secureBootPolicyResult struct { // reflect the new components each time. If the digest being matched is SHA-1, it sets the flag in the return // value indicating a weak algorithm. If any of these checks fail, an error is returned. If an event type // other than EV_EFI_VARIABLE_AUTHORITY is detected, an error is returned. - +// // Upon detecting the launch of the initial boot loader in PCR4, it extracts the authenticode signatures from // the supplied image, and matches these to a previously measured CA. If no match is found, an error is returned. // If a match is found, it ensures that the signing certificate has an RSA public key with a modulus that is at @@ -389,23 +380,18 @@ func checkSecureBootPolicyMeasurementsAndObtainAuthorities(ctx context.Context, return nil, ErrNoSecureBoot } + result = new(secureBootPolicyResult) + // On UEFI 2.5 and later, we require that deployed mode is enabled, because if it's disabled, it // changes the sequence of events for PCR7 (the DeployedMode and AuditMode global variables are // also measured). - // TODO(chrisccoulson): relax this later on in the profile generation to support user mode, but - // maybe add a new flag (RequireDeployedMode or AllowUserMode) to RunChecks. We should be - // able to generate policies for user mode as well - it shouldn't be necessary to enable deployed - // mode as long as secure boot is enabled, particularly because the only paths back from deployed - // mode are platform specific (ie, it could be a one way operation!) if efi.IsDeployedModeSupported(varCtx) { secureBootMode, err := efi.ComputeSecureBootMode(varCtx) if err != nil { return nil, fmt.Errorf("cannot compute secure boot mode: %w", err) } if secureBootMode != efi.DeployedMode { - // WithSecureBootPolicyProfile() doesn't generate working profiles if deployed mode is not - // enabled on UEFI >= 2.5. - return nil, ErrNoDeployedMode + result.Flags |= secureBootNoDeployedMode } } @@ -430,13 +416,6 @@ func checkSecureBootPolicyMeasurementsAndObtainAuthorities(ctx context.Context, // TODO(chrisccoulson): Not sure if there's any indication that we might get SPDM related measurements, // which our profile generation for PCR7 currently doesn't support. - // Obtain the load option for the current boot. We need this so that we can identify the launch of - // the initial boot loader later on. - bootOpt, err := readCurrentBootLoadOptionFromLog(varCtx, log) - if err != nil { - return nil, err - } - // Make sure that the secure boot config in the log is measured in the // expected order, else WithSecureBootPolicyProfile() will generate an invalid policy, // because we hard code the order. The order here is what we expect to see. @@ -449,12 +428,10 @@ func checkSecureBootPolicyMeasurementsAndObtainAuthorities(ctx context.Context, // TODO: Add optional dbt / SPDM in the future. } - result = new(secureBootPolicyResult) var ( - db efi.SignatureDatabase // The authorized signature database from the TCG log. - measuredSignatures tpm2.DigestList // The verification event digests measured by the firmware - seenOSPresentVerification bool // Whether we've seen a verification event in the OS-present phase - seenIBLLoadEvent bool // Whether we've seen the launch event for the OS initial boot loader + db efi.SignatureDatabase // The authorized signature database from the TCG log. + measuredSignatures tpm2.DigestList // The verification event digests measured by the firmware + seenIBLLoadEvent bool // Whether we've seen the launch event for the OS initial boot loader ) phaseTracker := newTcgLogPhaseTracker() @@ -466,12 +443,56 @@ NextEvent: } switch phase { - case tcglogPhaseMeasuringSecureBootConfig: + case tcglogPhaseFirmwareLaunch: if ev.PCRIndex != internal_efi.SecureBootPolicyPCR { // Not PCR7 continue NextEvent } + switch ev.EventType { + case tcglog.EventTypeEFIAction: + // An EV_EFI_ACTION event measured to PCR7 may indicate some degraded condition + // that weakens device security. 2 known ones are: + // - "UEFI Debug Mode", which indicates the presence of a debugging endpoint. + // The TCG PC Client PFP spec says this goes before the secure boot config + // is measured. + // - "DMA Protection Disabled" to indicate that pre-boot DMA protection was + // disabled. This event isn't formally documented anywhere - it is mentioned + // in some tianocore documentation, although EDK2 doesn't have a reference + // implementation. This event can be permitted, which means that we can + // generate a policy that includes it. However, the tianocore documentation + // doesn't specify event ordering, so we need to accommodate any possible + // ordering of events. + // + // The presence of an EV_EFI_ACTION event other than "DMA Protection Disabled" + // will result in WithSecureBootPolicyProfile() creating an invalid policy, + // because it generally doesn't emit these measurements. Just return an error + // here to prevent the use of WithSecureBootPolicyProfile() unless it is a + // "DMA Protection Disabled" event and it is permitted. + // + // Note that "UEFI Debug Mode" and "DMA Protection Disabled" events are both + // caught by the host security checks, which run before this. + if permitDMAProtectionDisabledEvent && (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 + // profile. We don't need to do anything else here other than make sure + // this event only appears once. + permitDMAProtectionDisabledEvent = false // Don't allow this more than once. + continue NextEvent + } + fallthrough + default: + // Anything that isn't EV_EFI_ACTION ends up here. + 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. switch ev.EventType { case tcglog.EventTypeEFIVariableDriverConfig: if len(configs) == 0 { @@ -523,34 +544,29 @@ NextEvent: db = sigDb } case tcglog.EventTypeEFIAction: - // An EV_EFI_ACTION events with the string "UEFI Debug Mode" appears at the - // start of the log if a debugging endpoint is enabled. It's also possible that - // EV_EFI_ACTION events are used for other conditions in PCR7 that weaken device - // security (eg, the "DMA Protection Disabled" event). - // - // In general, it's not normal to see EV_EFI_ACTION events and these indicate some - // sort of abnormal condition that has a detrimental effect on device security. - // WithSecureBootPolicyProfile() will generate an invalid policy in this case because, - // with some exceptions, it doesn't emit them. - // - // Just return an error here to prevent the use of WithSecureBootPolicyProfile(). The - // "UEFI Debug Mode" and "DMA Protection Disabled" cases are already picked up by the - // firmware protection checks, so we don't need any special handling here. - // - // We do permit the "DMA Protection Disabled" case if required. In this case, - // WithSecureBootPolicyProfile() needs a separate option. - if permitDMAProtectionDisabledEvent && (bytes.Equal(ev.Data.Bytes(), []byte(tcglog.DMAProtectionDisabled)) || + // 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. 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 so we can skip it here. - // We'll emit a flag in the results which is picked up by the code in profile.go - // to add an option to permit this with WithSecureBootPolicyProfile(). + // 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 + // profile. We don't need to do anything else here other than make sure + // this event only appears once. permitDMAProtectionDisabledEvent = false // Don't allow this more than once. continue 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 { @@ -599,30 +615,28 @@ NextEvent: case tcglog.EventTypeSeparator: // ok case tcglog.EventTypeEFIAction: - // In general, it's not normal to see EV_EFI_ACTION events and these indicate some - // sort of abnormal condition that has a detrimental effect on device security. - // WithSecureBootPolicyProfile() will generate an invalid policy in this case because, - // with some exceptions, it doesn't emit them. - // - // Just return an error here to prevent the use of WithSecureBootPolicyProfile(). The - // "UEFI Debug Mode" and "DMA Protection Disabled" cases are already picked up by the - // firmware protection checks, so we don't need any special handling here. - // - // We do permit the "DMA Protection Disabled" case if required. In this case, - // WithSecureBootPolicyProfile() needs a separate option. Some firmware measures - // this after the EV_SEPARATOR in PCR7 but part of the pre-OS environment. + // 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)) || bytes.Equal(ev.Data.Bytes(), append([]byte(tcglog.DMAProtectionDisabled), 0x00))) { - // This event is detected by the host security checks so we can skip it here. - // We'll emit a flag in the results which is picked up by the code in profile.go - // to add an option to permit this with WithSecureBootPolicyProfile(). + // 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 + // profile. We don't need to do anything else here other than make sure + // this event only appears once. permitDMAProtectionDisabledEvent = false // Don't allow this more than once. continue 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 { @@ -639,28 +653,41 @@ NextEvent: // and we haven't seen the event for the IBL yet. We stop once we see this // because at this point, the rest of the measurements in this PCR are under // the control of the OS. - yes, err := isLaunchedFromLoadOption(ev, bootOpt) - if err != nil { - return nil, fmt.Errorf("cannot determine if OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for is associated with the current boot load option: %w", err) + data, ok := ev.Data.(*tcglog.EFIImageLoadEvent) + if !ok { + // The data resulting from decode errors are guaranteed to implement the error interface + return nil, fmt.Errorf("invalid event data for EV_EFI_BOOT_SERVICES_APPLICATION event: %w", ev.Data.(error)) } - if !yes { - // This is not the launch event for the initial boot loader - ignore it. - if seenOSPresentVerification { - // The way we build profiles for PCR7 requires that any verification - // events in PCR7 during OS-present to be associated with the OS. If - // we've seen a verification event and we're in OS-present, then the - // next expected event is the load event for the initial boot loader. - // If we get verification events for Absolute (which is loaded from - // Flash and is normally verified earlier on with the verification of - // other Flash volumes), then we'll generate a potentially invalid - // profile for PCR7, because we don't copy events from the log once - // we're in OS-present. - return nil, fmt.Errorf("unexpected EV_EFI_BOOT_SERVICES_APPLICATION event for %v after already seeing a verification event during the OS-present environment. "+ - "This event should be for the initial boot loader", ev.Data.(*tcglog.EFIImageLoadEvent).DevicePath) - } + + switch isAbsolute, err := internal_efi.IsAbsoluteAgentLaunch(ev); { + case err != nil: + return nil, fmt.Errorf("cannot determine if OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for %v is associated with Absolute: %w", data.DevicePath, err) + case isAbsolute: + // skip this one continue NextEvent + default: + isIBLLoadEvent, err := func() (bool, error) { + r, err := iblImage.Open() + if err != nil { + return false, fmt.Errorf("cannot open initial boot loader image: %w", err) + } + defer r.Close() + + digest, err := efiComputePeImageDigest(pcrAlg.GetHash(), r, r.Size()) + if err != nil { + return false, fmt.Errorf("cannot compute Authenticode digest of initial boot loader image: %w", err) + } + return bytes.Equal(digest, ev.Digests[pcrAlg]), nil + }() + switch { + case err != nil: + return nil, fmt.Errorf("cannot determine if OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for %v is associated with the initial boot loader image: %w", data.DevicePath, err) + case !isIBLLoadEvent: + return nil, fmt.Errorf("OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for %v is not associated with the initial boot loader image", data.DevicePath) + } } + // We assume this is the IBL for the OS. Obtain signatures from binary // This is the IBL for the OS. Obtain signatures from binary seenIBLLoadEvent = true signer, err := extractSignerWithTrustAnchorFromImage(result.UsedAuthorities, iblImage) @@ -671,7 +698,7 @@ NextEvent: return nil, fmt.Errorf("cannot determine if OS initial boot loader was verified by any X.509 certificate measured by any EV_EFI_VARIABLE_AUTHORITY event: %w", err) } - ok, err := checkX509CertificatePublicKeyStrength(signer) + ok, err = checkX509CertificatePublicKeyStrength(signer) if err != nil { return nil, fmt.Errorf("cannot determine public key strength of initial OS boot loader signer: %w", err) } @@ -702,7 +729,6 @@ NextEvent: } measuredSignatures = append(measuredSignatures, ev.Digests[pcrAlg]) - seenOSPresentVerification = true ok, err := checkSignatureDataStrength(eslType, esdData) if err != nil { return nil, fmt.Errorf("cannot check strength of EFI_SIGNATURE_DATA associated with EV_EFI_VARIABLE_AUTHORITY event in OS-present phase: %w", err) @@ -725,12 +751,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) - } - case tcglogPhasePreOSThirdPartyDispatchUnterminated: - if ev.PCRIndex == internal_efi.SecureBootPolicyPCR { - return nil, fmt.Errorf("unexpected %v event in PCR7 after measuring config but before transitioning to OS-present", ev.EventType) + // 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) + } } } } diff --git a/efi/preinstall/check_pcr7_test.go b/efi/preinstall/check_pcr7_test.go index c2f8d83b..425d87b9 100644 --- a/efi/preinstall/check_pcr7_test.go +++ b/efi/preinstall/check_pcr7_test.go @@ -83,6 +83,15 @@ func (s *pcr7Suite) testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c }) defer restore() + restore = MockEfiComputePeImageDigest(func(alg crypto.Hash, r io.ReaderAt, sz int64) ([]byte, error) { + c.Check(alg, Equals, params.pcrAlg.GetHash()) + c.Assert(r, testutil.ConvertibleTo, &mockImageReader{}) + imageReader := r.(*mockImageReader) + c.Check(sz, Equals, int64(len(imageReader.contents))) + return imageReader.digest, nil + }) + defer restore() + log, err := params.env.ReadEventLog() c.Assert(err, IsNil) @@ -103,8 +112,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -116,6 +123,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, expectedFlags: SecureBootPolicyResultFlags(0), expectedUsedAuthorities: []*X509CertificateID{ @@ -130,8 +138,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -143,6 +149,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "030ac3c913dab858f1d69239115545035cff671d6229f95577bb0ffbd827b35abaf6af6bfd223e04ecc9b60a9803642d"), }, expectedFlags: SecureBootPolicyResultFlags(0), expectedUsedAuthorities: []*X509CertificateID{ @@ -157,8 +164,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -173,6 +178,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, expectedFlags: SecureBootPolicyResultFlags(0), expectedUsedAuthorities: []*X509CertificateID{ @@ -187,8 +193,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -204,6 +208,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, expectedFlags: SecureBootPreOSVerificationIncludesDigest, expectedUsedAuthorities: []*X509CertificateID{ @@ -218,8 +223,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -235,6 +238,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, expectedFlags: SecureBootIncludesWeakAlg | SecureBootPreOSVerificationIncludesDigest, expectedUsedAuthorities: []*X509CertificateID{ @@ -244,13 +248,70 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo c.Check(err, IsNil) } +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoodSecureBootSeparatorAfterPreOS(c *C) { + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + SecureBootSeparatorOrder: efitest.SecureBootSeparatorAfterPreOS, + })), + ), + pcrAlg: tpm2.HashAlgorithmSHA256, + iblImage: &mockImage{ + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + expectedFlags: SecureBootPolicyResultFlags(0), + expectedUsedAuthorities: []*X509CertificateID{ + NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert)), + }, + }) + c.Check(err, IsNil) +} + +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoodWithDriverLaunchAndSecureBootSeparatorAfterPreOS(c *C) { + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + SecureBootSeparatorOrder: efitest.SecureBootSeparatorAfterPreOS, + IncludeDriverLaunch: true, + })), + ), + pcrAlg: tpm2.HashAlgorithmSHA256, + iblImage: &mockImage{ + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + expectedFlags: SecureBootPolicyResultFlags(0), + expectedUsedAuthorities: []*X509CertificateID{ + NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert)), + }, + }) + c.Check(err, IsNil) +} + func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoodWithSysPrepLaunch(c *C) { err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -265,6 +326,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, expectedFlags: SecureBootPolicyResultFlags(0), expectedUsedAuthorities: []*X509CertificateID{ @@ -279,8 +341,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -295,6 +355,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, expectedFlags: SecureBootPolicyResultFlags(0), expectedUsedAuthorities: []*X509CertificateID{ @@ -308,8 +369,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), @@ -320,6 +379,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoo signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, expectedFlags: SecureBootPolicyResultFlags(0), expectedUsedAuthorities: []*X509CertificateID{ @@ -334,8 +394,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesWit env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -350,6 +408,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesWit signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, permitDMAProtectionDisabled: true, expectedFlags: SecureBootPolicyResultFlags(0), @@ -360,20 +419,18 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesWit c.Check(err, IsNil) } -func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesWithPermittedDMAProtectionDisabledDifferentLocation(c *C) { +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesWithPermittedDMAProtectionDisabledNullTerminated(c *C) { err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - DMAProtection: efitest.DMAProtectionDisabled | efitest.DMAProtectionDisabledEventOrderAfterSeparator, + DMAProtection: efitest.DMAProtectionDisabled | efitest.DMAProtectionDisabledEventNullTerminated, })), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -381,6 +438,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesWit signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, permitDMAProtectionDisabled: true, expectedFlags: SecureBootPolicyResultFlags(0), @@ -391,20 +449,18 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesWit c.Check(err, IsNil) } -func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadNoSecureBoot(c *C) { +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesWithPermittedDMAProtectionDisabledDifferentLocation(c *C) { err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - }.SetSecureBoot(false).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ - Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - SecureBootDisabled: true, + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + DMAProtection: efitest.DMAProtectionDisabled | efitest.DMAProtectionDisabledEventOrderAfterSeparator, })), ), pcrAlg: tpm2.HashAlgorithmSHA256, @@ -412,18 +468,22 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + permitDMAProtectionDisabled: true, + expectedFlags: SecureBootPolicyResultFlags(0), + expectedUsedAuthorities: []*X509CertificateID{ + NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert)), }, }) - c.Check(err, Equals, ErrNoSecureBoot) + c.Check(err, IsNil) } -func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadUserMode(c *C) { +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoodUserMode(c *C) { err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -435,89 +495,199 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + expectedFlags: SecureBootNoDeployedMode, + expectedUsedAuthorities: []*X509CertificateID{ + NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert)), }, }) - c.Check(err, Equals, ErrNoDeployedMode) + c.Check(err, IsNil) } -func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadFWSupportsDBT(c *C) { +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoodWithVendorEventBeforeConfig(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 + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), + efitest.WithLog(log), ), pcrAlg: tpm2.HashAlgorithmSHA256, iblImage: &mockImage{ signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + expectedFlags: SecureBootPolicyResultFlags(0), + expectedUsedAuthorities: []*X509CertificateID{ + NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert)), }, }) - c.Check(err, ErrorMatches, `generating secure boot profiles for systems with timestamp revocation \(dbt\) support is currently not supported`) + c.Check(err, IsNil) } -func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadFWSupportsDBR(c *C) { +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoodWithVendorEventWithConfig(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 + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), + efitest.WithLog(log), ), pcrAlg: tpm2.HashAlgorithmSHA256, iblImage: &mockImage{ signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + expectedFlags: SecureBootPolicyResultFlags(0), + expectedUsedAuthorities: []*X509CertificateID{ + NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert)), }, }) - c.Check(err, ErrorMatches, `generating secure boot profiles for systems with OS recovery support, which requires dbr support, is not supported`) + c.Check(err, IsNil) } -func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadNoBootCurrent(c *C) { +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesGoodWithVendorEventWithVerification(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 + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), + efitest.WithLog(log), ), pcrAlg: tpm2.HashAlgorithmSHA256, iblImage: &mockImage{ signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + expectedFlags: SecureBootPolicyResultFlags(0), + expectedUsedAuthorities: []*X509CertificateID{ + NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert)), }, }) - c.Check(err, ErrorMatches, `cannot read BootCurrent variable: variable does not exist`) + c.Check(err, IsNil) } -func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadNoLoadOption(c *C) { +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadNoSecureBoot(c *C) { err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x4, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(false).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + SecureBootDisabled: true, + })), + ), + pcrAlg: tpm2.HashAlgorithmSHA256, + iblImage: &mockImage{ + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + }) + c.Check(err, Equals, ErrNoSecureBoot) +} + +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadFWSupportsDBT(c *C) { + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), ), @@ -526,9 +696,32 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) - c.Check(err, ErrorMatches, `cannot read current Boot0004 load option from log: cannot find specified boot option`) + c.Check(err, ErrorMatches, `generating secure boot profiles for systems with timestamp revocation \(dbt\) support is currently not supported`) +} + +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadFWSupportsDBR(c *C) { + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), + ), + pcrAlg: tpm2.HashAlgorithmSHA256, + iblImage: &mockImage{ + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + }) + c.Check(err, ErrorMatches, `generating secure boot profiles for systems with OS recovery support, which requires dbr support, is not supported`) } func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadUnexpectedConfigMeasurement(c *C) { @@ -556,8 +749,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -569,6 +760,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `unexpected EV_EFI_VARIABLE_DRIVER_CONFIG event: all expected secure boot variable have been measured`) @@ -594,8 +786,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -607,6 +797,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `invalid event data for EV_EFI_VARIABLE_DRIVER_CONFIG event: some error`) @@ -639,8 +830,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -652,6 +841,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `unexpected EV_EFI_VARIABLE_DRIVER_CONFIG event ordering \(expected db-d719b2cb-3d3a-4596-a3bc-dad00e67656f, got dbx-d719b2cb-3d3a-4596-a3bc-dad00e67656f\)`) @@ -677,8 +867,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -690,6 +878,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `event data inconsistent with measured digest for EV_EFI_VARIABLE_DRIVER_CONFIG event \(name:\"dbx\", GUID:d719b2cb-3d3a-4596-a3bc-dad00e67656f, expected digest:0x1963d580fcc0cede165e23837b55335eebe18750c0b795883386026ea071e3c6, measured digest:0x8c8d89cdf0f2de4a1e97d436d7f6a19c49ab55d33bdb81c27470d4140b3de220\)`) @@ -716,8 +905,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -729,6 +916,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `invalid event data for EV_EFI_VARIABLE_DRIVER_CONFIG event: SecureBoot value is not consistent with the current EFI variable value`) @@ -739,8 +927,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -755,9 +941,10 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) - c.Check(err, ErrorMatches, `unexpected EV_EFI_ACTION event \"UEFI Debug Mode\" whilst measuring config`) + c.Check(err, ErrorMatches, `unexpected EV_EFI_ACTION event \"UEFI Debug Mode\" before config`) } func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadMissingConfigMeasurement(c *C) { @@ -785,8 +972,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -798,6 +983,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `EV_EFI_VARIABLE_DRIVER_CONFIG events for some secure boot variables missing from log`) @@ -809,7 +995,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad seenIBLVerification := false for _, ev := range log.Events { eventsCopy = append(eventsCopy, ev) - switch { case ev.PCRIndex == internal_efi.BootManagerCodePCR && ev.EventType == tcglog.EventTypeEFIBootServicesApplication: // Delete measurement @@ -827,8 +1012,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -840,6 +1023,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `missing load event for initial boot loader`) @@ -850,8 +1034,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -863,9 +1045,10 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "3875f8b0611b9e5264603f28b9d2dedc544420bc68b45db72f8794fbd1cb6303"), }, }) - c.Check(err, ErrorMatches, `unexpected EV_EFI_BOOT_SERVICES_APPLICATION event for \\PciRoot\(0x0\)\\Pci\(0x1d,0x0\)\\Pci\(0x0,0x0\)\\NVMe\(0x1,00-00-00-00-00-00-00-00\)\\HD\(1,GPT,66de947b-fdb2-4525-b752-30d66bb2b960\)\\\\EFI\\ubuntu\\shimx64.efi after already seeing a verification event during the OS-present environment. This event should be for the initial boot loader`) + c.Check(err, ErrorMatches, `OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for \\PciRoot\(0x0\)\\Pci\(0x1d,0x0\)\\Pci\(0x0,0x0\)\\NVMe\(0x1,00-00-00-00-00-00-00-00\)\\HD\(1,GPT,66de947b-fdb2-4525-b752-30d66bb2b960\)\\\\EFI\\ubuntu\\shimx64.efi is not associated with the initial boot loader image`) } func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadInvalidSourceForFirstOSPresentVerification(c *C) { @@ -887,8 +1070,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -900,6 +1081,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `cannot handle EV_EFI_VARIABLE_AUTHORITY event in OS-present phase: event is not from db \(got db-8be4df61-93ca-11d2-aa0d-00e098032b8c\)`) @@ -922,8 +1104,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -935,6 +1115,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `cannot handle EV_EFI_VARIABLE_AUTHORITY event in OS-present phase: event data inconsistent with TPM_ALG_SHA256 event digest \(log digest:0x8c8d89cdf0f2de4a1e97d436d7f6a19c49ab55d33bdb81c27470d4140b3de220, expected digest:0x4d4a8e2c74133bbdc01a16eaf2dbb5d575afeb36f5d8dfcf609ae043909e2ee9\)`) @@ -970,8 +1151,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -983,6 +1162,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `cannot handle EV_EFI_VARIABLE_AUTHORITY event in OS-present phase: digest 0x4d4a8e2c74133bbdc01a16eaf2dbb5d575afeb36f5d8dfcf609ae043909e2ee9 has been measured by the firmware already`) @@ -1005,8 +1185,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1018,9 +1196,10 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) - c.Check(err, ErrorMatches, `cannot determine if OS-present EV_EFI_BOOT_SERVICES_APPLICATION event for is associated with the current boot load option: event has invalid event data: some error`) + c.Check(err, ErrorMatches, `invalid event data for EV_EFI_BOOT_SERVICES_APPLICATION event: some error`) } func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadInvalidVerificationEventData(c *C) { @@ -1040,8 +1219,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1053,9 +1230,10 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) - c.Check(err, ErrorMatches, `cannot handle EV_EFI_VARIABLE_AUTHORITY event in OS-present phase: event has wong data format: some error`) + c.Check(err, ErrorMatches, `cannot handle EV_EFI_VARIABLE_AUTHORITY event in OS-present phase: event has wrong data format: some error`) } func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadDMAProtectionDisabled(c *C) { @@ -1063,8 +1241,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1079,6 +1255,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `unexpected EV_EFI_ACTION event \"DMA Protection Disabled\" whilst measuring config`) @@ -1089,8 +1266,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1105,9 +1280,10 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) - c.Check(err, ErrorMatches, `unexpected EV_EFI_ACTION event \"DMA Protection Disabled\" whilst measuring config`) + c.Check(err, ErrorMatches, `unexpected EV_EFI_ACTION event \"DMA Protection Disabled\" before config`) } func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadDMAProtectionDisabledBeforeVerification(c *C) { @@ -1115,8 +1291,31 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + DMAProtection: efitest.DMAProtectionDisabled, + })), + ), + pcrAlg: tpm2.HashAlgorithmSHA256, + iblImage: &mockImage{ + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + }) + c.Check(err, ErrorMatches, `unexpected EV_EFI_ACTION event \"DMA Protection Disabled\" whilst measuring config`) +} + +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadDMAProtectionDisabledAfterSeparator(c *C) { + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1131,6 +1330,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `unexpected EV_EFI_ACTION event \"DMA Protection Disabled\" whilst measuring verification`) @@ -1141,8 +1341,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1154,6 +1352,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `cannot read SecureBoot variable: variable does not exist`) @@ -1164,8 +1363,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1177,6 +1374,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `cannot compute secure boot mode: inconsistent secure boot mode: firmware indicates audit mode is enabled when not in setup mode`) @@ -1186,11 +1384,9 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ - {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, - {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), ), @@ -1199,6 +1395,7 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad signatures: []*efi.WinCertificateAuthenticode{ efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), }, }) c.Check(err, ErrorMatches, `cannot read OsIndicationsSupported variable: variable does not exist`) @@ -1209,8 +1406,6 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1222,6 +1417,111 @@ func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBad c.Check(err, ErrorMatches, `must supply the initial boot loader image`) } +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadUnexpectedVendorEventInConfig(c *C) { + // Add a vendor event that is measured in the middle of the signature database measurements. + 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 && !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 + + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + efitest.WithLog(log), + ), + pcrAlg: tpm2.HashAlgorithmSHA256, + iblImage: &mockImage{ + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + expectedFlags: SecureBootPolicyResultFlags(0), + expectedUsedAuthorities: []*X509CertificateID{ + NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert)), + }, + }) + c.Check(err, ErrorMatches, `unexpected 00008041 event "" whilst measuring config`) +} + +func (s *pcr7Suite) TestCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesBadUnexpectedDMAProtectionDisabledEventInConfig(c *C) { + // Add a "DMA Protection Disabled" event that is measured in the middle of the signature database measurements. + 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 && !added { + eventsCopy = append(eventsCopy, &tcglog.Event{ + PCRIndex: internal_efi.SecureBootPolicyPCR, + EventType: tcglog.EventTypeEFIAction, + Digests: tcglog.DigestMap{ + tpm2.HashAlgorithmSHA256: testutil.DecodeHexString(c, "019537eeff4f1858181e09d26faa59a5ad3a9d8eef3d1bbbb35288e0e16d656c"), + }, + Data: tcglog.DMAProtectionDisabled, + }) + added = true + } + + } + log.Events = eventsCopy + + err := s.testCheckSecureBootPolicyMeasurementsAndObtainAuthorities(c, &testCheckSecureBootPolicyMeasurementsAndObtainAuthoritiesParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + efitest.WithLog(log), + ), + pcrAlg: tpm2.HashAlgorithmSHA256, + iblImage: &mockImage{ + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + }, + permitDMAProtectionDisabled: true, + expectedFlags: SecureBootPolicyResultFlags(0), + expectedUsedAuthorities: []*X509CertificateID{ + NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert)), + }, + }) + c.Check(err, ErrorMatches, `unexpected EV_EFI_ACTION event "DMA Protection Disabled" whilst measuring config`) +} + // TODO (some harder, and some of these may require a more customizable test log generation in internal/efitest/log.go): // - Various PK/KEK/db/dbx decoding errors // - Failure to open initial boot loader image diff --git a/efi/preinstall/check_tcglog.go b/efi/preinstall/check_tcglog.go index 1d7c8d21..4eb55fd0 100644 --- a/efi/preinstall/check_tcglog.go +++ b/efi/preinstall/check_tcglog.go @@ -381,40 +381,34 @@ type tcglogPhase int const ( // tcglogPhaseFirmwareLaunch is the phase of the log that contains the initial // platform firmware launch, before the execution of any third party code. This - // is the starting point. + // is the starting point, and should only contain measurements to PCRs 0 and 1, + // and it may include EV_EFI_ACTION measurements to PCR7 to indicate conditions + // that degrade security. tcglogPhaseFirmwareLaunch tcglogPhase = iota // tcglogPhaseMeasuringSecureBootConfig is the phase of the log where the secure // boot configuration is being measured, before the execution of any third party - // code. tcglogPhaseFirmwareLaunch transitions to this phase by the first non - // EV_SEPARATOR event in PCR7. + // code. tcglogPhaseFirmwareLaunch transitions to this phase by the first + // EV_EFI_VARIABLE_DRIVER_CONFIG event in PCR7. tcglogPhaseMeasuringSecureBootConfig // tcglogPhasePreOSThirdPartyDispatch is the pre-OS phase of the log after measuring // the secure boot configuration and which may contain authentication and loading - // of third-party pre-OS components. An EV_SEPARATOR in PCR7 transitions - // tcglogPhaseMeasuringSecureBootConfig to this phase. Some older firmware - // implementations skip this phase because they measure EV_SEPARATORS in PCRs 0-7 to - // indicate the transition to OS-present. + // of third-party pre-OS components. A EV_EFI_VARIABLE_AUTHORITY or EV_SEPARATOR + // event in PCR7 transitions tcglogPhaseMeasuringSecureBootConfig to this phase. This + // handles firmware implementations that measure the EV_SEPARATOR event in PCR7 as part + // of the boundary between configuration and image verification, and as part of the + // transition to OS-present. tcglogPhasePreOSThirdPartyDispatch - // tcglogPhasePreOSThirdPartyDispatchUnterminated happens on some older firmware - // implementations that don't use a EV_SEPARATOR in PCR7 to separate secure boot config - // from secure boot verification, but instead measure the separator as part of the pre-OS - // to OS-present transition. There shouldn't be any more events in PCR7 until - // tcglogPhaseOSPresent. - // XXX(chrisccoulson): This state is temporary and will likely disappear as part of - // the fix for https://github.com/canonical/secboot/issues/410. - tcglogPhasePreOSThirdPartyDispatchUnterminated - // tcglogPhaseTransitioningToOSPresent describes the phase of the log where the transition - // to OS-present happens. Either of the 2 previous pre-OS phases can transition to this one - // by an EV_SEPARATOR event in PCRs 0-6. + // to OS-present happens. Either tcglogPhaseMeasuringSecureBootConfig and + // tcglogPhasePreOSThirdPartyDispatch can transition to this one. tcglogPhaseTransitioningToOSPresent // tcglogPhaseOSPresent describes the phase of the log where the OS is in control. The - // tcglogPhaseTransitioningToOSPresent phase transitions to this when all EV_SEPARATOR - // events in PCRs 0-7 have been seen. + // tcglogPhaseTransitioningToOSPresent phase transitions to this when the final EV_SEPARATOR + // event in PCRs 0-7 has been seen. tcglogPhaseOSPresent // tcglogPhaseErr indicates that a previous event was interpreted as an error. Attempting @@ -502,46 +496,30 @@ func (t *tcglogPhaseTracker) processEvent(ev *tcglog.Event) (phase tcglogPhase, // the data for the separator should have indicated the error, which is caught above. // If we get here then this is a normal EV_SEPARATOR event. return 0, fmt.Errorf("unexpected normal EV_SEPARATOR event in PCR %d", ev.PCRIndex) - case ev.PCRIndex == internal_efi.SecureBootPolicyPCR: - // A non EV_SEPARATOR event to PCR7 signals the beginning of the secure boot config measurements. + case ev.PCRIndex == internal_efi.SecureBootPolicyPCR && ev.EventType == tcglog.EventTypeEFIVariableDriverConfig: + // A EV_EFI_VARIABLE_DRIVER_CONFIG event in PCR7 signals the beginning of the + // secure boot config measurements. t.phase = tcglogPhaseMeasuringSecureBootConfig default: - // No change for any other event + // No change for any other event. } case t.phase == tcglogPhaseMeasuringSecureBootConfig: switch { case ev.PCRIndex != internal_efi.SecureBootPolicyPCR && ev.EventType == tcglog.EventTypeSeparator: // An EV_SEPARATOR event in PCRs 0-6 after measuring the secure boot configuration begins the - // transition to OS-present, skipping the part of the pre-OS phase after the secure boot config - // has been measured. + // transition to OS-present. This transition isn't really expected here because it *should* + // begin with measurement of the boot variables to PCR1, and a EV_EFI_ACTION event in PCR4. t.phase = tcglogPhaseTransitioningToOSPresent - case ev.PCRIndex != internal_efi.SecureBootPolicyPCR: - // Any other events that aren't to PCR7 terminate the measurement of the secure - // boot config. This path should only happen on older firmware implementations. - t.phase = tcglogPhasePreOSThirdPartyDispatchUnterminated - case ev.EventType == tcglog.EventTypeSeparator: - // An EV_SEPARATOR in PCR7 transitions to the part of the pre-OS phase where pre-OS - // components can be verified and executed. + case ev.PCRIndex != internal_efi.SecureBootPolicyPCR || ev.EventType == tcglog.EventTypeEFIVariableAuthority || ev.EventType == tcglog.EventTypeSeparator: + // Any other event that isn't in PCR7, or a EV_EFI_VARIABLE_AUTHORITY or EV_SEPARATOR event + // in PCR7 terminates the measurement of the secure boot config. This is permissive, handling + // the case where an EV_SEPARATOR event in PCR7 signals the boundary between secure boot config + // and secure boot image verification, and the case where the EV_SEPARATOR event in PCR7 is + // measured later as part of the transition to OS-present. t.phase = tcglogPhasePreOSThirdPartyDispatch default: // No change for any other event to PCR7 } - case t.phase == tcglogPhasePreOSThirdPartyDispatchUnterminated: - // XXX(chrisccoulson): It's not clear whether this should return to - // tcglogPhaseMeasuringSecureBootConfig if there is an event in PCR7. The - // justification for this is that PCR7 should begin with an extra event indicating - // that there is a debugger active if that is the case. EDK2 measures this in the - // same block of events as the secure boot configuration, but we don't know whether - // all firmware does this. The consequence of some firmware measuring it separately - // is that we may end up failing other PCRs unnecessarily for tests that use this - // functionality, because of the logic here. - switch { - case ev.EventType == tcglog.EventTypeSeparator: - // Any EV_SEPARATOR from this phase begins the transition to OS present. - t.phase = tcglogPhaseTransitioningToOSPresent - default: - // No change for events in any other PCR. - } case t.phase == tcglogPhasePreOSThirdPartyDispatch: switch { case ev.EventType == tcglog.EventTypeSeparator: @@ -552,16 +530,16 @@ func (t *tcglogPhaseTracker) processEvent(ev *tcglog.Event) (phase tcglogPhase, } case t.phase == tcglogPhaseTransitioningToOSPresent: switch { - case ev.EventType == tcglog.EventTypeSeparator: - // No change here - we're still transitioning to OS present. - case t.numSeparatorsSeen != 8: + case ev.EventType != tcglog.EventTypeSeparator: // If we see any other event type before seeing all EV_SEPARATOR // events, return an error return 0, fmt.Errorf("unexpected %v event in PCR %d whilst transitioning to OS-present (expected EV_SEPARATOR)", ev.EventType, ev.PCRIndex) - default: - // Any non EV_SEPARATOR event when we've seen all expected separators - // completes the transition to OS-present, and we're done! + case t.numSeparatorsSeen == 8: + // This is the last EV_SEPARATOR, completing the transition to + // OS-present. t.phase = tcglogPhaseOSPresent + default: + // No change here - we're still transitioning to OS present. } } diff --git a/efi/preinstall/check_tcglog_test.go b/efi/preinstall/check_tcglog_test.go index 3b6f92d4..5127b68b 100644 --- a/efi/preinstall/check_tcglog_test.go +++ b/efi/preinstall/check_tcglog_test.go @@ -1159,7 +1159,7 @@ func (s *tcglogSuite) TestCheckFirmwareLogAndChoosePCRBankEmptyPCRBanksError(c * }, 0, ) - c.Check(err, ErrorMatches, `cannot determine whether PCR bank TPM_ALG_SHA512 is active but empty on the TPM: cannot obtain active PCRs: TPM returned a TPM_RC_BAD_TAG error whilst executing command TPM_CC_GetCapability`) + c.Check(err, ErrorMatches, `cannot determine whether PCR bank TPM_ALG_SHA512 is active but empty on the TPM: cannot obtain active PCRs: TPM returned an error whilst executing command TPM_CC_GetCapability: TPM_RC_BAD_TAG \(defined for compatibility with TPM 1.2\)`) } func (s *tcglogSuite) TestCheckFirmwareLogAndChoosePCRBankBadSHA1(c *C) { diff --git a/efi/preinstall/check_tpm.go b/efi/preinstall/check_tpm.go index 35d72546..55ba7e13 100644 --- a/efi/preinstall/check_tpm.go +++ b/efi/preinstall/check_tpm.go @@ -404,6 +404,26 @@ func openAndCheckTPM2Device(env internal_efi.HostEnvironment, flags checkTPM2Dev // Make sure the lockout hierarchy auth value is not set. if tpm2.PermanentAttributes(perm)&tpm2.AttrLockoutAuthSet > 0 { ownedErr.addAuthValue(tpm2.HandleLockout) + + // Check if the lockout hierarchy has an authorization policy set. We only check this + // if there is an authorization value because tpm2.Connection.EnsureProvisioned will set + // it accordingly if there is no authorization value. The presence of an authorization + // policy is indicated as additional information to the original error. + // + // We don't check this for other hierarchies because we don't take ownership of those, + // and so the presence of a policy when the authorization value is unset is not worth + // indicating. XXX(chrisccoulson): Perhaps this should be presented as a warning in the + // public API eventually. + switch ta, err := tpm.GetCapabilityAuthPolicy(tpm2.HandleLockout); { + case tpm2.IsTPMParameterError(err, tpm2.ErrorValue, tpm2.CommandGetCapability, 1): + // TPM implements a version of the reference library spec that is older than + // v1.38. Never mind - we'll ensure that the policy for TPM_RH_LOCKOUT is + // initialized appropriately in tpm2.Connection.EnsureProvisioned. + case err != nil: + return nil, fmt.Errorf("cannot determine if %v hierarchy has an authorization policy: %w", tpm2.HandleLockout, err) + case ta.HashAlg != tpm2.HashAlgorithmNull: + ownedErr.addAuthPolicy(tpm2.HandleLockout) + } } // Make sure the owner hierarchy authorization value is not set. @@ -416,17 +436,6 @@ func openAndCheckTPM2Device(env internal_efi.HostEnvironment, flags checkTPM2Dev ownedErr.addAuthValue(tpm2.HandleEndorsement) } - // Make sure that none of the hierarchies have an authorization policy. - for _, handle := range []tpm2.Handle{tpm2.HandleLockout, tpm2.HandleOwner, tpm2.HandleEndorsement} { - ta, err := tpm.GetCapabilityAuthPolicy(handle) - if err != nil { - return nil, fmt.Errorf("cannot determine if %v hierarchy has an authorization policy: %w", handle, err) - } - if ta.HashAlg != tpm2.HashAlgorithmNull { - ownedErr.addAuthPolicy(handle) - } - } - if !ownedErr.isEmpty() { errs = append(errs, ownedErr) } diff --git a/efi/preinstall/check_tpm_amd64_test.go b/efi/preinstall/check_tpm_amd64_test.go index 486a05df..a6a8ea90 100644 --- a/efi/preinstall/check_tpm_amd64_test.go +++ b/efi/preinstall/check_tpm_amd64_test.go @@ -34,7 +34,7 @@ var _ = Suite(&tpmAmd64Suite{}) func (s *tpmIntelSuite) TestIsTPMDiscreteIntelYes(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 1, map[uint32]uint64{0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 1, map[uint32]uint64{0x13a: (2 << 1)}), ) discrete, err := IsTPMDiscrete(env) c.Check(err, IsNil) @@ -43,7 +43,7 @@ func (s *tpmIntelSuite) TestIsTPMDiscreteIntelYes(c *C) { func (s *tpmIntelSuite) TestIsTPMDiscreteIntelNo(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 1, map[uint32]uint64{0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 1, map[uint32]uint64{0x13a: (3 << 1)}), ) discrete, err := IsTPMDiscrete(env) c.Check(err, IsNil) @@ -52,7 +52,7 @@ func (s *tpmIntelSuite) TestIsTPMDiscreteIntelNo(c *C) { func (s *tpmIntelSuite) TestIsTPMDiscreteIntelNoTPM2(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 1, map[uint32]uint64{0x13a: (0 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 1, map[uint32]uint64{0x13a: (0 << 1)}), ) _, err := IsTPMDiscrete(env) c.Check(err, ErrorMatches, `cannot check TPM discreteness using Intel BootGuard status: no TPM2 device is available`) @@ -60,7 +60,7 @@ func (s *tpmIntelSuite) TestIsTPMDiscreteIntelNoTPM2(c *C) { } func (s *tpmIntelSuite) TestIsTPMDiscreteAMD(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("AuthenticAMD", nil, 1, nil)) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 1, nil)) _, err := IsTPMDiscrete(env) c.Check(err, ErrorMatches, `unsupported platform: cannot check TPM discreteness on AMD systems`) @@ -69,7 +69,7 @@ func (s *tpmIntelSuite) TestIsTPMDiscreteAMD(c *C) { } func (s *tpmIntelSuite) TestIsTPMDiscreteUnrecognizedCPUVendor(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineInte", nil, 1, nil)) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineInte", 0x6, nil, 1, nil)) _, err := IsTPMDiscrete(env) c.Check(err, ErrorMatches, `unsupported platform: cannot determine CPU vendor: unknown CPU vendor: GenuineInte`) diff --git a/efi/preinstall/check_tpm_intel.go b/efi/preinstall/check_tpm_intel.go index cda0a42d..1a5d9fe0 100644 --- a/efi/preinstall/check_tpm_intel.go +++ b/efi/preinstall/check_tpm_intel.go @@ -28,30 +28,8 @@ import ( internal_efi "github.com/snapcore/secboot/internal/efi" ) -const bootGuardStatusMsr = 0x13a - -type bootGuardStatus uint64 - -const ( - bootGuardStatusTPMShift = 1 - bootGuardStatusTPMMask bootGuardStatus = (3 << bootGuardStatusTPMShift) -) - -type bootGuardTPMStatus uint64 - -const ( - bootGuardTPMStatusNone bootGuardTPMStatus = 0 - bootGuardTPMStatus12 bootGuardTPMStatus = 1 - bootGuardTPMStatus2 bootGuardTPMStatus = 2 - bootGuardTPMStatusPTT bootGuardTPMStatus = 3 -) - -func (s bootGuardStatus) tpmStatus() bootGuardTPMStatus { - return bootGuardTPMStatus(s&bootGuardStatusTPMMask) >> bootGuardStatusTPMShift -} - func isTPMDiscreteFromIntelBootGuard(env internal_efi.HostEnvironmentAMD64) (bool, error) { - msrValue, err := env.ReadMSRs(bootGuardStatusMsr) + status, err := readIntelBootGuardStatus(env) switch { case errors.Is(err, internal_efi.ErrNoKernelMSRSupport): return false, MissingKernelModuleError("msr") @@ -59,9 +37,6 @@ func isTPMDiscreteFromIntelBootGuard(env internal_efi.HostEnvironmentAMD64) (boo return false, fmt.Errorf("cannot read BootGuard status MSR: %w", err) } - status := bootGuardStatus(msrValue[0]) - - // NOTE: bootGuardStatus[0] is fine because BootGuard status MSR has the same value across all CPUs switch status.tpmStatus() { case bootGuardTPMStatusNone, bootGuardTPMStatus12: // System has no TPM or unsupported TPM 1.2 device diff --git a/efi/preinstall/check_tpm_intel_test.go b/efi/preinstall/check_tpm_intel_test.go index d150bbe6..7c76081c 100644 --- a/efi/preinstall/check_tpm_intel_test.go +++ b/efi/preinstall/check_tpm_intel_test.go @@ -32,7 +32,7 @@ var _ = Suite(&tpmIntelSuite{}) func (s *tpmIntelSuite) TestIsTPMDiscreteFromIntelBootguardTPM2(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 1, map[uint32]uint64{0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 1, map[uint32]uint64{0x13a: (2 << 1)}), ) amd64, err := env.AMD64() c.Assert(err, IsNil) @@ -43,7 +43,7 @@ func (s *tpmIntelSuite) TestIsTPMDiscreteFromIntelBootguardTPM2(c *C) { func (s *tpmIntelSuite) TestIsTPMDiscreteFromIntelBootguardPTT(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 1, map[uint32]uint64{0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 1, map[uint32]uint64{0x13a: (3 << 1)}), ) amd64, err := env.AMD64() c.Assert(err, IsNil) @@ -54,7 +54,7 @@ func (s *tpmIntelSuite) TestIsTPMDiscreteFromIntelBootguardPTT(c *C) { func (s *tpmIntelSuite) TestIsTPMDiscreteFromIntelBootguardTPM12(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 1, map[uint32]uint64{0x13a: (1 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 1, map[uint32]uint64{0x13a: (1 << 1)}), ) amd64, err := env.AMD64() c.Assert(err, IsNil) @@ -64,7 +64,7 @@ func (s *tpmIntelSuite) TestIsTPMDiscreteFromIntelBootguardTPM12(c *C) { func (s *tpmIntelSuite) TestIsTPMDiscreteFromIntelBootguardNoTPM(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 1, map[uint32]uint64{0x13a: (0 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 1, map[uint32]uint64{0x13a: (0 << 1)}), ) amd64, err := env.AMD64() c.Assert(err, IsNil) @@ -74,7 +74,7 @@ func (s *tpmIntelSuite) TestIsTPMDiscreteFromIntelBootguardNoTPM(c *C) { func (s *tpmIntelSuite) TestIsTPMDiscreteFromIntelBootguardNoMSRSupport(c *C) { env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithAMD64Environment("GenuineIntel", nil, 0, nil), + efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 0, nil), ) amd64, err := env.AMD64() c.Assert(err, IsNil) diff --git a/efi/preinstall/check_tpm_test.go b/efi/preinstall/check_tpm_test.go index 8eb0bee7..93a7e43c 100644 --- a/efi/preinstall/check_tpm_test.go +++ b/efi/preinstall/check_tpm_test.go @@ -1,5 +1,3 @@ -// -*- Mode: Go; indent-tabs-mode: t -*- - /* * Copyright (C) 2024 Canonical Ltd * @@ -487,6 +485,66 @@ func (s *tpmSuite) TestOpenAndCheckTPM2DeviceIsNotPCClientWithSuccessfulFeatureC c.Check(dev.NumberOpen(), Equals, int(1)) } +func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedOwnerWithPolicy(c *C) { + s.addTPMPropertyModifiers(c, map[tpm2.Property]uint32{ + tpm2.PropertyPSFamilyIndicator: 1, + tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), + }) + + // Set an authorization policy and test that we get the appropriate error. + c.Assert(s.TPM.SetPrimaryPolicy(s.TPM.OwnerHandleContext(), testutil.DecodeHexString(c, "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5"), tpm2.HashAlgorithmSHA256, nil), IsNil) + + dev := tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithTPMDevice(newTpmDevice(dev, nil, tpm2_device.ErrNoPPI))) + tpm, err := OpenAndCheckTPM2Device(env, 0) + c.Check(err, IsNil) + c.Check(tpm, NotNil) + var tmpl tpm2_testutil.TransportWrapper + c.Assert(tpm.Transport(), Implements, &tmpl) + c.Check(tpm.Transport().(tpm2_testutil.TransportWrapper).Unwrap(), Equals, s.Transport) + c.Check(dev.NumberOpen(), Equals, int(1)) +} + +func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedEndorsementWithPolicy(c *C) { + s.addTPMPropertyModifiers(c, map[tpm2.Property]uint32{ + tpm2.PropertyPSFamilyIndicator: 1, + tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), + }) + + // Set an authorization policy and test that we get the appropriate error. + c.Assert(s.TPM.SetPrimaryPolicy(s.TPM.EndorsementHandleContext(), testutil.DecodeHexString(c, "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5"), tpm2.HashAlgorithmSHA256, nil), IsNil) + + dev := tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithTPMDevice(newTpmDevice(dev, nil, tpm2_device.ErrNoPPI))) + tpm, err := OpenAndCheckTPM2Device(env, 0) + c.Check(err, IsNil) + c.Check(tpm, NotNil) + var tmpl tpm2_testutil.TransportWrapper + c.Assert(tpm.Transport(), Implements, &tmpl) + c.Check(tpm.Transport().(tpm2_testutil.TransportWrapper).Unwrap(), Equals, s.Transport) + c.Check(dev.NumberOpen(), Equals, int(1)) +} + +func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedLockoutWithPolicy(c *C) { + s.addTPMPropertyModifiers(c, map[tpm2.Property]uint32{ + tpm2.PropertyPSFamilyIndicator: 1, + tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), + }) + + // Set an authorization policy and test that we get the appropriate error. + c.Assert(s.TPM.SetPrimaryPolicy(s.TPM.LockoutHandleContext(), testutil.DecodeHexString(c, "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5"), tpm2.HashAlgorithmSHA256, nil), IsNil) + + dev := tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithTPMDevice(newTpmDevice(dev, nil, tpm2_device.ErrNoPPI))) + tpm, err := OpenAndCheckTPM2Device(env, 0) + c.Check(err, IsNil) + c.Check(tpm, NotNil) + var tmpl tpm2_testutil.TransportWrapper + c.Assert(tpm.Transport(), Implements, &tmpl) + c.Check(tpm.Transport().(tpm2_testutil.TransportWrapper).Unwrap(), Equals, s.Transport) + c.Check(dev.NumberOpen(), Equals, int(1)) +} + // XXX: See the commented out TPM2_SelfTest result handling code in check_tpm.go //func (s *tpmSuite) TestOpenAndCheckTPM2DeviceGoodPreInstallNoVMInfiniteCountersDiscreteTPMWithBackgroundSelfTest(c *C) { // // Test the good case for pre-install on bare-metal with a discrete TPM and @@ -729,107 +787,112 @@ func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedLockout(c *C) { c.Check(dev.NumberOpen(), Equals, int(1)) } -func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedOwner(c *C) { +func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedLockoutWithAuthValueAndPolicy(c *C) { s.addTPMPropertyModifiers(c, map[tpm2.Property]uint32{ tpm2.PropertyPSFamilyIndicator: 1, tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), }) - // Set the owner hierarchy auth value so we get an error indicating that the TPM is already owned. - c.Assert(s.TPM.HierarchyChangeAuth(s.TPM.OwnerHandleContext(), []byte{1, 2, 3, 4}, nil), IsNil) + // Set the lockout hierarchy auth value and policy so we get an error indicating that the TPM is already owned. + c.Assert(s.TPM.HierarchyChangeAuth(s.TPM.LockoutHandleContext(), []byte{1, 2, 3, 4}, nil), IsNil) + c.Assert(s.TPM.SetPrimaryPolicy(s.TPM.LockoutHandleContext(), testutil.DecodeHexString(c, "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5"), tpm2.HashAlgorithmSHA256, nil), IsNil) dev := tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1) env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithTPMDevice(newTpmDevice(dev, nil, tpm2_device.ErrNoPPI))) tpm, err := OpenAndCheckTPM2Device(env, 0) - c.Check(err, ErrorMatches, `one or more of the TPM hierarchies is already owned: -- TPM_RH_OWNER has an authorization value + c.Check(err, ErrorMatches, `2 errors detected: +- availability of TPM's lockout hierarchy was not checked because the lockout hierarchy has an authorization value set +- one or more of the TPM hierarchies is already owned: + - TPM_RH_LOCKOUT has an authorization value + - TPM_RH_LOCKOUT has an authorization policy `) var tmpl CompoundError c.Assert(err, Implements, &tmpl) - c.Assert(err.(CompoundError).Unwrap(), HasLen, 1) + c.Assert(err.(CompoundError).Unwrap(), HasLen, 2) + + c.Check(errors.Is(err.(CompoundError).Unwrap()[0], ErrTPMLockoutAvailabilityNotChecked), testutil.IsTrue) var e *TPM2OwnedHierarchiesError - c.Check(errors.As(err.(CompoundError).Unwrap()[0], &e), testutil.IsTrue) - c.Check(e.WithAuthValue, DeepEquals, tpm2.HandleList{tpm2.HandleOwner}) - c.Check(e.WithAuthPolicy, HasLen, 0) + c.Check(errors.As(err.(CompoundError).Unwrap()[1], &e), testutil.IsTrue) + c.Check(e.WithAuthValue, DeepEquals, tpm2.HandleList{tpm2.HandleLockout}) + c.Check(e.WithAuthPolicy, DeepEquals, tpm2.HandleList{tpm2.HandleLockout}) c.Check(tpm, NotNil) c.Check(dev.NumberOpen(), Equals, int(1)) } -func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedEndorsement(c *C) { +func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedLockoutWithAuthValueAndPolicyLessThanV138(c *C) { s.addTPMPropertyModifiers(c, map[tpm2.Property]uint32{ tpm2.PropertyPSFamilyIndicator: 1, tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), }) - // Set the endorsement hierarchy auth value so we get an error indicating that the TPM is already owned. - c.Assert(s.TPM.HierarchyChangeAuth(s.TPM.EndorsementHandleContext(), []byte{1, 2, 3, 4}, nil), IsNil) - - dev := tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1) - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithTPMDevice(newTpmDevice(dev, nil, tpm2_device.ErrNoPPI))) - tpm, err := OpenAndCheckTPM2Device(env, 0) - c.Check(err, ErrorMatches, `one or more of the TPM hierarchies is already owned: -- TPM_RH_ENDORSEMENT has an authorization value -`) - - var tmpl CompoundError - c.Assert(err, Implements, &tmpl) - c.Assert(err.(CompoundError).Unwrap(), HasLen, 1) - - var e *TPM2OwnedHierarchiesError - c.Check(errors.As(err.(CompoundError).Unwrap()[0], &e), testutil.IsTrue) - c.Check(e.WithAuthValue, DeepEquals, tpm2.HandleList{tpm2.HandleEndorsement}) - c.Check(e.WithAuthPolicy, HasLen, 0) + origIntercept := s.Transport.ResponseIntercept + s.transport.ResponseIntercept = func(cmdCode tpm2.CommandCode, cmdHandles tpm2.HandleList, cmdAuthArea []tpm2.AuthCommand, cpBytes []byte, rsp *bytes.Buffer) { + if cmdCode != tpm2.CommandGetCapability { + return + } - c.Check(tpm, NotNil) - c.Check(dev.NumberOpen(), Equals, int(1)) -} + // Unpack the command parameters + var capability tpm2.Capability + var property uint32 + var propertyCount uint32 + _, err := mu.UnmarshalFromBytes(cpBytes, &capability, &property, &propertyCount) + c.Assert(err, IsNil) + if capability != tpm2.CapabilityAuthPolicies { + origIntercept(cmdCode, cmdHandles, cmdAuthArea, cpBytes, rsp) + return + } -func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedLockoutWithPolicy(c *C) { - s.addTPMPropertyModifiers(c, map[tpm2.Property]uint32{ - tpm2.PropertyPSFamilyIndicator: 1, - tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), - }) + // Return a TPM_RC_VALUE + TPM_RC_P + TPM_RC_1 error + rsp.Reset() + c.Check(tpm2.WriteResponsePacket(rsp, tpm2.ResponseValue+tpm2.ResponseP+tpm2.ResponseIndex1, nil, nil, nil), IsNil) + } + defer func() { s.Transport.ResponseIntercept = origIntercept }() - // Set an authorization policy and test that we get the appropriate error. + // Set the lockout hierarchy auth value and policy so we get an error indicating that the TPM is already owned. + c.Assert(s.TPM.HierarchyChangeAuth(s.TPM.LockoutHandleContext(), []byte{1, 2, 3, 4}, nil), IsNil) c.Assert(s.TPM.SetPrimaryPolicy(s.TPM.LockoutHandleContext(), testutil.DecodeHexString(c, "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5"), tpm2.HashAlgorithmSHA256, nil), IsNil) dev := tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1) env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithTPMDevice(newTpmDevice(dev, nil, tpm2_device.ErrNoPPI))) tpm, err := OpenAndCheckTPM2Device(env, 0) - c.Check(err, ErrorMatches, `one or more of the TPM hierarchies is already owned: -- TPM_RH_LOCKOUT has an authorization policy + c.Check(err, ErrorMatches, `2 errors detected: +- availability of TPM's lockout hierarchy was not checked because the lockout hierarchy has an authorization value set +- one or more of the TPM hierarchies is already owned: + - TPM_RH_LOCKOUT has an authorization value `) var tmpl CompoundError c.Assert(err, Implements, &tmpl) - c.Assert(err.(CompoundError).Unwrap(), HasLen, 1) + c.Assert(err.(CompoundError).Unwrap(), HasLen, 2) + + c.Check(errors.Is(err.(CompoundError).Unwrap()[0], ErrTPMLockoutAvailabilityNotChecked), testutil.IsTrue) var e *TPM2OwnedHierarchiesError - c.Check(errors.As(err.(CompoundError).Unwrap()[0], &e), testutil.IsTrue) - c.Check(e.WithAuthValue, HasLen, 0) - c.Check(e.WithAuthPolicy, DeepEquals, tpm2.HandleList{tpm2.HandleLockout}) + c.Check(errors.As(err.(CompoundError).Unwrap()[1], &e), testutil.IsTrue) + c.Check(e.WithAuthValue, DeepEquals, tpm2.HandleList{tpm2.HandleLockout}) + c.Check(e.WithAuthPolicy, IsNil) c.Check(tpm, NotNil) c.Check(dev.NumberOpen(), Equals, int(1)) } -func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedOwnerWithPolicy(c *C) { +func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedOwner(c *C) { s.addTPMPropertyModifiers(c, map[tpm2.Property]uint32{ tpm2.PropertyPSFamilyIndicator: 1, tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), }) - // Set an authorization policy and test that we get the appropriate error. - c.Assert(s.TPM.SetPrimaryPolicy(s.TPM.OwnerHandleContext(), testutil.DecodeHexString(c, "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5"), tpm2.HashAlgorithmSHA256, nil), IsNil) + // Set the owner hierarchy auth value so we get an error indicating that the TPM is already owned. + c.Assert(s.TPM.HierarchyChangeAuth(s.TPM.OwnerHandleContext(), []byte{1, 2, 3, 4}, nil), IsNil) dev := tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1) env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithTPMDevice(newTpmDevice(dev, nil, tpm2_device.ErrNoPPI))) tpm, err := OpenAndCheckTPM2Device(env, 0) c.Check(err, ErrorMatches, `one or more of the TPM hierarchies is already owned: -- TPM_RH_OWNER has an authorization policy +- TPM_RH_OWNER has an authorization value `) var tmpl CompoundError @@ -838,27 +901,27 @@ func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedOwnerWithPolicy(c *C) { var e *TPM2OwnedHierarchiesError c.Check(errors.As(err.(CompoundError).Unwrap()[0], &e), testutil.IsTrue) - c.Check(e.WithAuthValue, HasLen, 0) - c.Check(e.WithAuthPolicy, DeepEquals, tpm2.HandleList{tpm2.HandleOwner}) + c.Check(e.WithAuthValue, DeepEquals, tpm2.HandleList{tpm2.HandleOwner}) + c.Check(e.WithAuthPolicy, HasLen, 0) c.Check(tpm, NotNil) c.Check(dev.NumberOpen(), Equals, int(1)) } -func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedEndorsementWithPolicy(c *C) { +func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedEndorsement(c *C) { s.addTPMPropertyModifiers(c, map[tpm2.Property]uint32{ tpm2.PropertyPSFamilyIndicator: 1, tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), }) - // Set an authorization policy and test that we get the appropriate error. - c.Assert(s.TPM.SetPrimaryPolicy(s.TPM.EndorsementHandleContext(), testutil.DecodeHexString(c, "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5"), tpm2.HashAlgorithmSHA256, nil), IsNil) + // Set the endorsement hierarchy auth value so we get an error indicating that the TPM is already owned. + c.Assert(s.TPM.HierarchyChangeAuth(s.TPM.EndorsementHandleContext(), []byte{1, 2, 3, 4}, nil), IsNil) dev := tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1) env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithTPMDevice(newTpmDevice(dev, nil, tpm2_device.ErrNoPPI))) tpm, err := OpenAndCheckTPM2Device(env, 0) c.Check(err, ErrorMatches, `one or more of the TPM hierarchies is already owned: -- TPM_RH_ENDORSEMENT has an authorization policy +- TPM_RH_ENDORSEMENT has an authorization value `) var tmpl CompoundError @@ -867,8 +930,8 @@ func (s *tpmSuite) TestOpenAndCheckTPM2DeviceAlreadyOwnedEndorsementWithPolicy(c var e *TPM2OwnedHierarchiesError c.Check(errors.As(err.(CompoundError).Unwrap()[0], &e), testutil.IsTrue) - c.Check(e.WithAuthValue, HasLen, 0) - c.Check(e.WithAuthPolicy, DeepEquals, tpm2.HandleList{tpm2.HandleEndorsement}) + c.Check(e.WithAuthValue, DeepEquals, tpm2.HandleList{tpm2.HandleEndorsement}) + c.Check(e.WithAuthPolicy, HasLen, 0) c.Check(tpm, NotNil) c.Check(dev.NumberOpen(), Equals, int(1)) diff --git a/efi/preinstall/checks.go b/efi/preinstall/checks.go index 8a22e70a..8981a909 100644 --- a/efi/preinstall/checks.go +++ b/efi/preinstall/checks.go @@ -143,6 +143,10 @@ const ( // and/or if no kernel IOMMU support was detected. // This weakens security because it allows DMA attacks to compromise system integrity. PermitInsufficientDMAProtection + + // PermitSecureBootUserMode will prevent RunChecks from returning an error if secure + // boot is enabled but not in deployed mode on systems that support UEFI >= 2.5. + PermitSecureBootUserMode ) var ( @@ -303,7 +307,8 @@ func RunChecks(ctx context.Context, flags CheckFlags, loadedImages []secboot_efi if virtMode == detectVirtNone { // Only run host security checks if we are not in a VM - if err := checkHostSecurity(runChecksEnv, log); err != nil { + fwIntegrity, err := checkHostSecurity(runChecksEnv, log) + if err != nil { var ce CompoundError if !errors.As(err, &ce) { return nil, &HostSecurityError{err} @@ -316,6 +321,9 @@ func RunChecks(ctx context.Context, flags CheckFlags, loadedImages []secboot_efi } } } + if fwIntegrity == platformFirmwareIntegrityMeasured { + result.Flags |= RequireLockToPlatformFirmware + } status, err := checkDiscreteTPMPartialResetAttackMitigationStatus(runChecksEnv, logResults) if err != nil { @@ -432,6 +440,9 @@ func RunChecks(ctx context.Context, flags CheckFlags, loadedImages []secboot_efi if pcr7Result.Flags&secureBootPreOSVerificationIncludesDigest > 0 { addDeferredErrorOrWarning(ErrPreOSSecureBootAuthByEnrolledDigests, PermitPreOSSecureBootAuthByEnrolledDigests) } + if pcr7Result.Flags&secureBootNoDeployedMode > 0 { + addDeferredErrorOrWarning(ErrNoDeployedMode, PermitSecureBootUserMode) + } result.UsedSecureBootCAs = pcr7Result.UsedAuthorities } @@ -444,6 +455,11 @@ func RunChecks(ctx context.Context, flags CheckFlags, loadedImages []secboot_efi result.AcceptedErrors[kind] = nil } } + for info, flag := range errorKindWithArgsToProceedFlag { + if flag&flags > 0 { + result.AcceptedErrors[info.kind] = nil + } + } if len(warnings) > 0 { result.Warnings = joinErrors(warnings...).(CompoundError) } diff --git a/efi/preinstall/checks_context.go b/efi/preinstall/checks_context.go index 4bf57fa8..e753078b 100644 --- a/efi/preinstall/checks_context.go +++ b/efi/preinstall/checks_context.go @@ -26,6 +26,7 @@ import ( "fmt" "time" + efi "github.com/canonical/go-efilib" "github.com/canonical/go-tpm2" "github.com/canonical/go-tpm2/ppi" secboot_efi "github.com/snapcore/secboot/efi" @@ -61,6 +62,13 @@ var errorKindToActions map[ErrorKind][]Action // to ignore the error. Not all errors can be ignored in this way. var errorKindToProceedFlag map[ErrorKind]CheckFlags +type errorKindWithArgs struct { + kind ErrorKind + args any +} + +var errorKindWithArgsToProceedFlag map[errorKindWithArgs]CheckFlags + // unsupportedPcrs are the PCRs that are currently unsupported. var unsupportedPcrs tpm2.HandleList @@ -159,6 +167,10 @@ func init() { ErrorKindPreOSSecureBootAuthByEnrolledDigests: PermitPreOSSecureBootAuthByEnrolledDigests, } + errorKindWithArgsToProceedFlag = map[errorKindWithArgs]CheckFlags{ + {kind: ErrorKindInvalidSecureBootMode, args: SecureBootModeArg{Enabled: true, Mode: efi.UserMode}}: PermitSecureBootUserMode, + } + unsupportedPcrs = tpm2.HandleList{ internal_efi.PlatformConfigPCR, internal_efi.DriversAndAppsConfigPCR, @@ -198,7 +210,7 @@ type RunChecksContext struct { // proceedFlags indicates the CheckFlags that can be enabled if Run is called // with ActionProceed. - proceedFlags CheckFlags + proceedFlags map[ErrorKind]CheckFlags } // NewRunChecksContext returns a new RunChecksContext instance with the initial flags for [RunChecks] @@ -376,7 +388,7 @@ func insertActionProceed(actions []Action) []Action { // (see the documentation for each error kind). // // Note that certain errors can make some actions become unavailable. -func (c *RunChecksContext) classifyRunChecksError(err error) (info errorInfo, outErr error) { +func (c *RunChecksContext) classifyRunChecksError(ctx context.Context, err error) (info errorInfo, outErr error) { defer func() { if outErr != nil { return @@ -579,7 +591,22 @@ func (c *RunChecksContext) classifyRunChecksError(err error) (info errorInfo, ou } if errors.Is(err, ErrNoSecureBoot) || errors.Is(err, ErrNoDeployedMode) { - return errorInfo{kind: ErrorKindInvalidSecureBootMode}, nil + varCtx := runChecksEnv.VarContext(ctx) + enabled, err := efi.ReadSecureBootVariable(varCtx) + if err != nil { + return errorInfo{}, fmt.Errorf("cannot read secure boot variable: %w", err) + } + mode, err := efi.ComputeSecureBootMode(varCtx) + if err != nil { + return errorInfo{}, fmt.Errorf("cannot compute secure boot mode: %w", err) + } + return errorInfo{ + kind: ErrorKindInvalidSecureBootMode, + args: SecureBootModeArg{ + Enabled: enabled, + Mode: mode, + }, + }, nil } if errors.Is(err, ErrWeakSecureBootAlgorithmDetected) { return errorInfo{kind: ErrorKindWeakSecureBootAlgorithmsDetected}, nil @@ -755,20 +782,14 @@ func (c *RunChecksContext) runAction(action Action, args map[string]json.RawMess } for i, kind := range kinds { - flag, ok := errorKindToProceedFlag[kind] - if !ok { - return NewWithKindAndActionsError( - ErrorKindInvalidArgument, - InvalidActionArgumentDetails{ - Field: fieldName, - Reason: InvalidActionArgumentReasonValue, - }, - nil, // actions - fmt.Errorf("invalid value for argument %q at index %d: %q does not support the %q action", fieldName, i, kind, ActionProceed), - ) + var ( + flag CheckFlags + ok bool + ) + if c.proceedFlags != nil { + flag, ok = c.proceedFlags[kind] } - - if c.proceedFlags&flag == 0 { + if !ok { return NewWithKindAndActionsError( ErrorKindInvalidArgument, InvalidActionArgumentDetails{ @@ -781,15 +802,17 @@ func (c *RunChecksContext) runAction(action Action, args map[string]json.RawMess } proceedFlags |= flag - c.proceedFlags &^= flag + delete(c.proceedFlags, kind) } } - if proceedFlags == CheckFlags(0) { + if proceedFlags == CheckFlags(0) && c.proceedFlags != nil { // Handle the case where no argument is supplied or // an empty []ErrorKind slice is supplied - proceedFlags = c.proceedFlags - c.proceedFlags = 0 + for _, flag := range c.proceedFlags { + proceedFlags |= flag + } + c.proceedFlags = nil } c.flags |= proceedFlags @@ -869,7 +892,7 @@ func (c *RunChecksContext) Run(ctx context.Context, action Action, args map[stri c.expectedActions = nil // Reset the flags that would be enabled if ActionProceed is used. - c.proceedFlags = 0 + c.proceedFlags = nil // errInfo contains the error kind and arguments for each error. var errInfo []errorInfo @@ -879,7 +902,7 @@ func (c *RunChecksContext) Run(ctx context.Context, action Action, args map[stri // the WithKindAndActionsError because some errors encountered here // may change the available actions. for _, e := range unwrapCompoundError(err) { - info, err := c.classifyRunChecksError(e) + info, err := c.classifyRunChecksError(ctx, e) if err != nil { return nil, NewWithKindAndActionsError( ErrorKindInternal, @@ -901,6 +924,8 @@ func (c *RunChecksContext) Run(ctx context.Context, action Action, args map[stri // ordering these errors to appear after all other errors. var errsProceed []*WithKindAndActionsError + proceedFlags := make(map[ErrorKind]CheckFlags) + // Iterate over the error info, creating a WithKindAndActionsError // for each one with associated actions. for _, info := range errInfo { @@ -914,7 +939,11 @@ func (c *RunChecksContext) Run(ctx context.Context, action Action, args map[stri ) } - if _, canProceed := errorKindToProceedFlag[info.kind]; !canProceed { + proceedFlag, canProceed := errorKindToProceedFlag[info.kind] + if !canProceed { + proceedFlag, canProceed = errorKindWithArgsToProceedFlag[errorKindWithArgs{kind: info.kind, args: info.args}] + } + if !canProceed { // This error kind doesn't support ActionProceed. Don't // permit it at all for now, waiting until all of the errors // we return support it. @@ -922,6 +951,7 @@ func (c *RunChecksContext) Run(ctx context.Context, action Action, args map[stri errs = append(errs, NewWithKindAndActionsError(info.kind, info.args, actions, info.err)) } else { errsProceed = append(errsProceed, NewWithKindAndActionsError(info.kind, info.args, actions, info.err)) + proceedFlags[info.kind] = proceedFlag } c.expectedActions = append(c.expectedActions, actions...) @@ -931,14 +961,14 @@ func (c *RunChecksContext) Run(ctx context.Context, action Action, args map[stri // right now, and append these errors to the list of errors we return. for _, e := range errsProceed { if permitActionProceed { - flag := errorKindToProceedFlag[e.Kind] - c.proceedFlags |= flag e.Actions = insertActionProceed(e.Actions) } errs = append(errs, e) } - - if c.proceedFlags != 0 { + if permitActionProceed { + c.proceedFlags = proceedFlags + } + if len(c.proceedFlags) > 0 { // We are returning errors with ActionProceed enabled. c.expectedActions = append(c.expectedActions, ActionProceed) } diff --git a/efi/preinstall/checks_context_test.go b/efi/preinstall/checks_context_test.go index 8bcddf6c..26ec19a6 100644 --- a/efi/preinstall/checks_context_test.go +++ b/efi/preinstall/checks_context_test.go @@ -241,12 +241,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -313,12 +311,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256, tpm2.HashAlgorithmSHA384}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -384,12 +380,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA1}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -461,12 +455,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, DMAProtection: efitest.DMAProtectionDisabled, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -540,12 +532,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, DMAProtection: efitest.DMAProtectionDisabled, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -633,12 +623,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -705,12 +693,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -752,12 +738,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -827,12 +811,10 @@ C7E003CB efitest.WithVirtMode("qemu", internal_efi.DetectVirtModeVM), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -902,12 +884,10 @@ C7E003CB efitest.WithVirtMode("qemu", internal_efi.DetectVirtModeVM), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -996,12 +976,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, StartupLocality: 3, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1072,12 +1050,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, StartupLocality: 4, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1146,12 +1122,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1230,12 +1204,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1314,12 +1286,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1397,12 +1367,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeDriverLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1478,12 +1446,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeDriverLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1604,12 +1570,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeSysPrepAppLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1697,12 +1661,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeSysPrepAppLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1842,12 +1804,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeOSPresentFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1920,12 +1880,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeOSPresentFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2021,12 +1979,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2101,12 +2057,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA256, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2151,6 +2105,174 @@ C7E003CB c.Check(errs, HasLen, 0) } +func (s *runChecksContextSuite) TestRunGoodActionProceedPermitSecureBootUserMode(c *C) { + meiAttrs := map[string][]byte{ + "fw_ver": []byte(`0:16.1.27.2176 +0:16.1.27.2176 +0:16.0.15.1624 +`), + "fw_status": []byte(`94000245 +09F10506 +00000020 +00004000 +00041F03 +C7E003CB +`), + } + devices := []internal_efi.SysfsDevice{ + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar0", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar1", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", meiAttrs, efitest.NewMockSysfsDevice( + "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, + )), + } + + errs := s.testRun(c, &testRunChecksContextRunParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), + efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + })), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithSysfsDevices(devices...), + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + ), + tpmPropertyModifiers: map[tpm2.Property]uint32{ + tpm2.PropertyNVCountersMax: 0, + tpm2.PropertyPSFamilyIndicator: 1, + tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), + }, + enabledBanks: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + iterations: 2, + loadedImages: []secboot_efi.Image{ + &mockImage{ + contents: []byte("mock shim executable"), + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + }, + &mockImage{contents: []byte("mock grub executable"), digest: testutil.DecodeHexString(c, "d5a9780e9f6a43c2e53fe9fda547be77f7783f31aea8013783242b040ff21dc0")}, + &mockImage{contents: []byte("mock kernel executable"), digest: testutil.DecodeHexString(c, "2ddfbd91fa1698b0d133c38ba90dbba76c9e08371ff83d03b5fb4c2e56d7e81f")}, + }, + profileOpts: PCRProfileOptionsDefault, + actions: []actionAndArgs{ + {action: ActionNone}, + {action: ActionProceed}, + }, + checkIntermediateErrs: func(i int, errs []*WithKindAndActionsError) { + switch i { + case 0: + c.Assert(errs, HasLen, 1) + + c.Check(errs[0], ErrorMatches, `secure boot is enabled but not in deployed mode`) + c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( + ErrorKindInvalidSecureBootMode, + SecureBootModeArg{ + Enabled: true, + Mode: efi.UserMode, + }, + []Action{ActionRebootToFWSettings, ActionProceed}, + ErrNoDeployedMode, + )) + } + }, + expectedPcrAlg: tpm2.HashAlgorithmSHA256, + expectedUsedSecureBootCAs: []*X509CertificateID{NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert))}, + expectedFlags: NoPlatformConfigProfileSupport | NoDriversAndAppsConfigProfileSupport | NoBootManagerConfigProfileSupport, + expectedAcceptedErrors: map[ErrorKind]json.RawMessage{ + ErrorKindInvalidSecureBootMode: nil, + }, + expectedWarningsMatch: `4 errors detected: +- error with platform config \(PCR1\) measurements: generating profiles for PCR 1 is not supported yet, see https://github.com/canonical/secboot/issues/322 +- error with drivers and apps config \(PCR3\) measurements: generating profiles for PCR 3 is not supported yet, see https://github.com/canonical/secboot/issues/341 +- error with boot manager config \(PCR5\) measurements: generating profiles for PCR 5 is not supported yet, see https://github.com/canonical/secboot/issues/323 +- secure boot is enabled but not in deployed mode +`, + }) + c.Check(errs, HasLen, 0) +} + +func (s *runChecksContextSuite) TestRunGoodPermitSecureBootUserModeFromInitialFlags(c *C) { + meiAttrs := map[string][]byte{ + "fw_ver": []byte(`0:16.1.27.2176 +0:16.1.27.2176 +0:16.0.15.1624 +`), + "fw_status": []byte(`94000245 +09F10506 +00000020 +00004000 +00041F03 +C7E003CB +`), + } + devices := []internal_efi.SysfsDevice{ + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar0", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar1", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", meiAttrs, efitest.NewMockSysfsDevice( + "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, + )), + } + + errs := s.testRun(c, &testRunChecksContextRunParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), + efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + })), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithSysfsDevices(devices...), + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + ), + tpmPropertyModifiers: map[tpm2.Property]uint32{ + tpm2.PropertyNVCountersMax: 0, + tpm2.PropertyPSFamilyIndicator: 1, + tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), + }, + enabledBanks: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + initialFlags: PermitSecureBootUserMode, + loadedImages: []secboot_efi.Image{ + &mockImage{ + contents: []byte("mock shim executable"), + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + }, + &mockImage{contents: []byte("mock grub executable"), digest: testutil.DecodeHexString(c, "d5a9780e9f6a43c2e53fe9fda547be77f7783f31aea8013783242b040ff21dc0")}, + &mockImage{contents: []byte("mock kernel executable"), digest: testutil.DecodeHexString(c, "2ddfbd91fa1698b0d133c38ba90dbba76c9e08371ff83d03b5fb4c2e56d7e81f")}, + }, + profileOpts: PCRProfileOptionsDefault, + actions: []actionAndArgs{{action: ActionNone}}, + expectedPcrAlg: tpm2.HashAlgorithmSHA256, + expectedUsedSecureBootCAs: []*X509CertificateID{NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert))}, + expectedFlags: NoPlatformConfigProfileSupport | NoDriversAndAppsConfigProfileSupport | NoBootManagerConfigProfileSupport, + expectedAcceptedErrors: map[ErrorKind]json.RawMessage{ + ErrorKindInvalidSecureBootMode: nil, + }, + expectedWarningsMatch: `4 errors detected: +- error with platform config \(PCR1\) measurements: generating profiles for PCR 1 is not supported yet, see https://github.com/canonical/secboot/issues/322 +- error with drivers and apps config \(PCR3\) measurements: generating profiles for PCR 3 is not supported yet, see https://github.com/canonical/secboot/issues/341 +- error with boot manager config \(PCR5\) measurements: generating profiles for PCR 5 is not supported yet, see https://github.com/canonical/secboot/issues/323 +- secure boot is enabled but not in deployed mode +`, + }) + c.Check(errs, HasLen, 0) +} + func (s *runChecksContextSuite) TestRunGoodActionProceedPermitPreOSSecureBootAuthByEnrolledDigests(c *C) { // Test that ActionProceed enables the PermitPreOSSecureBootAuthByEnrolledDigests flag. As // this test generates 2 errors, it also tests the case where ActionProceed can @@ -2185,12 +2307,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA256, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2322,12 +2442,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA1, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2408,12 +2526,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA1, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2555,12 +2671,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA1, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2725,12 +2839,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2824,12 +2936,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2932,12 +3042,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3041,12 +3149,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3139,12 +3245,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3214,12 +3318,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, StartupLocality: 3, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3373,12 +3475,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ - {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Err: efi.ErrVarDeviceError}, + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Err: efi.ErrVarDeviceError}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3406,7 +3506,7 @@ C7E003CB expectedPcrAlg: tpm2.HashAlgorithmSHA256, }) c.Check(errs, HasLen, 1) - c.Assert(errs[0], ErrorMatches, `cannot access EFI variable: cannot obtain boot option support: variable access failed because of a hardware error`) + c.Assert(errs[0], ErrorMatches, `cannot access EFI variable: cannot compute secure boot mode: cannot read AuditMode variable: variable access failed because of a hardware error`) c.Check(errs[0], DeepEquals, NewWithKindAndActionsError(ErrorKindEFIVariableAccess, EFIVarDeviceError, []Action{ActionContactOEM}, errs[0].Unwrap())) } @@ -3652,12 +3752,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3671,21 +3769,18 @@ C7E003CB enabledBanks: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, profileOpts: PCRProfileOptionsDefault, prepare: func(_ int) { - // Set an authorization value for the endorsement hierarchy and - // an authorization policy for the storage hierarchy. + // Set an authorization value for the endorsement hierarchy s.HierarchyChangeAuth(c, tpm2.HandleEndorsement, []byte("1234")) - c.Check(s.TPM.SetPrimaryPolicy(s.TPM.OwnerHandleContext(), make([]byte, 32), tpm2.HashAlgorithmSHA256, nil), IsNil) }, actions: []actionAndArgs{{action: ActionNone}}, }) c.Assert(errs, HasLen, 1) c.Check(errs[0], ErrorMatches, `error with TPM2 device: one or more of the TPM hierarchies is already owned: - TPM_RH_ENDORSEMENT has an authorization value -- TPM_RH_OWNER has an authorization policy `) c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( ErrorKindTPMHierarchiesOwned, - &TPM2OwnedHierarchiesError{WithAuthValue: tpm2.HandleList{tpm2.HandleEndorsement}, WithAuthPolicy: tpm2.HandleList{tpm2.HandleOwner}}, + &TPM2OwnedHierarchiesError{WithAuthValue: tpm2.HandleList{tpm2.HandleEndorsement}}, []Action{ActionClearTPMViaFirmware, ActionEnableAndClearTPMViaFirmware, ActionClearTPMSimple, ActionClearTPM, ActionRebootToFWSettings}, errs[0].Unwrap(), )) @@ -3731,12 +3826,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3753,11 +3846,9 @@ C7E003CB prepare: func(i int) { switch i { case 0: - // Set an authorization value for the endorsement hierarchy and - // an authorization policy for the storage hierarchy on the + // Set an authorization value for the endorsement hierarchy on the // first iteration. s.HierarchyChangeAuth(c, tpm2.HandleEndorsement, []byte("1234")) - c.Check(s.TPM.SetPrimaryPolicy(s.TPM.OwnerHandleContext(), make([]byte, 32), tpm2.HashAlgorithmSHA256, nil), IsNil) } }, actions: []actionAndArgs{ @@ -3770,7 +3861,7 @@ C7E003CB c.Assert(errs, HasLen, 1) c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( ErrorKindTPMHierarchiesOwned, - &TPM2OwnedHierarchiesError{WithAuthValue: tpm2.HandleList{tpm2.HandleEndorsement}, WithAuthPolicy: tpm2.HandleList{tpm2.HandleOwner}}, + &TPM2OwnedHierarchiesError{WithAuthValue: tpm2.HandleList{tpm2.HandleEndorsement}}, []Action{ActionClearTPMViaFirmware, ActionEnableAndClearTPMViaFirmware, ActionClearTPMSimple, ActionClearTPM, ActionRebootToFWSettings}, errs[0].Unwrap(), )) @@ -3824,12 +3915,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3846,11 +3935,8 @@ C7E003CB prepare: func(i int) { switch i { case 0: - // Set an authorization value for the endorsement hierarchy and - // an authorization policy for the storage hierarchy on the - // first iteration. + // Set an authorization value for the endorsement hierarchy on the first iteration. s.HierarchyChangeAuth(c, tpm2.HandleEndorsement, []byte("1234")) - c.Check(s.TPM.SetPrimaryPolicy(s.TPM.OwnerHandleContext(), make([]byte, 32), tpm2.HashAlgorithmSHA256, nil), IsNil) } }, actions: []actionAndArgs{ @@ -3863,7 +3949,7 @@ C7E003CB c.Assert(errs, HasLen, 1) c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( ErrorKindTPMHierarchiesOwned, - &TPM2OwnedHierarchiesError{WithAuthValue: tpm2.HandleList{tpm2.HandleEndorsement}, WithAuthPolicy: tpm2.HandleList{tpm2.HandleOwner}}, + &TPM2OwnedHierarchiesError{WithAuthValue: tpm2.HandleList{tpm2.HandleEndorsement}}, []Action{ActionClearTPMViaFirmware, ActionEnableAndClearTPMViaFirmware, ActionClearTPMSimple, ActionClearTPM, ActionRebootToFWSettings}, errs[0].Unwrap(), )) @@ -3917,12 +4003,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4007,12 +4091,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4115,12 +4197,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4223,12 +4303,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4293,12 +4371,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4373,12 +4449,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4456,12 +4530,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4511,7 +4583,7 @@ func (s *runChecksContextSuite) TestRunBadTCGLog(c *C) { efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), ), tpmPropertyModifiers: map[tpm2.Property]uint32{ tpm2.PropertyNVCountersMax: 0, @@ -4559,12 +4631,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4633,12 +4703,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4708,12 +4776,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4786,7 +4852,7 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, FirmwareDebugger: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -4834,7 +4900,7 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, DMAProtection: efitest.DMAProtectionDisabled, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -4882,7 +4948,7 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -4944,7 +5010,7 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, StartupLocality: 3, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (2 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -4993,7 +5059,7 @@ func (s *runChecksContextSuite) TestRunBadHostSecurityErrorMissingIntelMEModule( efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -5039,7 +5105,7 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 0, nil), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 0, nil), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -5086,7 +5152,7 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -5099,7 +5165,7 @@ C7E003CB actions: []actionAndArgs{{action: ActionNone}}, }) c.Assert(errs, HasLen, 1) - c.Check(errs[0], ErrorMatches, `error with system security: encountered an error when checking Intel BootGuard configuration: no hardware root-of-trust properly configured: ME is in manufacturing mode`) + c.Check(errs[0], ErrorMatches, `error with system security: encountered an error when checking Intel BootGuard configuration: no hardware root-of-trust properly configured: system is in manufacturing mode`) c.Check(errs[0], DeepEquals, NewWithKindAndActionsError(ErrorKindHostSecurity, nil, []Action{ActionContactOEM}, errs[0].Unwrap())) } @@ -5132,12 +5198,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA1}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -5203,12 +5267,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -5277,12 +5339,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -5356,12 +5416,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeDriverLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -5460,12 +5518,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeSysPrepAppLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -5583,12 +5639,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeOSPresentFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -5659,12 +5713,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -5695,75 +5747,6 @@ C7E003CB c.Check(errs[0], DeepEquals, NewWithKindAndActionsError(ErrorKindPCRUnusable, PCRUnusableArg(4), []Action{ActionContactOEM}, errs[0].Unwrap())) } -func (s *runChecksContextSuite) TestRunBadInvalidSecureBootMode(c *C) { - // Test the error case where PCR7 is mandatory with the supplied profile options, - // but is marked invalid because the system is not in deployed mode. Note that it is - // my intention to support user mode in the future. - meiAttrs := map[string][]byte{ - "fw_ver": []byte(`0:16.1.27.2176 -0:16.1.27.2176 -0:16.0.15.1624 -`), - "fw_status": []byte(`94000245 -09F10506 -00000020 -00004000 -00041F03 -C7E003CB -`), - } - devices := []internal_efi.SysfsDevice{ - efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar0", nil, "iommu", nil, nil), - efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar1", nil, "iommu", nil, nil), - efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", meiAttrs, efitest.NewMockSysfsDevice( - "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, - )), - } - - errs := s.testRun(c, &testRunChecksContextRunParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), - efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ - Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), - efitest.WithSysfsDevices(devices...), - efitest.WithMockVars(efitest.MockVars{ - {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), - ), - tpmPropertyModifiers: map[tpm2.Property]uint32{ - tpm2.PropertyNVCountersMax: 0, - tpm2.PropertyPSFamilyIndicator: 1, - tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), - }, - enabledBanks: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - loadedImages: []secboot_efi.Image{ - &mockImage{ - contents: []byte("mock shim executable"), - digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), - signatures: []*efi.WinCertificateAuthenticode{ - efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), - }, - }, - &mockImage{contents: []byte("mock grub executable"), digest: testutil.DecodeHexString(c, "d5a9780e9f6a43c2e53fe9fda547be77f7783f31aea8013783242b040ff21dc0")}, - &mockImage{contents: []byte("mock kernel executable"), digest: testutil.DecodeHexString(c, "2ddfbd91fa1698b0d133c38ba90dbba76c9e08371ff83d03b5fb4c2e56d7e81f")}, - }, - profileOpts: PCRProfileOptionsDefault, - actions: []actionAndArgs{{action: ActionNone}}, - expectedPcrAlg: tpm2.HashAlgorithmSHA256, - }) - c.Check(errs, HasLen, 1) - c.Check(errs[0], ErrorMatches, `error with secure boot policy \(PCR7\) measurements: deployed mode should be enabled in order to generate secure boot profiles`) - c.Check(errs[0], DeepEquals, NewWithKindAndActionsError(ErrorKindInvalidSecureBootMode, nil, []Action{ActionRebootToFWSettings}, errs[0].Unwrap())) -} - func (s *runChecksContextSuite) TestRunBadInvalidSecureBootModeSecureBootDisabled(c *C) { // Test the error case where PCR7 is mandatory with the supplied profile options, // but is marked invalid because secure boot is disabled. @@ -5796,12 +5779,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, SecureBootDisabled: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -5830,7 +5811,15 @@ C7E003CB }) c.Check(errs, HasLen, 1) c.Check(errs[0], ErrorMatches, `error with secure boot policy \(PCR7\) measurements: secure boot should be enabled in order to generate secure boot profiles`) - c.Check(errs[0], DeepEquals, NewWithKindAndActionsError(ErrorKindInvalidSecureBootMode, nil, []Action{ActionRebootToFWSettings}, errs[0].Unwrap())) + c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( + ErrorKindInvalidSecureBootMode, + SecureBootModeArg{ + Enabled: false, + Mode: efi.UserMode, + }, + []Action{ActionRebootToFWSettings}, + errs[0].Unwrap(), + )) } func (s *runChecksContextSuite) TestRunBadInvalidSecureBootModeSecureBootDisabledAndNoSBATLevel(c *C) { @@ -5868,12 +5857,10 @@ C7E003CB SecureBootDisabled: true, NoSBAT: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -5902,7 +5889,15 @@ C7E003CB }) c.Check(errs, HasLen, 1) c.Check(errs[0], ErrorMatches, `error with secure boot policy \(PCR7\) measurements: secure boot should be enabled in order to generate secure boot profiles`) - c.Check(errs[0], DeepEquals, NewWithKindAndActionsError(ErrorKindInvalidSecureBootMode, nil, []Action{ActionRebootToFWSettings}, errs[0].Unwrap())) + c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( + ErrorKindInvalidSecureBootMode, + SecureBootModeArg{ + Enabled: false, + Mode: efi.UserMode, + }, + []Action{ActionRebootToFWSettings}, + errs[0].Unwrap(), + )) } func (s *runChecksContextSuite) TestRunBadNoSecureBootPolicySupport(c *C) { @@ -5954,12 +5949,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(log), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -6025,12 +6018,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA1, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -6113,6 +6104,80 @@ C7E003CB )) } +func (s *runChecksContextSuite) TestRunBadInvalidSecureBootModeNoDeployedMode(c *C) { + // Test the error case where PCR7 is mandatory with the supplied profile options, + // but is marked invalid because the system is not in deployed mode. + meiAttrs := map[string][]byte{ + "fw_ver": []byte(`0:16.1.27.2176 +0:16.1.27.2176 +0:16.0.15.1624 +`), + "fw_status": []byte(`94000245 +09F10506 +00000020 +00004000 +00041F03 +C7E003CB +`), + } + devices := []internal_efi.SysfsDevice{ + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar0", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar1", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", meiAttrs, efitest.NewMockSysfsDevice( + "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, + )), + } + + errs := s.testRun(c, &testRunChecksContextRunParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), + efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ + Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + })), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithSysfsDevices(devices...), + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + ), + tpmPropertyModifiers: map[tpm2.Property]uint32{ + tpm2.PropertyNVCountersMax: 0, + tpm2.PropertyPSFamilyIndicator: 1, + tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), + }, + enabledBanks: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + loadedImages: []secboot_efi.Image{ + &mockImage{ + contents: []byte("mock shim executable"), + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + }, + &mockImage{contents: []byte("mock grub executable"), digest: testutil.DecodeHexString(c, "d5a9780e9f6a43c2e53fe9fda547be77f7783f31aea8013783242b040ff21dc0")}, + &mockImage{contents: []byte("mock kernel executable"), digest: testutil.DecodeHexString(c, "2ddfbd91fa1698b0d133c38ba90dbba76c9e08371ff83d03b5fb4c2e56d7e81f")}, + }, + profileOpts: PCRProfileOptionsDefault, + actions: []actionAndArgs{{action: ActionNone}}, + expectedPcrAlg: tpm2.HashAlgorithmSHA256, + }) + c.Assert(errs, HasLen, 1) + c.Check(errs[0], ErrorMatches, `secure boot is enabled but not in deployed mode`) + c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( + ErrorKindInvalidSecureBootMode, + SecureBootModeArg{ + Enabled: true, + Mode: efi.UserMode, + }, + []Action{ActionRebootToFWSettings, ActionProceed}, + ErrNoDeployedMode, + )) +} + // TODO: This is disabled temporarily until a follow-up PR which adds warnings to the returned errors // if RunChecks is going to return one or more errors anyway. //func (s *runChecksContextSuite) TestRunChecksBadTPMHierarchiesOwnedAndNoSecureBootPolicySupport(c *C) { @@ -6145,12 +6210,10 @@ C7E003CB // efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ // Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, // })), -// efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), +// efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), // efitest.WithSysfsDevices(devices...), // efitest.WithMockVars(efitest.MockVars{ // {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, -// {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, -// {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, // {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, // {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, // {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -6224,12 +6287,10 @@ C7E003CB // efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ // Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, // })), -// efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), +// efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), // efitest.WithSysfsDevices(devices...), // efitest.WithMockVars(efitest.MockVars{ // {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, -// {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, -// {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, // {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, // {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, // {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -6302,12 +6363,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, DMAProtection: efitest.DMAProtectionDisabled, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -6466,12 +6525,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -6485,21 +6542,18 @@ C7E003CB enabledBanks: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, profileOpts: PCRProfileOptionsDefault, prepare: func(_ int) { - // Set an authorization value for the endorsement hierarchy and - // an authorization policy for the storage hierarchy. + // Set an authorization value for the endorsement hierarchy s.HierarchyChangeAuth(c, tpm2.HandleEndorsement, []byte("1234")) - c.Check(s.TPM.SetPrimaryPolicy(s.TPM.OwnerHandleContext(), make([]byte, 32), tpm2.HashAlgorithmSHA256, nil), IsNil) }, actions: []actionAndArgs{{action: ActionNone}}, }) c.Assert(errs, HasLen, 1) c.Check(errs[0], ErrorMatches, `error with TPM2 device: one or more of the TPM hierarchies is already owned: - TPM_RH_ENDORSEMENT has an authorization value -- TPM_RH_OWNER has an authorization policy `) c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( ErrorKindTPMHierarchiesOwned, - &TPM2OwnedHierarchiesError{WithAuthValue: tpm2.HandleList{tpm2.HandleEndorsement}, WithAuthPolicy: tpm2.HandleList{tpm2.HandleOwner}}, + &TPM2OwnedHierarchiesError{WithAuthValue: tpm2.HandleList{tpm2.HandleEndorsement}}, []Action{ActionEnableAndClearTPMViaFirmware, ActionClearTPMSimple, ActionClearTPM, ActionRebootToFWSettings}, errs[0].Unwrap(), )) @@ -6591,12 +6645,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, DMAProtection: efitest.DMAProtectionDisabled, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -6677,7 +6729,7 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, DMAProtection: efitest.DMAProtectionDisabled, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -6747,12 +6799,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeDriverLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -6838,129 +6888,6 @@ C7E003CB )) } -func (s *runChecksContextSuite) TestRunChecksActionProceedUnsupportedErrorKind(c *C) { - // Test that passing an unsupported ErrorKind as an argument to ActionProceed - // generates an error. - meiAttrs := map[string][]byte{ - "fw_ver": []byte(`0:16.1.27.2176 -0:16.1.27.2176 -0:16.0.15.1624 -`), - "fw_status": []byte(`94000245 -09F10506 -00000020 -00004000 -00041F03 -C7E003CB -`), - } - devices := []internal_efi.SysfsDevice{ - efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar0", nil, "iommu", nil, nil), - efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar1", nil, "iommu", nil, nil), - efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", meiAttrs, efitest.NewMockSysfsDevice( - "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, - )), - } - - errs := s.testRun(c, &testRunChecksContextRunParams{ - env: efitest.NewMockHostEnvironmentWithOpts( - efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), - efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ - Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - IncludeDriverLaunch: true, - })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), - efitest.WithSysfsDevices(devices...), - efitest.WithMockVars(efitest.MockVars{ - {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, - {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, - {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), - ), - tpmPropertyModifiers: map[tpm2.Property]uint32{ - tpm2.PropertyNVCountersMax: 0, - tpm2.PropertyPSFamilyIndicator: 1, - tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), - }, - enabledBanks: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - iterations: 2, - loadedImages: []secboot_efi.Image{ - &mockImage{ - contents: []byte("mock shim executable"), - digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), - signatures: []*efi.WinCertificateAuthenticode{ - efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), - }, - }, - &mockImage{contents: []byte("mock grub executable"), digest: testutil.DecodeHexString(c, "d5a9780e9f6a43c2e53fe9fda547be77f7783f31aea8013783242b040ff21dc0")}, - &mockImage{contents: []byte("mock kernel executable"), digest: testutil.DecodeHexString(c, "2ddfbd91fa1698b0d133c38ba90dbba76c9e08371ff83d03b5fb4c2e56d7e81f")}, - }, - profileOpts: PCRProfileOptionsDefault, - actions: []actionAndArgs{ - {action: ActionNone}, - {action: ActionProceed, args: ActionProceedArgs{ErrorKindInvalidSecureBootMode}}, - }, - checkIntermediateErrs: func(i int, errs []*WithKindAndActionsError) { - switch i { - case 0: - c.Check(errs, HasLen, 1) - imageInfo := []*LoadedImageInfo{ - { - DevicePath: efi.DevicePath{ - &efi.ACPIDevicePathNode{ - HID: 0x0a0341d0, - UID: 0x0, - }, - &efi.PCIDevicePathNode{ - Function: 0x1c, - Device: 0x2, - }, - &efi.PCIDevicePathNode{ - Function: 0x0, - Device: 0x0, - }, - &efi.MediaRelOffsetRangeDevicePathNode{ - StartingOffset: 0x38, - EndingOffset: 0x11dff, - }, - }, - DigestAlg: tpm2.HashAlgorithmSHA256, - Digest: testutil.DecodeHexString(c, "1e94aaed2ad59a4409f3230dca2ad8c03ef8e3fde77cc47dc7b81bb8b242f3e6"), - }, - } - - c.Check(errs[0], ErrorMatches, `addon drivers were detected: -- \[no description\] path=\\PciRoot\(0x0\)\\Pci\(0x2,0x1c\)\\Pci\(0x0,0x0\)\\Offset\(0x38,0x11dff\) authenticode-digest=TPM_ALG_SHA256:1e94aaed2ad59a4409f3230dca2ad8c03ef8e3fde77cc47dc7b81bb8b242f3e6 -`) - c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( - ErrorKindAddonDriversPresent, - LoadedImagesInfoArg(imageInfo), - []Action{ActionProceed}, - &AddonDriversPresentError{ - Drivers: imageInfo, - }, - )) - } - }, - expectedPcrAlg: tpm2.HashAlgorithmSHA256, - }) - c.Assert(errs, HasLen, 1) - c.Check(errs[0], ErrorMatches, `invalid value for argument "error-kinds" at index 0: "invalid-secure-boot-mode" does not support the "proceed" action`) - c.Check(errs[0], DeepEquals, NewWithKindAndActionsError( - ErrorKindInvalidArgument, - InvalidActionArgumentDetails{ - Field: "error-kinds", - Reason: InvalidActionArgumentReasonValue, - }, - nil, - errs[0].Unwrap(), - )) -} - func (s *runChecksContextSuite) TestRunChecksActionProceedUnexpectedErrorKind1(c *C) { // Test that passing an unexpected ErrorKind as an argument to ActionProceed // generates an error. @@ -6993,12 +6920,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeDriverLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -7117,12 +7042,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA256, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -7258,12 +7181,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA256, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -7397,12 +7318,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -7478,12 +7397,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -7555,12 +7472,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -7670,12 +7585,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -7785,12 +7698,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -7913,12 +7824,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -8030,12 +7939,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -8146,12 +8053,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -8261,12 +8166,10 @@ C7E003CB nil, )), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0x13a: (3 << 1), 0xc80: 0x40000000}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, diff --git a/efi/preinstall/checks_test.go b/efi/preinstall/checks_test.go index 8359de09..9e7effa2 100644 --- a/efi/preinstall/checks_test.go +++ b/efi/preinstall/checks_test.go @@ -154,12 +154,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -237,12 +235,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256, tpm2.HashAlgorithmSHA384}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -316,12 +312,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA1}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -395,12 +389,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -479,12 +471,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -543,8 +533,6 @@ func (s *runChecksSuite) TestRunChecksGoodVirtualMachine(c *C) { efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -622,12 +610,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -710,12 +696,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, StartupLocality: 3, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -792,12 +776,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, StartupLocality: 3, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -880,12 +862,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, StartupLocality: 4, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -962,12 +942,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, StartupLocality: 4, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1047,12 +1025,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1135,12 +1111,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (2 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1231,12 +1205,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1321,12 +1293,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1411,12 +1381,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1502,12 +1470,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeDriverLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1615,12 +1581,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeDriverLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1737,12 +1701,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeSysPrepAppLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -1869,12 +1831,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeSysPrepAppLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2010,12 +1970,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeOSPresentFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2095,12 +2053,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeOSPresentFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2188,12 +2144,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2279,12 +2233,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA256, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2396,12 +2348,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA256, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2522,12 +2472,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA1, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2642,12 +2590,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA1, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2767,16 +2713,14 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + }.SetSecureBoot(false).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), ), tpmPropertyModifiers: map[tpm2.Property]uint32{ tpm2.PropertyNVCountersMax: 0, @@ -2818,7 +2762,90 @@ C7E003CB c.Check(errors.As(warning, &bmce), testutil.IsTrue) warning = warnings[3] - c.Check(warning, ErrorMatches, `error with secure boot policy \(PCR7\) measurements: deployed mode should be enabled in order to generate secure boot profiles`) + c.Check(warning, ErrorMatches, `error with secure boot policy \(PCR7\) measurements: secure boot should be enabled in order to generate secure boot profiles`) + var sbpe *SecureBootPolicyPCRError + c.Assert(errors.As(warning, &sbpe), testutil.IsTrue) + c.Check(errors.Is(sbpe, ErrNoSecureBoot), testutil.IsTrue) +} + +func (s *runChecksSuite) TestRunChecksGoodNoSecureBootDeployedMode(c *C) { + meiAttrs := map[string][]byte{ + "fw_ver": []byte(`0:16.1.27.2176 +0:16.1.27.2176 +0:16.0.15.1624 +`), + "fw_status": []byte(`94000245 +09F10506 +00000020 +00004000 +00041F03 +C7E003CB +`), + } + devices := []internal_efi.SysfsDevice{ + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar0", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/virtual/iommu/dmar1", nil, "iommu", nil, nil), + efitest.NewMockSysfsDevice("/sys/devices/pci0000:00/0000:00:16.0/mei/mei0", map[string]string{"DEVNAME": "mei0"}, "mei", meiAttrs, efitest.NewMockSysfsDevice( + "/sys/devices/pci0000:00:16:0", map[string]string{"DRIVER": "mei_me"}, "pci", nil, nil, + )), + } + + warnings, err := s.testRunChecks(c, &testRunChecksParams{ + env: efitest.NewMockHostEnvironmentWithOpts( + efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), + efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithSysfsDevices(devices...), + efitest.WithMockVars(efitest.MockVars{ + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, + {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + ), + tpmPropertyModifiers: map[tpm2.Property]uint32{ + tpm2.PropertyNVCountersMax: 0, + tpm2.PropertyPSFamilyIndicator: 1, + tpm2.PropertyManufacturer: uint32(tpm2.TPMManufacturerINTC), + }, + enabledBanks: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, + flags: PermitNoPlatformConfigProfileSupport | PermitNoDriversAndAppsConfigProfileSupport | PermitNoBootManagerConfigProfileSupport | PermitSecureBootUserMode, + loadedImages: []secboot_efi.Image{ + &mockImage{ + contents: []byte("mock shim executable"), + digest: testutil.DecodeHexString(c, "25e1b08db2f31ff5f5d2ea53e1a1e8fda6e1d81af4f26a7908071f1dec8611b7"), + signatures: []*efi.WinCertificateAuthenticode{ + efitest.ReadWinCertificateAuthenticodeDetached(c, shimUbuntuSig4), + }, + }, + &mockImage{contents: []byte("mock grub executable"), digest: testutil.DecodeHexString(c, "d5a9780e9f6a43c2e53fe9fda547be77f7783f31aea8013783242b040ff21dc0")}, + &mockImage{contents: []byte("mock kernel executable"), digest: testutil.DecodeHexString(c, "2ddfbd91fa1698b0d133c38ba90dbba76c9e08371ff83d03b5fb4c2e56d7e81f")}, + }, + expectedPcrAlg: tpm2.HashAlgorithmSHA256, + expectedUsedSecureBootCAs: []*X509CertificateID{NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert))}, + expectedFlags: NoPlatformConfigProfileSupport | NoDriversAndAppsConfigProfileSupport | NoBootManagerConfigProfileSupport, + }) + c.Assert(err, IsNil) + c.Assert(warnings, HasLen, 4) + + warning := warnings[0] + c.Check(warning, ErrorMatches, `error with platform config \(PCR1\) measurements: generating profiles for PCR 1 is not supported yet, see https://github.com/canonical/secboot/issues/322`) + var pce *PlatformConfigPCRError + c.Check(errors.As(warning, &pce), testutil.IsTrue) + + warning = warnings[1] + c.Check(warning, ErrorMatches, `error with drivers and apps config \(PCR3\) measurements: generating profiles for PCR 3 is not supported yet, see https://github.com/canonical/secboot/issues/341`) + var dce *DriversAndAppsConfigPCRError + c.Check(errors.As(warning, &dce), testutil.IsTrue) + + warning = warnings[2] + c.Check(warning, ErrorMatches, `error with boot manager config \(PCR5\) measurements: generating profiles for PCR 5 is not supported yet, see https://github.com/canonical/secboot/issues/323`) + var bmce *BootManagerConfigPCRError + c.Check(errors.As(warning, &bmce), testutil.IsTrue) + + warning = warnings[3] + c.Check(warning, ErrorMatches, `secure boot is enabled but not in deployed mode`) c.Check(errors.Is(warning, ErrNoDeployedMode), testutil.IsTrue) } @@ -2849,12 +2876,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -2940,12 +2965,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3031,8 +3054,6 @@ func (s *runChecksSuite) TestRunChecksBadTPM2DeviceDisabled(c *C) { efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3086,7 +3107,7 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -3135,7 +3156,7 @@ func (s *runChecksSuite) TestRunChecksBadInvalidPCR0Value(c *C) { efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{}, 1, map[uint32]uint64{0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{}, 1, map[uint32]uint64{0x13a: (3 << 1)}), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), tpmPropertyModifiers: map[tpm2.Property]uint32{ @@ -3167,7 +3188,7 @@ func (s *runChecksSuite) TestRunChecksBadInvalidPCR2Value(c *C) { efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{}, 1, map[uint32]uint64{0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{}, 1, map[uint32]uint64{0x13a: (3 << 1)}), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), tpmPropertyModifiers: map[tpm2.Property]uint32{ @@ -3199,7 +3220,7 @@ func (s *runChecksSuite) TestRunChecksBadInvalidPCR4Value(c *C) { efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{}, 1, map[uint32]uint64{0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{}, 1, map[uint32]uint64{0x13a: (3 << 1)}), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), tpmPropertyModifiers: map[tpm2.Property]uint32{ @@ -3231,7 +3252,7 @@ func (s *runChecksSuite) TestRunChecksBadInvalidPCR7Value(c *C) { efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{}, 1, map[uint32]uint64{0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{}, 1, map[uint32]uint64{0x13a: (3 << 1)}), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), tpmPropertyModifiers: map[tpm2.Property]uint32{ @@ -3285,7 +3306,7 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -3297,7 +3318,7 @@ C7E003CB enabledBanks: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, flags: PermitNoPlatformConfigProfileSupport | PermitNoDriversAndAppsConfigProfileSupport | PermitNoBootManagerConfigProfileSupport, }) - c.Check(err, ErrorMatches, `error with system security: encountered an error when checking Intel BootGuard configuration: no hardware root-of-trust properly configured: ME is in manufacturing mode`) + c.Check(err, ErrorMatches, `error with system security: encountered an error when checking Intel BootGuard configuration: no hardware root-of-trust properly configured: system is in manufacturing mode`) var hse *HostSecurityError c.Assert(errors.As(err, &hse), testutil.IsTrue) @@ -3318,7 +3339,7 @@ func (s *runChecksSuite) TestRunChecksBadHostSecurityMissingIntelMEModule(c *C) efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -3364,7 +3385,7 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 0, nil), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 0, nil), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -3411,7 +3432,7 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, FirmwareDebugger: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{}.SetSecureBoot(false)), ), @@ -3469,12 +3490,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA1}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3540,12 +3559,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3610,12 +3627,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3680,12 +3695,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3753,12 +3766,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeDriverLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3852,12 +3863,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeSysPrepAppLaunch: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -3970,12 +3979,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, IncludeOSPresentFirmwareAppLaunch: efi.MakeGUID(0x821aca26, 0x29ea, 0x4993, 0x839f, [...]byte{0x59, 0x7f, 0xc0, 0x21, 0x70, 0x8d}), })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4043,12 +4050,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA1, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4120,12 +4125,10 @@ C7E003CB IncludeDriverLaunch: true, PreOSVerificationUsesDigests: crypto.SHA256, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4162,7 +4165,7 @@ C7E003CB c.Check(errors.Is(errs[0], ErrPreOSSecureBootAuthByEnrolledDigests), testutil.IsTrue) } -func (s *runChecksSuite) TestRunChecksBadEFIVariableAccessErrorBootOptionSupport(c *C) { +func (s *runChecksSuite) TestRunChecksBadEFIVariableAccessError(c *C) { meiAttrs := map[string][]byte{ "fw_ver": []byte(`0:16.1.27.2176 0:16.1.27.2176 @@ -4191,12 +4194,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ - {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Err: efi.ErrVarDeviceError}, + {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Err: efi.ErrVarDeviceError}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4222,7 +4223,7 @@ C7E003CB }, expectedPcrAlg: tpm2.HashAlgorithmSHA256, }) - c.Check(err, ErrorMatches, `cannot access EFI variable: cannot obtain boot option support: variable access failed because of a hardware error`) + c.Check(err, ErrorMatches, `cannot access EFI variable: cannot compute secure boot mode: cannot read AuditMode variable: variable access failed because of a hardware error`) var e *EFIVariableAccessError c.Assert(errors.As(err, &e), testutil.IsTrue) @@ -4258,12 +4259,10 @@ C7E003CB efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4331,12 +4330,10 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), @@ -4394,16 +4391,14 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + }.SetSecureBoot(false).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), ), tpmPropertyModifiers: map[tpm2.Property]uint32{ tpm2.PropertyNVCountersMax: 0, @@ -4425,7 +4420,7 @@ C7E003CB }, expectedPcrAlg: tpm2.HashAlgorithmSHA256, }) - c.Check(err, ErrorMatches, `error with secure boot policy \(PCR7\) measurements: deployed mode should be enabled in order to generate secure boot profiles`) + c.Check(err, ErrorMatches, `error with secure boot policy \(PCR7\) measurements: secure boot should be enabled in order to generate secure boot profiles`) var ce CompoundError c.Assert(err, Implements, &ce) @@ -4435,10 +4430,10 @@ C7E003CB var sbe *SecureBootPolicyPCRError c.Assert(errors.As(errs[0], &sbe), testutil.IsTrue) - c.Check(errors.Is(sbe, ErrNoDeployedMode), testutil.IsTrue) + c.Check(errors.Is(sbe, ErrNoSecureBoot), testutil.IsTrue) } -func (s *runChecksSuite) TestRunChecksBadNoSecureBootPolicyProfileSupportSecureBootDisabled(c *C) { +func (s *runChecksSuite) TestRunChecksBadNoSecureBootPolicyProfileSupportNoDeployedMode(c *C) { meiAttrs := map[string][]byte{ "fw_ver": []byte(`0:16.1.27.2176 0:16.1.27.2176 @@ -4464,20 +4459,15 @@ C7E003CB env: efitest.NewMockHostEnvironmentWithOpts( efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{ - Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, - SecureBootDisabled: true, - })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - }.SetSecureBoot(false).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), ), tpmPropertyModifiers: map[tpm2.Property]uint32{ tpm2.PropertyNVCountersMax: 0, @@ -4499,7 +4489,7 @@ C7E003CB }, expectedPcrAlg: tpm2.HashAlgorithmSHA256, }) - c.Check(err, ErrorMatches, `error with secure boot policy \(PCR7\) measurements: secure boot should be enabled in order to generate secure boot profiles`) + c.Check(err, ErrorMatches, `secure boot is enabled but not in deployed mode`) var ce CompoundError c.Assert(err, Implements, &ce) @@ -4507,9 +4497,7 @@ C7E003CB errs := ce.Unwrap() c.Assert(errs, HasLen, 1) - var sbe *SecureBootPolicyPCRError - c.Assert(errors.As(errs[0], &sbe), testutil.IsTrue) - c.Check(errors.Is(sbe, ErrNoSecureBoot), testutil.IsTrue) + c.Check(errors.Is(errs[0], ErrNoDeployedMode), testutil.IsTrue) } func (s *runChecksSuite) TestRunChecksBadNoSecureBootPolicyProfileSupportSecureBootDisabledAndNoSBATLevel(c *C) { @@ -4547,12 +4535,10 @@ C7E003CB SecureBootDisabled: true, NoSBAT: true, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4618,16 +4604,14 @@ C7E003CB efitest.WithVirtMode(internal_efi.VirtModeNone, internal_efi.DetectVirtModeAll), efitest.WithTPMDevice(newTpmDevice(tpm2_testutil.NewTransportBackedDevice(s.Transport, false, 1), nil, tpm2_device.ErrNoPPI)), efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}})), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - }.SetSecureBoot(true).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), + }.SetSecureBoot(false).SetPK(c, efitest.NewSignatureListX509(c, snakeoilCert, efi.MakeGUID(0x03f66fa4, 0x5eee, 0x479c, 0xa408, [...]uint8{0xc4, 0xdc, 0x0a, 0x33, 0xfc, 0xde})))), ), tpmPropertyModifiers: map[tpm2.Property]uint32{ tpm2.PropertyNVCountersMax: 0, @@ -4657,7 +4641,7 @@ C7E003CB c.Assert(err, ErrorMatches, `2 errors detected: - error with TPM2 device: one or more of the TPM hierarchies is already owned: - TPM_RH_LOCKOUT has an authorization value -- error with secure boot policy \(PCR7\) measurements: deployed mode should be enabled in order to generate secure boot profiles +- error with secure boot policy \(PCR7\) measurements: secure boot should be enabled in order to generate secure boot profiles `) var ce CompoundError @@ -4673,6 +4657,7 @@ C7E003CB var sbpe *SecureBootPolicyPCRError c.Check(errors.As(errs[1], &sbpe), testutil.IsTrue) + c.Check(errors.Is(sbpe, ErrNoSecureBoot), testutil.IsTrue) } func (s *runChecksSuite) TestRunChecksBadInsufficientDMAProtectionAndNoBootManagerCodeProfileSupport(c *C) { @@ -4707,12 +4692,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, DMAProtection: efitest.DMAProtectionDisabled, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4792,12 +4775,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, DMAProtection: efitest.DMAProtectionDisabled, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, @@ -4876,12 +4857,10 @@ C7E003CB Algorithms: []tpm2.HashAlgorithmId{tpm2.HashAlgorithmSHA256}, DMAProtection: efitest.DMAProtectionDisabled, })), - efitest.WithAMD64Environment("GenuineIntel", []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), + efitest.WithAMD64Environment("GenuineIntel", 0x6, []uint64{cpuid.SDBG, cpuid.SMX}, 4, map[uint32]uint64{0xc80: 0x40000000, 0x13a: (3 << 1)}), efitest.WithSysfsDevices(devices...), efitest.WithMockVars(efitest.MockVars{ {Name: "AuditMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - {Name: "BootOptionSupport", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x13, 0x03, 0x00, 0x00}}, {Name: "DeployedMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeNonVolatile | efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x1}}, {Name: "SetupMode", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x0}}, {Name: "OsIndicationsSupported", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, diff --git a/efi/preinstall/error_kinds.go b/efi/preinstall/error_kinds.go index ab276ac8..a570c52f 100644 --- a/efi/preinstall/error_kinds.go +++ b/efi/preinstall/error_kinds.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" + efi "github.com/canonical/go-efilib" "github.com/canonical/go-tpm2" ) @@ -287,3 +288,75 @@ type InvalidActionArgumentDetails struct { func (a *InvalidActionArgumentDetails) String() string { return fmt.Sprintf("invalid action argument %q: invalid %s", a.Field, a.Reason) } + +type secureBootModeJson efi.SecureBootMode + +func (m secureBootModeJson) MarshalJSON() ([]byte, error) { + var s string + switch efi.SecureBootMode(m) { + case efi.SetupMode: + s = "setup" + case efi.AuditMode: + s = "audit" + case efi.UserMode: + s = "user" + case efi.DeployedMode: + s = "deployed" + default: + return nil, errors.New("invalid secure boot mode") + } + + return json.Marshal(s) +} + +func (m *secureBootModeJson) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + + switch s { + case "setup": + *m = secureBootModeJson(efi.SetupMode) + case "audit": + *m = secureBootModeJson(efi.AuditMode) + case "user": + *m = secureBootModeJson(efi.UserMode) + case "deployed": + *m = secureBootModeJson(efi.DeployedMode) + default: + return fmt.Errorf("invalid secure boot mode %q", s) + } + + return nil +} + +type secureBootModeArgJson struct { + Enabled bool `json:"enabled"` + Mode secureBootModeJson `json:"mode"` +} + +type SecureBootModeArg struct { + Enabled bool + Mode efi.SecureBootMode +} + +func (a SecureBootModeArg) MarshalJSON() ([]byte, error) { + return json.Marshal(secureBootModeArgJson{ + Enabled: a.Enabled, + Mode: secureBootModeJson(a.Mode), + }) +} + +func (a *SecureBootModeArg) UnmarshalJSON(data []byte) error { + var m secureBootModeArgJson + if err := json.Unmarshal(data, &m); err != nil { + return err + } + + *a = SecureBootModeArg{ + Enabled: m.Enabled, + Mode: efi.SecureBootMode(m.Mode), + } + return nil +} diff --git a/efi/preinstall/errors.go b/efi/preinstall/errors.go index 5ec2faee..555dbcff 100644 --- a/efi/preinstall/errors.go +++ b/efi/preinstall/errors.go @@ -926,10 +926,8 @@ var ( ErrNoSecureBoot = errors.New("secure boot should be enabled in order to generate secure boot profiles") // ErrNoDeployedMode is returned wrapped in SecureBootPolicyPCRError to indicate - // that deployed mode is not enabled. In the future, this package will permit - // generation of profiles on systems that implement UEFI >= 2.5 that are in user - // mode, but this is not the case today. - ErrNoDeployedMode = errors.New("deployed mode should be enabled in order to generate secure boot profiles") + // that deployed mode is not enabled. + ErrNoDeployedMode = errors.New("secure boot is enabled but not in deployed mode") // ErrWeakSecureBootAlgorithmDetected is returned wrapped in a type that implements CompoundError and // indicates that weak algorithms were detected during secure boot verification, such as authenticating diff --git a/efi/preinstall/export_amd64_test.go b/efi/preinstall/export_amd64_test.go index 73903a4b..03de4c17 100644 --- a/efi/preinstall/export_amd64_test.go +++ b/efi/preinstall/export_amd64_test.go @@ -45,6 +45,7 @@ var ( CheckHostSecurityIntelBootGuard = checkHostSecurityIntelBootGuard CheckHostSecurityIntelBootGuardCSME11 = checkHostSecurityIntelBootGuardCSME11 CheckHostSecurityIntelBootGuardCSME18 = checkHostSecurityIntelBootGuardCSME18 + CheckHostSecurityIntelBootGuardMSR = checkHostSecurityIntelBootGuardMSR CheckHostSecurityIntelCPUDebuggingLocked = checkHostSecurityIntelCPUDebuggingLocked DetermineCPUVendor = determineCPUVendor IsTPMDiscreteFromIntelBootGuard = isTPMDiscreteFromIntelBootGuard diff --git a/efi/preinstall/export_test.go b/efi/preinstall/export_test.go index 0ba171e7..753f468e 100644 --- a/efi/preinstall/export_test.go +++ b/efi/preinstall/export_test.go @@ -56,8 +56,11 @@ const ( DtpmPartialResetAttackMitigationPreferred = dtpmPartialResetAttackMitigationPreferred DtpmPartialResetAttackMitigationUnavailable = dtpmPartialResetAttackMitigationUnavailable InsufficientDMAProtectionDetected = insufficientDMAProtectionDetected + PlatformFirmwareIntegrityMeasured = platformFirmwareIntegrityMeasured + PlatformFirmwareIntegrityVerified = platformFirmwareIntegrityVerified SecureBootIncludesWeakAlg = secureBootIncludesWeakAlg SecureBootPreOSVerificationIncludesDigest = secureBootPreOSVerificationIncludesDigest + SecureBootNoDeployedMode = secureBootNoDeployedMode StartupLocalityNotProtected = startupLocalityNotProtected ) @@ -76,7 +79,6 @@ var ( DetectVirtualization = detectVirtualization ErrInvalidLockoutAuthValueSupplied = errInvalidLockoutAuthValueSupplied InsertActionProceed = insertActionProceed - IsLaunchedFromFirmwareVolume = isLaunchedFromFirmwareVolume IsLaunchedFromLoadOption = isLaunchedFromLoadOption IsPPIActionAvailable = isPPIActionAvailable IsTPMDiscrete = isTPMDiscrete @@ -84,8 +86,6 @@ var ( MatchLaunchToLoadOption = matchLaunchToLoadOption NewX509CertificateID = newX509CertificateID OpenAndCheckTPM2Device = openAndCheckTPM2Device - ReadCurrentBootLoadOptionFromLog = readCurrentBootLoadOptionFromLog - ReadLoadOptionFromLog = readLoadOptionFromLog ReadOrderedLoadOptionVariables = readOrderedLoadOptionVariables RestrictedTPMLocalitiesIntel = restrictedTPMLocalitiesIntel RunPPIAction = runPPIAction diff --git a/efi/preinstall/intel_util.go b/efi/preinstall/intel_util.go new file mode 100644 index 00000000..f044d1b9 --- /dev/null +++ b/efi/preinstall/intel_util.go @@ -0,0 +1,91 @@ +//go:build amd64 + +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2026 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package preinstall + +import ( + "errors" + + internal_efi "github.com/snapcore/secboot/internal/efi" +) + +const bootGuardStatusMsr = 0x13a + +type bootGuardStatus uint64 + +const ( + bootGuardNEM bootGuardStatus = 1 << 0 + bootGuardFACB bootGuardStatus = 1 << 4 + bootGuardMeasuredBoot bootGuardStatus = 1 << 5 + bootGuardVerifiedBoot bootGuardStatus = 1 << 6 + bootGuardCapability bootGuardStatus = 1 << 32 + + bootGuardStatusTPMShift = 1 + bootGuardStatusTPMMask bootGuardStatus = (3 << bootGuardStatusTPMShift) +) + +type bootGuardTPMStatus uint64 + +const ( + bootGuardTPMStatusNone bootGuardTPMStatus = 0 + bootGuardTPMStatus12 bootGuardTPMStatus = 1 + bootGuardTPMStatus2 bootGuardTPMStatus = 2 + bootGuardTPMStatusPTT bootGuardTPMStatus = 3 +) + +func (s bootGuardStatus) tpmStatus() bootGuardTPMStatus { + return bootGuardTPMStatus(s&bootGuardStatusTPMMask) >> bootGuardStatusTPMShift +} + +func (s bootGuardStatus) btgProfile() (btgProfile, error) { + // We can't check the error enforcement policy here, either because it's + // not mirrored into the MSR, or it is but we don't know which 2 bits to + // use. We just interpret the other bits into one of the well known No_FVME, + // VM, FVE and FVME profiles. This is ok because there are no known profiles + // where these bits are reused with different error enforcement policies. + f := s&bootGuardFACB > 0 + v := s&bootGuardVerifiedBoot > 0 + m := s&bootGuardMeasuredBoot > 0 + p := s&bootGuardNEM > 0 + + switch { + case !f && !v && !m && !p: + return btgProfileNoFVME, nil + case !f && v && m && p: + return btgProfileVM, nil + case f && v && !m && p: + return btgProfileFVE, nil + case f && v && m && p: + return btgProfileFVME, nil + default: + return 0, errors.New("invalid profile") + } +} + +func readIntelBootGuardStatus(env internal_efi.HostEnvironmentAMD64) (bootGuardStatus, error) { + msrValue, err := env.ReadMSRs(bootGuardStatusMsr) + if err != nil { + return 0, err + } + + // NOTE: msrValue[0] is fine because BootGuard status MSR has the same value across all CPUs + return bootGuardStatus(msrValue[0]), nil +} diff --git a/efi/preinstall/load_option_util.go b/efi/preinstall/load_option_util.go index 89fa01b7..299809de 100644 --- a/efi/preinstall/load_option_util.go +++ b/efi/preinstall/load_option_util.go @@ -20,85 +20,14 @@ package preinstall import ( - "bytes" "context" "errors" "fmt" - "strings" efi "github.com/canonical/go-efilib" "github.com/canonical/tcglog-parser" - internal_efi "github.com/snapcore/secboot/internal/efi" ) -// readLoadOptionFromLog reads the corresponding Boot#### load option from the log, -// which reflects the value of it at boot time, as opposed to reading it from an -// EFI variable which may have been modified since booting. -func readLoadOptionFromLog(log *tcglog.Log, n uint16) (*efi.LoadOption, error) { - events := log.Events - for len(events) > 0 { - ev := events[0] - events = events[1:] - - if ev.PCRIndex != internal_efi.PlatformConfigPCR { - continue - } - - if ev.EventType != tcglog.EventTypeEFIVariableBoot && ev.EventType != tcglog.EventTypeEFIVariableBoot2 { - // not a boot variable - continue - } - - data, ok := ev.Data.(*tcglog.EFIVariableData) - if !ok { - // decode error data is guaranteed to implement the error interface - return nil, fmt.Errorf("boot variable measurement has wrong data format: %w", ev.Data.(error)) - } - if data.VariableName != efi.GlobalVariable { - // not a global variable - continue - } - if !strings.HasPrefix(data.UnicodeName, "Boot") || len(data.UnicodeName) != 8 { - // name has unexpected prefix or length - continue - } - - var x uint16 - if c, err := fmt.Sscanf(data.UnicodeName, "Boot%x", &x); err != nil || c != 1 { - continue - } - if x != n { - // wrong load option - continue - } - - // We've found the correct load option. Decode it from the data stored in the log. - opt, err := efi.ReadLoadOption(bytes.NewReader(data.VariableData)) - if err != nil { - return nil, fmt.Errorf("cannot read load option from event data: %w", err) - } - return opt, nil - } - - return nil, errors.New("cannot find specified boot option") -} - -// readCurrentBootLoadOptionFromLog reads the load option associated with the current boot. -// It reads the BootCurrent global EFI variable and then looks up the corresponding BootXXXX -// entry that was measured to the TPM and present in the log, as BootXXXX variables are mutable -// and could have been modified between boot time and now. -func readCurrentBootLoadOptionFromLog(ctx context.Context, log *tcglog.Log) (*efi.LoadOption, error) { - current, err := efi.ReadBootCurrentVariable(ctx) - if err != nil { - return nil, fmt.Errorf("cannot read BootCurrent variable: %w", err) - } - opt, err := readLoadOptionFromLog(log, current) - if err != nil { - return nil, fmt.Errorf("cannot read current Boot%04X load option from log: %w", current, err) - } - return opt, nil -} - func readOrderedLoadOptionVariables(ctx context.Context, class efi.LoadOptionClass) (opts []*efi.LoadOption, order []uint16, err error) { switch class { case efi.LoadOptionClassDriver, efi.LoadOptionClassSysPrep, efi.LoadOptionClassBoot: diff --git a/efi/preinstall/load_option_util_test.go b/efi/preinstall/load_option_util_test.go index 7d1fb500..05545980 100644 --- a/efi/preinstall/load_option_util_test.go +++ b/efi/preinstall/load_option_util_test.go @@ -38,126 +38,6 @@ type loadOptionUtilSuite struct{} var _ = Suite(&loadOptionUtilSuite{}) -func (s *loadOptionUtilSuite) TestReadLoadOptionFromLog(c *C) { - log := efitest.NewLog(c, &efitest.LogOptions{}) - opt, err := ReadLoadOptionFromLog(log, 3) - c.Assert(err, IsNil) - c.Check(opt, DeepEquals, &efi.LoadOption{ - Attributes: 1, - Description: "ubuntu", - FilePath: efi.DevicePath{ - &efi.HardDriveDevicePathNode{ - PartitionNumber: 1, - PartitionStart: 0x800, - PartitionSize: 0x100000, - Signature: efi.GUIDHardDriveSignature(efi.MakeGUID(0x66de947b, 0xfdb2, 0x4525, 0xb752, [...]uint8{0x30, 0xd6, 0x6b, 0xb2, 0xb9, 0x60})), - MBRType: efi.GPT}, - efi.FilePathDevicePathNode("\\EFI\\ubuntu\\shimx64.efi"), - }, - OptionalData: []byte{}, - }) -} - -func (s *loadOptionUtilSuite) TestReadLoadOptionFromLogNotExist(c *C) { - log := efitest.NewLog(c, &efitest.LogOptions{}) - _, err := ReadLoadOptionFromLog(log, 10) - c.Check(err, ErrorMatches, `cannot find specified boot option`) -} - -func (s *loadOptionUtilSuite) TestReadLoadOptionFromLogInvalidData(c *C) { - log := efitest.NewLog(c, &efitest.LogOptions{}) - for _, ev := range log.Events { - if ev.PCRIndex != internal_efi.PlatformConfigPCR { - continue - } - if ev.EventType != tcglog.EventTypeEFIVariableBoot { - continue - } - data, ok := ev.Data.(*tcglog.EFIVariableData) - c.Assert(ok, testutil.IsTrue) - if data.UnicodeName != "Boot0003" { - continue - } - ev.Data = &invalidEventData{errors.New("some error")} - } - _, err := ReadLoadOptionFromLog(log, 3) - c.Check(err, ErrorMatches, `boot variable measurement has wrong data format: some error`) -} - -func (s *loadOptionUtilSuite) TestReadLoadOptionFromLogInvalidVariableName(c *C) { - log := efitest.NewLog(c, &efitest.LogOptions{}) - for _, ev := range log.Events { - if ev.PCRIndex != internal_efi.PlatformConfigPCR { - continue - } - if ev.EventType != tcglog.EventTypeEFIVariableBoot { - continue - } - data, ok := ev.Data.(*tcglog.EFIVariableData) - c.Assert(ok, testutil.IsTrue) - data.VariableName = efi.MakeGUID(0x6be4d043, 0x2ded, 0x4669, 0xa43b, [...]byte{0x91, 0x37, 0xb8, 0xa9, 0xd1, 0xa4}) - } - _, err := ReadLoadOptionFromLog(log, 3) - c.Check(err, ErrorMatches, `cannot find specified boot option`) -} - -func (s *loadOptionUtilSuite) TestReadCurrentBootLoadOptionFromLog(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{})), - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0x3, 0x0}}, - }), - ) - - log, err := env.ReadEventLog() - c.Assert(err, IsNil) - - opt, err := ReadCurrentBootLoadOptionFromLog(env.VarContext(context.Background()), log) - c.Assert(err, IsNil) - c.Check(opt, DeepEquals, &efi.LoadOption{ - Attributes: 1, - Description: "ubuntu", - FilePath: efi.DevicePath{ - &efi.HardDriveDevicePathNode{ - PartitionNumber: 1, - PartitionStart: 0x800, - PartitionSize: 0x100000, - Signature: efi.GUIDHardDriveSignature(efi.MakeGUID(0x66de947b, 0xfdb2, 0x4525, 0xb752, [...]uint8{0x30, 0xd6, 0x6b, 0xb2, 0xb9, 0x60})), - MBRType: efi.GPT}, - efi.FilePathDevicePathNode("\\EFI\\ubuntu\\shimx64.efi"), - }, - OptionalData: []byte{}, - }) -} - -func (s *loadOptionUtilSuite) TestReadCurrentBootLoadOptionFromLogMissingBootCurrent(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{})), - efitest.WithMockVars(efitest.MockVars{}), - ) - - log, err := env.ReadEventLog() - c.Assert(err, IsNil) - - _, err = ReadCurrentBootLoadOptionFromLog(env.VarContext(context.Background()), log) - c.Check(err, ErrorMatches, `cannot read BootCurrent variable: variable does not exist`) -} - -func (s *loadOptionUtilSuite) TestReadCurrentBootLoadOptionFromLogInvalidBootCurrent(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts( - efitest.WithLog(efitest.NewLog(c, &efitest.LogOptions{})), - efitest.WithMockVars(efitest.MockVars{ - {Name: "BootCurrent", GUID: efi.GlobalVariable}: &efitest.VarEntry{Attrs: efi.AttributeBootserviceAccess | efi.AttributeRuntimeAccess, Payload: []byte{0xA, 0x0}}, - }), - ) - - log, err := env.ReadEventLog() - c.Assert(err, IsNil) - - _, err = ReadCurrentBootLoadOptionFromLog(env.VarContext(context.Background()), log) - c.Check(err, ErrorMatches, `cannot read current Boot000A load option from log: cannot find specified boot option`) -} - func (s *loadOptionUtilSuite) TestReadOrderedLoadOptionVariables(c *C) { optsPayloads := [][]byte{ efitest.MakeVarPayload(c, &efi.LoadOption{ diff --git a/efi/preinstall/profile.go b/efi/preinstall/profile.go index 8e6baa37..2a342b77 100644 --- a/efi/preinstall/profile.go +++ b/efi/preinstall/profile.go @@ -342,7 +342,7 @@ func (o *pcrProfileAutoSetPcrsOption) pcrOptions() ([]secboot_efi.PCRProfileEnab // error with the appropriate set of required but unsupported PCRs. pcrs[internal_efi.SecureBootPolicyPCR] = true - if o.opts&PCRProfileOptionLockToPlatformFirmware > 0 { + if o.opts&PCRProfileOptionLockToPlatformFirmware > 0 || o.result.Flags&RequireLockToPlatformFirmware > 0 { pcrs[internal_efi.PlatformFirmwarePCR] = true } if o.opts&PCRProfileOptionLockToPlatformConfig > 0 { @@ -429,7 +429,14 @@ func (o *pcrProfileAutoSetPcrsOption) pcrOptions() ([]secboot_efi.PCRProfileEnab } } - if o.opts&PCRProfileOptionNoPartialDiscreteTPMResetAttackMitigation == 0 && o.result.Flags&RequestPartialDiscreteTPMResetAttackMitigation > 0 { + switch { + case o.opts&PCRProfileOptionNoPartialDiscreteTPMResetAttackMitigation > 0 && o.opts&PCRProfileOptionLockToPlatformFirmware > 0: + return nil, fmt.Errorf("%q option is incompatible with %q option", PCRProfileOptionNoPartialDiscreteTPMResetAttackMitigation, PCRProfileOptionLockToPlatformFirmware) + case o.opts&PCRProfileOptionNoPartialDiscreteTPMResetAttackMitigation > 0: + if _, required := pcrs[internal_efi.PlatformFirmwarePCR]; required { + return nil, fmt.Errorf("%q option cannot be used when platform firmware profile is required", PCRProfileOptionNoPartialDiscreteTPMResetAttackMitigation) + } + case o.result.Flags&RequestPartialDiscreteTPMResetAttackMitigation > 0: // Enable reset attack mitigations by including PCR0, because the startup locality // is protected making it impossible to reconstruct PCR0 from software if the TPM is // reset indepdendently of the host platform. Note that it is still possible for an @@ -493,6 +500,11 @@ func (o *pcrProfileAutoSetPcrsOption) ApplyOptionTo(visitor internal_efi.PCRProf return fmt.Errorf("cannot add DMA allow insufficient protection profile option: %w", err) } } + if _, permitted := o.result.AcceptedErrors[ErrorKindInvalidSecureBootMode]; permitted { + if err := secboot_efi.WithAllowSecureBootUserMode().ApplyOptionTo(visitor); err != nil { + return fmt.Errorf("cannot add profile option for secure boot user mode: %w", err) + } + } return nil } diff --git a/efi/preinstall/profile_test.go b/efi/preinstall/profile_test.go index 9bb93b4e..53713ac9 100644 --- a/efi/preinstall/profile_test.go +++ b/efi/preinstall/profile_test.go @@ -191,6 +191,14 @@ func (s *profileSuite) TestWithAutoTCGPCRProfilePCRSelectionLockToPlatformFirmar }) } +func (s *profileSuite) TestWithAutoTCGPCRProfilePCRSelectionRequireLockToPlatformFirmare(c *C) { + s.testWithAutoTCGPCRProfilePCRSelection(c, &testWithAutoTCGPCRProfilePCRSelectionParams{ + usedSecureBootCAs: [][]byte{msUefiCACert}, + flags: RequireLockToPlatformFirmware, + expectedPcrs: tpm2.HandleList{0, 2, 4, 7}, + }) +} + // XXX: Uncomment when secboot_efi.WithPlatformConfigProfile exists. //func (s *profileSuite) TestWithAutoTCGPCRProfilePCRSelectionLockToPlatformConfig(c *C) { // s.testWithAutoTCGPCRProfilePCRSelection(c, &testWithAutoTCGPCRProfilePCRSelectionParams{ @@ -358,6 +366,21 @@ func (s *profileSuite) TestWithAutoTCGPCRProfilePCRSelectionNoPartialDTPMResetAt }) } +func (s *profileSuite) TestWithAutoTCGPCRProfileNoPartialDTPMResetAttackMitigationIncompatibleWithLockToPlatformFirmware(c *C) { + profile := WithAutoTCGPCRProfile(new(CheckResult), PCRProfileOptionLockToPlatformFirmware|PCRProfileOptionNoPartialDiscreteTPMResetAttackMitigation) + c.Check(profile.ApplyOptionTo(new(mockPcrProfileOptionVisitor)), ErrorMatches, + `cannot select an appropriate set of TCG defined PCRs with the current options: "no-partial-dtpm-reset-attack-mitigation" option is incompatible with "lock-platform-firmware" option`) +} + +func (s *profileSuite) TestWithAutoTCGPCRProfileNoPartialDTPMResetAttackMitigationIncompatibleWithRequireLockToPlatformFirmware(c *C) { + result := &CheckResult{ + Flags: RequireLockToPlatformFirmware, + } + profile := WithAutoTCGPCRProfile(result, PCRProfileOptionNoPartialDiscreteTPMResetAttackMitigation) + c.Check(profile.ApplyOptionTo(new(mockPcrProfileOptionVisitor)), ErrorMatches, + `cannot select an appropriate set of TCG defined PCRs with the current options: "no-partial-dtpm-reset-attack-mitigation" option cannot be used when platform firmware profile is required`) +} + func (s *profileSuite) TestWithAutoTCGPCRProfileLockToDriversAndAppsIncompatibleWithTrustSecureBootAuthoritiesForAddonDrivers(c *C) { profile := WithAutoTCGPCRProfile(new(CheckResult), PCRProfileOptionLockToDriversAndApps|PCRProfileOptionTrustSecureBootAuthoritiesForAddonDrivers) c.Check(profile.ApplyOptionTo(new(mockPcrProfileOptionVisitor)), ErrorMatches, @@ -545,3 +568,27 @@ func (s *profileSuite) TestWithAutoTCGPCRInsufficientDMAProtection(c *C) { }, }) } + +func (s *profileSuite) TestWithAutoTCGPCRInvalidSecureBootMode(c *C) { + result := &CheckResult{ + PCRAlg: tpm2.HashAlgorithmSHA256, + UsedSecureBootCAs: []*X509CertificateID{NewX509CertificateID(testutil.ParseCertificate(c, msUefiCACert))}, + AcceptedErrors: map[ErrorKind]json.RawMessage{ErrorKindInvalidSecureBootMode: nil}, + } + profile := WithAutoTCGPCRProfile(result, PCRProfileOptionsDefault) + + profile = profile.Options(PCRProfileOptionsDefault) + + visitor := &mockPcrProfileOptionVisitor{ + imageLoadParams: []internal_efi.LoadParams{{}}, + } + c.Check(profile.ApplyOptionTo(visitor), IsNil) + c.Check(visitor.imageLoadParams, DeepEquals, []internal_efi.LoadParams{ + { + "include_secure_boot_user_mode": false, + }, + { + "include_secure_boot_user_mode": true, + }, + }) +} diff --git a/efi/preinstall/result.go b/efi/preinstall/result.go index 763c4a48..853e096e 100644 --- a/efi/preinstall/result.go +++ b/efi/preinstall/result.go @@ -99,6 +99,10 @@ const ( discreteTPMDetected startupLocalityNotProtected insufficientDMAProtectionDetected + + // RequireLockTOPlatformFirmware means that PCR0 is required in a profile, using + // efi.WithPlatformFirmwareProfile. + RequireLockToPlatformFirmware ) func (f CheckResultFlags) toStringSlice() []string { @@ -127,6 +131,8 @@ func (f CheckResultFlags) toStringSlice() []string { str = "no-secure-boot-policy-profile-support" case RequestPartialDiscreteTPMResetAttackMitigation: str = "request-partial-dtpm-reset-attack-mitigation" + case RequireLockToPlatformFirmware: + str = "require-lock-platform-firmware" default: str = fmt.Sprintf("%#08x", uint32(flag)) } @@ -171,6 +177,8 @@ func (f *CheckResultFlags) UnmarshalJSON(data []byte) error { val = NoSecureBootPolicyProfileSupport case "request-partial-dtpm-reset-attack-mitigation": val = RequestPartialDiscreteTPMResetAttackMitigation + case "require-lock-platform-firmware": + val = RequireLockToPlatformFirmware case "insufficient-dma-protection-detected": val = insufficientDMAProtectionDetected case "discrete-tpm-detected": diff --git a/efi/preinstall/result_test.go b/efi/preinstall/result_test.go index 28dafabb..26f1c590 100644 --- a/efi/preinstall/result_test.go +++ b/efi/preinstall/result_test.go @@ -67,6 +67,7 @@ func (s *resultSuite) TestCheckResultFlagsUnmarshalJSON(c *C) { {flags: `["no-boot-manager-config-profile-support"]`, expected: NoBootManagerConfigProfileSupport}, {flags: `["no-secure-boot-policy-profile-support"]`, expected: NoSecureBootPolicyProfileSupport}, {flags: `["request-partial-dtpm-reset-attack-mitigation"]`, expected: RequestPartialDiscreteTPMResetAttackMitigation}, + {flags: `["require-lock-platform-firmware"]`, expected: RequireLockToPlatformFirmware}, {flags: `["insufficient-dma-protection-detected"]`, expected: InsufficientDMAProtectionDetected}, {flags: `["no-platform-config-profile-support","no-drivers-and-apps-config-profile-support","no-boot-manager-config-profile-support"]`, expected: NoPlatformConfigProfileSupport | NoDriversAndAppsConfigProfileSupport | NoBootManagerConfigProfileSupport}, {flags: `["0x8"]`, expected: NoDriversAndAppsConfigProfileSupport}, @@ -102,6 +103,7 @@ func (s *resultSuite) TestCheckResultFlagsString(c *C) { {flags: NoBootManagerConfigProfileSupport, expected: "no-boot-manager-config-profile-support"}, {flags: NoSecureBootPolicyProfileSupport, expected: "no-secure-boot-policy-profile-support"}, {flags: RequestPartialDiscreteTPMResetAttackMitigation, expected: "request-partial-dtpm-reset-attack-mitigation"}, + {flags: RequireLockToPlatformFirmware, expected: "require-lock-platform-firmware"}, {flags: NoPlatformConfigProfileSupport | NoDriversAndAppsConfigProfileSupport | NoBootManagerConfigProfileSupport, expected: "no-platform-config-profile-support,no-drivers-and-apps-config-profile-support,no-boot-manager-config-profile-support"}, {flags: InsufficientDMAProtectionDetected, expected: "0x00000400"}, } { diff --git a/efi/preinstall/util_amd64_test.go b/efi/preinstall/util_amd64_test.go index 5bff1f9e..3b15a95e 100644 --- a/efi/preinstall/util_amd64_test.go +++ b/efi/preinstall/util_amd64_test.go @@ -30,7 +30,7 @@ type utilAmd64Suite struct{} var _ = Suite(&utilAmd64Suite{}) func (s *utilAmd64Suite) TestDetermineCPUVendorIntel(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", nil, 0, nil)) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineIntel", 0x6, nil, 0, nil)) vendor, err := DetermineCPUVendor(env) c.Check(err, IsNil) @@ -38,7 +38,7 @@ func (s *utilAmd64Suite) TestDetermineCPUVendorIntel(c *C) { } func (s *utilAmd64Suite) TestDetermineCPUVendorAMD(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("AuthenticAMD", nil, 0, nil)) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("AuthenticAMD", 0x1a, nil, 0, nil)) vendor, err := DetermineCPUVendor(env) c.Check(err, IsNil) @@ -46,7 +46,7 @@ func (s *utilAmd64Suite) TestDetermineCPUVendorAMD(c *C) { } func (s *utilAmd64Suite) TestDetermineCPUVendorUnknown(c *C) { - env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineInte", nil, 0, nil)) + env := efitest.NewMockHostEnvironmentWithOpts(efitest.WithAMD64Environment("GenuineInte", 0x6, nil, 0, nil)) _, err := DetermineCPUVendor(env) c.Check(err, ErrorMatches, `unknown CPU vendor: GenuineInte`) diff --git a/efi/secureboot.go b/efi/secureboot.go index 733fcfd1..28615747 100644 --- a/efi/secureboot.go +++ b/efi/secureboot.go @@ -315,3 +315,43 @@ func (o allowInsufficientDmaProtectionOption) ApplyOptionTo(visitor internal_efi func WithAllowInsufficientDmaProtection() PCRProfileOption { return allowInsufficientDmaProtectionOption{} } + +const ( + // includeSecureBootUserModeParamKey is used to indicate that user mode related + // measurements should be included in the secure boot PCR profile if the system is + // in user mode. + includeSecureBootUserModeParamKey = "include_secure_boot_user_mode" +) + +type allowSecureBootUserModeOption struct{} + +func (o allowSecureBootUserModeOption) ApplyOptionTo(visitor internal_efi.PCRProfileOptionVisitor) error { + visitor.AddImageLoadParams(func(params ...loadParams) []loadParams { + var out []loadParams + for _, v := range []bool{false, true} { + var newParams []loadParams + for _, p := range params { + newParams = append(newParams, p.Clone()) + } + for _, p := range newParams { + p[includeSecureBootUserModeParamKey] = v + } + out = append(out, newParams...) + } + return out + }) + return nil +} + +// WithAllowSecureBootUserMode can be supplied to AddPCRProfile to allow for secure boot +// PCR profiles that support user mode to be generated on systems where user mode is +// currently enabled. This is opt-in to ensure that a system that was originally in +// deployed mode doesn't automatically regenerate a PCR profile for user mode in the case +// where the firmware settings are inadvertently degraded. +// +// If the system is in user mode, PCR profile branches will be generated both for user mode +// and deployed mode to allow a system to be placed back into deployed mode without making +// the generated policy invalid. If the system is in deployed mode, this option has no effect. +func WithAllowSecureBootUserMode() PCRProfileOption { + return allowSecureBootUserModeOption{} +} diff --git a/go.mod b/go.mod index d7887601..f031dd6d 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/canonical/go-kbkdf v0.0.0-20250104172618-3b1308f9acf9 github.com/canonical/go-password-validator v0.0.0-20250617132709-1b205303ca54 github.com/canonical/go-sp800.90a-drbg v0.0.0-20210314144037-6eeb1040d6c3 - github.com/canonical/go-tpm2 v1.13.0 + github.com/canonical/go-tpm2 v1.15.0 github.com/canonical/tcglog-parser v0.0.0-20240924110432-d15eaf652981 github.com/jessevdk/go-flags v1.5.0 github.com/snapcore/snapd v0.0.0-20220714152900-4a1f4c93fc85 diff --git a/go.sum b/go.sum index 8653bad0..6622f560 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/canonical/go-tpm2 v1.12.2 h1:7sWef6xVlWwBAn7hsY+3j62ANzoAO+GZvrltMHXq github.com/canonical/go-tpm2 v1.12.2/go.mod h1:zK+qESVwu78XyX+NPhiBdN+zwPPDoKk4rYlQ7VUsRp4= github.com/canonical/go-tpm2 v1.13.0 h1:Ka9VmUVwoz9pJef5JXP6Gd4CIhxFE70X26K8x3LeGtI= github.com/canonical/go-tpm2 v1.13.0/go.mod h1:P50xMwC7y5/uxPikzWdK4d9pW9orKi8+ZL5sBifxoBQ= +github.com/canonical/go-tpm2 v1.15.0 h1:T4dVCO8qCs76vDDs4vWNpvPdh7UHuSORPH4Scq7N2gw= +github.com/canonical/go-tpm2 v1.15.0/go.mod h1:P50xMwC7y5/uxPikzWdK4d9pW9orKi8+ZL5sBifxoBQ= github.com/canonical/tcglog-parser v0.0.0-20210824131805-69fa1e9f0ad2/go.mod h1:QoW2apR2tBl6T/4czdND/EHjL1Ia9cCmQnIj9Xe0Kt8= github.com/canonical/tcglog-parser v0.0.0-20240924110432-d15eaf652981 h1:vrUzSfbhl8mzdXPzjxq4jXZPCCNLv18jy6S7aVTS2tI= github.com/canonical/tcglog-parser v0.0.0-20240924110432-d15eaf652981/go.mod h1:ywdPBqUGkuuiitPpVWCfilf2/gq+frhq4CNiNs9KyHU= diff --git a/internal/efi/default_env_amd64.go b/internal/efi/default_env_amd64.go index 90ab259f..b9b13917 100644 --- a/internal/efi/default_env_amd64.go +++ b/internal/efi/default_env_amd64.go @@ -43,6 +43,11 @@ func (defaultEnvAMD64Impl) CPUVendorIdentificator() string { return cpuid.VendorIdentificatorString } +// CPUFamily implements [HostEnvironmentAMD64.CPUFamily]. +func (defaultEnvAMD64Impl) CPUFamily() uint32 { + return cpuid.DisplayFamily +} + // HasCPUIDFeature implements [HostEnvironmentAMD64.HasCPUIDFeature]. func (defaultEnvAMD64Impl) HasCPUIDFeature(feature uint64) bool { return cpuidHasFeature(feature) diff --git a/internal/efi/default_env_amd64_test.go b/internal/efi/default_env_amd64_test.go index c496de73..abec67f1 100644 --- a/internal/efi/default_env_amd64_test.go +++ b/internal/efi/default_env_amd64_test.go @@ -56,6 +56,26 @@ func (s *defaultEnvAMD64Suite) TestCPUVendorIdentificatorAMD(c *C) { c.Check(amd64.CPUVendorIdentificator(), Equals, "AuthenticAMD") } +func (s *defaultEnvAMD64Suite) TestCPUFamily1(c *C) { + orig := cpuid.DisplayFamily + cpuid.DisplayFamily = 0x12 + defer func() { cpuid.DisplayFamily = orig }() + + amd64, err := DefaultEnv.AMD64() + c.Assert(err, IsNil) + c.Check(amd64.CPUFamily(), Equals, uint32(0x12)) +} + +func (s *defaultEnvAMD64Suite) TestCPUFamily2(c *C) { + orig := cpuid.DisplayFamily + cpuid.DisplayFamily = 0x17 + defer func() { cpuid.DisplayFamily = orig }() + + amd64, err := DefaultEnv.AMD64() + c.Assert(err, IsNil) + c.Check(amd64.CPUFamily(), Equals, uint32(0x17)) +} + func (s *defaultEnvAMD64Suite) TestCPUIDHasFeatureSDBGTrue(c *C) { restore := MockCPUIDHasFeature(func(feature uint64) bool { c.Check(feature, Equals, cpuid.SDBG) diff --git a/internal/efi/env.go b/internal/efi/env.go index 4700ed19..20b05d52 100644 --- a/internal/efi/env.go +++ b/internal/efi/env.go @@ -71,6 +71,9 @@ type HostEnvironmentAMD64 interface { // CPUVendorIdentificator returns the CPU vendor. CPUVendorIdentificator() string + // CPUFamily returns the CPU family ID. + CPUFamily() uint32 + // HasCPUIDFeature returns if feature from FeatureNames map in the // github.com/intel-go/cpuid package is available. HasCPUIDFeature(feature uint64) bool diff --git a/internal/efi/tcg_events.go b/internal/efi/tcg_events.go new file mode 100644 index 00000000..b6f49e80 --- /dev/null +++ b/internal/efi/tcg_events.go @@ -0,0 +1,66 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2026 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package efi + +import ( + "errors" + "fmt" + + efi "github.com/canonical/go-efilib" + "github.com/canonical/tcglog-parser" +) + +// IsVendorEventType indicates whether the supplied event type is vendor +// defined. Officially, this applies to any event type that is not within the +// range of TCG reserved types (0x00000000-0x0000ffff and 0x80000000-0x8000ffff), +// however, this also considers event types between 0x00008000-0x0000ffff to be +// vendor defined because AMD firmware is using these and it's unlikely that +// these types are going to be used by the TCG. +func IsVendorEventType(t tcglog.EventType) bool { + switch { + case t&0x80000000 > 0: + return t > 0x8000ffff + default: + return t > 0x7fff + } +} + +// IsLaunchedFromFirmwareVolume indicates that the supplied event is associated +// with an image launch from a firmware volume. +func IsLaunchedFromFirmwareVolume(ev *tcglog.Event) (yes bool, err error) { + // The caller should check this. + switch ev.EventType { + case tcglog.EventTypeEFIBootServicesDriver, tcglog.EventTypeEFIRuntimeServicesDriver, tcglog.EventTypeEFIBootServicesApplication: + // ok + default: + return false, fmt.Errorf("unexpected event type %v", ev.EventType) + } + + data, ok := ev.Data.(*tcglog.EFIImageLoadEvent) + if !ok { + return false, fmt.Errorf("event has invalid event data: %w", ev.Data.(error)) + } + + if len(data.DevicePath) == 0 { + return false, errors.New("empty device path") + } + + return data.DevicePath[0].CompoundType() == efi.DevicePathNodeFwVolType, nil +} diff --git a/internal/efi/tcg_events_test.go b/internal/efi/tcg_events_test.go new file mode 100644 index 00000000..90bb6a26 --- /dev/null +++ b/internal/efi/tcg_events_test.go @@ -0,0 +1,138 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2026 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package efi_test + +import ( + "errors" + "io" + + efi "github.com/canonical/go-efilib" + "github.com/canonical/tcglog-parser" + . "github.com/snapcore/secboot/internal/efi" + "github.com/snapcore/secboot/internal/testutil" + + . "gopkg.in/check.v1" +) + +type tcgEventsSuite struct{} + +var _ = Suite(&tcgEventsSuite{}) + +func (*tcgEventsSuite) TestIsVendorEventType(c *C) { + for _, params := range []struct { + t tcglog.EventType + expected bool + }{ + {t: tcglog.EventTypeSCRTMContents, expected: false}, + {t: tcglog.EventTypeEFIVariableDriverConfig, expected: false}, + {t: 0x00007011, expected: false}, + {t: 0x80008412, expected: false}, + {t: 0x00008401, expected: true}, + {t: 0x80010000, expected: true}, + } { + c.Check(IsVendorEventType(params.t), Equals, params.expected, Commentf("%x", params.t)) + } +} + +type invalidEventData struct { + err error +} + +func (e *invalidEventData) String() string { return "invalid event data: " + e.err.Error() } +func (*invalidEventData) Bytes() []byte { return nil } +func (*invalidEventData) Write(w io.Writer) error { return errors.New("not supported") } +func (e *invalidEventData) Error() string { return e.err.Error() } + +func (s *tcgEventsSuite) TestIsLaunchedFromFirmwareVolumeYes(c *C) { + yes, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ + EventType: tcglog.EventTypeEFIBootServicesDriver, + Data: &tcglog.EFIImageLoadEvent{ + DevicePath: efi.DevicePath{ + efi.FWVolDevicePathNode(efi.MakeGUID(0xf0d99c58, 0x3e06, 0x430c, 0x8d02, [...]uint8{0x9a, 0xb8, 0x8b, 0xa1, 0x61, 0x20})), + efi.FWFileDevicePathNode(efi.MakeGUID(0x0c2c4003, 0x6551, 0x4eea, 0xb006, [...]uint8{0x0f, 0xec, 0xb4, 0xbb, 0x30, 0x0b})), + }, + }, + }) + c.Check(err, IsNil) + c.Check(yes, testutil.IsTrue) +} + +func (s *tcgEventsSuite) TestIsLaunchedFromFirmwareVolumeNo(c *C) { + yes, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ + EventType: tcglog.EventTypeEFIBootServicesDriver, + Data: &tcglog.EFIImageLoadEvent{ + DevicePath: efi.DevicePath{ + &efi.ACPIDevicePathNode{ + HID: 0x0a0341d0, + UID: 0x0, + }, + &efi.PCIDevicePathNode{ + Function: 0x1c, + Device: 0x2, + }, + &efi.PCIDevicePathNode{ + Function: 0x0, + Device: 0x0, + }, + &efi.MediaRelOffsetRangeDevicePathNode{ + StartingOffset: 0x38, + EndingOffset: 0x11dff, + }, + }, + }, + }) + c.Check(err, IsNil) + c.Check(yes, testutil.IsFalse) +} + +func (s *tcgEventsSuite) TestIsLaunchedFromFirmwareVolumeYesRuntimeDriver(c *C) { + yes, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ + EventType: tcglog.EventTypeEFIRuntimeServicesDriver, + Data: &tcglog.EFIImageLoadEvent{ + DevicePath: efi.DevicePath{ + efi.FWVolDevicePathNode(efi.MakeGUID(0xf0d99c58, 0x3e06, 0x430c, 0x8d02, [...]uint8{0x9a, 0xb8, 0x8b, 0xa1, 0x61, 0x20})), + efi.FWFileDevicePathNode(efi.MakeGUID(0x0c2c4003, 0x6551, 0x4eea, 0xb006, [...]uint8{0x0f, 0xec, 0xb4, 0xbb, 0x30, 0x0b})), + }, + }, + }) + c.Check(err, IsNil) + c.Check(yes, testutil.IsTrue) +} + +func (s *tcgEventsSuite) TestIsLaunchedFromFirmwareVolumeErrInvalidEventType(c *C) { + _, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{EventType: tcglog.EventTypeSeparator}) + c.Check(err, ErrorMatches, `unexpected event type EV_SEPARATOR`) +} + +func (s *tcgEventsSuite) TestIsLaunchedFromFirmwareVolumeErrInvalidEventData(c *C) { + _, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ + EventType: tcglog.EventTypeEFIBootServicesDriver, + Data: &invalidEventData{errors.New("some error")}, + }) + c.Check(err, ErrorMatches, `event has invalid event data: some error`) +} + +func (s *tcgEventsSuite) TestIsLaunchedFromFirmwareVolumeErrEmptyPath(c *C) { + _, err := IsLaunchedFromFirmwareVolume(&tcglog.Event{ + EventType: tcglog.EventTypeEFIBootServicesDriver, + Data: &tcglog.EFIImageLoadEvent{}, + }) + c.Check(err, ErrorMatches, `empty device path`) +} diff --git a/internal/efitest/hostenv.go b/internal/efitest/hostenv.go index 69f3a9f9..a1773682 100644 --- a/internal/efitest/hostenv.go +++ b/internal/efitest/hostenv.go @@ -115,6 +115,7 @@ func WithDelayedVirtModeError(err error) MockHostEnvironmentOption { type mockHostEnvironmentAMD64 struct { vendorIdentificator string + family uint32 features map[uint64]struct{} cpus uint32 msrs map[uint32]uint64 @@ -124,6 +125,10 @@ func (e *mockHostEnvironmentAMD64) CPUVendorIdentificator() string { return e.vendorIdentificator } +func (e *mockHostEnvironmentAMD64) CPUFamily() uint32 { + return e.family +} + func (e *mockHostEnvironmentAMD64) HasCPUIDFeature(feature uint64) bool { _, has := e.features[feature] return has @@ -200,7 +205,7 @@ func WithSysfsDevices(devices ...internal_efi.SysfsDevice) MockHostEnvironmentOp // WithAMD64Environment adds a [github.com/snapcore/secboot/efi/internal.HostEnvironmentAMD64] to the [MockHostEnvironment]. // Whilst this supports mocking MSRs, it only supports the same value for every CPU. -func WithAMD64Environment(cpuVendorIdentificator string, cpuidFeatures []uint64, cpus uint32, msrs map[uint32]uint64) MockHostEnvironmentOption { +func WithAMD64Environment(cpuVendorIdentificator string, family uint32, cpuidFeatures []uint64, cpus uint32, msrs map[uint32]uint64) MockHostEnvironmentOption { return func(env *MockHostEnvironment) { features := make(map[uint64]struct{}) for _, feature := range cpuidFeatures { @@ -208,6 +213,7 @@ func WithAMD64Environment(cpuVendorIdentificator string, cpuidFeatures []uint64, } env.AMD64Env = &mockHostEnvironmentAMD64{ vendorIdentificator: cpuVendorIdentificator, + family: family, features: features, cpus: cpus, msrs: msrs, diff --git a/tpm2/export_test.go b/tpm2/export_test.go index d545aa24..2a0a9272 100644 --- a/tpm2/export_test.go +++ b/tpm2/export_test.go @@ -90,6 +90,7 @@ func NewSealedObjectKeySealer(tpm *Connection) keySealer { type KeyDataConstructor = keyDataConstructor type KeySealer = keySealer +type LockoutAuthParams = lockoutAuthParams type PcrPolicyVersionOption = pcrPolicyVersionOption type PolicyDataError = policyDataError diff --git a/tpm2/lockoutauth.go b/tpm2/lockoutauth.go new file mode 100644 index 00000000..6fb4e70f --- /dev/null +++ b/tpm2/lockoutauth.go @@ -0,0 +1,223 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2026 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package tpm2 + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/canonical/go-tpm2" + "github.com/canonical/go-tpm2/mu" + "github.com/canonical/go-tpm2/policyutil" +) + +var ( + // ErrEmptyLockoutAuthValue is returned from Connection.ResetDictionaryAttackLock if + // the authorization value for the lockout hierarchy is unset. + ErrEmptyLockoutAuthValue = errors.New("the authorization value for the lockout hierarchy is empty") + + // ErrInvalidLockoutAuthPolicy is returned from Connection.ResetDictionaryAttackLock if + // the authorization policy for the lockout hierarchy is not consistent with the supplied + // data. + ErrInvalidLockoutAuthPolicy = errors.New("the authorization policy for the lockout hierarchy is invalid") +) + +// InvalidLockoutAuthDataError is returned from [Connection.ResetDictionaryAttackLock] if the +// supplied lockout hierarchy authorization data is invalid. +type InvalidLockoutAuthDataError struct { + err error +} + +func (e *InvalidLockoutAuthDataError) Error() string { + return "invalid lockout hierarchy authorization data: " + e.err.Error() +} + +func (e *InvalidLockoutAuthDataError) Unwrap() error { + return e.err +} + +type lockoutAuthParamsJson struct { + AuthValue []byte `json:"auth-value"` + AuthPolicy []byte `json:"auth-policy,omitempty"` + NewAuthValue []byte `json:"new-auth-value,omitempty"` + NewAuthPolicy []byte `json:"new-auth-policy,omitempty"` +} + +type lockoutAuthParams struct { + AuthValue tpm2.Auth + AuthPolicy *policyutil.Policy + NewAuthValue tpm2.Auth + NewAuthPolicy *policyutil.Policy +} + +func (p *lockoutAuthParams) MarshalJSON() ([]byte, error) { + j := &lockoutAuthParamsJson{ + AuthValue: p.AuthValue, + NewAuthValue: p.NewAuthValue, + } + if p.AuthPolicy != nil { + data, err := mu.MarshalToBytes(p.AuthPolicy) + if err != nil { + return nil, fmt.Errorf("cannot encode auth-policy: %w", err) + } + j.AuthPolicy = data + } + if p.NewAuthPolicy != nil { + data, err := mu.MarshalToBytes(p.NewAuthPolicy) + if err != nil { + return nil, fmt.Errorf("cannot encode new-auth-policy: %w", err) + } + j.NewAuthPolicy = data + } + + return json.Marshal(j) +} + +func (p *lockoutAuthParams) UnmarshalJSON(data []byte) error { + var j *lockoutAuthParamsJson + if err := json.Unmarshal(data, &j); err != nil { + return err + } + + *p = lockoutAuthParams{ + AuthValue: j.AuthValue, + NewAuthValue: j.NewAuthValue, + } + if len(j.AuthPolicy) > 0 { + if _, err := mu.UnmarshalFromBytes(j.AuthPolicy, &p.AuthPolicy); err != nil { + return fmt.Errorf("cannot decode auth-policy: %w", err) + } + } + if len(j.NewAuthPolicy) > 0 { + if _, err := mu.UnmarshalFromBytes(j.NewAuthPolicy, &p.NewAuthPolicy); err != nil { + return fmt.Errorf("cannot decode new-auth-policy: %w", err) + } + } + + return nil +} + +func (t *Connection) resetDictionaryAttackLockImpl(params *lockoutAuthParams) error { + if len(params.NewAuthValue) > 0 || params.NewAuthPolicy != nil { + return errors.New("lockout hierarchy auth value change not supported yet") + } + + var authValue []byte + + val, err := t.GetCapabilityTPMProperty(tpm2.PropertyPermanent) + if err != nil { + return fmt.Errorf("cannot obtain value of TPM_PT_PERMANENT: %w", err) + } + lockoutAuthSet := tpm2.PermanentAttributes(val)&tpm2.AttrLockoutAuthSet > 0 + if lockoutAuthSet { + authValue = params.AuthValue + } + + var session tpm2.SessionContext + switch { + case params.AuthPolicy == nil: + session = t.HmacSession() + default: + session, err = t.StartAuthSession(nil, nil, tpm2.SessionTypePolicy, nil, defaultSessionHashAlgorithm) + if err != nil { + return fmt.Errorf("cannot start policy session: %w", err) + } + defer t.FlushContext(session) + + // Execute policy session, constraining the use to the TPM2_DictionaryAttackLockReset command so + // that the correct branch executes. + _, err := params.AuthPolicy.Execute( + policyutil.NewPolicyExecuteSession(t.TPMContext, session), + policyutil.WithSessionUsageCommandConstraint(tpm2.CommandDictionaryAttackLockReset, []policyutil.NamedHandle{t.LockoutHandleContext()}), + ) + if err != nil { + return ErrInvalidLockoutAuthPolicy + } + } + + t.LockoutHandleContext().SetAuthValue(authValue) + defer t.LockoutHandleContext().SetAuthValue(nil) + + switch err := t.DictionaryAttackLockReset(t.LockoutHandleContext(), session); { + case isAuthFailError(err, tpm2.CommandDictionaryAttackLockReset, 1): + return AuthFailError{tpm2.HandleLockout} + case tpm2.IsTPMWarning(err, tpm2.WarningLockout, tpm2.CommandDictionaryAttackLockReset): + return ErrTPMLockout + case tpm2.IsTPMSessionError(err, tpm2.ErrorPolicyFail, tpm2.CommandDictionaryAttackLockReset, 1): + return ErrInvalidLockoutAuthPolicy + case err != nil: + return fmt.Errorf("cannot reset dictionary attack counter: %w", err) + } + + if !lockoutAuthSet { + return ErrEmptyLockoutAuthValue + } + return nil +} + +// ResetDictionaryAttackLock resets the TPM's dictionary attack counter using the +// TPM2_DictionaryAttackLockReset command. The caller supplies authorization data for the TPM's +// lockout hierarchy which will have been supplied by a previous call to +// [Connection.EnsureProvisioned] (XXX: in a future PR). +// +// If the supplied authorization data is invalid, a *[InvalidLockoutAuthDataError] error will +// be returned. +// +// If the TPM indicates that the lockout hierarchy has an empty authorization value, this function +// will still succeed but will return an [ErrEmptyLockoutAuthValue] error. +// +// If authorization of the TPM's lockout hierarchy fails, an [AuthFailError] error will be returned. +// In this case, the lockout hierarchy will become unavailable for the current lockout recovery +// time ([Connection.EnsureProvisioned] sets it to 86400 seconds). +// +// If the TPM's lockout hierarchy is unavailable because of a previous authorization failure, an +// [ErrTPMLockout] error will be returned. +// +// If the authorization policy for the TPM's lockout hierarchy is invalid, an +// [ErrInvalidLockoutAuthPolicy] error will be returned. +func (t *Connection) ResetDictionaryAttackLock(lockoutAuthData []byte) error { + var params *lockoutAuthParams + if err := json.Unmarshal(lockoutAuthData, ¶ms); err != nil { + return &InvalidLockoutAuthDataError{err: err} + } + return t.resetDictionaryAttackLockImpl(params) +} + +// ResetDictionaryAttackLockWithAuthValue resets the TPM's dictionary attack counter using the +// TPM2_DictionaryAttackLockReset command. The caller supplies the authorization value for the +// TPM's lockout hierarchy. This API is for systems that were configured with an older version +// of [Connection.EnsureProvisioned] (XXX: not yet) where an authorization value was chosen and +// supplied by the caller. +// +// If the TPM indicates that the lockout hierarchy has an empty authorization value, this function +// will still succeed but will return an [ErrEmptyLockoutAuthValue] error. +// +// If authorization of the TPM's lockout hierarchy fails, an [AuthFailError] error will be returned. +// In this case, the lockout hierarchy will become unavailable for the current lockout recovery +// time ([Connection.EnsureProvisioned] sets it to 86400 seconds). +// +// If the TPM's lockout hierarchy is unavailable because of a previous authorization failure, an +// [ErrTPMLockout] error will be returned. +func (t *Connection) ResetDictionaryAttackLockWithAuthValue(lockoutAuthValue []byte) error { + return t.resetDictionaryAttackLockImpl(&lockoutAuthParams{ + AuthValue: lockoutAuthValue, + }) +} diff --git a/tpm2/lockoutauth_test.go b/tpm2/lockoutauth_test.go new file mode 100644 index 00000000..af8455a3 --- /dev/null +++ b/tpm2/lockoutauth_test.go @@ -0,0 +1,447 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2026 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package tpm2_test + +import ( + "crypto/elliptic" + "crypto/rand" + "encoding/json" + "errors" + + "golang.org/x/crypto/hkdf" + . "gopkg.in/check.v1" + + "github.com/canonical/go-tpm2" + "github.com/canonical/go-tpm2/objectutil" + "github.com/canonical/go-tpm2/policyutil" + internal_crypto "github.com/snapcore/secboot/internal/crypto" + "github.com/snapcore/secboot/internal/testutil" + "github.com/snapcore/secboot/internal/tpm2test" + . "github.com/snapcore/secboot/tpm2" +) + +type lockoutauthSuiteMixin struct{} + +func (*lockoutauthSuiteMixin) newDefaultLockoutAuthPolicy(c *C, alg tpm2.HashAlgorithmId) (tpm2.Digest, *policyutil.Policy) { + builder := policyutil.NewPolicyBuilder(alg) + builder.RootBranch().AddBranchNode(func(n *policyutil.PolicyBuilderBranchNode) { + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.AddBranchNode(func(n *policyutil.PolicyBuilderBranchNode) { + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.PolicyCommandCode(tpm2.CommandDictionaryAttackLockReset) + }) + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.PolicyCommandCode(tpm2.CommandDictionaryAttackParameters) + }) + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.PolicyCommandCode(tpm2.CommandClearControl) + }) + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.PolicyCommandCode(tpm2.CommandClear) + }) + }) + b.PolicyAuthValue() + }) + }) + + digest, policy, err := builder.Policy() + c.Assert(err, IsNil) + return digest, policy +} + +func (*lockoutauthSuiteMixin) newRotateAuthValueLockoutAuthPolicy(c *C, alg tpm2.HashAlgorithmId, oldAuthValue []byte) (tpm2.Digest, *policyutil.Policy) { + r := hkdf.Expand(alg.NewHash, oldAuthValue, []byte("CHANGE-AUTH")) + key, err := internal_crypto.GenerateECDSAKey(elliptic.P256(), r) + c.Assert(err, IsNil) + pubKey, err := objectutil.NewECCPublicKey(&key.PublicKey) + c.Assert(err, IsNil) + + builder := policyutil.NewPolicyBuilder(alg) + builder.RootBranch().AddBranchNode(func(n *policyutil.PolicyBuilderBranchNode) { + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.AddBranchNode(func(n *policyutil.PolicyBuilderBranchNode) { + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.PolicyCommandCode(tpm2.CommandDictionaryAttackLockReset) + }) + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.PolicyCommandCode(tpm2.CommandDictionaryAttackParameters) + }) + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.PolicyCommandCode(tpm2.CommandClearControl) + }) + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.PolicyCommandCode(tpm2.CommandClear) + }) + }) + b.PolicyAuthValue() + }) + n.AddBranch("", func(b *policyutil.PolicyBuilderBranch) { + b.PolicyCommandCode(tpm2.CommandHierarchyChangeAuth) + b.PolicySigned(pubKey, []byte("CHANGE-AUTH")) + }) + }) + + digest, policy, err := builder.Policy() + c.Assert(err, IsNil) + return digest, policy +} + +type lockoutauthSuiteNoTPM struct { + lockoutauthSuiteMixin +} + +func (s *lockoutauthSuiteNoTPM) newDefaultLockoutAuthPolicy(c *C, alg tpm2.HashAlgorithmId) *policyutil.Policy { + _, policy := s.lockoutauthSuiteMixin.newDefaultLockoutAuthPolicy(c, alg) + return policy +} + +func (s *lockoutauthSuiteNoTPM) newRotateAuthValueLockoutAuthPolicy(c *C, alg tpm2.HashAlgorithmId, oldAuthValue []byte) *policyutil.Policy { + _, policy := s.lockoutauthSuiteMixin.newRotateAuthValueLockoutAuthPolicy(c, alg, oldAuthValue) + return policy +} + +type lockoutauthSuite struct { + tpm2test.TPMTest + lockoutauthSuiteMixin +} + +func (s *lockoutauthSuite) SetUpSuite(c *C) { + s.TPMFeatures = tpm2test.TPMFeatureLockoutHierarchy | + tpm2test.TPMFeaturePlatformHierarchy | + tpm2test.TPMFeatureClear | + tpm2test.TPMFeatureNV +} + +func (s *lockoutauthSuite) SetUpTest(c *C) { + s.TPMTest.SetUpTest(c) + + c.Assert(s.TPM().DictionaryAttackParameters(s.TPM().LockoutHandleContext(), 32, 7200, 86400, nil), IsNil) +} + +func (s *lockoutauthSuite) makeLockoutAuthData(c *C, params *LockoutAuthParams) []byte { + data, err := json.Marshal(params) + c.Assert(err, IsNil) + return data +} + +var _ = Suite(&lockoutauthSuiteNoTPM{}) +var _ = Suite(&lockoutauthSuite{}) + +func (s *lockoutauthSuiteNoTPM) TestLockoutAuthParamsMarshalJSON(c *C) { + params := &LockoutAuthParams{ + AuthValue: testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1"), + AuthPolicy: s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256), + } + + data, err := json.Marshal(params) + c.Check(err, IsNil) + c.Check(data, DeepEquals, []byte(`{"auth-value":"x9oO1va6Pz6nQeeGOgoXSBOLbsyw4IQTKwSpyXbw0LE=","auth-policy":"AAAAAAAAAAEAC5xRENPNjPxvymnylptEkkmB67kMJSALrpC4PA2joYWCAAAAAAAAAAEgAQFxAAAAAQAAAAAAAQAL+21OPQovgBAFA+/1biwvpZu8ItTlnZBiGL/DKXTgoIIAAAACIAEBcQAAAAQAAAAAAAEAC7bFwF5YGQnN6n33pfkcDy7tN/128VUi7uW1X4lvLVY/AAAAAQAAAWwAAAE5AAAAAAABAAscaCd8nWVk3YG8z35Wuj7cqziPxgzpWzpEK9JyWPYN/AAAAAEAAAFsAAABOgAAAAAAAQALlAz7Qhe7Htz3+0GTfKl0qmjmmKt4uBJLBwET4hH9RvwAAAABAAABbAAAAScAAAAAAAEAC8Tfq87ajeg2yVZhlSiSsd73IDr7Rv7+xD/8/JO+VAcwAAAAAQAAAWwAAAEmAAABaw=="}`)) +} + +func (s *lockoutauthSuiteNoTPM) TestLockoutAuthParamsMarshalJSONNoPolicy(c *C) { + params := &LockoutAuthParams{ + AuthValue: testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1"), + } + + data, err := json.Marshal(params) + c.Check(err, IsNil) + c.Check(data, DeepEquals, []byte(`{"auth-value":"x9oO1va6Pz6nQeeGOgoXSBOLbsyw4IQTKwSpyXbw0LE="}`)) +} + +func (s *lockoutauthSuiteNoTPM) TestLockoutAuthParamsMarshalJSONForChangeAuth(c *C) { + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + params := &LockoutAuthParams{ + AuthValue: authValue, + AuthPolicy: s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256), + NewAuthValue: testutil.DecodeHexString(c, "db82cbebd10ebd831b48ff8ae7275a23029074ba622c0416d97cd34dd38d8186"), + NewAuthPolicy: s.newRotateAuthValueLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256, authValue), + } + + data, err := json.Marshal(params) + c.Check(err, IsNil) + c.Check(data, DeepEquals, []byte(`{"auth-value":"x9oO1va6Pz6nQeeGOgoXSBOLbsyw4IQTKwSpyXbw0LE=","auth-policy":"AAAAAAAAAAEAC5xRENPNjPxvymnylptEkkmB67kMJSALrpC4PA2joYWCAAAAAAAAAAEgAQFxAAAAAQAAAAAAAQAL+21OPQovgBAFA+/1biwvpZu8ItTlnZBiGL/DKXTgoIIAAAACIAEBcQAAAAQAAAAAAAEAC7bFwF5YGQnN6n33pfkcDy7tN/128VUi7uW1X4lvLVY/AAAAAQAAAWwAAAE5AAAAAAABAAscaCd8nWVk3YG8z35Wuj7cqziPxgzpWzpEK9JyWPYN/AAAAAEAAAFsAAABOgAAAAAAAQALlAz7Qhe7Htz3+0GTfKl0qmjmmKt4uBJLBwET4hH9RvwAAAABAAABbAAAAScAAAAAAAEAC8Tfq87ajeg2yVZhlSiSsd73IDr7Rv7+xD/8/JO+VAcwAAAAAQAAAWwAAAEmAAABaw==","new-auth-value":"24LL69EOvYMbSP+K5ydaIwKQdLpiLAQW2XzTTdONgYY=","new-auth-policy":"AAAAAAAAAAEAC8iuOzJsfCEvz5HdnLSO98fhopBFpLgo9fX7/1TF/6KqAAAAAAAAAAEgAQFxAAAAAgAAAAAAAQAL+21OPQovgBAFA+/1biwvpZu8ItTlnZBiGL/DKXTgoIIAAAACIAEBcQAAAAQAAAAAAAEAC7bFwF5YGQnN6n33pfkcDy7tN/128VUi7uW1X4lvLVY/AAAAAQAAAWwAAAE5AAAAAAABAAscaCd8nWVk3YG8z35Wuj7cqziPxgzpWzpEK9JyWPYN/AAAAAEAAAFsAAABOgAAAAAAAQALlAz7Qhe7Htz3+0GTfKl0qmjmmKt4uBJLBwET4hH9RvwAAAABAAABbAAAAScAAAAAAAEAC8Tfq87ajeg2yVZhlSiSsd73IDr7Rv7+xD/8/JO+VAcwAAAAAQAAAWwAAAEmAAABawAAAAAAAQALDDnMvDFtHshfTn3M6F3KHOta8q5u4GWsqsqB8JnLJCYAAAACAAABbAAAASkAAAFgACMACwAEAAAAAAAQABAAAwAQACC2BaF5zNUOUWsO9Vxdw5PNDslawcvHjS3x54a1VHxZfAAgaOCKN2rpEFpajypuc/XSGSr0LnK/e8W9IyZMM8DufpUAC0NIQU5HRS1BVVRIAAAAAAAA"}`)) +} + +func (s *lockoutauthSuiteNoTPM) TestLockoutAuthParamsUnmarshalJSON(c *C) { + data := []byte(`{"auth-value":"x9oO1va6Pz6nQeeGOgoXSBOLbsyw4IQTKwSpyXbw0LE=","auth-policy":"AAAAAAAAAAEAC5xRENPNjPxvymnylptEkkmB67kMJSALrpC4PA2joYWCAAAAAAAAAAEgAQFxAAAAAQAAAAAAAQAL+21OPQovgBAFA+/1biwvpZu8ItTlnZBiGL/DKXTgoIIAAAACIAEBcQAAAAQAAAAAAAEAC7bFwF5YGQnN6n33pfkcDy7tN/128VUi7uW1X4lvLVY/AAAAAQAAAWwAAAE5AAAAAAABAAscaCd8nWVk3YG8z35Wuj7cqziPxgzpWzpEK9JyWPYN/AAAAAEAAAFsAAABOgAAAAAAAQALlAz7Qhe7Htz3+0GTfKl0qmjmmKt4uBJLBwET4hH9RvwAAAABAAABbAAAAScAAAAAAAEAC8Tfq87ajeg2yVZhlSiSsd73IDr7Rv7+xD/8/JO+VAcwAAAAAQAAAWwAAAEmAAABaw=="}`) + + expected := &LockoutAuthParams{ + AuthValue: testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1"), + AuthPolicy: s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256), + } + + var params *LockoutAuthParams + c.Assert(json.Unmarshal(data, ¶ms), IsNil) + c.Check(params, DeepEquals, expected) +} + +func (s *lockoutauthSuiteNoTPM) TestLockoutAuthParamsUnmarshalJSONForChangeAuth(c *C) { + data := []byte(`{"auth-value":"x9oO1va6Pz6nQeeGOgoXSBOLbsyw4IQTKwSpyXbw0LE=","auth-policy":"AAAAAAAAAAEAC5xRENPNjPxvymnylptEkkmB67kMJSALrpC4PA2joYWCAAAAAAAAAAEgAQFxAAAAAQAAAAAAAQAL+21OPQovgBAFA+/1biwvpZu8ItTlnZBiGL/DKXTgoIIAAAACIAEBcQAAAAQAAAAAAAEAC7bFwF5YGQnN6n33pfkcDy7tN/128VUi7uW1X4lvLVY/AAAAAQAAAWwAAAE5AAAAAAABAAscaCd8nWVk3YG8z35Wuj7cqziPxgzpWzpEK9JyWPYN/AAAAAEAAAFsAAABOgAAAAAAAQALlAz7Qhe7Htz3+0GTfKl0qmjmmKt4uBJLBwET4hH9RvwAAAABAAABbAAAAScAAAAAAAEAC8Tfq87ajeg2yVZhlSiSsd73IDr7Rv7+xD/8/JO+VAcwAAAAAQAAAWwAAAEmAAABaw==","new-auth-value":"24LL69EOvYMbSP+K5ydaIwKQdLpiLAQW2XzTTdONgYY=","new-auth-policy":"AAAAAAAAAAEAC8iuOzJsfCEvz5HdnLSO98fhopBFpLgo9fX7/1TF/6KqAAAAAAAAAAEgAQFxAAAAAgAAAAAAAQAL+21OPQovgBAFA+/1biwvpZu8ItTlnZBiGL/DKXTgoIIAAAACIAEBcQAAAAQAAAAAAAEAC7bFwF5YGQnN6n33pfkcDy7tN/128VUi7uW1X4lvLVY/AAAAAQAAAWwAAAE5AAAAAAABAAscaCd8nWVk3YG8z35Wuj7cqziPxgzpWzpEK9JyWPYN/AAAAAEAAAFsAAABOgAAAAAAAQALlAz7Qhe7Htz3+0GTfKl0qmjmmKt4uBJLBwET4hH9RvwAAAABAAABbAAAAScAAAAAAAEAC8Tfq87ajeg2yVZhlSiSsd73IDr7Rv7+xD/8/JO+VAcwAAAAAQAAAWwAAAEmAAABawAAAAAAAQALDDnMvDFtHshfTn3M6F3KHOta8q5u4GWsqsqB8JnLJCYAAAACAAABbAAAASkAAAFgACMACwAEAAAAAAAQABAAAwAQACC2BaF5zNUOUWsO9Vxdw5PNDslawcvHjS3x54a1VHxZfAAgaOCKN2rpEFpajypuc/XSGSr0LnK/e8W9IyZMM8DufpUAC0NIQU5HRS1BVVRIAAAAAAAA"}`) + + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + expected := &LockoutAuthParams{ + AuthValue: authValue, + AuthPolicy: s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256), + NewAuthValue: testutil.DecodeHexString(c, "db82cbebd10ebd831b48ff8ae7275a23029074ba622c0416d97cd34dd38d8186"), + NewAuthPolicy: s.newRotateAuthValueLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256, authValue), + } + + var params *LockoutAuthParams + c.Assert(json.Unmarshal(data, ¶ms), IsNil) + c.Check(params, DeepEquals, expected) +} + +func (s *lockoutauthSuiteNoTPM) TestLockoutAuthParamsUnmarshalJSONInvalidAuthPolicy(c *C) { + data := []byte(`{"auth-value":"x9oO1va6Pz6nQeeGOgoXSBOLbsyw4IQTKwSpyXbw0LE=","auth-policy":"AA=="}`) + + var params *LockoutAuthParams + c.Assert(json.Unmarshal(data, ¶ms), ErrorMatches, `cannot decode auth-policy: cannot unmarshal argument 0 whilst processing element of type uint32: unexpected EOF + +=== BEGIN STACK === +\.\.\. policyutil\.Policy location .+\.go:[0-9]+, argument 0 +=== END STACK === +`) +} + +type testResetDictionaryAttackLockParams struct { + authValue tpm2.Auth + policyDigest tpm2.Digest + policyAlg tpm2.HashAlgorithmId + prepare func() + data []byte +} + +func (s *lockoutauthSuite) testResetDictionaryAttackLock(c *C, params *testResetDictionaryAttackLockParams) error { + // Setup hierarchy authorization + // XXX: A subequent PR will make EnsureProvisioned do this instead + s.HierarchyChangeAuth(c, tpm2.HandleLockout, params.authValue) + c.Assert(s.TPM().SetPrimaryPolicy(s.TPM().LockoutHandleContext(), params.policyDigest, params.policyAlg, nil), IsNil) + s.TPM().LockoutHandleContext().SetAuthValue(nil) // Make sure ResetDictionaryAttackLock sets this. + + // Increment the DA counter by 1 + pub, sensitive, err := objectutil.NewSealedObject(rand.Reader, []byte("foo"), []byte("5678")) + c.Assert(err, IsNil) + key, err := s.TPM().LoadExternal(sensitive, pub, tpm2.HandleNull) + c.Assert(err, IsNil) + key.SetAuthValue(nil) + _, err = s.TPM().Unseal(key, nil) + c.Assert(tpm2.IsTPMSessionError(err, tpm2.ErrorAuthFail, tpm2.CommandUnseal, 1), testutil.IsTrue) + + // Check the DA counter + val, err := s.TPM().GetCapabilityTPMProperty(tpm2.PropertyLockoutCounter) + c.Assert(err, IsNil) + c.Assert(val, Equals, uint32(1)) + + if params.prepare != nil { + params.prepare() + } + + resetErr := s.TPM().ResetDictionaryAttackLock(params.data) + if resetErr != nil && !errors.Is(resetErr, ErrEmptyLockoutAuthValue) { + return resetErr + } + + val, err = s.TPM().GetCapabilityTPMProperty(tpm2.PropertyLockoutCounter) + c.Assert(err, IsNil) + c.Assert(val, Equals, uint32(0)) + + c.Check(s.TPM().LockoutHandleContext().AuthValue(), DeepEquals, []byte(nil)) + + return resetErr +} + +func (s *lockoutauthSuite) TestResetDictionaryAttackLock(c *C) { + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + digest, policy := s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256) + + err := s.testResetDictionaryAttackLock(c, &testResetDictionaryAttackLockParams{ + authValue: authValue, + policyDigest: digest, + policyAlg: tpm2.HashAlgorithmSHA256, + data: s.makeLockoutAuthData(c, &LockoutAuthParams{ + AuthValue: authValue, + AuthPolicy: policy, + }), + }) + c.Check(err, IsNil) + + cmds := s.CommandLog() + c.Assert(len(cmds) > 2, testutil.IsTrue) + cmd := cmds[len(cmds)-3] + c.Check(cmd.CmdCode, Equals, tpm2.CommandDictionaryAttackLockReset) + c.Assert(cmd.CmdAuthArea, HasLen, 1) + c.Check(cmd.CmdAuthArea[0].SessionHandle.Type(), Equals, tpm2.HandleTypePolicySession) + + c.Check(s.TPM().DoesHandleExist(cmd.CmdAuthArea[0].SessionHandle), testutil.IsFalse) +} + +func (s *lockoutauthSuite) TestResetDictionaryAttackLockAuthValueUnset(c *C) { + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + digest, policy := s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256) + + err := s.testResetDictionaryAttackLock(c, &testResetDictionaryAttackLockParams{ + policyDigest: digest, + policyAlg: tpm2.HashAlgorithmSHA256, + data: s.makeLockoutAuthData(c, &LockoutAuthParams{ + AuthValue: authValue, + AuthPolicy: policy, + }), + }) + c.Check(err, ErrorMatches, `the authorization value for the lockout hierarchy is empty`) + c.Check(err, Equals, ErrEmptyLockoutAuthValue) + + cmds := s.CommandLog() + c.Assert(len(cmds) > 2, testutil.IsTrue) + cmd := cmds[len(cmds)-3] + c.Check(cmd.CmdCode, Equals, tpm2.CommandDictionaryAttackLockReset) + c.Assert(cmd.CmdAuthArea, HasLen, 1) + c.Check(cmd.CmdAuthArea[0].SessionHandle.Type(), Equals, tpm2.HandleTypePolicySession) + + c.Check(s.TPM().DoesHandleExist(cmd.CmdAuthArea[0].SessionHandle), testutil.IsFalse) +} + +func (s *lockoutauthSuite) TestResetDictionaryAttackLockWithAuthValue(c *C) { + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + + // Setup hierarchy authorization + // XXX: A subequent PR will make EnsureProvisioned do this instead + s.HierarchyChangeAuth(c, tpm2.HandleLockout, authValue) + s.TPM().LockoutHandleContext().SetAuthValue(nil) // Make sure ResetDictionaryAttackLock sets this. + + // Increment the DA counter by 1 + pub, sensitive, err := objectutil.NewSealedObject(rand.Reader, []byte("foo"), []byte("5678")) + c.Assert(err, IsNil) + key, err := s.TPM().LoadExternal(sensitive, pub, tpm2.HandleNull) + c.Assert(err, IsNil) + key.SetAuthValue(nil) + _, err = s.TPM().Unseal(key, nil) + c.Assert(tpm2.IsTPMSessionError(err, tpm2.ErrorAuthFail, tpm2.CommandUnseal, 1), testutil.IsTrue) + + // Check the DA counter + val, err := s.TPM().GetCapabilityTPMProperty(tpm2.PropertyLockoutCounter) + c.Assert(err, IsNil) + c.Assert(val, Equals, uint32(1)) + + c.Check(s.TPM().ResetDictionaryAttackLockWithAuthValue(authValue), IsNil) + + val, err = s.TPM().GetCapabilityTPMProperty(tpm2.PropertyLockoutCounter) + c.Assert(err, IsNil) + c.Assert(val, Equals, uint32(0)) + + c.Check(s.TPM().LockoutHandleContext().AuthValue(), DeepEquals, []byte(nil)) + + cmds := s.CommandLog() + c.Assert(len(cmds) > 1, testutil.IsTrue) + cmd := cmds[len(cmds)-2] + c.Check(cmd.CmdCode, Equals, tpm2.CommandDictionaryAttackLockReset) + c.Assert(cmd.CmdAuthArea, HasLen, 1) + c.Check(cmd.CmdAuthArea[0].SessionHandle, Equals, s.TPM().HmacSession().Handle()) + + c.Check(s.TPM().DoesHandleExist(s.TPM().HmacSession().Handle()), testutil.IsTrue) +} + +func (s *lockoutauthSuite) TestResetDictionaryAttackLockInvalidData(c *C) { + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + digest, _ := s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256) + + err := s.testResetDictionaryAttackLock(c, &testResetDictionaryAttackLockParams{ + authValue: authValue, + policyDigest: digest, + policyAlg: tpm2.HashAlgorithmSHA256, + data: []byte(`foo`), + }) + c.Check(err, ErrorMatches, `invalid lockout hierarchy authorization data: invalid character 'o' in literal false \(expecting 'a'\)`) + c.Check(err, testutil.ConvertibleTo, &InvalidLockoutAuthDataError{}) +} + +func (s *lockoutauthSuite) TestResetDictionaryAttackLockUnsupportedAuthValueRotation(c *C) { + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + digest, policy := s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256) + + err := s.testResetDictionaryAttackLock(c, &testResetDictionaryAttackLockParams{ + authValue: authValue, + policyDigest: digest, + policyAlg: tpm2.HashAlgorithmSHA256, + data: s.makeLockoutAuthData(c, &LockoutAuthParams{ + AuthValue: authValue, + AuthPolicy: policy, + NewAuthValue: testutil.DecodeHexString(c, "db82cbebd10ebd831b48ff8ae7275a23029074ba622c0416d97cd34dd38d8186"), + }), + }) + c.Check(err, ErrorMatches, `lockout hierarchy auth value change not supported yet`) +} + +func (s *lockoutauthSuite) TestResetDictionaryAttackLockAuthFail(c *C) { + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + digest, policy := s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256) + + defer s.ClearTPMUsingPlatformHierarchy(c) + + err := s.testResetDictionaryAttackLock(c, &testResetDictionaryAttackLockParams{ + authValue: authValue, + policyDigest: digest, + policyAlg: tpm2.HashAlgorithmSHA256, + data: s.makeLockoutAuthData(c, &LockoutAuthParams{ + AuthPolicy: policy, + }), + }) + c.Check(err, ErrorMatches, `cannot access resource at handle TPM_RH_LOCKOUT because an authorization check failed`) + c.Assert(err, testutil.ConvertibleTo, AuthFailError{}) + c.Check(err.(AuthFailError).Handle, Equals, tpm2.HandleLockout) +} + +func (s *lockoutauthSuite) TestResetDictionaryAttackLockLockout(c *C) { + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + digest, policy := s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256) + + defer s.ClearTPMUsingPlatformHierarchy(c) + + err := s.testResetDictionaryAttackLock(c, &testResetDictionaryAttackLockParams{ + authValue: authValue, + policyDigest: digest, + policyAlg: tpm2.HashAlgorithmSHA256, + prepare: func() { + c.Check(s.TPM().HierarchyChangeAuth(s.TPM().LockoutHandleContext(), nil, nil), testutil.ErrorIs, + &tpm2.TPMSessionError{TPMError: &tpm2.TPMError{Command: tpm2.CommandHierarchyChangeAuth, Code: tpm2.ErrorAuthFail}, Index: 1}) + }, + data: s.makeLockoutAuthData(c, &LockoutAuthParams{ + AuthValue: authValue, + AuthPolicy: policy, + }), + }) + c.Check(err, ErrorMatches, `the TPM is in DA lockout mode`) + c.Check(err, Equals, ErrTPMLockout) +} + +func (s *lockoutauthSuite) TestResetDictionaryAttackLockInvalidPolicy(c *C) { + authValue := testutil.DecodeHexString(c, "c7da0ed6f6ba3f3ea741e7863a0a1748138b6eccb0e084132b04a9c976f0d0b1") + _, policy := s.newDefaultLockoutAuthPolicy(c, tpm2.HashAlgorithmSHA256) + + err := s.testResetDictionaryAttackLock(c, &testResetDictionaryAttackLockParams{ + authValue: authValue, + policyDigest: testutil.DecodeHexString(c, "5e517fa9d3184d1b37338b34a0a8aa4fb8f4c74cdde8cade3ba4357d31af7b7c"), + policyAlg: tpm2.HashAlgorithmSHA256, + data: s.makeLockoutAuthData(c, &LockoutAuthParams{ + AuthPolicy: policy, + }), + }) + c.Check(err, ErrorMatches, `the authorization policy for the lockout hierarchy is invalid`) + c.Check(err, Equals, ErrInvalidLockoutAuthPolicy) +} diff --git a/tpm2/pcr_profile_test.go b/tpm2/pcr_profile_test.go index 5a847c8b..9f3b2f22 100644 --- a/tpm2/pcr_profile_test.go +++ b/tpm2/pcr_profile_test.go @@ -1124,5 +1124,5 @@ func (s *pcrProfileTPMSuite) TestAddValueFromTPMInvalidPCR(c *C) { c.Check(p.RootBranch().AddPCRValueFromTPM(tpm2.HashAlgorithmSHA256, 100), Equals, p.RootBranch()) _, _, err := p.ComputePCRDigests(s.TPM().TPMContext, tpm2.HashAlgorithmSHA256) - c.Check(err, ErrorMatches, `cannot read current PCR values from TPM: TPM returned an error for parameter 1 whilst executing command TPM_CC_PCR_Read: TPM_RC_VALUE \(value is out of range or is not correct for the context\)`) + c.Check(err, ErrorMatches, `cannot read current PCR values from TPM: TPM returned an error for parameter 1 whilst executing command TPM_CC_PCR_Read: TPM_RC_VALUE \+ TPM_RC_P \+ TPM_RC_1 \(value is out of range or is not correct for the context\)`) } diff --git a/tpm2/platform_test.go b/tpm2/platform_test.go index 8f47eb19..b9760269 100644 --- a/tpm2/platform_test.go +++ b/tpm2/platform_test.go @@ -904,7 +904,7 @@ func (s *platformSuite) TestRecoverKeysWithIncorrectAuthKey(c *C) { c.Assert(err, testutil.ConvertibleTo, &secboot.PlatformHandlerError{}) c.Check(err.(*secboot.PlatformHandlerError).Type, Equals, secboot.PlatformHandlerErrorInvalidAuthKey) c.Check(err, ErrorMatches, "cannot unseal key: TPM returned an error for session 1 whilst executing command TPM_CC_Unseal: "+ - "TPM_RC_AUTH_FAIL \\(the authorization HMAC check failed and DA counter incremented\\)") + "TPM_RC_AUTH_FAIL \\+ TPM_RC_S \\+ TPM_RC_1 \\(the authorization HMAC check failed and DA counter incremented\\)") } func (s *platformSuite) TestChangeAuthKeyWithIncorrectAuthKey(c *C) { @@ -986,7 +986,7 @@ func (s *platformSuite) TestChangeAuthKeyWithIncorrectAuthKey(c *C) { c.Assert(err, testutil.ConvertibleTo, &secboot.PlatformHandlerError{}) c.Check(err.(*secboot.PlatformHandlerError).Type, Equals, secboot.PlatformHandlerErrorInvalidAuthKey) c.Check(err, ErrorMatches, "TPM returned an error for session 1 whilst executing command TPM_CC_ObjectChangeAuth: "+ - "TPM_RC_AUTH_FAIL \\(the authorization HMAC check failed and DA counter incremented\\)") + "TPM_RC_AUTH_FAIL \\+ TPM_RC_S \\+ TPM_RC_1 \\(the authorization HMAC check failed and DA counter incremented\\)") } func (s *platformSuite) TestChangeAuthKeyWithTPMLockout(c *C) { diff --git a/tpm2/policy_v0_test.go b/tpm2/policy_v0_test.go index c5c5fb21..ac612ee7 100644 --- a/tpm2/policy_v0_test.go +++ b/tpm2/policy_v0_test.go @@ -1448,7 +1448,7 @@ func (s *policyV0Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthPublicKey(c }) c.Check(IsPolicyDataError(err), testutil.IsTrue) c.Check(err, ErrorMatches, "public area of dynamic authorization policy signing key is invalid: TPM returned an error for parameter 2 whilst executing command TPM_CC_LoadExternal: "+ - "TPM_RC_HASH \\(hash algorithm not supported or not appropriate\\)") + "TPM_RC_HASH \\+ TPM_RC_P \\+ TPM_RC_2 \\(hash algorithm not supported or not appropriate\\)") } func (s *policyV0Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthorizedPolicySignature(c *C) { @@ -1489,7 +1489,7 @@ func (s *policyV0Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthorizedPolicy }, }) c.Check(IsPCRPolicyDataError(err), testutil.IsTrue) - c.Check(err, ErrorMatches, "cannot verify PCR policy signature: TPM returned an error for parameter 2 whilst executing command TPM_CC_VerifySignature: TPM_RC_SIGNATURE \\(the signature is not valid\\)") + c.Check(err, ErrorMatches, "cannot verify PCR policy signature: TPM returned an error for parameter 2 whilst executing command TPM_CC_VerifySignature: TPM_RC_SIGNATURE \\+ TPM_RC_P \\+ TPM_RC_2 \\(the signature is not valid\\)") } func (s *policyV0Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthorizedPolicy(c *C) { diff --git a/tpm2/policy_v1_test.go b/tpm2/policy_v1_test.go index dd826cdc..5aca0a9b 100644 --- a/tpm2/policy_v1_test.go +++ b/tpm2/policy_v1_test.go @@ -1176,7 +1176,7 @@ func (s *policyV1Suite) TestExecutePCRPolicyErrorHandlingInvalidPCRPolicyCounter }, }) c.Check(IsPCRPolicyDataError(err), testutil.IsTrue) - c.Check(err, ErrorMatches, "cannot verify PCR policy signature: TPM returned an error for parameter 2 whilst executing command TPM_CC_VerifySignature: TPM_RC_SIGNATURE \\(the signature is not valid\\)") + c.Check(err, ErrorMatches, "cannot verify PCR policy signature: TPM returned an error for parameter 2 whilst executing command TPM_CC_VerifySignature: TPM_RC_SIGNATURE \\+ TPM_RC_P \\+ TPM_RC_2 \\(the signature is not valid\\)") } func (s *policyV1Suite) TestExecutePCRPolicyErrorHandlingRevoked(c *C) { @@ -1275,7 +1275,7 @@ func (s *policyV1Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthPublicKey(c }) c.Check(IsPolicyDataError(err), testutil.IsTrue) c.Check(err, ErrorMatches, "public area of dynamic authorization policy signing key is invalid: TPM returned an error for parameter 2 whilst executing command TPM_CC_LoadExternal: "+ - "TPM_RC_HASH \\(hash algorithm not supported or not appropriate\\)") + "TPM_RC_HASH \\+ TPM_RC_P \\+ TPM_RC_2 \\(hash algorithm not supported or not appropriate\\)") } func (s *policyV1Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthorizedPolicySignature(c *C) { @@ -1316,7 +1316,7 @@ func (s *policyV1Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthorizedPolicy }, }) c.Check(IsPCRPolicyDataError(err), testutil.IsTrue) - c.Check(err, ErrorMatches, "cannot verify PCR policy signature: TPM returned an error for parameter 2 whilst executing command TPM_CC_VerifySignature: TPM_RC_SIGNATURE \\(the signature is not valid\\)") + c.Check(err, ErrorMatches, "cannot verify PCR policy signature: TPM returned an error for parameter 2 whilst executing command TPM_CC_VerifySignature: TPM_RC_SIGNATURE \\+ TPM_RC_P \\+ TPM_RC_2 \\(the signature is not valid\\)") } func (s *policyV1Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthorizedPolicy(c *C) { diff --git a/tpm2/policy_v3_test.go b/tpm2/policy_v3_test.go index 28f6b561..05e663d3 100644 --- a/tpm2/policy_v3_test.go +++ b/tpm2/policy_v3_test.go @@ -1427,7 +1427,7 @@ func (s *policyV3Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthorizedPolicy }, }) c.Check(IsPCRPolicyDataError(err), testutil.IsTrue) - c.Check(err, ErrorMatches, "cannot verify PCR policy signature: TPM returned an error for parameter 2 whilst executing command TPM_CC_VerifySignature: TPM_RC_SIGNATURE \\(the signature is not valid\\)") + c.Check(err, ErrorMatches, "cannot verify PCR policy signature: TPM returned an error for parameter 2 whilst executing command TPM_CC_VerifySignature: TPM_RC_SIGNATURE \\+ TPM_RC_P \\+ TPM_RC_2 \\(the signature is not valid\\)") } func (s *policyV3Suite) TestExecutePCRPolicyErrorHandlingInvalidAuthorizedPolicy(c *C) { diff --git a/tpm2/provisioning.go b/tpm2/provisioning.go index e9bf008c..f9121438 100644 --- a/tpm2/provisioning.go +++ b/tpm2/provisioning.go @@ -429,6 +429,11 @@ func (t *Connection) EnsureProvisioned(options ...EnsureProvisionedOption) error // Set the lockout hierarchy authorization. Use command parameter encryption here for the new value. // Note that this only offers protections against passive interposers. + // XXX: Clear any policy for the lockout hierarchy first. A future PR will initialize this to something + // sensible. + if err := t.SetPrimaryPolicy(t.LockoutHandleContext(), nil, tpm2.HashAlgorithmNull, session); err != nil { + return fmt.Errorf("cannot clear the lockout hierarchy authorization policy: %w", err) + } if err := t.HierarchyChangeAuth(t.LockoutHandleContext(), params.newLockoutAuthValue, session.IncludeAttrs(tpm2.AttrCommandEncrypt)); err != nil { return xerrors.Errorf("cannot set the lockout hierarchy authorization value: %w", err) }