Skip to content

Commit

Permalink
many: update secboot and use new key format
Browse files Browse the repository at this point in the history
  • Loading branch information
valentindavid committed Sep 19, 2024
1 parent fbf2da4 commit 6380e6e
Show file tree
Hide file tree
Showing 44 changed files with 2,148 additions and 787 deletions.
8 changes: 5 additions & 3 deletions boot/export_sb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
package boot

import (
"context"

"github.com/canonical/go-efilib"
"github.com/canonical/go-efilib/linux"

Expand All @@ -33,19 +35,19 @@ var (
SetEfiBootOrderVariable = setEfiBootOrderVariable
)

func MockEfiListVariables(f func() ([]efi.VariableDescriptor, error)) (restore func()) {
func MockEfiListVariables(f func(ctx context.Context) ([]efi.VariableDescriptor, error)) (restore func()) {
restore = testutil.Backup(&efiListVariables)
efiListVariables = f
return restore
}

func MockEfiReadVariable(f func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error)) (restore func()) {
func MockEfiReadVariable(f func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error)) (restore func()) {
restore = testutil.Backup(&efiReadVariable)
efiReadVariable = f
return restore
}

func MockEfiWriteVariable(f func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error) (restore func()) {
func MockEfiWriteVariable(f func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error) (restore func()) {
restore = testutil.Backup(&efiWriteVariable)
efiWriteVariable = f
return restore
Expand Down
10 changes: 5 additions & 5 deletions boot/setefibootvars_sb.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func constructLoadOption(description string, assetPath string, optionalData []by
// number should be written. If a different error occurs, returns that error,
// and the returned boot number should be ignored.
func findMatchingBootOption(optionData []byte) (uint16, error) {
variables, err := efiListVariables()
variables, err := efiListVariables(efi.DefaultVarContext)
if err != nil {
return 0, err
}
Expand All @@ -101,7 +101,7 @@ func findMatchingBootOption(optionData []byte) (uint16, error) {
}
// Since we never overwrite an existing variable, we can ignore
// variable attributes when reading the variable
varData, _, err := efiReadVariable(varName, varGUID)
varData, _, err := efiReadVariable(efi.DefaultVarContext, varName, varGUID)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -135,7 +135,7 @@ func setEfiBootOptionVariable(loadOptionData []byte) (uint16, error) {
return 0, err
}
varName := fmt.Sprintf("Boot%04X", bootNum)
err = efiWriteVariable(varName, efi.GlobalVariable, defaultVarAttrs, loadOptionData)
err = efiWriteVariable(efi.DefaultVarContext, varName, efi.GlobalVariable, defaultVarAttrs, loadOptionData)
return bootNum, err
}

Expand All @@ -144,7 +144,7 @@ func setEfiBootOptionVariable(loadOptionData []byte) (uint16, error) {
// (and removes it from later in the list if it occurs) and writes the
// list as the new BootOrder variable.
func setEfiBootOrderVariable(newBootNum uint16) error {
origData, attrs, err := efiReadVariable("BootOrder", efi.GlobalVariable)
origData, attrs, err := efiReadVariable(efi.DefaultVarContext, "BootOrder", efi.GlobalVariable)
if err == efi.ErrVarNotExist {
attrs = defaultVarAttrs
origData = make([]byte, 0)
Expand Down Expand Up @@ -177,7 +177,7 @@ func setEfiBootOrderVariable(newBootNum uint16) error {
copy(newData[2:], origData[:optionOffset])
copy(newData[optionOffset+2:], origData[optionOffset+2:])
}
return efiWriteVariable("BootOrder", efi.GlobalVariable, attrs, newData)
return efiWriteVariable(efi.DefaultVarContext, "BootOrder", efi.GlobalVariable, attrs, newData)
}

// SetEfiBootVariables sets the Boot#### and BootOrder variables for the given
Expand Down
51 changes: 26 additions & 25 deletions boot/setefibootvars_sb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package boot_test

import (
"bytes"
"context"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -230,15 +231,15 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootOptionVariable(c *C) {
defaultVarAttrs,
},
}
restore := boot.MockEfiListVariables(func() ([]efi.VariableDescriptor, error) {
restore := boot.MockEfiListVariables(func(ctx context.Context) ([]efi.VariableDescriptor, error) {
varDescriptorList := make([]efi.VariableDescriptor, 0, len(fakeVariableData))
for key := range fakeVariableData {
varDescriptorList = append(varDescriptorList, key)
}
return varDescriptorList, nil
})
defer restore()
restore = boot.MockEfiReadVariable(func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
restore = boot.MockEfiReadVariable(func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
descriptor := efi.VariableDescriptor{
Name: name,
GUID: guid,
Expand All @@ -250,7 +251,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootOptionVariable(c *C) {
})
defer restore()
writeChan := make(chan []byte, 1)
restore = boot.MockEfiWriteVariable(func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
restore = boot.MockEfiWriteVariable(func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
for varDesc := range fakeVariableData {
if varDesc.Name == name && varDesc.GUID == guid {
return errShouldNotOverwrite
Expand Down Expand Up @@ -359,15 +360,15 @@ func (s *setEfiBootVarsSuite) TestMismatchedGuid(c *C) {
defaultVarAttrs,
},
}
restore := boot.MockEfiListVariables(func() ([]efi.VariableDescriptor, error) {
restore := boot.MockEfiListVariables(func(ctx context.Context) ([]efi.VariableDescriptor, error) {
varDescriptorList := make([]efi.VariableDescriptor, 0, len(fakeVariableData))
for key := range fakeVariableData {
varDescriptorList = append(varDescriptorList, key)
}
return varDescriptorList, nil
})
defer restore()
restore = boot.MockEfiReadVariable(func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
restore = boot.MockEfiReadVariable(func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
descriptor := efi.VariableDescriptor{
Name: name,
GUID: guid,
Expand All @@ -379,7 +380,7 @@ func (s *setEfiBootVarsSuite) TestMismatchedGuid(c *C) {
})
defer restore()
writeChan := make(chan []byte, 1)
restore = boot.MockEfiWriteVariable(func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
restore = boot.MockEfiWriteVariable(func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
for varDesc := range fakeVariableData {
if varDesc.Name == name && varDesc.GUID == guid {
return errShouldNotOverwrite
Expand Down Expand Up @@ -455,15 +456,15 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootOptionVarAttrs(c *C) {
grubAttrs,
},
}
restore := boot.MockEfiListVariables(func() ([]efi.VariableDescriptor, error) {
restore := boot.MockEfiListVariables(func(ctx context.Context) ([]efi.VariableDescriptor, error) {
varDescriptorList := make([]efi.VariableDescriptor, 0, len(fakeVariableData))
for key := range fakeVariableData {
varDescriptorList = append(varDescriptorList, key)
}
return varDescriptorList, nil
})
defer restore()
restore = boot.MockEfiReadVariable(func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
restore = boot.MockEfiReadVariable(func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
descriptor := efi.VariableDescriptor{
Name: name,
GUID: guid,
Expand All @@ -474,7 +475,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootOptionVarAttrs(c *C) {
return nil, 0, efi.ErrVarNotExist
})
defer restore()
restore = boot.MockEfiWriteVariable(func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
restore = boot.MockEfiWriteVariable(func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
for varDesc := range fakeVariableData {
if varDesc.Name == name && varDesc.GUID == guid {
return errShouldNotOverwrite
Expand Down Expand Up @@ -528,15 +529,15 @@ func (s *setEfiBootVarsSuite) TestOutOfBootNumbers(c *C) {

fakeVariableData := make(map[efi.VariableDescriptor]*varDataAttrs)

restore := boot.MockEfiListVariables(func() ([]efi.VariableDescriptor, error) {
restore := boot.MockEfiListVariables(func(ctx context.Context) ([]efi.VariableDescriptor, error) {
varDescriptorList := make([]efi.VariableDescriptor, 0, len(fakeVariableData))
for key := range fakeVariableData {
varDescriptorList = append(varDescriptorList, key)
}
return varDescriptorList, nil
})
defer restore()
restore = boot.MockEfiReadVariable(func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
restore = boot.MockEfiReadVariable(func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
descriptor := efi.VariableDescriptor{
Name: name,
GUID: guid,
Expand All @@ -548,7 +549,7 @@ func (s *setEfiBootVarsSuite) TestOutOfBootNumbers(c *C) {
})
defer restore()
writeChan := make(chan []byte, 1)
restore = boot.MockEfiWriteVariable(func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
restore = boot.MockEfiWriteVariable(func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
for varDesc := range fakeVariableData {
if varDesc.Name == name && varDesc.GUID == guid {
return errShouldNotOverwrite
Expand Down Expand Up @@ -682,7 +683,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootOrderVariable(c *C) {
},
}
readChan := make(chan []byte, 1)
restore := boot.MockEfiReadVariable(func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
restore := boot.MockEfiReadVariable(func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
value := <-readChan
if value == nil {
return nil, 0, efi.ErrVarNotExist
Expand All @@ -691,7 +692,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootOrderVariable(c *C) {
})
defer restore()
writeChan := make(chan []byte, 1)
restore = boot.MockEfiWriteVariable(func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
restore = boot.MockEfiWriteVariable(func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
c.Assert(name, Equals, "BootOrder")
c.Assert(guid, Equals, efi.GlobalVariable)
c.Assert(attrs, Equals, defaultVarAttrs)
Expand Down Expand Up @@ -728,12 +729,12 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootOrderVarAttrs(c *C) {
defaultVarAttrs | efi.AttributeAuthenticatedWriteAccess,
}
attrReadChan := make(chan efi.VariableAttributes, 1)
restore := boot.MockEfiReadVariable(func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
restore := boot.MockEfiReadVariable(func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
return initialBootOrder, <-attrReadChan, nil
})
defer restore()
attrWriteChan := make(chan efi.VariableAttributes, 1)
restore = boot.MockEfiWriteVariable(func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
restore = boot.MockEfiWriteVariable(func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
c.Assert(name, Equals, "BootOrder")
c.Assert(guid, Equals, efi.GlobalVariable)
c.Assert(data, DeepEquals, finalBootOrder)
Expand Down Expand Up @@ -780,7 +781,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootVariables(c *C) {
},
}

defer boot.MockEfiReadVariable(func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
defer boot.MockEfiReadVariable(func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
descriptor := efi.VariableDescriptor{
Name: name,
GUID: guid,
Expand All @@ -791,7 +792,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootVariables(c *C) {
return nil, 0, efi.ErrVarNotExist
})()

defer boot.MockEfiListVariables(func() ([]efi.VariableDescriptor, error) {
defer boot.MockEfiListVariables(func(ctx context.Context) ([]efi.VariableDescriptor, error) {
varDescriptorList := make([]efi.VariableDescriptor, 0, len(fakeVariableData))
for key := range fakeVariableData {
varDescriptorList = append(varDescriptorList, key)
Expand All @@ -800,7 +801,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootVariables(c *C) {
})()

written := 0
defer boot.MockEfiWriteVariable(func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
defer boot.MockEfiWriteVariable(func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
written += 1
if name == "BootOrder" && guid == efi.GlobalVariable {
return nil
Expand Down Expand Up @@ -850,7 +851,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootVariablesConstructError(c *C) {
},
}

defer boot.MockEfiReadVariable(func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
defer boot.MockEfiReadVariable(func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
descriptor := efi.VariableDescriptor{
Name: name,
GUID: guid,
Expand All @@ -861,15 +862,15 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootVariablesConstructError(c *C) {
return nil, 0, efi.ErrVarNotExist
})()

defer boot.MockEfiListVariables(func() ([]efi.VariableDescriptor, error) {
defer boot.MockEfiListVariables(func(ctx context.Context) ([]efi.VariableDescriptor, error) {
varDescriptorList := make([]efi.VariableDescriptor, 0, len(fakeVariableData))
for key := range fakeVariableData {
varDescriptorList = append(varDescriptorList, key)
}
return varDescriptorList, nil
})()

defer boot.MockEfiWriteVariable(func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
defer boot.MockEfiWriteVariable(func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
c.Fatalf("Not execpted to write variables")
return nil
})()
Expand Down Expand Up @@ -911,7 +912,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootVariablesErrorSetVariable(c *C) {
},
}

defer boot.MockEfiReadVariable(func(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
defer boot.MockEfiReadVariable(func(ctx context.Context, name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
descriptor := efi.VariableDescriptor{
Name: name,
GUID: guid,
Expand All @@ -922,7 +923,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootVariablesErrorSetVariable(c *C) {
return nil, 0, efi.ErrVarNotExist
})()

defer boot.MockEfiListVariables(func() ([]efi.VariableDescriptor, error) {
defer boot.MockEfiListVariables(func(ctx context.Context) ([]efi.VariableDescriptor, error) {
varDescriptorList := make([]efi.VariableDescriptor, 0, len(fakeVariableData))
for key := range fakeVariableData {
varDescriptorList = append(varDescriptorList, key)
Expand All @@ -931,7 +932,7 @@ func (s *setEfiBootVarsSuite) TestSetEfiBootVariablesErrorSetVariable(c *C) {
})()

written := 0
defer boot.MockEfiWriteVariable(func(name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
defer boot.MockEfiWriteVariable(func(ctx context.Context, name string, guid efi.GUID, attrs efi.VariableAttributes, data []byte) error {
written += 1
return fmt.Errorf(`INJECT ERROR`)
})()
Expand Down
8 changes: 2 additions & 6 deletions cmd/snap-bootstrap/cmd_initramfs_mounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import (
"github.com/snapcore/snapd/osutil/disks"
"github.com/snapcore/snapd/osutil/kcmdline"
"github.com/snapcore/snapd/secboot"
"github.com/snapcore/snapd/secboot/keys"
"github.com/snapcore/snapd/seed"
"github.com/snapcore/snapd/seed/seedtest"
"github.com/snapcore/snapd/snap"
Expand Down Expand Up @@ -8174,9 +8173,6 @@ echo '{"features":[]}'

writeGadget(c, "ubuntu-seed", "system-seed", "")

dataKey := keys.EncryptionKey{'d', 'a', 't', 'a', 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
saveKey := keys.EncryptionKey{'s', 'a', 'v', 'e', 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}

gadgetInstallCalled := false
restoreGadgetInstall := main.MockGadgetInstallRun(func(model gadget.Model, gadgetRoot string, kernelSnapInfo *gadgetInstall.KernelSnapInfo, bootDevice string, options gadgetInstall.Options, observer gadget.ContentObserver, perfTimings timings.Measurer) (*gadgetInstall.InstalledSystemSideData, error) {
gadgetInstallCalled = true
Expand All @@ -8189,8 +8185,8 @@ echo '{"features":[]}'
c.Assert(kernelSnapInfo.MountPoint, Equals, filepath.Join(boot.InitramfsRunMntDir, "kernel"))

installKeyForRole := map[string]secboot.BootstrappedContainer{
gadget.SystemData: secboot.CreateBootstrappedContainer(dataKey, ""),
gadget.SystemSave: secboot.CreateBootstrappedContainer(saveKey, ""),
gadget.SystemData: secboot.CreateMockBootstrappedContainer(),
gadget.SystemSave: secboot.CreateMockBootstrappedContainer(),
}
return &gadgetInstall.InstalledSystemSideData{BootstrappedContainerForRole: installKeyForRole}, nil
})
Expand Down
1 change: 1 addition & 0 deletions data/systemd/snapd.service.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ NotifyAccess=all
SuccessExitStatus=42
RestartPreventExitStatus=42
KillMode=process
KeyringMode=shared

[Install]
WantedBy=multi-user.target
26 changes: 9 additions & 17 deletions gadget/install/encrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,9 @@
package install

import (
"bytes"
"fmt"
"os/exec"

"github.com/snapcore/snapd/osutil"
"github.com/snapcore/snapd/secboot"
"github.com/snapcore/snapd/secboot/keys"
)

var (
Expand All @@ -52,7 +48,7 @@ var _ = encryptedDevice(&encryptedDeviceLUKS{})

// newEncryptedDeviceLUKS creates an encrypted device in the existing
// partition using the specified key with the LUKS backend.
func newEncryptedDeviceLUKS(devNode string, encType secboot.EncryptionType, key keys.EncryptionKey, label, name string) (encryptedDevice, error) {
func newEncryptedDeviceLUKS(devNode string, encType secboot.EncryptionType, key secboot.DiskUnlockKey, label, name string) (encryptedDevice, error) {
encLabel := label + "-enc"
if err := secbootFormatEncryptedDevice(key, encType, encLabel, devNode); err != nil {
return nil, fmt.Errorf("cannot format encrypted device: %v", err)
Expand Down Expand Up @@ -81,18 +77,14 @@ func (dev *encryptedDeviceLUKS) Close() error {
return cryptsetupClose(dev.name)
}

func cryptsetupOpen(key keys.EncryptionKey, node, name string) error {
cmd := exec.Command("cryptsetup", "open", "--key-file", "-", node, name)
cmd.Stdin = bytes.NewReader(key[:])
if output, err := cmd.CombinedOutput(); err != nil {
return osutil.OutputErr(output, err)
}
return nil
func cryptsetupOpenImpl(key secboot.DiskUnlockKey, node, name string) error {
return secboot.ActivateVolumeWithKey(name, node, key, nil)
}

func cryptsetupClose(name string) error {
if output, err := exec.Command("cryptsetup", "close", name).CombinedOutput(); err != nil {
return osutil.OutputErr(output, err)
}
return nil
var cryptsetupOpen = cryptsetupOpenImpl

func cryptsetupCloseImpl(name string) error {
return secboot.DeactivateVolume(name)
}

var cryptsetupClose = cryptsetupCloseImpl
Loading

0 comments on commit 6380e6e

Please sign in to comment.