From ec484217a2412d2f9b9aca92717154ee0ae51e58 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 5 Apr 2023 18:03:03 +0200 Subject: [PATCH] many: remove all `device-setup` fde-setup code (#12618) * many: remove all `device-setup` fde-setup code When we initially worked on the inline-cryto-engine (ICE) code we had a design based on the fde-setup hook that would return a `device-setup` feature as a hint that ICE should be used. It turned out this design was impractical and we moved to a much better approach that got merged in https://github.com/snapcore/snapd/pull/12589 and relies on support for ICE in the kernel and cryptsetup. With that new approach all the code that was supporting the `device-setup` approach can be removed now. * daemon: consider again the fde-setup hook case * client: consider the ICE encryption type * osu/disks,kernel: remove device-unlock support as well --------- Co-authored-by: Samuele Pedroni --- client/systems.go | 6 +- daemon/api_debug.go | 15 +- gadget/gadget_test.go | 9 - gadget/install/encrypt.go | 69 ------- gadget/install/encrypt_test.go | 105 ----------- gadget/install/export_secboot_test.go | 5 +- gadget/install/install.go | 18 +- gadget/update.go | 5 - kernel/fde/device_unlock.go | 96 ---------- kernel/fde/fde.go | 58 +----- kernel/fde/fde_test.go | 168 ------------------ kernel/fde/mapper.go | 52 ------ osutil/disks/disks.go | 1 + osutil/disks/disks_linux_test.go | 118 ------------ overlord/devicestate/devicemgr.go | 3 - .../devicestate_install_mode_test.go | 130 -------------- overlord/hookstate/ctlcmd/fde_setup.go | 4 +- overlord/hookstate/ctlcmd/fde_setup_test.go | 21 --- secboot/encrypt.go | 5 +- .../manual/uc20-fde-hooks-ice/task.yaml | 2 +- 20 files changed, 22 insertions(+), 868 deletions(-) delete mode 100644 kernel/fde/device_unlock.go delete mode 100644 kernel/fde/mapper.go diff --git a/client/systems.go b/client/systems.go index 4f3983058c3..44af0294780 100644 --- a/client/systems.go +++ b/client/systems.go @@ -1,7 +1,7 @@ // -*- Mode: Go; indent-tabs-mode: t -*- /* - * Copyright (C) 2020 Canonical Ltd + * Copyright (C) 2020-2023 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 @@ -160,8 +160,8 @@ type StorageEncryption struct { // StorageSafety can have values of asserts.StorageSafety StorageSafety string `json:"storage-safety,omitempty"` - // Type has values of secboot.Type: "", "cryptsetup", - // "device-setup-hook" + // Type has values of secboot.EncryptionType: "", "cryptsetup", + // "cryptsetup-with-inline-crypto-engine" Type string `json:"encryption-type,omitempty"` // UnavailableReason describes why the encryption is not diff --git a/daemon/api_debug.go b/daemon/api_debug.go index 5e6c93078a8..c15171746ce 100644 --- a/daemon/api_debug.go +++ b/daemon/api_debug.go @@ -1,7 +1,7 @@ // -*- Mode: Go; indent-tabs-mode: t -*- /* - * Copyright (C) 2015-2021 Canonical Ltd + * Copyright (C) 2015-2023 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 @@ -301,14 +301,15 @@ func getGadgetDiskMapping(st *state.State) Response { } // no sealed keys, so no encryption } else { + // TODO: is there a better way to find the encType + // than indirectly via the sealedKeyMethods? does not + // matter right now because there really is only one + // encryption type switch sealingMethod { - case device.SealingMethodLegacyTPM, device.SealingMethodTPM: + case device.SealingMethodLegacyTPM, device.SealingMethodTPM, device.SealingMethodFDESetupHook: + // LUKS and LUKS-with-ICE are the same for what is + // required here encType = secboot.EncryptionTypeLUKS - case device.SealingMethodFDESetupHook: - // TODO:ICE: device setup hook support goes away - // XXX: this also seems to be broken already, this sealing - // method should not imply ICE - encType = secboot.EncryptionTypeDeviceSetupHook default: return InternalError("unknown sealing method: %s", sealingMethod) } diff --git a/gadget/gadget_test.go b/gadget/gadget_test.go index bed3982cb4f..20519149d36 100644 --- a/gadget/gadget_test.go +++ b/gadget/gadget_test.go @@ -3217,15 +3217,6 @@ func (s *gadgetYamlTestSuite) TestLayoutCompatibilityWithLUKSEncryptedPartitions // unsupported encryption types invalidEncOptions := &gadget.VolumeCompatibilityOptions{ - AssumeCreatablePartitionsCreated: true, - ExpectedStructureEncryption: map[string]gadget.StructureEncryptionParameters{ - "Writable": {Method: gadget.EncryptionICE}, - }, - } - err = gadget.EnsureVolumeCompatibility(gadgetVolume, &deviceLayout, invalidEncOptions) - c.Assert(err, ErrorMatches, `cannot find disk partition /dev/node2 \(starting at 2097152\) in gadget: Inline Crypto Engine encrypted partitions currently unsupported`) - - invalidEncOptions = &gadget.VolumeCompatibilityOptions{ AssumeCreatablePartitionsCreated: true, ExpectedStructureEncryption: map[string]gadget.StructureEncryptionParameters{ "Writable": {Method: "other"}, diff --git a/gadget/install/encrypt.go b/gadget/install/encrypt.go index 92407291d7b..a37064fbb7d 100644 --- a/gadget/install/encrypt.go +++ b/gadget/install/encrypt.go @@ -26,11 +26,8 @@ import ( "fmt" "os/exec" - "github.com/snapcore/snapd/boot" "github.com/snapcore/snapd/gadget" - "github.com/snapcore/snapd/kernel/fde" "github.com/snapcore/snapd/osutil" - "github.com/snapcore/snapd/osutil/disks" "github.com/snapcore/snapd/secboot" "github.com/snapcore/snapd/secboot/keys" ) @@ -101,69 +98,3 @@ func cryptsetupClose(name string) error { } return nil } - -// encryptedDeviceWithSetupHook represents a block device that is setup using -// the "device-setup" hook. -type encryptedDeviceWithSetupHook struct { - parent *gadget.OnDiskStructure - name string - node string -} - -// expected interface is implemented -var _ = encryptedDevice(&encryptedDeviceWithSetupHook{}) - -// createEncryptedDeviceWithSetupHook creates an encrypted device in the -// existing partition using the specified key using the fde-setup hook -func createEncryptedDeviceWithSetupHook(part *gadget.OnDiskStructure, key keys.EncryptionKey, name string) (encryptedDevice, error) { - // for roles requiring encryption, the filesystem label is always set to - // either the implicit value or a value that has been validated - if part.Name != name || part.PartitionFSLabel != name { - return nil, fmt.Errorf("cannot use partition name %q for an encrypted structure with partition label %q or filesystem label %q", - name, part.Name, part.PartitionFSLabel) - } - - // 1. create linear mapper device with 1Mb of reserved space - uuid := "" - offset := fde.DeviceSetupHookPartitionOffset - sizeMinusOffset := uint64(part.Size) - offset - mapperDevice, err := disks.CreateLinearMapperDevice(part.Node, name, uuid, offset, sizeMinusOffset) - if err != nil { - return nil, err - } - - // 2. run fde-setup "device-setup" on it - // TODO: We may need a different way to run the fde-setup hook - // here. The hook right now runs with a locked state. But - // when this runs the state will be unlocked but our hook - // mechanism needs a locked state. This means we either need - // something like "boot.RunFDE*Device*SetupHook" or we run - // the entire install with the state locked (which may not - // be as terrible as it sounds as this is a rare situation). - runHook := boot.RunFDESetupHook - params := &fde.DeviceSetupParams{ - Key: key, - Device: mapperDevice, - PartitionName: name, - } - if err := fde.DeviceSetup(runHook, params); err != nil { - return nil, err - } - - return &encryptedDeviceWithSetupHook{ - parent: part, - name: name, - node: mapperDevice, - }, nil -} - -func (dev *encryptedDeviceWithSetupHook) Close() error { - if output, err := exec.Command("dmsetup", "remove", dev.name).CombinedOutput(); err != nil { - return osutil.OutputErr(output, err) - } - return nil -} - -func (dev *encryptedDeviceWithSetupHook) Node() string { - return dev.node -} diff --git a/gadget/install/encrypt_test.go b/gadget/install/encrypt_test.go index 0a5ad4304fb..14b6179f61a 100644 --- a/gadget/install/encrypt_test.go +++ b/gadget/install/encrypt_test.go @@ -32,7 +32,6 @@ import ( "github.com/snapcore/snapd/gadget" "github.com/snapcore/snapd/gadget/install" "github.com/snapcore/snapd/gadget/quantity" - "github.com/snapcore/snapd/kernel/fde" "github.com/snapcore/snapd/secboot" "github.com/snapcore/snapd/secboot/keys" "github.com/snapcore/snapd/testutil" @@ -128,107 +127,3 @@ func (s *encryptSuite) TestNewEncryptedDeviceLUKS(c *C) { }) } } - -var mockDeviceStructureForDeviceSetupHook = gadget.OnDiskStructure{ - Name: "ubuntu-data", - PartitionFSLabel: "ubuntu-data", - StartOffset: 0, - Size: 3 * quantity.SizeMiB, - Node: "/dev/node1", -} - -func (s *encryptSuite) TestCreateEncryptedDeviceWithSetupHook(c *C) { - - for _, tc := range []struct { - mockedOpenErr string - mockedRunFDESetupHookErr error - expectedErr string - }{ - { - mockedOpenErr: "", - mockedRunFDESetupHookErr: nil, - expectedErr: "", - }, - { - mockedRunFDESetupHookErr: errors.New("fde-setup hook error"), - mockedOpenErr: "", - expectedErr: "device setup failed with: fde-setup hook error", - }, - - { - mockedOpenErr: "open error", - mockedRunFDESetupHookErr: nil, - expectedErr: `cannot create mapper "ubuntu-data" on /dev/node1: open error`, - }, - } { - script := "" - if tc.mockedOpenErr != "" { - script = fmt.Sprintf("echo '%s'>&2; exit 1", tc.mockedOpenErr) - - } - - restore := install.MockBootRunFDESetupHook(func(req *fde.SetupRequest) ([]byte, error) { - return nil, tc.mockedRunFDESetupHookErr - }) - defer restore() - - mockDmsetup := testutil.MockCommand(c, "dmsetup", script) - s.AddCleanup(mockDmsetup.Restore) - - dev, err := install.CreateEncryptedDeviceWithSetupHook(&mockDeviceStructureForDeviceSetupHook, - s.mockedEncryptionKey, "ubuntu-data") - if tc.expectedErr == "" { - c.Assert(err, IsNil) - } else { - c.Assert(err, ErrorMatches, tc.expectedErr) - continue - } - c.Check(dev.Node(), Equals, "/dev/mapper/ubuntu-data") - - err = dev.Close() - c.Assert(err, IsNil) - - c.Check(mockDmsetup.Calls(), DeepEquals, [][]string{ - // Caculation is in 512 byte blocks. The total - // size of the mock device is 3Mb: 2Mb - // (4096*512) length if left and the offset is - // 1Mb (2048*512) at the start - {"dmsetup", "create", "ubuntu-data", "--table", "0 4096 linear /dev/node1 2048"}, - {"dmsetup", "remove", "ubuntu-data"}, - }) - } -} - -func (s *encryptSuite) TestCreateEncryptedDeviceWithSetupHookPartitionNameCheck(c *C) { - mockDeviceStructureBadName := gadget.OnDiskStructure{ - Name: "ubuntu-data", - PartitionFSLabel: "ubuntu-data", - StartOffset: 0, - Size: 3 * quantity.SizeMiB, - Node: "/dev/node1", - } - restore := install.MockBootRunFDESetupHook(func(req *fde.SetupRequest) ([]byte, error) { - c.Error("unexpected call") - return nil, fmt.Errorf("unexpected call") - }) - defer restore() - - mockDmsetup := testutil.MockCommand(c, "dmsetup", `echo "unexpected call" >&2; exit 1`) - s.AddCleanup(mockDmsetup.Restore) - - // pass a name that does not match partition name - dev, err := install.CreateEncryptedDeviceWithSetupHook(&mockDeviceStructureBadName, - s.mockedEncryptionKey, "some-name") - c.Assert(err, ErrorMatches, `cannot use partition name "some-name" for an encrypted structure with partition label "ubuntu-data" or filesystem label "ubuntu-data"`) - c.Check(dev, IsNil) - c.Check(mockDmsetup.Calls(), HasLen, 0) - // make structure name different than the label, which is set to either - // the implicit value or has already been validated and matches what is - // expected for the particular role - mockDeviceStructureBadName.Name = "bad-name" - dev, err = install.CreateEncryptedDeviceWithSetupHook(&mockDeviceStructureBadName, - s.mockedEncryptionKey, "bad-name") - c.Assert(err, ErrorMatches, `cannot use partition name "bad-name" for an encrypted structure with partition label "bad-name" or filesystem label "ubuntu-data"`) - c.Check(dev, IsNil) - c.Check(mockDmsetup.Calls(), HasLen, 0) -} diff --git a/gadget/install/export_secboot_test.go b/gadget/install/export_secboot_test.go index c558c402639..cdfbbfeae5f 100644 --- a/gadget/install/export_secboot_test.go +++ b/gadget/install/export_secboot_test.go @@ -30,9 +30,8 @@ import ( ) var ( - DiskWithSystemSeed = diskWithSystemSeed - NewEncryptedDeviceLUKS = newEncryptedDeviceLUKS - CreateEncryptedDeviceWithSetupHook = createEncryptedDeviceWithSetupHook + DiskWithSystemSeed = diskWithSystemSeed + NewEncryptedDeviceLUKS = newEncryptedDeviceLUKS ) func MockSecbootFormatEncryptedDevice(f func(key keys.EncryptionKey, encType secboot.EncryptionType, label, node string) error) (restore func()) { diff --git a/gadget/install/install.go b/gadget/install/install.go index df146f83acd..4960cc4c084 100644 --- a/gadget/install/install.go +++ b/gadget/install/install.go @@ -136,17 +136,8 @@ func maybeEncryptPartition(laidOut *gadget.LaidOutStructure, encryptionType secb if err != nil { return nil, nil, err } - - //TODO:ICE: device-setup hook support goes away - case secboot.EncryptionTypeDeviceSetupHook: - timings.Run(perfTimings, fmt.Sprintf("new-encrypted-device-setup-hook[%s]", laidOut.Role()), - fmt.Sprintf("Create encryption device for %s using device-setup-hook", laidOut.Role()), - func(timings.Measurer) { - dataPart, err = createEncryptedDeviceWithSetupHook(&laidOut.OnDiskStructure, encryptionKey, laidOut.Name()) - }) - if err != nil { - return nil, nil, err - } + default: + return nil, nil, fmt.Errorf("internal error: unknown encryption type: %v", encryptionType) } // update the encrypted device node, such that subsequent steps @@ -292,12 +283,9 @@ func createEncryptionParams(encTyp secboot.EncryptionType) gadget.StructureEncry switch encTyp { case secboot.EncryptionTypeLUKS, secboot.EncryptionTypeLUKSWithICE: return gadget.StructureEncryptionParameters{ + // TODO:ICE: remove "Method" entirely, there is only LUKS Method: gadget.EncryptionLUKS, } - case secboot.EncryptionTypeDeviceSetupHook: - return gadget.StructureEncryptionParameters{ - Method: gadget.EncryptionICE, - } } logger.Noticef("internal error: unknown encryption parameter %q", encTyp) return gadget.StructureEncryptionParameters{} diff --git a/gadget/update.go b/gadget/update.go index df9d3475f94..b79b84dfa16 100644 --- a/gadget/update.go +++ b/gadget/update.go @@ -374,8 +374,6 @@ func EnsureVolumeCompatibility(gadgetVolume *Volume, diskVolume *OnDiskVolume, o } switch encTypeParams.Method { - case EncryptionICE: - return false, "Inline Crypto Engine encrypted partitions currently unsupported" case EncryptionLUKS: // then this partition is expected to have been encrypted, the // filesystem label on disk will need "-enc" appended @@ -587,9 +585,6 @@ const ( // standard LUKS as it is used for automatic FDE using SecureBoot and TPM // 2.0 in UC20+ EncryptionLUKS DiskEncryptionMethod = "LUKS" - - // TODO:ICE: remove this - EncryptionICE DiskEncryptionMethod = "ICE" ) // DiskVolumeValidationOptions is a set of options on how to validate a disk to diff --git a/kernel/fde/device_unlock.go b/kernel/fde/device_unlock.go deleted file mode 100644 index 791b9105536..00000000000 --- a/kernel/fde/device_unlock.go +++ /dev/null @@ -1,96 +0,0 @@ -// -*- Mode: Go; indent-tabs-mode: t -*- - -/* - * Copyright (C) 2021 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 fde - -import ( - "encoding/json" - "fmt" - - "github.com/snapcore/snapd/logger" - "github.com/snapcore/snapd/osutil" -) - -// DeviceUnlockRequest carries the operation and parameters for the -// fde-device-unlock hook that receives them serialized over stdin. -type DeviceUnlockRequest struct { - Op string `json:"op"` - - Key []byte `json:"key,omitempty"` - - // Device is the device to unlock in /dev/ somewhere such as - // /dev/disk/by-partuuid/foo. - Device string `json:"device,omitempty"` - - PartitionName string `json:"partition-name,omitempty"` -} - -// runFDEDeviceUnlockCommand returns the output of -// fde-device-unlock run with systemd. -// -// Note that systemd-run in the initrd can only talk to the private -// systemd bus so this cannot use "--pipe" or "--wait", see -// https://github.com/snapcore/core-initrd/issues/13 -func runFDEDeviceUnlockCommand(req *DeviceUnlockRequest) (output []byte, err error) { - stdin, err := json.Marshal(req) - if err != nil { - return nil, fmt.Errorf(`cannot build request %q for fde-device-unlock: %v`, req, err) - } - - return runFDEinitramfsHelper("fde-device-unlock", stdin) -} - -var runFDEDeviceUnlock = runFDEDeviceUnlockCommand - -func MockRunFDEDeviceUnlock(mock func(*DeviceUnlockRequest) ([]byte, error)) (restore func()) { - osutil.MustBeTestBinary("fde-device-unlock can only be mocked in tests") - oldRunFDEDeviceUnlock := runFDEDeviceUnlock - runFDEDeviceUnlock = mock - return func() { - runFDEDeviceUnlock = oldRunFDEDeviceUnlock - } -} - -// DeviceUnlockParams contains the parameters for fde-device-unlock -// "device-unlock" operation. -type DeviceUnlockParams struct { - Key []byte - Device string - // Name of the partition - PartitionName string -} - -// DeviceUnlock invokes the "fde-device-unlock" helper with the -// "device-unlock" operation. -func DeviceUnlock(params *DeviceUnlockParams) (err error) { - req := &DeviceUnlockRequest{ - Op: "device-unlock", - Key: params.Key, - Device: params.Device, - PartitionName: params.PartitionName, - } - - logger.Debugf("running fde-device-unlock on %q with name %q", req.Device, req.PartitionName) - - output, err := runFDEDeviceUnlock(req) - if err != nil { - return fmt.Errorf(`cannot run fde-device-unlock "device-unlock": %v`, osutil.OutputErr(output, err)) - } - return nil -} diff --git a/kernel/fde/fde.go b/kernel/fde/fde.go index 7599d1c9b92..6c6899e5079 100644 --- a/kernel/fde/fde.go +++ b/kernel/fde/fde.go @@ -1,7 +1,7 @@ // -*- Mode: Go; indent-tabs-mode: t -*- /* - * Copyright (C) 2021 Canonical Ltd + * Copyright (C) 2021-2023 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 @@ -29,16 +29,8 @@ import ( "encoding/json" "fmt" "os/exec" - - "github.com/snapcore/snapd/logger" - "github.com/snapcore/snapd/osutil" ) -// DeviceSetupHookPartitionOffset defines the free space that is reserved -// at the start of a device-setup based partition for future use (like -// to simulate LUKS keyslot like setup). -const DeviceSetupHookPartitionOffset = uint64(1 * 1024 * 1024) - // HasRevealKey return true if the current system has a "fde-reveal-key" // binary (usually used in the initrd). // @@ -51,16 +43,6 @@ func HasRevealKey() bool { return err == nil } -// HasDeviceUnlock returns true if the current system has a -// "fde-device-unlock" binary (usually used in the initrd). -// -// This will be used by the initrd to determine if cryptsetup is -// skipped and a hook needs to be used to unlock individual device. -func HasDeviceUnlock() bool { - _, err := exec.LookPath("fde-device-unlock") - return err == nil -} - func isV1Hook(hookOutput []byte) bool { // This is the prefix of a tpm secboot v1 key as used in the // "denver" project. So if we see this prefix we know it's @@ -105,10 +87,6 @@ type SetupRequest struct { // Only used when called with "initial-setup" KeyName string `json:"key-name,omitempty"` - // The part of the device kernel path for a "setup-device" call. - // Only used when called with "device-setup" - Device string `json:"device,omitempty"` - // Name of the partition PartitionName string `json:"partition-name,omitempty"` } @@ -172,37 +150,3 @@ func CheckFeatures(runSetupHook RunSetupHookFunc) ([]string, error) { } return res.Features, nil } - -// DeviceSetupParams contains the inputs for the fde-setup hook. -// The encryption key and the device (partition) are passed in. -type DeviceSetupParams struct { - Key []byte - Device string - PartitionName string -} - -// DeviceSetup invokes the "device-setup" op running the fde-setup -// hook via runSetupHook. This can be used to e.g. initialize -// inline crypto hardware. -func DeviceSetup(runSetupHook RunSetupHookFunc, params *DeviceSetupParams) error { - req := &SetupRequest{ - Op: "device-setup", - Key: params.Key, - Device: params.Device, - PartitionName: params.PartitionName, - } - logger.Debugf("running device-setup hook on %q with name %q", req.Device, req.PartitionName) - - hookOutput, err := runSetupHook(req) - if err != nil { - return fmt.Errorf("device setup failed with: %v", osutil.OutputErr(hookOutput, err)) - } - - return nil -} - -// EncryptedDeviceMapperName returns the name to use in device mapper for a -// device that is encrypted using FDE hooks -func EncryptedDeviceMapperName(name string) string { - return name + "-device-locked" -} diff --git a/kernel/fde/fde_test.go b/kernel/fde/fde_test.go index af9fbc25df1..83f0eaf7840 100644 --- a/kernel/fde/fde_test.go +++ b/kernel/fde/fde_test.go @@ -528,171 +528,3 @@ func (s *fdeSuite) TestRevealErr(c *C) { // ensure no tmp files are left behind c.Check(osutil.FileExists(filepath.Join(dirs.GlobalRootDir, "/run/fde-reveal-key")), Equals, false) } - -func (s *fdeSuite) TestDeviceSetupHappy(c *C) { - mockKey := []byte{1, 2, 3, 4} - mockDevice := "/dev/sda2" - - runSetupHook := func(req *fde.SetupRequest) ([]byte, error) { - c.Check(req, DeepEquals, &fde.SetupRequest{ - Op: "device-setup", - Key: mockKey, - Device: mockDevice, - }) - // empty reply: no error - mockJSON := `{}` - return []byte(mockJSON), nil - } - - params := &fde.DeviceSetupParams{ - Key: mockKey, - Device: mockDevice, - } - err := fde.DeviceSetup(runSetupHook, params) - c.Assert(err, IsNil) -} - -func (s *fdeSuite) TestDeviceSetupError(c *C) { - mockKey := []byte{1, 2, 3, 4} - mockDevice := "/dev/sda2" - - runSetupHook := func(req *fde.SetupRequest) ([]byte, error) { - c.Check(req, DeepEquals, &fde.SetupRequest{ - Op: "device-setup", - Key: mockKey, - Device: mockDevice, - }) - // empty reply: no error - mockJSON := `something failed badly` - return []byte(mockJSON), fmt.Errorf("exit status 1") - } - - params := &fde.DeviceSetupParams{ - Key: mockKey, - Device: mockDevice, - } - err := fde.DeviceSetup(runSetupHook, params) - c.Check(err, ErrorMatches, "device setup failed with: something failed badly") -} - -func (s *fdeSuite) TestDeviceUnlock(c *C) { - checkSystemdRunOrSkip(c) - - restore := fde.MockFdeInitramfsHelperCommandExtra([]string{"--user"}) - defer restore() - fdeDeviceUnlockStdin := filepath.Join(c.MkDir(), "stdin") - mockDeviceUnlockHook := testutil.MockCommand(c, "fde-device-unlock", fmt.Sprintf(` -cat - > %s -`, fdeDeviceUnlockStdin)) - defer mockDeviceUnlockHook.Restore() - - // ensure we have a device-unlock hook - c.Assert(fde.HasDeviceUnlock(), Equals, true) - key := []byte{0, 1, 2, 3, 4, 5} - err := fde.DeviceUnlock(&fde.DeviceUnlockParams{ - Key: key, - Device: "/dev/mapper/data-device-locked", - PartitionName: "data", - }) - c.Assert(err, IsNil) - c.Check(mockDeviceUnlockHook.Calls(), DeepEquals, [][]string{ - {"fde-device-unlock"}, - }) - exp := fmt.Sprintf(`{"op":"device-unlock","key":%q,"device":"/dev/mapper/data-device-locked","partition-name":"data"}`, base64.StdEncoding.EncodeToString(key)) - c.Check(fdeDeviceUnlockStdin, testutil.FileEquals, exp) - - // ensure no tmp files are left behind - c.Check(osutil.FileExists(filepath.Join(dirs.GlobalRootDir, "/run/fde-device-unlock")), Equals, false) -} - -func (s *fdeSuite) TestDeviceUnlockErr(c *C) { - checkSystemdRunOrSkip(c) - - restore := fde.MockFdeInitramfsHelperCommandExtra([]string{"--user"}) - defer restore() - mockDeviceUnlockHook := testutil.MockCommand(c, "fde-device-unlock", ` -echo "output-only-used-for-errors" 1>&2 -sleep .5 -exit 1 -`) - defer mockDeviceUnlockHook.Restore() - - p := fde.DeviceUnlockParams{ - Key: []byte{0, 1, 2, 3, 4, 5}, - Device: "/dev/mapper/data-device-locked", - PartitionName: "data", - } - err := fde.DeviceUnlock(&p) - c.Assert(err, ErrorMatches, `cannot run fde-device-unlock "device-unlock": ------ -output-only-used-for-errors -service result: exit-code ------`) - - c.Assert(mockDeviceUnlockHook.Calls(), DeepEquals, [][]string{ - {"fde-device-unlock"}, - }) - - // ensure no tmp files are left behind - c.Check(osutil.FileExists(filepath.Join(dirs.GlobalRootDir, "/run/fde-device-unlock")), Equals, false) -} - -func (s *fdeSuite) TestHasDeviceUnlock(c *C) { - oldPath := os.Getenv("PATH") - defer func() { os.Setenv("PATH", oldPath) }() - - mockRoot := c.MkDir() - os.Setenv("PATH", mockRoot+"/bin") - mockBin := mockRoot + "/bin/" - err := os.Mkdir(mockBin, 0755) - c.Assert(err, IsNil) - - // no fde-device-unlock binary - c.Check(fde.HasDeviceUnlock(), Equals, false) - - // fde-device-unlock without +x - err = ioutil.WriteFile(mockBin+"fde-device-unlock", nil, 0644) - c.Assert(err, IsNil) - c.Check(fde.HasDeviceUnlock(), Equals, false) - - // correct fde-device-unlock, no logging - err = os.Chmod(mockBin+"fde-device-unlock", 0755) - c.Assert(err, IsNil) - - c.Check(fde.HasDeviceUnlock(), Equals, true) -} - -func (s *fdeSuite) TestIsEncryptedDeviceMapperName(c *C) { - // matches - for _, t := range []string{ - "something-device-locked", - "foo23-device-locked", - "device-device-locked", - "WE-DON'T-CARE-WHAT-THE-PREFIX-IS-AND-YOU-CAN'T-MAKE-US-device-locked", - } { - c.Assert(fde.IsHardwareEncryptedDeviceMapperName(t), Equals, true) - } - - // doesn't match - for _, t := range []string{ - "", - "-device-locked", - "device-locked", - "-device-locked-foo", - "some-device", - "CRYPT-LUKS2-5a522809c87e4dfa81a88dc5667d1304-ubuntu-data-3776bab4-8bcc-46b7-9da2-6a84ce7f93b4", - } { - c.Assert(fde.IsHardwareEncryptedDeviceMapperName(t), Equals, false) - } -} - -func (s *fdeSuite) TestEncryptedDeviceMapperName(c *C) { - for _, str := range []string{ - "ubuntu-data", - "ubuntu-save", - "foo", - "other", - } { - c.Assert(fde.EncryptedDeviceMapperName(str), Equals, str+"-device-locked") - } -} diff --git a/kernel/fde/mapper.go b/kernel/fde/mapper.go deleted file mode 100644 index a1928a697b8..00000000000 --- a/kernel/fde/mapper.go +++ /dev/null @@ -1,52 +0,0 @@ -// -*- Mode: Go; indent-tabs-mode: t -*- - -/* - * Copyright (C) 2021 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 fde - -import ( - "path/filepath" - "strings" - - "github.com/snapcore/snapd/osutil/disks" -) - -// IsEncryptedDevice returns true when the provided device mapper name indicates -// that it is encrypted using FDE hooks. -func IsHardwareEncryptedDeviceMapperName(dmName string) bool { - // TODO: is there anything more we can use to limit the prefix of the - // dmName? - return dmName != "-device-locked" && strings.HasSuffix(dmName, "-device-locked") -} - -// DeviceUnlockKernelHookDeviceMapperBackResolver is a back resolver to be used -// with disks.RegisterDeviceMapperBackResolver for devices that implement full -// disk encryption via hardware devices with kernel snap hooks. -func DeviceUnlockKernelHookDeviceMapperBackResolver(dmUUID, dmName []byte) (dev string, ok bool) { - if !IsHardwareEncryptedDeviceMapperName(string(dmName)) { - return "", false - } - // this is a device encrypted using FDE hooks - - // the uuid of the mapper device is the same as the partuuid - return filepath.Join("/dev/disk/by-partuuid", string(dmUUID)), true -} - -func init() { - disks.RegisterDeviceMapperBackResolver("device-unlock-kernel-fde", DeviceUnlockKernelHookDeviceMapperBackResolver) -} diff --git a/osutil/disks/disks.go b/osutil/disks/disks.go index 72a6fb39964..b0c696b0304 100644 --- a/osutil/disks/disks.go +++ b/osutil/disks/disks.go @@ -206,6 +206,7 @@ var ( _ = error(PartitionNotFoundError{}) ) +// TODO: simplify this away as now we have only LUKS? var deviceMapperBackResolvers = map[string]func(dmUUID, dmName []byte) (dev string, ok bool){} // RegisterDeviceMapperBackResolver takes a callback function which is used when diff --git a/osutil/disks/disks_linux_test.go b/osutil/disks/disks_linux_test.go index 8423bd570c5..dee56fda1a3 100644 --- a/osutil/disks/disks_linux_test.go +++ b/osutil/disks/disks_linux_test.go @@ -30,7 +30,6 @@ import ( "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/gadget/quantity" - "github.com/snapcore/snapd/kernel/fde" "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/osutil/disks" "github.com/snapcore/snapd/testutil" @@ -773,123 +772,6 @@ func (s *diskSuite) TestDiskFromMountPointIsDecryptedLUKSDeviceVolumeHappy(c *C) c.Assert(d.Schema(), Equals, "dos") } -func (s *diskSuite) TestDiskFromMountPointIsDecryptedUnlockedDeviceVolumeHappy(c *C) { - // for udevadm trigger and udevadm settle which are called on the partitions - mockUdevadm := testutil.MockCommand(c, "udevadm", ``) - defer mockUdevadm.Restore() - - restore := osutil.MockMountInfo(`130 30 242:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/mapper/something-device-locked rw -`) - defer restore() - - // un-register the fde handler so we can make sure that the default - // handler(s) don't match this device mapper - this name needs to be kept in - // sync with what's in kernel/fde/fde.go - disks.UnregisterDeviceMapperBackResolver("device-unlock-kernel-fde") - defer func() { - // this is registered by default in this file since we import the fde - // package so make sure it is re-registered at the end - disks.RegisterDeviceMapperBackResolver("device-unlock-kernel-fde", fde.DeviceUnlockKernelHookDeviceMapperBackResolver) - }() - - restore = disks.MockUdevPropertiesForDevice(func(typeOpt, dev string) (map[string]string, error) { - c.Assert(typeOpt, Equals, "--name") - switch dev { - case "/dev/mapper/something-device-locked": - return map[string]string{ - "DEVTYPE": "disk", - "MAJOR": "242", - "MINOR": "1", - }, nil - case "/dev/disk/by-partuuid/5a522809-c87e-4dfa-81a8-8dc5667d1304": - return map[string]string{ - "DEVTYPE": "disk", - "ID_PART_ENTRY_DISK": "41:3", - }, nil - case "/dev/block/41:3": - return map[string]string{ - "DEVTYPE": "disk", - "DEVNAME": "/dev/sda", - "DEVPATH": "/block/foo", - "ID_PART_TABLE_UUID": "foo-foo-foo-foo", - "ID_PART_TABLE_TYPE": "gpt", - }, nil - case "sda1": - return map[string]string{ - "DEVPATH": "/block/foo/sda1", - "DEVNAME": "/dev/sda1", - "ID_PART_ENTRY_UUID": "foo-foo-foo-foo-1", - "ID_PART_ENTRY_TYPE": "gooooooo", - "ID_PART_ENTRY_SIZE": "500000", - "ID_PART_ENTRY_NUMBER": "1", - "ID_PART_ENTRY_OFFSET": "2048", - "MAJOR": "41", - "MINOR": "4", - }, nil - default: - c.Errorf("unexpected udev device properties requested: %s", dev) - return nil, fmt.Errorf("unexpected udev device: %s", dev) - } - }) - defer restore() - - // mock the sysfs dm uuid and name files - dmDir := filepath.Join(filepath.Join(dirs.SysfsDir, "dev", "block"), "242:1", "dm") - err := os.MkdirAll(dmDir, 0755) - c.Assert(err, IsNil) - - // name expected by fde - b := []byte("something-device-locked") - err = ioutil.WriteFile(filepath.Join(dmDir, "name"), b, 0644) - c.Assert(err, IsNil) - - b = []byte("5a522809-c87e-4dfa-81a8-8dc5667d1304") - err = ioutil.WriteFile(filepath.Join(dmDir, "uuid"), b, 0644) - c.Assert(err, IsNil) - - opts := &disks.Options{IsDecryptedDevice: true} - - // first try without the handler fails - _, err = disks.DiskFromMountPoint("/run/mnt/point", opts) - c.Assert(err, ErrorMatches, `cannot process properties of /dev/mapper/something-device-locked parent device: internal error: no back resolver supports decrypted device mapper with UUID "5a522809-c87e-4dfa-81a8-8dc5667d1304" and name "something-device-locked"`) - - // next try with the FDE package handler works - disks.RegisterDeviceMapperBackResolver("device-unlock-kernel-fde", fde.DeviceUnlockKernelHookDeviceMapperBackResolver) - - d, err := disks.DiskFromMountPoint("/run/mnt/point", opts) - c.Assert(err, IsNil) - c.Assert(d.Dev(), Equals, "41:3") - c.Assert(d.HasPartitions(), Equals, true) - - // mock a partition - partFile := filepath.Join(dirs.SysfsDir, "/block/foo/sda1/partition") - err = os.MkdirAll(filepath.Dir(partFile), 0755) - c.Assert(err, IsNil) - err = ioutil.WriteFile(partFile, nil, 0644) - c.Assert(err, IsNil) - - parts, err := d.Partitions() - c.Assert(err, IsNil) - c.Assert(parts, DeepEquals, []disks.Partition{ - { - PartitionType: "GOOOOOOO", - DiskIndex: 1, - StartInBytes: 512 * 2048, - SizeInBytes: 500000 * 512, - PartitionUUID: "foo-foo-foo-foo-1", - Major: 41, - Minor: 4, - KernelDevicePath: filepath.Join(dirs.SysfsDir, "/block/foo/sda1"), - KernelDeviceNode: "/dev/sda1", - }, - }) - - c.Assert(mockUdevadm.Calls(), DeepEquals, [][]string{ - {"udevadm", "trigger", "--name-match=sda1"}, - {"udevadm", "settle", "--timeout=180"}, - }) -} - func (s *diskSuite) TestDiskFromMountPointNotDiskUnsupported(c *C) { restore := osutil.MockMountInfo(`130 30 42:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/not-a-disk rw `) diff --git a/overlord/devicestate/devicemgr.go b/overlord/devicestate/devicemgr.go index 8892fe803c5..389ed3dcb34 100644 --- a/overlord/devicestate/devicemgr.go +++ b/overlord/devicestate/devicemgr.go @@ -2391,9 +2391,6 @@ func (m *DeviceManager) checkFDEFeatures() (et secboot.EncryptionType, err error switch { case strutil.ListContains(features, "inline-crypto-engine"): et = secboot.EncryptionTypeLUKSWithICE - // TODO:ICE: remove this - case strutil.ListContains(features, "device-setup"): - et = secboot.EncryptionTypeDeviceSetupHook default: et = secboot.EncryptionTypeLUKS } diff --git a/overlord/devicestate/devicestate_install_mode_test.go b/overlord/devicestate/devicestate_install_mode_test.go index 66b398b321d..44197d3274d 100644 --- a/overlord/devicestate/devicestate_install_mode_test.go +++ b/overlord/devicestate/devicestate_install_mode_test.go @@ -1964,8 +1964,6 @@ func (s *deviceMgrInstallModeSuite) TestInstallCheckEncrypted(c *C) { {false, "[]", true, secboot.EncryptionTypeLUKS}, {true, "[]", false, secboot.EncryptionTypeLUKS}, {true, "[]", true, secboot.EncryptionTypeLUKS}, - // happy but device-setup hook - {true, `["device-setup"]`, true, secboot.EncryptionTypeDeviceSetupHook}, } { hookInvoke := func(ctx *hookstate.Context, tomb *tomb.Tomb) ([]byte, error) { ctx.Lock() @@ -2148,9 +2146,6 @@ func (s *deviceMgrInstallModeSuite) TestInstallCheckEncryptedFDEHook(c *C) { {`{"features":[1]}`, `cannot parse hook output ".*": json: cannot unmarshal number into Go struct.*`, secboot.EncryptionTypeNone}, {`{"features":1}`, `cannot parse hook output ".*": json: cannot unmarshal number into Go struct.*`, secboot.EncryptionTypeNone}, {`{"features":"1"}`, `cannot parse hook output ".*": json: cannot unmarshal string into Go struct.*`, secboot.EncryptionTypeNone}, - // valid and switches to "device-setup" - {`{"features":["device-setup"]}`, "", secboot.EncryptionTypeDeviceSetupHook}, - {`{"features":["a","device-setup","b"]}`, "", secboot.EncryptionTypeDeviceSetupHook}, // valid and uses ice {`{"features":["a","inline-crypto-engine","b"]}`, "", secboot.EncryptionTypeLUKSWithICE}, } { @@ -3665,131 +3660,6 @@ func (s *deviceMgrInstallModeSuite) TestEncryptionSupportInfoWithTPM(c *C) { } } -func (s *deviceMgrInstallModeSuite) TestEncryptionSupportInfoWithFdeHook(c *C) { - s.state.Lock() - defer s.state.Unlock() - - devicestatetest.SetDevice(s.state, &auth.DeviceState{ - Brand: "my-brand", - Model: "my-model", - }) - kernelInfo := makeInstalledMockKernelSnap(c, s.state, kernelYamlWithFdeSetup) - gadgetSnapInfo := s.makeMockInstalledPcGadget(c, "", "") - gadgetInfo, err := gadget.ReadInfo(gadgetSnapInfo.MountDir(), nil) - c.Assert(err, IsNil) - - var testCases = []struct { - grade, storageSafety string - hookErr error - - expected devicestate.EncryptionSupportInfo - }{ - { - "dangerous", "", nil, - devicestate.EncryptionSupportInfo{ - Available: true, Disabled: false, - StorageSafety: asserts.StorageSafetyPreferEncrypted, - Type: secboot.EncryptionTypeDeviceSetupHook, - }, - }, { - "dangerous", "", fmt.Errorf("hook error"), - devicestate.EncryptionSupportInfo{ - Available: false, Disabled: false, - StorageSafety: asserts.StorageSafetyPreferEncrypted, - Type: secboot.EncryptionTypeNone, - UnavailableWarning: `not encrypting device storage as querying kernel fde-setup hook did not succeed: cannot run hook for "features": run hook "fde-setup": hook error`, - }, - }, { - "dangerous", "encrypted", nil, - devicestate.EncryptionSupportInfo{ - Available: true, Disabled: false, - StorageSafety: asserts.StorageSafetyEncrypted, - Type: secboot.EncryptionTypeDeviceSetupHook, - }, - }, { - "dangerous", "encrypted", fmt.Errorf("hook error"), - devicestate.EncryptionSupportInfo{ - Available: false, Disabled: false, - StorageSafety: asserts.StorageSafetyEncrypted, - Type: secboot.EncryptionTypeNone, - UnavailableErr: fmt.Errorf(`cannot encrypt device storage as mandated by encrypted storage-safety model option: cannot run hook for "features": run hook "fde-setup": hook error`), - }, - }, { - "signed", "", nil, - devicestate.EncryptionSupportInfo{ - Available: true, Disabled: false, - StorageSafety: asserts.StorageSafetyPreferEncrypted, - Type: secboot.EncryptionTypeDeviceSetupHook, - }, - }, { - "signed", "", fmt.Errorf("hook error"), - devicestate.EncryptionSupportInfo{ - Available: false, Disabled: false, - StorageSafety: asserts.StorageSafetyPreferEncrypted, - Type: secboot.EncryptionTypeNone, - UnavailableWarning: `not encrypting device storage as querying kernel fde-setup hook did not succeed: cannot run hook for "features": run hook "fde-setup": hook error`, - }, - }, { - "signed", "encrypted", fmt.Errorf("hook error"), - devicestate.EncryptionSupportInfo{ - Available: false, Disabled: false, - StorageSafety: asserts.StorageSafetyEncrypted, - Type: secboot.EncryptionTypeNone, - UnavailableErr: fmt.Errorf(`cannot encrypt device storage as mandated by encrypted storage-safety model option: cannot run hook for "features": run hook "fde-setup": hook error`), - }, - }, { - "secured", "", fmt.Errorf("hook error"), - devicestate.EncryptionSupportInfo{ - Available: false, Disabled: false, - StorageSafety: asserts.StorageSafetyEncrypted, - Type: secboot.EncryptionTypeNone, - UnavailableErr: fmt.Errorf(`cannot encrypt device storage as mandated by model grade secured: cannot run hook for "features": run hook "fde-setup": hook error`), - }, - }, { - "secured", "", nil, - devicestate.EncryptionSupportInfo{ - Available: true, Disabled: false, - StorageSafety: asserts.StorageSafetyEncrypted, - Type: secboot.EncryptionTypeDeviceSetupHook, - }, - }, - } - for _, tc := range testCases { - hookInvoke := func(ctx *hookstate.Context, tomb *tomb.Tomb) ([]byte, error) { - ctx.Lock() - defer ctx.Unlock() - ctx.Set("fde-setup-result", []byte(`{"features":["device-setup"]}`)) - return nil, tc.hookErr - } - rhk := hookstate.MockRunHook(hookInvoke) - defer rhk() - - mockModel := s.makeModelAssertionInState(c, "my-brand", "my-model", map[string]interface{}{ - "display-name": "my model", - "architecture": "amd64", - "base": "core20", - "grade": tc.grade, - "storage-safety": tc.storageSafety, - "snaps": []interface{}{ - map[string]interface{}{ - "name": "pc-kernel", - "id": pcKernelSnapID, - "type": "kernel", - "default-channel": "20", - }, - map[string]interface{}{ - "name": "pc", - "id": pcSnapID, - "type": "gadget", - "default-channel": "20", - }}, - }) - res, err := devicestate.DeviceManagerEncryptionSupportInfo(s.mgr, mockModel, secboot.TPMProvisionFull, kernelInfo, gadgetInfo) - c.Assert(err, IsNil) - c.Check(res, DeepEquals, tc.expected, Commentf("%v", tc)) - } -} - func (s *deviceMgrInstallModeSuite) TestInstallWithUbuntuSaveSnapFoldersHappy(c *C) { restore := release.MockOnClassic(false) defer restore() diff --git a/overlord/hookstate/ctlcmd/fde_setup.go b/overlord/hookstate/ctlcmd/fde_setup.go index e5ac19dc372..ab24079afc1 100644 --- a/overlord/hookstate/ctlcmd/fde_setup.go +++ b/overlord/hookstate/ctlcmd/fde_setup.go @@ -75,9 +75,9 @@ func (c *fdeSetupRequestCommand) Execute(args []string) error { if err := context.Get("fde-setup-request", &fdeSetup); err != nil { return fmt.Errorf("cannot get fde-setup-op from context: %v", err) } - // Op is either "initial-setup", "device-setup" or "features" + // Op is either "initial-setup" or "features" switch fdeSetup.Op { - case "features", "initial-setup", "device-setup": + case "features", "initial-setup": // fine default: return fmt.Errorf("unknown fde-setup-request op %q", fdeSetup.Op) diff --git a/overlord/hookstate/ctlcmd/fde_setup_test.go b/overlord/hookstate/ctlcmd/fde_setup_test.go index dba2cbee1ef..324b4457a64 100644 --- a/overlord/hookstate/ctlcmd/fde_setup_test.go +++ b/overlord/hookstate/ctlcmd/fde_setup_test.go @@ -166,24 +166,3 @@ func (s *fdeSetupSuite) TestFdeSetupResult(c *C) { s.mockContext.Unlock() c.Check(fdeSetupResult, DeepEquals, mockStdin) } - -func (s *fdeSetupSuite) TestFdeSetupRequestOpDeviceSetup(c *C) { - mockKey := keys.EncryptionKey{1, 2, 3, 4} - fdeSetup := &fde.SetupRequest{ - Op: "device-setup", - Key: mockKey[:], - Device: "/dev/sda1", - } - s.mockContext.Lock() - s.mockContext.Set("fde-setup-request", fdeSetup) - s.mockContext.Unlock() - - stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"fde-setup-request"}, 0) - c.Assert(err, IsNil) - - // the encryption key should be base64 encoded - encodedBase64Key := base64.StdEncoding.EncodeToString(mockKey[:]) - - c.Check(string(stdout), Equals, fmt.Sprintf(`{"op":"device-setup","key":%q,"device":"/dev/sda1"}`+"\n", encodedBase64Key)) - c.Check(string(stderr), Equals, "") -} diff --git a/secboot/encrypt.go b/secboot/encrypt.go index 804afe5c6a3..9bb498f75ff 100644 --- a/secboot/encrypt.go +++ b/secboot/encrypt.go @@ -26,12 +26,9 @@ const ( EncryptionTypeNone EncryptionType = "" EncryptionTypeLUKS EncryptionType = "cryptsetup" EncryptionTypeLUKSWithICE EncryptionType = "cryptsetup-with-inline-crypto-engine" - - // TODO:ICE: remove this - EncryptionTypeDeviceSetupHook EncryptionType = "device-setup-hook" ) -// TODO:ICE: once all EncryptionTypes are LUKS based this can probably go +// TODO:ICE: all EncryptionTypes are LUKS based now so this could be removed? func (et EncryptionType) IsLUKS() bool { return et == EncryptionTypeLUKS || et == EncryptionTypeLUKSWithICE } diff --git a/tests/nested/manual/uc20-fde-hooks-ice/task.yaml b/tests/nested/manual/uc20-fde-hooks-ice/task.yaml index 3e75026e804..4ff8991401f 100644 --- a/tests/nested/manual/uc20-fde-hooks-ice/task.yaml +++ b/tests/nested/manual/uc20-fde-hooks-ice/task.yaml @@ -9,7 +9,7 @@ environment: NESTED_ENABLE_OVMF: true prepare: | - echo "Build a kernel snap with the fde-setup hook with device-setup support" + echo "Build a kernel snap with the fde-setup hook with ICE support" # shellcheck source=tests/lib/prepare.sh . "$TESTSLIB/prepare.sh"