-
Notifications
You must be signed in to change notification settings - Fork 582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
secboot: re-introduce v1 fde hook format #14638
secboot: re-introduce v1 fde hook format #14638
Conversation
b9599c8
to
837045c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
fcc5e2e
to
24018ee
Compare
837045c
to
9955ff3
Compare
This was manually tested with
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## fde-manager-features #14638 +/- ##
=======================================================
Coverage ? 78.83%
=======================================================
Files ? 1093
Lines ? 147894
Branches ? 0
=======================================================
Hits ? 116594
Misses ? 24022
Partials ? 7278
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚨 Try these New Features:
|
secboot/secboot_sb.go
Outdated
@@ -161,6 +161,22 @@ func UnlockVolumeUsingSealedKeyIfEncrypted(disk disks.Disk, name string, sealedE | |||
return res, fmt.Errorf("internal error: cannot build an auth requestor: %v", err) | |||
} | |||
|
|||
if loadedKey.SealedKeyV1 != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this feels like it's a leaky abstraction which only muddies the whole picture, could we do something more explicit, eg:
// legacy fde-hooks keys which did not carry any metadata
var legacyV1Key []byte
// more modern keys with metadata
var keys []*sb.KeyData
// isLegacyV1Key - simply checks the header
if fdeHasRevealKey() && isLegacyV1Key(sealedEncryptioKeyFile) {
legacyV1Key, err = os.ReadFile()
...
} else {
if err := readKeyFile(sealedEncryptionKeyFile, loadedKey); err != nil {
return res, err
}
}
...
if len(legacyV1KeyFile) != 0 {
}
...
// continue with ActivateVolumeWithKeyData
and then simply drop the loader thingy
d3a6b29
to
e0c0e74
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
(although I added some changes here, so it should likely count as +0.5)
e0c0e74
to
3acc10f
Compare
I have retested. And it is broken. |
3acc10f
to
db273b6
Compare
It is working again. |
db273b6
to
8072bfb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just some minor comments
secboot/secboot_tpm.go
Outdated
LoadKeyData(kd *sb.KeyData) | ||
LoadSealedKeyObject(sko *sb_tpm2.SealedKeyObject) | ||
LoadFDEHookKeyV1(sk []byte) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LoadKeyData(kd *sb.KeyData) | |
LoadSealedKeyObject(sko *sb_tpm2.SealedKeyObject) | |
LoadFDEHookKeyV1(sk []byte) | |
// LoadKeyData is expected to keep track of key data wrappers | |
LoadKeyData(kd *sb.KeyData) | |
// LoadSealedKeyObject is expected to keep track of a TPM sealed key | |
LoadSealedKeyObject(sko *sb_tpm2.SealedKeyObject) | |
// LoadFDEHookV1Key is expected to keep track of a FDE hook v1 sealed key | |
LoadFDEHookKeyV1(sk []byte) |
secboot/secboot_tpm.go
Outdated
case oldSealedKey && hintExpectFDEHook: | ||
// FDE hook key v1 | ||
// | ||
// It has the same magic header has sealed key object, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// It has the same magic header has sealed key object, | |
// It has the same magic header as sealed key object, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small comments
secboot/secboot_hooks.go
Outdated
sb.RegisterPlatformKeyDataHandler(legacyFdeHooksPlatformName, handler) | ||
v2Handler := &fdeHookV2DataHandler{} | ||
sb.RegisterPlatformKeyDataHandler(legacyFdeHooksPlatformName, v2Handler) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick
type defaultKeyLoader struct { | ||
KeyData *sb.KeyData | ||
SealedKeyObject *sb_tpm2.SealedKeyObject | ||
FDEHookKeyV1 []byte |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick, a small doc comment explaining those fields and what the zero values mean would be helpful.
e.g.
FDEHookKeyV1 []byte | |
// Non-nil FDEHookKeyV1 indicates that V1 hook key is used | |
FDEHookKeyV1 []byte |
@@ -238,14 +238,40 @@ func newAuthRequestor() (sb.AuthRequestor, error) { | |||
) | |||
} | |||
|
|||
// TODO: consider moving this to secboot | |||
func readKeyFileImpl(keyfile string) (*sb.KeyData, *sb_tpm2.SealedKeyObject, error) { | |||
type keyLoader interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tiny nitpick, feel free to ignore.
For simplicity, can't this just be a struct that is returned as output from readKeyFileImpl
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had in mind that in the future we just make callbacks that ignore some input. For instance the sealed key objects for tpm are useless for unlocking, only for resealing. Though in the end I have just used the same type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try it and see if the code looks better. Maybe it can be done in another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonder if the interface should be called loadedKey now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also are we going to have other implementations of this interface in later PRs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. But I am not sure how it should look at this point. But one thing is sure is that having an interface here seemed a bit useless.
secboot/secboot_tpm.go
Outdated
// to use a hint we are using FDE hooks. | ||
sealedKey, err := os.ReadFile(keyfile) | ||
if err != nil { | ||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is ignoring the error here intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
a1ac728
to
cbc60bb
Compare
I had to resolve conflicts, so I squashed and and rebase. I also added some code in the resealing to ignore v1 keys and a test for it. So that will need to be reviewed. |
cbc60bb
to
81b7f52
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some comments
if loadedKey.FDEHookKeyV1 != nil { | ||
// Special case for hook keys v1. They do not have | ||
// primary keys. So we cannot wrap them in KeyData | ||
err := unlockDiskWithHookV1Key(mapperName, sourceDevice, loadedKey.FDEHookKeyV1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they also don't reach here
secboot/secboot_tpm.go
Outdated
func readKeyFileImpl(keyfile string) (*sb.KeyData, *sb_tpm2.SealedKeyObject, error) { | ||
type keyLoader interface { | ||
// LoadKeyData keeps track of keys in KeyData format. | ||
LoadKeyData(kd *sb.KeyData) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't Loaded... be clearer? this just keep tracks at the comment says, the loading has already happened
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my mind originally, it was that call that was loading the read content into what ever thing needs to actually interpret it. But I think it makes sense to call it Loaded...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, couple naming comments and some more questions/comments
@@ -238,14 +238,40 @@ func newAuthRequestor() (sb.AuthRequestor, error) { | |||
) | |||
} | |||
|
|||
// TODO: consider moving this to secboot | |||
func readKeyFileImpl(keyfile string) (*sb.KeyData, *sb_tpm2.SealedKeyObject, error) { | |||
type keyLoader interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonder if the interface should be called loadedKey now?
// with key data if there are some on the tokens. | ||
// Also the request for recovery key will happen in | ||
// ActivateVolumeWithKeyData | ||
logger.Noticef("WARNING: attempting opening device %s with key file %s failed: %v", sourceDevice, sealedEncryptionKeyFile, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this fallback path is not reached
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added `TestUnlockVolumeUsingSealedKeyIfEncryptedFdeRevealKeyV1FallbackKeyData
LoadedFDEHookKeyV1(sk []byte) | ||
} | ||
|
||
type defaultKeyLoader struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then this is also defaultLoadedKey?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have put a todo to the keyLoader
interface to change it.
I am not sure that defaultLoadedKey
makes total sense here since we create it empty. So it is not loaded yet. But it will make sense once we get rid of the interface and we return it.
@@ -238,14 +238,40 @@ func newAuthRequestor() (sb.AuthRequestor, error) { | |||
) | |||
} | |||
|
|||
// TODO: consider moving this to secboot | |||
func readKeyFileImpl(keyfile string) (*sb.KeyData, *sb_tpm2.SealedKeyObject, error) { | |||
type keyLoader interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also are we going to have other implementations of this interface in later PRs?
hasNewData = true | ||
} else { | ||
hasOldObject = true | ||
if loadedKey.SealedKeyObject != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should maybe leave a TODO about refactor some of these ifs into methods on the loadedKey interface, but also I as wrote elsewhere wondering if there will be other implementations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added a TODO to the definition of keyLoader
interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks
this has changed enough that it needs a re-review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, Thank you!
This could use a spread test in a follow up PR.
secboot/secboot_tpm.go
Outdated
// | ||
// It has the same magic header as sealed key object, | ||
// but there is no version information. Thus we need | ||
// to use a hint we are using FDE hooks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// to use a hint we are using FDE hooks. | |
// to use a hint that we are using FDE hooks. |
secboot/secboot_tpm.go
Outdated
// to use a hint we are using FDE hooks. | ||
sealedKey, err := os.ReadFile(keyfile) | ||
if err != nil { | ||
return fmt.Errorf("cannot FDE hook v1 key: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return fmt.Errorf("cannot FDE hook v1 key: %v", err) | |
return fmt.Errorf("cannot read FDE hook v1 key: %v", err) |
b8783af
to
327e6f6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. The cleanups can be done in a followup PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks ok to me, although I've not spent a lot of time looking at the test code.
327e6f6
to
ac88293
Compare
4e36599
into
canonical:fde-manager-features
No description provided.