Skip to content

Add reencryption - #569

Open
frederic-hoerni wants to merge 7 commits into
masterfrom
feature/luks-reencryption
Open

frederic-hoerni wants to merge 7 commits into
masterfrom
feature/luks-reencryption

Conversation

@frederic-hoerni

@frederic-hoerni frederic-hoerni commented Sep 8, 2026 •

Copy link
Copy Markdown
Collaborator

This adds the feature of reencryption of active LUKS2 containers.

Main changes:

  • API functions:
    • ReencryptionForActiveVolume
    • Initialize
    • Resume
    • Status
  • Named tokens now may have 2 keyslots, which happens during reencryption.
  • OpenRead sets a shared lock on the LUKS2 container so that reencryption cannot happen while a StorageContainerReader is open.
  • Introduction of secboot-tool, that is a tool to test and illustrates high-level functions of secboot (mostly reencryption at the moment).

@frederic-hoerni
frederic-hoerni force-pushed the feature/luks-reencryption branch 2 times, most recently from 3815939 to 731117d Compare September 17, 2026 08:54
@frederic-hoerni frederic-hoerni changed the title Add reencryption API (MVP) Add reencryption Sep 17, 2026
@tlaurion

Copy link
Copy Markdown

Would be awesome if this go cryptsetup api was in its own repository. u-root and other projects would benefit of this as well

@frederic-hoerni
frederic-hoerni force-pushed the feature/luks-reencryption branch from 0ba1781 to d6ced40 Compare September 22, 2026 16:25
@frederic-hoerni

Copy link
Copy Markdown
Collaborator Author

Would be awesome if this go cryptsetup api was in its own repository

@tlaurion, we have no plan for that at the moment.

@frederic-hoerni
frederic-hoerni force-pushed the feature/luks-reencryption branch from 81a124a to a95d46c Compare September 23, 2026 08:32
@frederic-hoerni
frederic-hoerni marked this pull request as ready for review September 24, 2026 06:34
@frederic-hoerni frederic-hoerni self-assigned this Sep 24, 2026
Comment thread internal/luksview/tokens_test.go
Comment thread internal/luks2/cryptsetup.go Outdated
Comment thread luks2/backend.go
Comment thread keydata_luks.go Outdated
@frederic-hoerni

Copy link
Copy Markdown
Collaborator Author

Please rebase on top of master (and expect conflicts).

@ruifm ruifm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great!

Comment thread internal/luks2/cryptsetup.go Outdated
Comment thread luks2/reencrypt.go
Comment thread reencrypt.go
Comment thread luks2/luks2_test.go
Comment thread luks2/reencrypt.go
Comment thread luks2/reencrypt.go
Comment thread luks2/reader.go Outdated
Comment thread internal/luks2/cryptsetup.go
@frederic-hoerni
frederic-hoerni force-pushed the feature/luks-reencryption branch from 5f920db to d95f727 Compare September 30, 2026 07:22

@ruifm ruifm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@frederic-hoerni
frederic-hoerni force-pushed the feature/luks-reencryption branch from f4029ad to 3176726 Compare September 30, 2026 12:44
@frederic-hoerni
frederic-hoerni force-pushed the feature/luks-reencryption branch from 3176726 to 41dcfa7 Compare September 30, 2026 13:58
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.
@frederic-hoerni
frederic-hoerni force-pushed the feature/luks-reencryption branch from 97850e3 to 6bff423 Compare October 1, 2026 09:47
)

const UsageActivate = `
usage: secboot-tool activate [<options>] <device> <active-name> <unlock-key-hex>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@valentindavid valentindavid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note while reviewing. The feature is https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/958

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we should wait for this to land upstream before we ship that in snapd.

"--key-file", "-",
"--batch-mode",
"--resume-only",
"--progress-frequency", "1",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it is something we will want to configure in the future.

}

// ReadCryptsetupStatus returns the cryptsetup status of an active dm volume
func ReadCryptsetupStatus(activeName string) (*CryptsetupStatus, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit afraid about parsing that. it feels like it might change in the future.

Should we add a json output upstream?

Comment thread internal/luksview/view.go

// KeyslotNamesSortedById returns the token names sorted
// by their keyslot identifier (in ascending order)
// Assumption: there is only one keyslot by token

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason to sort them? I wonder if we could use something different that is a bit more safe without this assumption.

Comment thread internal/luksview/view.go
case "online-reencrypt-v3":
return true
default:
continue

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if it is online-reencrypt-v4? We return false here.

Comment thread log/log.go

func Logf(level int, format string, v ...any) {
if level <= logLevelPolicy {
fmt.Fprintf(os.Stderr, format, v...)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to be able to initialized the output from snapd.

Comment thread luks2/keyslot.go
if len(i.keyslotIds) == 1 {
return i.keyslotIds[0]
} else {
return luks2.AnySlot

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Comment thread luks2/reencrypt.go
streamLines := func(pipe io.Reader, outputDone chan<- struct{}) {
scanner := bufio.NewScanner(pipe)
for scanner.Scan() {
rawBytes := scanner.Bytes() // should be in JSON format

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is newline delimited json sequence? Go's json does not support json sequence for rfc7464?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants