-
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
overlord/fdestate/backend/reseal.go: factor FDE hook and TPM resealing #14674
base: fde-manager-features
Are you sure you want to change the base?
overlord/fdestate/backend/reseal.go: factor FDE hook and TPM resealing #14674
Conversation
a305470
to
75bd290
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## fde-manager-features #14674 +/- ##
=======================================================
Coverage ? 78.81%
=======================================================
Files ? 1093
Lines ? 147878
Branches ? 0
=======================================================
Hits ? 116556
Misses ? 24037
Partials ? 7285
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
75bd290
to
9ffe2f3
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.
suggestion
overlord/fdestate/backend/reseal.go
Outdated
type StateUpdater func(role string, containerRole string, bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte) error | ||
type StateGetter func(role string, containerRole string) (bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte, err 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.
wouldn't it make sense to combine these two into an interface and have FDEManager implement it?
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. I will do that.
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.
Though, I will need to wrap it since we need to handle the unlocker.
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
overlord/fdestate/backend/reseal.go
Outdated
type FDEState interface { | ||
UpdateState(role string, containerRole string, bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte) error | ||
GetState(role string, containerRole string) (bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte, err 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.
type FDEState interface { | |
UpdateState(role string, containerRole string, bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte) error | |
GetState(role string, containerRole string) (bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte, err error) | |
} | |
type FDEStateManager interface { | |
Update(role string, containerRole string, bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte) error | |
Get(role string, containerRole string) (bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte, err error) | |
} |
depending on how useful it would be for mocking in the tests the interface can be split into *Getter
(eg. doReseal only uses Get(), and *Updater
and then have one interface combining the two. Although looking at test changes it's probably not worth it.
4fab00f
to
b467e2d
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
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 pass, bunch of comments and questions
return err | ||
} | ||
|
||
_, recoveryModels, recoveryPCRProfile, err := manager.Get("recover", "system-save") |
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.
gadget has constants for things like "system-save", I even wonder if we should give them a 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.
Yes we should. I think we have FIXMEs on the Set calls.
type StateUpdater func(role string, containerRole string, bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte) error | ||
type FDEStateManager interface { | ||
Update(role string, containerRole string, bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte) error | ||
Get(role string, containerRole string) (bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte, err 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.
not something we can do much about but is indeed not great that both things are called role, we need to be very careful
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 use types at least. Again, this is related to the FIXMEs on calls to Update.
overlord/fdestate/backend/reseal.go
Outdated
} | ||
} | ||
|
||
func resealKeyForBootChainsFDEHook(manager FDEStateManager, method device.SealingMethod, rootdir string, inputs resealInputs, opts resealOptions) 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 functions needs a new name no? is not really doing the reseal anymore?
overlord/fdestate/backend/reseal.go
Outdated
inputs resealInputs, | ||
opts resealOptions, | ||
) error { | ||
func resealKeyForBootChainsTPM(manager FDEStateManager, method device.SealingMethod, rootdir string, inputs resealInputs, opts resealOptions) 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.
same
overlord/fdestate/fdemgr.go
Outdated
unlocker boot.Unlocker | ||
m *FDEManager |
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 could be simplified to:
{
FDEManager
unlock bool
}
as we just check if unlocker is nil
overlord/fdestate/fdemgr.go
Outdated
|
||
func (m *unlockedStateManager) Update(role string, containerRole string, bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte) error { | ||
if m.unlocker != nil { | ||
m.m.state.Lock() |
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 would avoid the m.m here
return updateParameters(m.m.state, role, containerRole, bootModes, models, tpmPCRProfile) | ||
} | ||
|
||
func (m *unlockedStateManager) Get(role string, containerRole string) (bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte, err 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 testing
overlord/fdestate/fdestate.go
Outdated
var s FdeState | ||
err = st.Get(fdeStateKey, &s) | ||
if err != nil { | ||
return nil, nil, nil, 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.
as this is not tested
overlord/fdestate/fdestate.go
Outdated
return nil | ||
} | ||
|
||
func getParameters(st *state.State, role string, containerRole string) (bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte, err 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.
we have the manager now where get/updateParameters are called? can they become simply method on it?
} | ||
|
||
func (m *unlockedStateManager) Update(role string, containerRole string, bootModes []string, models []secboot.ModelForSealing, tpmPCRProfile []byte) error { | ||
if m.unlocker != 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.
so now we unlock to run reseal below, then lock/unlock to update, then lock/unlock again to get, then relock? can we avoid or coalesce some of these?
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 would have to bring the unlocker down. I think what we need to do use unlock while we calculate the profile. This is what takes time. Then we do not have to relock to Get/Update
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 it better to save the state after the Update or not? unlock does that too
otherwise we could give FDEStateManger interface a Unlock() (relock func()) method and indeed use it in the backend only when needed
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 sounds good. I will try that.
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 to do the unlocking only when calculating the profile. And put the unlocker into the FDEStateManager abstraction.
Instead of splitting completely FDE hook and TPM resealing, we split the calculation of role parameters, udpate the state, then do the resealing based on that state.
1a50feb
to
f981410
Compare
f981410
to
b753897
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, a few more cleanup comments
overlord/fdestate/fdemgr.go
Outdated
return m.GetParameters(role, containerRole) | ||
} | ||
|
||
func (m *unlockedStateManager) Unlock() { |
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 feels like returning the relock function or a nop function would be a bit simpler that needing to have a relock member?
overlord/fdestate/backend/reseal.go
Outdated
@@ -200,7 +191,7 @@ func resealKeys( | |||
pbcJSON, _ := json.Marshal(pbc) | |||
logger.Debugf("resealing (%d) to boot chains: %s", nextCount, pbcJSON) | |||
|
|||
err := resealRunObjectKeys(updateState, runOnlyPbc, pbc, inputs.signatureDBUpdate, authKeyFile, params.RoleToBlName) | |||
err := resealRunObjectKeys(manager, runOnlyPbc, pbc, inputs.signatureDBUpdate, params.RoleToBlName) |
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 seems these function also needs a new name, like updateRunObjectKeysProtectionProfile or something like that?
overlord/fdestate/backend/reseal.go
Outdated
@@ -227,7 +218,7 @@ func resealKeys( | |||
rpbcJSON, _ := json.Marshal(rpbc) | |||
logger.Debugf("resealing (%d) to recovery boot chains: %s", nextFallbackCount, rpbcJSON) | |||
|
|||
err := resealFallbackObjectKeys(updateState, rpbc, inputs.signatureDBUpdate, authKeyFile, params.RoleToBlName) | |||
err := resealFallbackObjectKeys(manager, rpbc, inputs.signatureDBUpdate, params.RoleToBlName) |
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.
same for this
Instead of splitting completely FDE hook and TPM resealing, we split the calculation of role parameters, udpate the state, then do the resealing based on that state.
This depends on #14305