Skip to content

Commit 831466a

Browse files
black-dragon74mergify[bot]
authored andcommitted
util: optimize key rotation flow for cryptsetup
This patch adds the missing memory limits to cryptsetup `AddKey`. If this limit is missing `cryptsetup` will determine its own limits in order to satisfy the KDF, which can lead to serious resource contentions, IOW, more power the system has, more resources will be used (this is intentional). `Open` and `RemoveKey` use the memory limits(set when format/adding) from the existing headers on the device and hence do not require manual limits. A limit on active threads is also enforced to run KDF on a single thread, reducing CPU contention when a lot of processes are active at the same time. Additionally, use the `--test-passphrase` with `open` for verification instead of calling `changeKey` with same passphrase to save on unnecessary derivations and disk IO (test-passphrase is read only). Signed-off-by: Niraj Yadav <niryadav@redhat.com>
1 parent c925e81 commit 831466a

1 file changed

Lines changed: 15 additions & 2 deletions

File tree

internal/util/cryptsetup/cryptsetup.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ const (
3939
// Maximum time to wait for cryptsetup commands to complete.
4040
ExecutionTimeout = 2*time.Minute + 30*time.Second
4141

42+
// Limit PBKDF parallel threads to 1 to reduce CPU contention
43+
// when many cryptsetup processes run concurrently.
44+
cryptsetupPBKDFParallelLimit = 1
45+
4246
// Limit memory used by Argon2i PBKDF to 32 MiB.
4347
cryptsetupPBKDFMemoryLimit = 32 << 10 // 32768 KiB
4448
luks2MetadataSize = 32 << 7 // 4096 KiB
@@ -580,6 +584,8 @@ func (l *luksWrapper) Format(devicePath, passphrase string, cipherOptions *Encry
580584
strconv.Itoa(luks2KeySlotsSize)+"k",
581585
"--pbkdf-memory",
582586
strconv.Itoa(cryptsetupPBKDFMemoryLimit),
587+
"--pbkdf-parallel",
588+
strconv.Itoa(cryptsetupPBKDFParallelLimit),
583589
devicePath,
584590
"-d",
585591
"-")
@@ -635,6 +641,10 @@ func (l *luksWrapper) AddKey(devicePath, passphrase, newPassphrase, slot string)
635641
"--verbose",
636642
"--key-file="+passFile.Name(),
637643
"--key-slot="+slot,
644+
"--pbkdf-memory",
645+
strconv.Itoa(cryptsetupPBKDFMemoryLimit),
646+
"--pbkdf-parallel",
647+
strconv.Itoa(cryptsetupPBKDFParallelLimit),
638648
"luksAddKey",
639649
devicePath,
640650
newPassFile.Name(),
@@ -720,14 +730,17 @@ func (l *luksWrapper) VerifyKey(devicePath, passphrase, slot string) (bool, erro
720730
}
721731
defer os.Remove(keyFile.Name()) //nolint:errcheck // failed to delete temp file :-(
722732

733+
// Use "open --test-passphrase" instead of "luksChangeKey" to avoid
734+
// an unnecessary PBKDF write derivation. --test-passphrase only
735+
// derives the key once (read-only) to verify it matches the slot.
723736
_, stderr, err := l.execCryptsetupCommand(
724737
nil,
725738
"--verbose",
726739
"--key-file="+keyFile.Name(),
727740
"--key-slot="+slot,
728-
"luksChangeKey",
741+
"open",
742+
"--test-passphrase",
729743
devicePath,
730-
keyFile.Name(),
731744
)
732745
if err != nil {
733746
// If the passphrase doesn't match the key in given slot

0 commit comments

Comments
 (0)