Skip to content

Commit 9998096

Browse files
committed
efi/preinstall: refine the checks for manufacturing mode on Intel
This refines the checks that run on Intel systems so that appropriate error messages are returned if the system is in manufacturing mode. The changes are based on checks in the coreboot repository, specifically https://github.com/coreboot/coreboot/blob/eb5bdf06b92534b6f66f612297a4ccb69008b4ac/src/soc/intel/common/block/cse/cse_spec.c#L15 Fixes: FR-12761 Fixes: #515
1 parent 86574c8 commit 9998096

7 files changed

Lines changed: 303 additions & 59 deletions

efi/preinstall/check_host_security_amd64_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,11 @@ C7E003CB
134134
)
135135

136136
err := CheckHostSecurity(env, nil)
137-
c.Check(err, ErrorMatches, `encountered an error when checking Intel BootGuard configuration: no hardware root-of-trust properly configured: ME is in manufacturing mode`)
137+
c.Check(err, ErrorMatches, `encountered an error when checking Intel BootGuard configuration: no hardware root-of-trust properly configured: system is in manufacturing mode`)
138138

139139
var nhrotErr *NoHardwareRootOfTrustError
140140
c.Check(errors.As(err, &nhrotErr), testutil.IsTrue)
141-
c.Check(nhrotErr, ErrorMatches, `no hardware root-of-trust properly configured: ME is in manufacturing mode`)
141+
c.Check(nhrotErr, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`)
142142
}
143143

144144
func (s *hostSecurityAMD64Suite) TestCheckHostSecurityAMDErrPSP(c *C) {

efi/preinstall/check_host_security_intel.go

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,12 @@ func (reg hfsts1) operationMode() meOperationMode {
6161
}
6262

6363
const (
64-
// hfsts1MfgMode indicates that the ME is in manufacturing mode. Fwupd refers to this
65-
// as manufacturing mode for CSME #11 and SPI protection mode for CSME #18. Slimbootloader
66-
// refers to this as the latter for everything other than Comet Lake.
67-
hfsts1MfgMode hfsts1 = 1 << 4
68-
6964
// hfsts1OperationMode is the ME operation mode bitmask, from fwupd and slimbootloader.
7065
hfsts1OperationMode hfsts1 = 0xf0000
7166

7267
hfsts5BtgAcmActive hfsts5 = 1 << 0
7368
hfsts5BtgAcmDone hfsts5 = 1 << 8
7469

75-
hfsts6FPFSOCLock hfsts6 = 1 << 30
76-
7770
meOperationModeNormal meOperationMode = 0x0
7871
meOperationModeDebug meOperationMode = 0x2
7972
meOperationModeDisabled meOperationMode = 0x3
@@ -316,24 +309,14 @@ func checkHostSecurityIntelBootGuard(env internal_efi.HostEnvironment) error {
316309
return &NoHardwareRootOfTrustError{errors.New("invalid ME operation mode")}
317310
}
318311

319-
// Check manufacturing mode is not enabled.
320-
if regs.Hfsts1&hfsts1MfgMode > 0 {
321-
return &NoHardwareRootOfTrustError{errors.New("ME is in manufacturing mode")}
322-
}
323-
324312
// Check that the BootGuard ACM is active. Fwupd only checks this for CSME #18, but it
325313
// appears that the same bits are defined for both versions.
326314
if regs.Hfsts5&(hfsts5BtgAcmActive|hfsts5BtgAcmDone) != hfsts5BtgAcmActive|hfsts5BtgAcmDone {
327315
return &NoHardwareRootOfTrustError{errors.New("BootGuard ACM is not active")}
328316
}
329317

330-
// Check that the FPFs are locked.
331-
if regs.Hfsts6&hfsts6FPFSOCLock == 0 {
332-
return &NoHardwareRootOfTrustError{errors.New("BootGuard OTP fuses are not locked")}
333-
}
334-
335318
if vers.Major < 18 {
336-
return checkHostSecurityIntelBootGuardCSME11(toHfstsRegistersCsme11(regs))
319+
return checkHostSecurityIntelBootGuardCSME11(vers, toHfstsRegistersCsme11(regs))
337320
}
338321

339322
return checkHostSecurityIntelBootGuardCSME18(toHfstsRegistersCsme18(regs))

efi/preinstall/check_host_security_intel_csme11.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,23 +83,55 @@ func toHfstsRegistersCsme11(regs hfstsRegisters) hfstsRegistersCsme11 {
8383
}
8484

8585
const (
86+
// hfsts1Csme11MfgMode indicates that the system is in manufacturing mode. Note that
87+
// fwupd and coreboot refer to this bit as manufacturing mode whilst slimbootloader refers
88+
// to this as SPI protection mode. Based on this and the comments in coreboot, this bit
89+
// is set when the SPI flash descriptor is locked.
90+
hfsts1Csme11MfgMode hfsts1Csme11 = 1 << 4
91+
8692
hfsts6Csme11ForceBootPolicy hfsts6Csme11 = 1 << 0
8793
hfsts6Csme11CpuDebugDisable hfsts6Csme11 = 1 << 1
8894
hfsts6Csme11ProtectBIOSEnv hfsts6Csme11 = 1 << 3
8995
hfsts6Csme11ErrorEnforcementPolicy hfsts6Csme11 = 0xc0
9096
hfsts6Csme11MeasuredBoot hfsts6Csme11 = 1 << 8
9197
hfsts6Csme11VerifiedBoot hfsts6Csme11 = 1 << 9
98+
hfsts6Csme11MfgLock hfsts6Csme11 = 1 << 21
9299
hfsts6Csme11BootGuardDisable hfsts6Csme11 = 1 << 28
100+
hfsts6Csme11FPFSOCLock hfsts6Csme11 = 1 << 30
93101

94102
errorEnforcementPolicyCsme11Nothing errorEnforcementPolicyCsme11 = 0
95103
errorEnforcementPolicyCsme11Shutdown30Mins errorEnforcementPolicyCsme11 = 1 // fwupd defines this as 3, which I think is wrong.
96104
errorEnforcementPolicyCsme11ShutdownNow errorEnforcementPolicyCsme11 = 3 // fwupd defines this as 2, which I think is wrong.
97105
)
98106

99-
func checkHostSecurityIntelBootGuardCSME11(regs hfstsRegistersCsme11) error {
107+
func isInManufacturingModeCSME11(vers meVersion, regs hfstsRegistersCsme11) bool {
108+
// This is based on the checks from
109+
// https://github.com/coreboot/coreboot/blob/eb5bdf06b92534b6f66f612297a4ccb69008b4ac/src/soc/intel/common/block/cse/cse_spec.c#L15
110+
if regs.Hfsts1&hfsts1Csme11MfgMode > 0 {
111+
return true
112+
}
113+
if vers.Major > 13 {
114+
if regs.Hfsts6&hfsts6Csme11FPFSOCLock == 0 {
115+
return true
116+
}
117+
}
118+
if vers.Major > 15 {
119+
if regs.Hfsts6&hfsts6Csme11MfgLock == 0 {
120+
return true
121+
}
122+
}
123+
return false
124+
}
125+
126+
func checkHostSecurityIntelBootGuardCSME11(vers meVersion, regs hfstsRegistersCsme11) error {
100127
// These checks are based on the HSI checks performed in the pci-mei
101128
// plugin in fwupd.
102129

130+
// Make sure that the system is not in manufacturing mode.
131+
if isInManufacturingModeCSME11(vers, regs) {
132+
return &NoHardwareRootOfTrustError{errors.New("system is in manufacturing mode")}
133+
}
134+
103135
// Check that BootGuard is enabled.
104136
if regs.Hfsts6&hfsts6Csme11BootGuardDisable > 0 {
105137
return &NoHardwareRootOfTrustError{errors.New("BootGuard is disabled")}

efi/preinstall/check_host_security_intel_csme11_test.go

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,35 +32,96 @@ type hostSecurityIntelCsme11Suite struct{}
3232
var _ = Suite(&hostSecurityIntelCsme11Suite{})
3333

3434
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11GoodFVMEProfile(c *C) {
35-
err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E003CB})
35+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{
36+
Hfsts1: 0x94000245,
37+
Hfsts6: 0xC7E003CB,
38+
})
3639
c.Check(err, IsNil)
3740
}
3841

3942
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11GoodFVEProfile(c *C) {
40-
err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E002CB})
43+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{
44+
Hfsts1: 0x94000245,
45+
Hfsts6: 0xC7E002CB,
46+
})
4147
c.Check(err, IsNil)
4248
}
4349

50+
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11Good13(c *C) {
51+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 13}, HfstsRegistersCsme11{
52+
Hfsts1: 0x94000245,
53+
Hfsts6: 0x87C003CB,
54+
})
55+
c.Check(err, IsNil)
56+
}
57+
58+
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11Good15(c *C) {
59+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 15}, HfstsRegistersCsme11{
60+
Hfsts1: 0x94000245,
61+
Hfsts6: 0xC7C003CB,
62+
})
63+
c.Check(err, IsNil)
64+
}
65+
66+
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrMfgMode(c *C) {
67+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 13}, HfstsRegistersCsme11{
68+
Hfsts1: 0x94000255,
69+
Hfsts6: 0x87C003CB,
70+
})
71+
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`)
72+
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
73+
}
74+
75+
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrFPFsNotLocked(c *C) {
76+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 15}, HfstsRegistersCsme11{
77+
Hfsts1: 0x94000245,
78+
Hfsts6: 0x87C003CB,
79+
})
80+
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`)
81+
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
82+
}
83+
84+
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrNoManufLock(c *C) {
85+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{
86+
Hfsts1: 0x94000245,
87+
Hfsts6: 0x87C003CB,
88+
})
89+
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`)
90+
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
91+
}
92+
4493
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrBootGuardDisabled(c *C) {
45-
err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xD7E003CB})
94+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{
95+
Hfsts1: 0x94000245,
96+
Hfsts6: 0xD7E003CB,
97+
})
4698
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: BootGuard is disabled`)
4799
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
48100
}
49101

50102
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrInvalidProfile(c *C) {
51-
err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E0024A})
103+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{
104+
Hfsts1: 0x94000245,
105+
Hfsts6: 0xC7E0024A,
106+
})
52107
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: cannot determine BootGuard profile: invalid profile`)
53108
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
54109
}
55110

56111
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrUnsupportedNoFVMEProfile(c *C) {
57-
err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E00002})
112+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{
113+
Hfsts1: 0x94000245,
114+
Hfsts6: 0xC7E00002,
115+
})
58116
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`)
59117
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
60118
}
61119

62120
func (*hostSecurityIntelCsme11Suite) TestCheckHostSecurityIntelBootGuardCSME11ErrUnsupportedVMProfile(c *C) {
63-
err := CheckHostSecurityIntelBootGuardCSME11(HfstsRegistersCsme11{Hfsts6: 0xC7E0030A})
121+
err := CheckHostSecurityIntelBootGuardCSME11(MeVersion{Major: 16}, HfstsRegistersCsme11{
122+
Hfsts1: 0x94000245,
123+
Hfsts6: 0xC7E0030A,
124+
})
64125
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`)
65126
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
66127
}

efi/preinstall/check_host_security_intel_csme18.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,13 @@ func (reg hfsts5Csme18) btgProfile() btgProfile {
4646
}
4747

4848
const (
49+
hfsts1Csme18SPIProtectionMode hfsts1Csme18 = 1 << 4
50+
4951
hfsts5Csme18BtgProfileValid hfsts5Csme18 = 1 << 1
5052

53+
hfsts6Csme18MfgLock hfsts6Csme18 = 1 << 21
54+
hfsts6Csme18FPFSOCLock hfsts6Csme18 = 1 << 30
55+
5156
// hfsts5Csme18BtgProfile is the bitmask for the BootGuard profile.
5257
// fwupd defines this as 0xe0000, but I think this is off by one bit.
5358
// I see a profile value of 5 on my XPS16 (which is what I expect) if
@@ -68,10 +73,30 @@ func toHfstsRegistersCsme18(regs hfstsRegisters) hfstsRegistersCsme18 {
6873
}
6974
}
7075

76+
func isInManufacturingModeCSME18(regs hfstsRegistersCsme18) bool {
77+
// This is based on the checks from
78+
// https://github.com/coreboot/coreboot/blob/eb5bdf06b92534b6f66f612297a4ccb69008b4ac/src/soc/intel/common/block/cse/cse_spec.c#L15
79+
if regs.Hfsts1&hfsts1Csme18SPIProtectionMode > 0 {
80+
return true
81+
}
82+
if regs.Hfsts6&hfsts6Csme18MfgLock == 0 {
83+
return true
84+
}
85+
if regs.Hfsts6&hfsts6Csme18FPFSOCLock == 0 {
86+
return true
87+
}
88+
return false
89+
}
90+
7191
func checkHostSecurityIntelBootGuardCSME18(regs hfstsRegistersCsme18) error {
7292
// These checks are based on the HSI checks performed in the pci-mei
7393
// plugin in fwupd.
7494

95+
// Make sure that the system is not in manufacturing mode.
96+
if isInManufacturingModeCSME18(regs) {
97+
return &NoHardwareRootOfTrustError{errors.New("system is in manufacturing mode")}
98+
}
99+
75100
// Check that the BootGuard profile is valid. I think that's what this
76101
// is checking - fwupd's definition of this bit is just called "valid".
77102
// This bit does exist for CSME #11, but the definition in slimbootloader

efi/preinstall/check_host_security_intel_csme18_test.go

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,79 @@ type hostSecurityIntelCsme18Suite struct{}
3232
var _ = Suite(&hostSecurityIntelCsme18Suite{})
3333

3434
func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18GoodFVMEProfile(c *C) {
35-
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02F61F03})
35+
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{
36+
Hfsts1: 0x94000245,
37+
Hfsts5: 0x02F61F03,
38+
Hfsts6: 0x40200000,
39+
})
3640
c.Check(err, IsNil)
3741
}
3842

3943
func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18GoodFVEProfile(c *C) {
40-
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02F21F03})
44+
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{
45+
Hfsts1: 0x94000245,
46+
Hfsts5: 0x02F21F03,
47+
Hfsts6: 0x40200000,
48+
})
4149
c.Check(err, IsNil)
4250
}
4351

52+
func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrNoSPIProtection(c *C) {
53+
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{
54+
Hfsts1: 0x94000255,
55+
Hfsts5: 0x02F61F03,
56+
Hfsts6: 0x40200000,
57+
})
58+
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`)
59+
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
60+
}
61+
62+
func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrFPFsNotLocked(c *C) {
63+
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{
64+
Hfsts1: 0x94000245,
65+
Hfsts5: 0x02F61F03,
66+
Hfsts6: 0x00200000,
67+
})
68+
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`)
69+
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
70+
}
71+
72+
func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrNoManufLock(c *C) {
73+
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{
74+
Hfsts1: 0x94000245,
75+
Hfsts5: 0x02F61F03,
76+
Hfsts6: 0x40000000,
77+
})
78+
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: system is in manufacturing mode`)
79+
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
80+
}
81+
4482
func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrInvalidProfile(c *C) {
45-
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02F61F01})
83+
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{
84+
Hfsts1: 0x94000245,
85+
Hfsts5: 0x02F61F01,
86+
Hfsts6: 0x40200000,
87+
})
4688
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: invalid BootGuard profile`)
4789
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
4890
}
4991

5092
func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrUnsupportedNoFVMEProfile(c *C) {
51-
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02E21F03})
93+
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{
94+
Hfsts1: 0x94000245,
95+
Hfsts5: 0x02E21F03,
96+
Hfsts6: 0x40200000,
97+
})
5298
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`)
5399
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
54100
}
55101

56102
func (*hostSecurityIntelCsme18Suite) TestCheckHostSecurityIntelBootGuardCSME18ErrUnsupportedVMProfile(c *C) {
57-
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{Hfsts5: 0x02EE1F03})
103+
err := CheckHostSecurityIntelBootGuardCSME18(HfstsRegistersCsme18{
104+
Hfsts1: 0x94000245,
105+
Hfsts5: 0x02EE1F03,
106+
Hfsts6: 0x40200000,
107+
})
58108
c.Check(err, ErrorMatches, `no hardware root-of-trust properly configured: unsupported BootGuard profile`)
59109
c.Check(err, FitsTypeOf, &NoHardwareRootOfTrustError{})
60110
}

0 commit comments

Comments
 (0)