-
Notifications
You must be signed in to change notification settings - Fork 595
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
many: rework the way we allocate counter handles #14910
base: fde-manager-features
Are you sure you want to change the base?
many: rework the way we allocate counter handles #14910
Conversation
3766f88
to
796c572
Compare
796c572
to
bb2978a
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## fde-manager-features #14910 +/- ##
=======================================================
Coverage ? 78.09%
=======================================================
Files ? 1170
Lines ? 155133
Branches ? 0
=======================================================
Hits ? 121147
Misses ? 26449
Partials ? 7537
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
5802840
to
5ec2e43
Compare
bb2978a
to
20133bc
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.
did a first quick pass, some questions
// keys. | ||
|
||
// FIXME: maybe there is better if we had a function returning the devname instead. | ||
func deleteOldKeys(saveMntPnt string) error { |
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 needs a doc comment about what is doing
secboot/secboot_tpm.go
Outdated
if err != nil { | ||
if os.IsNotExist(err) { | ||
if readKeyDataErr != nil { | ||
// FIXME: we need to check for |
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.
That fixme is not complete...
a96331b
to
0dc4a83
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 for the changes, some small comments, please ping people to get more reviews
|
||
var oldKeys []string | ||
renameKey := false | ||
if osutil.FileExists(saveFallbackKeyFactory) { |
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 little bit of logic probably needs a small comment
@@ -1360,7 +1360,18 @@ func createSaveBootstrappedContainer(saveNode string) (secboot.BootstrappedConta | |||
return secbootCreateBootstrappedContainer(secboot.DiskUnlockKey(saveEncryptionKey), saveNode), nil | |||
} | |||
|
|||
|
|||
// deleteOldKeys remove old keys that were used in previous installation after successful factory reset. | |||
// * Key files ubuntu-save.recovery.sealed-key has to be replaced by key file ubuntu-save.recovery.sealed-key.factory-reset |
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.
given this bit, shouldn't the name say something like swap save key as well?
secboot/secboot_tpm.go
Outdated
@@ -936,6 +936,9 @@ func mockableReadKeyFileImpl(keyFile string, keyLoader *mockableKeyLoader, hintE | |||
|
|||
var mockableReadKeyFile = mockableReadKeyFileImpl | |||
|
|||
// GetPCRHandle returns the handle used by a key. The key will be | |||
// search on as token on node in the keySlot. If keySlot has no |
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.
s/search on/searched/ ?
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.
Maybe "searched on the token of the keySlot from the node". I will change that.
0dc4a83
to
374fffa
Compare
374fffa
to
4883247
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.
Just some trivial comments. TBH I'm not fond of all the mocking we do right now. On the one hand, it'd be nice to think about it a little, on the other there are things to deliver.
// * Key files ubuntu-save.recovery.sealed-key has to be replaced by key file ubuntu-save.recovery.sealed-key.factory-reset | ||
// * Keyslots factory-reset-* have to be removed | ||
// * TPM handles used by the removed keys have to be released |
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.
// * Key files ubuntu-save.recovery.sealed-key has to be replaced by key file ubuntu-save.recovery.sealed-key.factory-reset | |
// * Keyslots factory-reset-* have to be removed | |
// * TPM handles used by the removed keys have to be released | |
// - rotate ubuntu-save key file, replace ubuntu-save.recovery.sealed-key with | |
// ubuntu-save.recovery.sealed-key.factory-reset, which was successfully recovered | |
// - remove factory-reset-* keyslots | |
// - reelase TPM handles used by the removed keys |
// If the fallback save key exists, then it is the new | ||
// key. That means the default save key is the old save key | ||
// that needs to be removed. |
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.
// If the fallback save key exists, then it is the new | |
// key. That means the default save key is the old save key | |
// that needs to be removed. | |
// ubuntu-save key rotation, delete old key and use | |
// fallback save key if it exists |
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 is more confusing. If the fallback key does not exist, the default one is not the old key, because the rotation might have happened already.
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.
shouldn't we capture in the comment a bit what are the cases when is missing as well then?
// If the fallback save key exists, then it is the new | ||
// key. That means the default save key is the old save key | ||
// that needs to be removed. | ||
if osutil.FileExists(saveFallbackKeyFactory) { |
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.
maybe I'm missing something, but is it possible this key doesn't exist?
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 think it is possible if we already swapped it before but we did not finish clean up.
secboot/secboot_tpm.go
Outdated
// possibleKeyFiles is a list to paths. hintExpectFDEHook helps | ||
// reading old key object files. If not TPM2 key is found, nothing | ||
// happens. | ||
func RemoveOldCounterHandles(node string, possibleOldKeys map[string]bool, possibleKeyFiles []string, hintExpectFDEHook bool) error { |
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.
unless other code is using node already
func RemoveOldCounterHandles(node string, possibleOldKeys map[string]bool, possibleKeyFiles []string, hintExpectFDEHook bool) error { | |
func RemoveOldCounterHandles(device string, possibleOldKeys map[string]bool, possibleKeyFiles []string, hintExpectFDEHook bool) error { |
secboot/secboot_tpm.go
Outdated
// RemoveOldCounterHandles tracks and release TPM2 handles used by | ||
// given keys node and possibleOldKeys point to keyslot tokens. And | ||
// possibleKeyFiles is a list to paths. hintExpectFDEHook helps | ||
// reading old key object files. If not TPM2 key is found, nothing | ||
// happens. |
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.
// RemoveOldCounterHandles tracks and release TPM2 handles used by | |
// given keys node and possibleOldKeys point to keyslot tokens. And | |
// possibleKeyFiles is a list to paths. hintExpectFDEHook helps | |
// reading old key object files. If not TPM2 key is found, nothing | |
// happens. | |
// RemoveOldCounterHandles releases TPM2 handles of keys used on a given | |
// device, which are either stored in key slots matching possibleOldKeys or in key | |
// files listed in possibleKeyFiles. If not TPM2 key is found, nothing happens. |
readKeyDataErr = err | ||
break | ||
} | ||
keyData, err := mockableReadKeyData(reader) |
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 is slightly annoying
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.
thank you, couple small comments
renameKey = true | ||
} | ||
|
||
// FIXME: we are missing a bit of context here. We should do this only if we are using TPM2. |
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.
do we still need this comment, now that we pass hasHook?
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.
Removed.
saveFallbackKeyFactory := device.FactoryResetFallbackSaveSealedKeyUnder(boot.InitramfsSeedEncryptionKeyDir) | ||
|
||
var oldKeys []string | ||
renameKey := false |
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.
maybe this should be called rotateKey to match the doc comment of the function
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 changed it.
|
||
takenHandles := make(map[uint32]bool) | ||
for _, handle := range handles { | ||
takenHandles[uint32(handle)] = true |
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 would log which handles are in use here
for _, tentative := range randutil.Perm(int(PCRPolicyCounterHandleRange)) { | ||
handle := PCRPolicyCounterHandleStart + uint32(tentative) | ||
if !takenHandles[PCRPolicyCounterHandleStart+uint32(tentative)] { | ||
return handle, 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.
and here, log the free handle
func rotateSaveKeyAndDeleteOldKeys(saveMntPnt string) error { | ||
hasHook, err := boot.HasFDESetupHook(nil) | ||
if err != nil { | ||
logger.Noticef("WARNING: cannot figure out if FDE hooks are in use: %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.
logger.Noticef("WARNING: cannot figure out if FDE hooks are in use: %v", err) | |
logger.Noticef("WARNING: cannot determine whether FDE hooks are in use: %v", err) |
overlord/managers_test.go
Outdated
@@ -7482,6 +7482,11 @@ func (s *mgrsSuiteCore) testRemodelUC20WithRecoverySystem(c *C, encrypted bool) | |||
}) | |||
defer restore() | |||
|
|||
restore = fdestate.MockSecbootGetPCRHandle(func(devicePath, keySlot, keyFile string) (uint32, error) { | |||
return 42, 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.
FWIW, I would return an int which looks like the actual handles we expect, such that when looking at the logs you'd see familiar values, so eg. 0x1880002
We used 4 handles from 0x01880001-0x01880004 for PCR policies. We always used a pair and would switch to the other pair after factory reset. No instead we look for free handle in range 0x01880005-0x0188000F. We also use only one handle per primary key. When we factory reset, we should remove the handles correctly since the old primary key for the save partition should have been the same as the data partition that was removed, thus the handles should be the same. We also now correctly populate the FDE state with the correct handles.
24ce51f
to
2d88bcf
Compare
We used 4 handles from 0x01880001-0x01880004 for PCR policies. We always used a pair and would switch to the other pair after factory reset.
No instead we look for free handle in range 0x01880005-0x0188000F. We also use only one handle per primary key.
When we factory reset, we should remove the handles correctly since the old primary key for the save partition should have been the same as the data partition that was removed, thus the handles should be the same.
We also now correctly populate the FDE state with the correct handles.
Thanks for helping us make a better snapd!
Have you signed the license agreement and read the contribution guide?