Skip to content

Commit

Permalink
overload/fdestate/backend: implement FDE hook resealing
Browse files Browse the repository at this point in the history
  • Loading branch information
valentindavid committed Sep 20, 2024
1 parent 57de81a commit b0bd57d
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
55 changes: 54 additions & 1 deletion overlord/fdestate/backend/reseal.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"fmt"
"path/filepath"

"github.com/snapcore/snapd/asserts"
"github.com/snapcore/snapd/boot"
"github.com/snapcore/snapd/bootloader"
"github.com/snapcore/snapd/dirs"
Expand All @@ -48,12 +49,64 @@ func MockSecbootResealKeys(f func(params *secboot.ResealKeysParams) error) (rest
}
}

type comparableModel struct {
BrandID string
SignKeyID string
Model string
Classic bool
Grade asserts.ModelGrade
Series string
}

func toComparable(m secboot.ModelForSealing) comparableModel {
return comparableModel{
BrandID: m.BrandID(),
SignKeyID: m.SignKeyID(),
Model: m.Model(),
Classic: m.Classic(),
Grade: m.Grade(),
Series: m.Series(),
}
}

func resealKeyForBootChainsFDEHook(method device.SealingMethod, rootdir string, params *boot.ResealKeyForBootChainsParams, expectReseal bool) error {
uniqueModels := make(map[comparableModel]secboot.ModelForSealing)

for _, bc := range params.RunModeBootChains {
m := bc.ModelForSealing()
uniqueModels[toComparable(m)] = m
}
for _, bc := range params.RecoveryBootChainsForRunKey {
m := bc.ModelForSealing()
uniqueModels[toComparable(m)] = m
}
for _, bc := range params.RecoveryBootChains {
m := bc.ModelForSealing()
uniqueModels[toComparable(m)] = m
}

var models []secboot.ModelForSealing
for _, m := range uniqueModels {
models = append(models, m)
}

keys := []string{
device.DataSealedKeyUnder(boot.InitramfsBootEncryptionKeyDir),
device.FallbackDataSealedKeyUnder(boot.InitramfsSeedEncryptionKeyDir),
device.FallbackSaveSealedKeyUnder(boot.InitramfsSeedEncryptionKeyDir),
}

primaryKey := filepath.Join(boot.InstallHostFDESaveDir, "aux-key")

return secboot.ResealKeysWithFDESetupHook(keys, primaryKey, models)
}

// ResealKeyForBootChains reseals disk encryption keys with the given bootchains.
func ResealKeyForBootChains(method device.SealingMethod, rootdir string, params *boot.ResealKeyForBootChainsParams, expectReseal bool) error {
switch method {
case device.SealingMethodFDESetupHook:
// FIXME: do something
return nil
return resealKeyForBootChainsFDEHook(method, rootdir, params, expectReseal)
case device.SealingMethodTPM, device.SealingMethodLegacyTPM:
default:
return fmt.Errorf("unknown key sealing method: %q", method)
Expand Down
31 changes: 31 additions & 0 deletions secboot/secboot_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,37 @@ func SealKeysWithFDESetupHook(runHook fde.RunSetupHookFunc, keys []SealKeyReques
return nil
}

func ResealKeysWithFDESetupHook(keyFiles []string, primaryKeyFile string, models []ModelForSealing) error {
primaryKeyBuf, err := os.ReadFile(primaryKeyFile)
if err != nil {
return fmt.Errorf("cannot read primary key file: %v", err)
}
primaryKey := sb.PrimaryKey(primaryKeyBuf)

var sbModels []sb.SnapModel
for _, model := range models {
sbModels = append(sbModels, model)
}
for _, keyFile := range keyFiles {
reader, err := sbNewFileKeyDataReader(keyFile)
if err != nil {
return fmt.Errorf("cannot open key data: %v", err)
}
keyData, err := sbReadKeyData(reader)
if err != nil {
return fmt.Errorf("cannot read key data: %v", err)
}
keyData.SetAuthorizedSnapModels(primaryKey, sbModels...)

writer := sb.NewFileKeyDataWriter(keyFile)
if err := keyData.WriteAtomic(writer); err != nil {
return err
}
}

return nil
}

func isV1EncryptedKeyFile(p string) bool {
// XXX move some of this to kernel/fde
var v1KeyPrefix = []byte("USK$")
Expand Down

0 comments on commit b0bd57d

Please sign in to comment.