Skip to content

Commit

Permalink
overlord/install/install.go: use plainkey for save key
Browse files Browse the repository at this point in the history
  • Loading branch information
valentindavid committed Nov 20, 2024
1 parent b26c8b3 commit 76c9119
Show file tree
Hide file tree
Showing 16 changed files with 274 additions and 55 deletions.
7 changes: 5 additions & 2 deletions boot/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func isAssetHashTrackedInMap(bam bootAssetsMap, assetName, assetHash string) boo
type TrustedAssetsInstallObserver interface {
BootLoaderSupportsEfiVariables() bool
ObserveExistingTrustedRecoveryAssets(recoveryRootDir string) error
SetBootstrappedContainers(key, saveKey secboot.BootstrappedContainer)
SetBootstrappedContainers(key, saveKey secboot.BootstrappedContainer, primaryKey []byte)
UpdateBootEntry() error
Observe(op gadget.ContentOperation, partRole, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeAction, error)
}
Expand Down Expand Up @@ -284,6 +284,8 @@ type trustedAssetsInstallObserverImpl struct {
saveBootstrappedContainer secboot.BootstrappedContainer

seedBootloader bootloader.Bootloader

primaryKey []byte
}

func (o *trustedAssetsInstallObserverImpl) BootLoaderSupportsEfiVariables() bool {
Expand Down Expand Up @@ -368,10 +370,11 @@ func (o *trustedAssetsInstallObserverImpl) currentTrustedRecoveryBootAssetsMap()
return o.trackedRecoveryAssets
}

func (o *trustedAssetsInstallObserverImpl) SetBootstrappedContainers(key, saveKey secboot.BootstrappedContainer) {
func (o *trustedAssetsInstallObserverImpl) SetBootstrappedContainers(key, saveKey secboot.BootstrappedContainer, primaryKey []byte) {
o.useEncryption = true
o.dataBootstrappedContainer = key
o.saveBootstrappedContainer = saveKey
o.primaryKey = primaryKey
}

func (o *trustedAssetsInstallObserverImpl) UpdateBootEntry() error {
Expand Down
4 changes: 2 additions & 2 deletions boot/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ func (s *assetsSuite) TestInstallObserverNonTrustedBootloader(c *C) {
dataBootstrappedContainer := secboot.CreateMockBootstrappedContainer()
saveBootstrappedContainer := secboot.CreateMockBootstrappedContainer()
c.Assert(dataBootstrappedContainer, Not(Equals), saveBootstrappedContainer)
obs.SetBootstrappedContainers(dataBootstrappedContainer, saveBootstrappedContainer)
obs.SetBootstrappedContainers(dataBootstrappedContainer, saveBootstrappedContainer, nil)

observerImpl, ok := obs.(*boot.TrustedAssetsInstallObserverImpl)
c.Assert(ok, Equals, true)
Expand All @@ -507,7 +507,7 @@ func (s *assetsSuite) TestInstallObserverTrustedButNoAssets(c *C) {
c.Assert(obs, NotNil)
dataBootstrappedContainer := secboot.CreateMockBootstrappedContainer()
saveBootstrappedContainer := secboot.CreateMockBootstrappedContainer()
obs.SetBootstrappedContainers(dataBootstrappedContainer, saveBootstrappedContainer)
obs.SetBootstrappedContainers(dataBootstrappedContainer, saveBootstrappedContainer, nil)

observerImpl, ok := obs.(*boot.TrustedAssetsInstallObserverImpl)
c.Assert(ok, Equals, true)
Expand Down
2 changes: 1 addition & 1 deletion boot/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func MockResealKeyForBootChains(f func(unlocker Unlocker, method device.SealingM
}
}

func MockSealKeyForBootChains(f func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, params *SealKeyForBootChainsParams) error) (restore func()) {
func MockSealKeyForBootChains(f func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, params *SealKeyForBootChainsParams) error) (restore func()) {
old := SealKeyForBootChains
SealKeyForBootChains = f
return func() {
Expand Down
6 changes: 3 additions & 3 deletions boot/makebootable.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ func cryptsetupSupportsTokenReplaceImpl() bool {

var cryptsetupSupportsTokenReplace = cryptsetupSupportsTokenReplaceImpl

func useTokens(model *asserts.Model) bool {
func UseTokens(model *asserts.Model) bool {
// For now we enable writing key data in tokens only for
// classic when it is possible.
if model.Classic() {
Expand Down Expand Up @@ -581,13 +581,13 @@ func makeRunnableSystem(model *asserts.Model, bootWith *BootableSet, observer Tr
FactoryReset: makeOpts.AfterDataReset,
SeedDir: makeOpts.SeedDir,
StateUnlocker: makeOpts.StateUnlocker,
UseTokens: useTokens(model),
UseTokens: UseTokens(model),
}
if makeOpts.Standalone {
flags.SnapsDir = snapBlobDir
}
// seal the encryption key to the parameters specified in modeenv
if err := sealKeyToModeenv(observerImpl.dataBootstrappedContainer, observerImpl.saveBootstrappedContainer, model, modeenv, flags); err != nil {
if err := sealKeyToModeenv(observerImpl.dataBootstrappedContainer, observerImpl.saveBootstrappedContainer, observerImpl.primaryKey, model, modeenv, flags); err != nil {
return err
}
}
Expand Down
12 changes: 6 additions & 6 deletions boot/makebootable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ version: 5.0
// set encryption key
myKey := secboot.CreateMockBootstrappedContainer()
myKey2 := secboot.CreateMockBootstrappedContainer()
obs.SetBootstrappedContainers(myKey, myKey2)
obs.SetBootstrappedContainers(myKey, myKey2, nil)

// set a mock recovery kernel
readSystemEssentialCalls := 0
Expand All @@ -646,7 +646,7 @@ version: 5.0
defer restore()

sealKeyForBootChainsCalled := 0
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, params *boot.SealKeyForBootChainsParams) error {
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, params *boot.SealKeyForBootChainsParams) error {
sealKeyForBootChainsCalled++
c.Check(method, Equals, device.SealingMethodTPM)
c.Check(key, Equals, myKey)
Expand Down Expand Up @@ -1083,7 +1083,7 @@ version: 5.0
// set encryption key
myKey := secboot.CreateMockBootstrappedContainer()
myKey2 := secboot.CreateMockBootstrappedContainer()
obs.SetBootstrappedContainers(myKey, myKey2)
obs.SetBootstrappedContainers(myKey, myKey2, nil)

// set a mock recovery kernel
readSystemEssentialCalls := 0
Expand All @@ -1094,7 +1094,7 @@ version: 5.0
defer restore()

sealKeyForBootChainsCalled := 0
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, params *boot.SealKeyForBootChainsParams) error {
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, params *boot.SealKeyForBootChainsParams) error {
sealKeyForBootChainsCalled++
c.Check(method, Equals, device.SealingMethodTPM)
c.Check(key, Equals, myKey)
Expand Down Expand Up @@ -1276,7 +1276,7 @@ version: 5.0
c.Assert(err, IsNil)
myKey := secboot.CreateMockBootstrappedContainer()
myKey2 := secboot.CreateMockBootstrappedContainer()
obs.SetBootstrappedContainers(myKey, myKey2)
obs.SetBootstrappedContainers(myKey, myKey2, nil)

// set a mock recovery kernel
readSystemEssentialCalls := 0
Expand All @@ -1287,7 +1287,7 @@ version: 5.0
defer restore()

sealKeyForBootChainsCalled := 0
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, params *boot.SealKeyForBootChainsParams) error {
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, params *boot.SealKeyForBootChainsParams) error {
sealKeyForBootChainsCalled++
c.Check(method, Equals, device.SealingMethodTPM)
c.Check(key, DeepEquals, myKey)
Expand Down
15 changes: 9 additions & 6 deletions boot/seal.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func MockResealKeyToModeenv(f func(rootdir string, modeenv *Modeenv, expectResea
type MockSealKeyToModeenvFlags = sealKeyToModeenvFlags

// MockSealKeyToModeenv is used for testing from other packages.
func MockSealKeyToModeenv(f func(key, saveKey secboot.BootstrappedContainer, model *asserts.Model, modeenv *Modeenv, flags MockSealKeyToModeenvFlags) error) (restore func()) {
func MockSealKeyToModeenv(f func(key, saveKey secboot.BootstrappedContainer, primaryKey []byte, model *asserts.Model, modeenv *Modeenv, flags MockSealKeyToModeenvFlags) error) (restore func()) {

Check warning on line 83 in boot/seal.go

View check run for this annotation

Codecov / codecov/patch

boot/seal.go#L83

Added line #L83 was not covered by tests
old := sealKeyToModeenv
sealKeyToModeenv = f
return func() {
Expand Down Expand Up @@ -109,7 +109,7 @@ type sealKeyToModeenvFlags struct {
// sealKeyToModeenvImpl seals the supplied keys to the parameters specified
// in modeenv.
// It assumes to be invoked in install mode.
func sealKeyToModeenvImpl(key, saveKey secboot.BootstrappedContainer, model *asserts.Model, modeenv *Modeenv, flags sealKeyToModeenvFlags) error {
func sealKeyToModeenvImpl(key, saveKey secboot.BootstrappedContainer, primaryKey []byte, model *asserts.Model, modeenv *Modeenv, flags sealKeyToModeenvFlags) error {
if !isModeeenvLocked() {
return fmt.Errorf("internal error: cannot seal without the modeenv lock")
}
Expand Down Expand Up @@ -137,7 +137,7 @@ func sealKeyToModeenvImpl(key, saveKey secboot.BootstrappedContainer, model *ass
}
}

return sealKeyToModeenvForMethod(method, key, saveKey, model, modeenv, flags)
return sealKeyToModeenvForMethod(method, key, saveKey, primaryKey, model, modeenv, flags)
}

type SealKeyForBootChainsParams struct {
Expand All @@ -156,19 +156,22 @@ type SealKeyForBootChainsParams struct {
UseTokens bool
// InstallHostWritableDir...
InstallHostWritableDir string

PrimaryKey []byte
}

func sealKeyForBootChainsImpl(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, params *SealKeyForBootChainsParams) error {
func sealKeyForBootChainsImpl(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, params *SealKeyForBootChainsParams) error {

Check warning on line 163 in boot/seal.go

View check run for this annotation

Codecov / codecov/patch

boot/seal.go#L163

Added line #L163 was not covered by tests
return fmt.Errorf("FDE manager backend was not built in")
}

var SealKeyForBootChains = sealKeyForBootChainsImpl

func sealKeyToModeenvForMethod(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, model *asserts.Model, modeenv *Modeenv, flags sealKeyToModeenvFlags) error {
func sealKeyToModeenvForMethod(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, model *asserts.Model, modeenv *Modeenv, flags sealKeyToModeenvFlags) error {
params := &SealKeyForBootChainsParams{
FactoryReset: flags.FactoryReset,
UseTokens: flags.UseTokens,
InstallHostWritableDir: InstallHostWritableDir(model),
PrimaryKey: primaryKey,
}

var tbl bootloader.TrustedAssetsBootloader
Expand Down Expand Up @@ -228,7 +231,7 @@ func sealKeyToModeenvForMethod(method device.SealingMethod, key, saveKey secboot
params.RoleToBlName[bootloader.RoleRunMode] = bl.Name()
}

return SealKeyForBootChains(method, key, saveKey, params)
return SealKeyForBootChains(method, key, saveKey, primaryKey, params)
}

func UsesAltPCRHandles() (bool, error) {
Expand Down
12 changes: 6 additions & 6 deletions boot/seal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func (s *sealSuite) TestSealKeyToModeenv(c *C) {
defer restore()

sealKeyForBootChainsCalled := 0
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, params *boot.SealKeyForBootChainsParams) error {
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, params *boot.SealKeyForBootChainsParams) error {
sealKeyForBootChainsCalled++

for _, d := range []string{boot.InitramfsSeedEncryptionKeyDir, filepath.Join(dirs.GlobalRootDir, "/run/mnt/ubuntu-data/system-data/var/lib/snapd/device/fde")} {
Expand Down Expand Up @@ -233,7 +233,7 @@ func (s *sealSuite) TestSealKeyToModeenv(c *C) {
defer restore()

u := mockUnlocker{}
err = boot.SealKeyToModeenv(myKey, myKey2, model, modeenv, boot.MockSealKeyToModeenvFlags{
err = boot.SealKeyToModeenv(myKey, myKey2, nil, model, modeenv, boot.MockSealKeyToModeenvFlags{
FactoryReset: tc.factoryReset,
StateUnlocker: u.unlocker,
UseTokens: !tc.disableTokens,
Expand Down Expand Up @@ -1608,7 +1608,7 @@ func (s *sealSuite) TestSealToModeenvWithFdeHookHappy(c *C) {
myKey2 := secboot.CreateMockBootstrappedContainer()

sealKeyForBootChainsCalled := 0
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, params *boot.SealKeyForBootChainsParams) error {
restore = boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, params *boot.SealKeyForBootChainsParams) error {
sealKeyForBootChainsCalled++
c.Check(method, Equals, device.SealingMethodFDESetupHook)
c.Check(key, DeepEquals, myKey)
Expand Down Expand Up @@ -1637,7 +1637,7 @@ func (s *sealSuite) TestSealToModeenvWithFdeHookHappy(c *C) {

defer boot.MockModeenvLocked()()

err := boot.SealKeyToModeenv(myKey, myKey2, model, modeenv, boot.MockSealKeyToModeenvFlags{HasFDESetupHook: true, UseTokens: true})
err := boot.SealKeyToModeenv(myKey, myKey2, nil, model, modeenv, boot.MockSealKeyToModeenvFlags{HasFDESetupHook: true, UseTokens: true})
c.Assert(err, IsNil)
c.Check(sealKeyForBootChainsCalled, Equals, 1)
}
Expand All @@ -1650,7 +1650,7 @@ func (s *sealSuite) TestSealToModeenvWithFdeHookSad(c *C) {
model := boottest.MakeMockUC20Model()

sealKeyForBootChainsCalled := 0
restore := boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, params *boot.SealKeyForBootChainsParams) error {
restore := boot.MockSealKeyForBootChains(func(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, params *boot.SealKeyForBootChainsParams) error {
sealKeyForBootChainsCalled++

return fmt.Errorf("seal key failed")
Expand All @@ -1670,7 +1670,7 @@ func (s *sealSuite) TestSealToModeenvWithFdeHookSad(c *C) {

defer boot.MockModeenvLocked()()

err := boot.SealKeyToModeenv(key, saveKey, model, modeenv, boot.MockSealKeyToModeenvFlags{HasFDESetupHook: true})
err := boot.SealKeyToModeenv(key, saveKey, nil, model, modeenv, boot.MockSealKeyToModeenvFlags{HasFDESetupHook: true})
c.Assert(err, ErrorMatches, `seal key failed`)
c.Check(sealKeyForBootChainsCalled, Equals, 1)
}
Expand Down
10 changes: 5 additions & 5 deletions cmd/snap-bootstrap/cmd_initramfs_mounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8086,7 +8086,7 @@ func (s *initramfsMountsSuite) TestInitramfsMountsInstallAndRunMissingFdeSetup(c
type MockObserver struct {
BootLoaderSupportsEfiVariablesFunc func() bool
ObserveExistingTrustedRecoveryAssetsFunc func(recoveryRootDir string) error
SetBootstrappedContainersFunc func(key, saveKey secboot.BootstrappedContainer)
SetBootstrappedContainersFunc func(key, saveKey secboot.BootstrappedContainer, primaryKey []byte)
UpdateBootEntryFunc func() error
ObserveFunc func(op gadget.ContentOperation, partRole, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeAction, error)
}
Expand All @@ -8099,8 +8099,8 @@ func (m *MockObserver) ObserveExistingTrustedRecoveryAssets(recoveryRootDir stri
return m.ObserveExistingTrustedRecoveryAssetsFunc(recoveryRootDir)
}

func (m *MockObserver) SetBootstrappedContainers(key, saveKey secboot.BootstrappedContainer) {
m.SetBootstrappedContainersFunc(key, saveKey)
func (m *MockObserver) SetBootstrappedContainers(key, saveKey secboot.BootstrappedContainer, primaryKey []byte) {
m.SetBootstrappedContainersFunc(key, saveKey, primaryKey)
}

func (m *MockObserver) UpdateBootEntry() error {
Expand Down Expand Up @@ -8236,7 +8236,7 @@ echo '{"features":[]}'
observeExistingTrustedRecoveryAssetsCalled += 1
return nil
},
SetBootstrappedContainersFunc: func(key, saveKey secboot.BootstrappedContainer) {
SetBootstrappedContainersFunc: func(key, saveKey secboot.BootstrappedContainer, primaryKey []byte) {
},
UpdateBootEntryFunc: func() error {
return nil
Expand Down Expand Up @@ -8393,7 +8393,7 @@ func (s *initramfsMountsSuite) TestInitramfsMountsInstallAndRunFdeSetupNotPresen
observeExistingTrustedRecoveryAssetsCalled += 1
return nil
},
SetBootstrappedContainersFunc: func(key, saveKey secboot.BootstrappedContainer) {
SetBootstrappedContainersFunc: func(key, saveKey secboot.BootstrappedContainer, primaryKey []byte) {
},
UpdateBootEntryFunc: func() error {
return nil
Expand Down
2 changes: 1 addition & 1 deletion overlord/devicestate/devicestate_install_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ func (s *deviceMgrInstallAPISuite) testInstallFinishStep(c *C, opts finishStepOp
return nil
})
s.AddCleanup(restore)
restore = boot.MockSealKeyToModeenv(func(key, saveKey secboot.BootstrappedContainer, model *asserts.Model, modeenv *boot.Modeenv, flags boot.MockSealKeyToModeenvFlags) error {
restore = boot.MockSealKeyToModeenv(func(key, saveKey secboot.BootstrappedContainer, primaryKey []byte, model *asserts.Model, modeenv *boot.Modeenv, flags boot.MockSealKeyToModeenvFlags) error {
c.Check(model.Classic(), Equals, opts.installClassic)
// Note that we cannot compare the full structure and we check
// separately bits as the types for these are not exported.
Expand Down
12 changes: 6 additions & 6 deletions overlord/fdestate/backend/seal.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ func fallbackKeySealRequests(key, saveKey secboot.BootstrappedContainer, factory
}
}

func sealRunObjectKeys(key secboot.BootstrappedContainer, pbc boot.PredictableBootChains, roleToBlName map[bootloader.Role]string, pcrHandle uint32, useTokens bool) ([]byte, error) {
func sealRunObjectKeys(key secboot.BootstrappedContainer, pbc boot.PredictableBootChains, primaryKey []byte, roleToBlName map[bootloader.Role]string, pcrHandle uint32, useTokens bool) ([]byte, error) {
modelParams, err := boot.SealKeyModelParams(pbc, roleToBlName)
if err != nil {
return nil, fmt.Errorf("cannot prepare for key sealing: %v", err)
}

sealKeyParams := &secboot.SealKeysParams{
ModelParams: modelParams,
PrimaryKey: nil,
PrimaryKey: primaryKey,
TPMPolicyAuthKeyFile: filepath.Join(boot.InstallHostFDESaveDir, "tpm-policy-auth-key"),
PCRPolicyCounterHandle: pcrHandle,
}
Expand All @@ -112,12 +112,12 @@ func sealRunObjectKeys(key secboot.BootstrappedContainer, pbc boot.PredictableBo
// path only unseals one object because unsealing is expensive.
// Furthermore, the run object key is stored on ubuntu-boot so that we do not
// need to continually write/read keys from ubuntu-seed.
primaryKey, err := secbootSealKeys(runKeySealRequests(key, useTokens), sealKeyParams)
createdPrimaryKey, err := secbootSealKeys(runKeySealRequests(key, useTokens), sealKeyParams)
if err != nil {
return nil, fmt.Errorf("cannot seal the encryption keys: %v", err)
}

return primaryKey, nil
return createdPrimaryKey, nil
}

func sealFallbackObjectKeys(key, saveKey secboot.BootstrappedContainer, pbc boot.PredictableBootChains, primaryKey []byte, roleToBlName map[bootloader.Role]string, factoryReset bool, pcrHandle uint32, useTokens bool) error {
Expand Down Expand Up @@ -175,7 +175,7 @@ func sealKeyForBootChainsHook(key, saveKey secboot.BootstrappedContainer, params
return nil
}

func sealKeyForBootChainsBackend(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, params *boot.SealKeyForBootChainsParams) error {
func sealKeyForBootChainsBackend(method device.SealingMethod, key, saveKey secboot.BootstrappedContainer, primaryKey []byte, params *boot.SealKeyForBootChainsParams) error {
if method == device.SealingMethodFDESetupHook {
return sealKeyForBootChainsHook(key, saveKey, params)
}
Expand Down Expand Up @@ -228,7 +228,7 @@ func sealKeyForBootChainsBackend(method device.SealingMethod, key, saveKey secbo

// TODO: refactor sealing functions to take a struct instead of so many
// parameters
primaryKey, err := sealRunObjectKeys(key, pbc, params.RoleToBlName, runObjectKeyPCRHandle, params.UseTokens)
primaryKey, err := sealRunObjectKeys(key, pbc, primaryKey, params.RoleToBlName, runObjectKeyPCRHandle, params.UseTokens)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 76c9119

Please sign in to comment.