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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions efi/fw_load_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,19 @@ func (h *fwLoadHandler) measureSecureBootPolicyPreOS(ctx pcrBranchContext) error
// permitted with the WithSecureBootUserMode option and they are being included in this
// branch.
includeUserMode := boolParamOrFalse(ctx.Params(), includeSecureBootUserModeParamKey)
autoIncludeUserMode := boolParamOrFalse(ctx.Params(), autoIncludeSecureBootUserModeParamKey)
if autoIncludeUserMode {
for _, e := range h.log.Events {
switch {
case e.PCRIndex == internal_efi.SecureBootPolicyPCR && e.EventType == tcglog.EventTypeEFIVariableDriverConfig:
if data, ok := e.Data.(*tcglog.EFIVariableData); ok {
if data.VariableName == efi.GlobalVariable && data.UnicodeName == "AuditMode" {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's enough to check one of the two vars?

includeUserMode = true
}
}
}
}
}
switch deployedMode, _, err := ctx.Vars().ReadVar("DeployedMode", efi.GlobalVariable); {
case errors.Is(err, efi.ErrVarNotExist):
// pre-2.5 UEFI system
Expand Down
119 changes: 118 additions & 1 deletion efi/pcr_profile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,7 @@ func (s *pcrProfileSuite) TestAddPCRProfileLoadFailsFromLeafImage(c *C) {
),
),
}, WithSecureBootPolicyProfile(), WithBootManagerCodeProfile(), WithKernelConfigProfile())
c.Check(err, ErrorMatches, `cannot measure image 0x[[:xdigit:]]{10}: cannot measure image load: kernel is a leaf image`)
c.Check(err, ErrorMatches, `cannot measure image 0x[[:xdigit:]]*: cannot measure image load: kernel is a leaf image`)
}

func (s *pcrProfileSuite) TestAddPCRProfileUC20WithDbxUpdateWithAllowInsufficientDMAProtection(c *C) {
Expand Down Expand Up @@ -1441,3 +1441,120 @@ func (s *pcrProfileSuite) TestAddPCRProfileUC20WithAllowSecureBootUserMode(c *C)
}, WithSecureBootPolicyProfile(), WithBootManagerCodeProfile(), WithKernelConfigProfile(), WithAllowSecureBootUserMode())
c.Check(err, IsNil)
}

func (s *pcrProfileSuite) TestAddPCRProfileUC20WithAutoAllowSecureBootUserModeWithMeasurements(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},
DisableDeployedMode: true,
}),
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(), WithAutoAllowSecureBootUserMode())
c.Check(err, IsNil)
}

func (s *pcrProfileSuite) TestAddPCRProfileUC20WithAutoAllowSecureBootUserModeNoMeasurements(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},
// This is the weird case some user have AuditMode/DeployedMode variables are defined, but not measured
DisableDeployedMode: false,
}),
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"),
},
},
},
}, WithSecureBootPolicyProfile(), WithBootManagerCodeProfile(), WithKernelConfigProfile(), WithAutoAllowSecureBootUserMode())
c.Check(err, IsNil)
}
35 changes: 34 additions & 1 deletion efi/secureboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,8 @@ 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"
includeSecureBootUserModeParamKey = "include_secure_boot_user_mode"
autoIncludeSecureBootUserModeParamKey = "auto_include_secure_boot_user_mode"
)

type allowSecureBootUserModeOption struct{}
Expand All @@ -343,6 +344,26 @@ func (o allowSecureBootUserModeOption) ApplyOptionTo(visitor internal_efi.PCRPro
return nil
}

type autoAllowSecureBootUserModeOption struct{}

func (o autoAllowSecureBootUserModeOption) ApplyOptionTo(visitor internal_efi.PCRProfileOptionVisitor) error {
visitor.AddImageLoadParams(func(params ...loadParams) []loadParams {
var out []loadParams
for _, v := range []bool{false, true} {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to set both to true and false, in case the firmware behavior changes?

var newParams []loadParams
for _, p := range params {
newParams = append(newParams, p.Clone())
}
for _, p := range newParams {
p[autoIncludeSecureBootUserModeParamKey] = 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
Expand All @@ -355,3 +376,15 @@ func (o allowSecureBootUserModeOption) ApplyOptionTo(visitor internal_efi.PCRPro
func WithAllowSecureBootUserMode() PCRProfileOption {
return allowSecureBootUserModeOption{}
}

// WithAutoAllowSecureBootUserMode is like WithAllowSecureBootUserMode but will
// only expect measurements if the event log contains them.
// The variables still need to also be defined.
// For Ubuntu Core users there are hardware that define AuditMode/DeployedMode variables
// and still fail to measure that in PCR7. So we need to detect that hardware from the event
// log.
//
// This option should only be used by Ubuntu Core.
func WithAutoAllowSecureBootUserMode() PCRProfileOption {
return autoAllowSecureBootUserModeOption{}
}
Loading