Repository navigation
Add reencryption - #569
Add reencryption#569frederic-hoerni wants to merge 10 commits into
Conversation
3815939 to
731117d
Compare
|
Would be awesome if this go cryptsetup api was in its own repository. u-root and other projects would benefit of this as well |
0ba1781 to
d6ced40
Compare
@tlaurion, we have no plan for that at the moment. |
81a124a to
a95d46c
Compare
|
Please rebase on top of master (and expect conflicts). |
5f920db to
d95f727
Compare
f4029ad to
3176726
Compare
3176726 to
41dcfa7
Compare
This adds support for reencrypting active LUKS2 containers.
Main changes:
- API functions:
* ReencryptionForActiveVolume
* Initialize
* Resume
* Status
- Named LUKS2 tokens now may have 2 keyslots, which happens during
reencryption.
OpenRead now sets a shared lock on the LUKS2 container so that reencryption cannot happen while a StorageContainerReader is open.
97850e3 to
6bff423
Compare
| ) | ||
|
|
||
| const UsageActivate = ` | ||
| usage: secboot-tool activate [<options>] <device> <active-name> <unlock-key-hex> |
There was a problem hiding this comment.
Is this a debugging tool? Is there a plan to ship that?
I do not think we want any key in command line. Unless everything was running in pid namespaces, this is public information.
There was a problem hiding this comment.
This is a debugging tool. We do not plan to ship it for now.
valentindavid
left a comment
There was a problem hiding this comment.
Very quick pass. Just some questions and remark for now.
| "--token-replace", "/dev/null"); err == nil { | ||
| features |= FeatureTokenReplace | ||
| } | ||
| if _, err := cryptsetupCmd(nil, "--test-args", "reencrypt", "--keys-from-stdin-sizes", "1,2", |
There was a problem hiding this comment.
Just a note while reviewing. The feature is https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/958
There was a problem hiding this comment.
I suppose we should wait for this to land upstream before we ship that in snapd.
There was a problem hiding this comment.
I think it does not prevent merging this PR.
If cryptsetup is lacking the feature, then the following code:
reencryption, err := secboot.ReencryptionForActiveVolume(activeName)
will return this error: luks2 backend is missing the reencryption feature.
| "--key-file", "-", | ||
| "--batch-mode", | ||
| "--resume-only", | ||
| "--progress-frequency", "1", |
There was a problem hiding this comment.
I wonder if it is something we will want to configure in the future.
There was a problem hiding this comment.
I don't think there is a need for a higher frequency. If we later find a need for a lower frequency we will discuss it then.
It is also worth noting that this parameter is somewhat approximate. With a setting of 1 second, the actually observed period between 2 reports is between 1 and 3 seconds.
| } | ||
|
|
||
| // ReadCryptsetupStatus returns the cryptsetup status of an active dm volume | ||
| func ReadCryptsetupStatus(activeName string) (*CryptsetupStatus, error) { |
There was a problem hiding this comment.
I am a bit afraid about parsing that. it feels like it might change in the future.
Should we add a json output upstream?
There was a problem hiding this comment.
cryptsetup status has a --debug-json option that does not produce any json. Attempts to upstream might be unpredictable.
Besides, don't we have integration tests that would detect incompatible changes?
|
|
||
| // KeyslotNamesSortedById returns the token names sorted | ||
| // by their keyslot identifier (in ascending order) | ||
| // Assumption: there is only one keyslot by token |
There was a problem hiding this comment.
What is the reason to sort them? I wonder if we could use something different that is a bit more safe without this assumption.
There was a problem hiding this comment.
This is based on how cryptsetup is organized. They look at all possible slots and unlock the active ones in this order.
| case "online-reencrypt-v3": | ||
| return true | ||
| default: | ||
| continue |
There was a problem hiding this comment.
What if it is online-reencrypt-v4? We return false here.
There was a problem hiding this comment.
Ok we can accept these as well. v4 is not used at the moment, but I found that cryptsetup has a test that considers online-reencrypt-v999 correct.
|
|
||
| func Logf(level int, format string, v ...any) { | ||
| if level <= logLevelPolicy { | ||
| fmt.Fprintf(os.Stderr, format, v...) |
There was a problem hiding this comment.
I think we need to be able to initialized the output from snapd.
There was a problem hiding this comment.
I added SetOuput.
There was a problem hiding this comment.
I meant "SetOutput":
func SetOutput(newOutput io.Writer)` { ... }
| if len(i.keyslotIds) == 1 { | ||
| return i.keyslotIds[0] | ||
| } else { | ||
| return luks2.AnySlot |
There was a problem hiding this comment.
Not sure if this the right return for len(i.keyslotIds) > 1. Do we verify somewhere else that we can have only 0 or 1?
There was a problem hiding this comment.
We can have 2 keyslots here. In that case, we cannot decide to choose one over the other. So we return Any.
There was a problem hiding this comment.
I added a description with this in mind.
| streamLines := func(pipe io.Reader, outputDone chan<- struct{}) { | ||
| scanner := bufio.NewScanner(pipe) | ||
| for scanner.Scan() { | ||
| rawBytes := scanner.Bytes() // should be in JSON format |
There was a problem hiding this comment.
So this is newline delimited json sequence? Go's json does not support json sequence for rfc7464?
There was a problem hiding this comment.
It is a newline delimited json sequence. But not rfc7464 as there is no ASCII Record Separator (0x1E).
Moreover we may also catch non-json errors here.
This lets the caller to change the default stderr log output.
This adds the feature of reencryption of active LUKS2 containers.
Main changes: