--key-slot option for cryptsetup open has no effect
Issue description
The description of --key-slot indicates that it will test the passphrase against that key slot and no other key slots. In practice, the key-slot option does not change the behavior of cryptsetup open, and the volume will be opened using a different key-slot regardless.
My understanding is based on this section of cryptsetup-open(8)
:
--key-slot, -S <0-N>
This option selects a specific key-slot to compare the passphrase against. If the
given passphrase would only match a different key-slot, the operation fails.
Steps for reproducing the issue
My volume has three active keyslots:
- unlocked with passphrase
- unlocked with fido2 key
- unlocked with tpm2 device
Without --key-slot, first with fido2 key present and then not present
$ sudo cryptsetup --verbose open --type=luks2 --test-passphrase /dev/nvme1n1p2
Asking FIDO2 token for authentication.
👆 Please confirm presence on security token to unlock.
Key slot 1 unlocked.
Command successful.
$ sudo cryptsetup --verbose open --type=luks2 --test-passphrase /dev/nvme1n1p2
Key slot 2 unlocked.
Command successful.
Again with --key-slot
$ sudo cryptsetup --verbose open --type=luks2 --test-passphrase --key-slot=0 /dev/nvme1n1p2
Asking FIDO2 token for authentication.
👆 Please confirm presence on security token to unlock.
Key slot 1 unlocked.
Command successful.
$ sudo cryptsetup --verbose open --type=luks2 --test-passphrase --key-slot=0 /dev/nvme1n1p2
Key slot 2 unlocked.
Command successful.
With the incorrect fido2 key present:
$ sudo cryptsetup --verbose open --type=luks2 --test-passphrase --key-slot=1 /dev/nvme1n1p2
Asking FIDO2 token for authentication.
👆 Please confirm presence on security token to unlock.
Wrong security token; needed credentials not present on token.
Key slot 2 unlocked.
Command successful.
$ sudo cryptsetup --verbose open --type=luks2 --test-passphrase --key-slot=2 /dev/nvme1n1p2
Asking FIDO2 token for authentication.
👆 Please confirm presence on security token to unlock.
Wrong security token; needed credentials not present on token.
Key slot 2 unlocked.
Command successful.
The key-slot option has absolutely no effect.
Additional info
Package versions:
$ pacman -Q linux systemd cryptsetup
linux 6.0.8.arch1-1
systemd 252.1-1
cryptsetup 2.5.0-4
$ uname -r
6.0.8-arch1-1
This volume is currently my active rootfs:
$ sudo cryptsetup status root
/dev/mapper/root is active and is in use.
type: LUKS2
cipher: aes-xts-plain64
keysize: 512 bits
key location: keyring
device: /dev/nvme1n1p2
sector size: 512
offset: 32768 sectors
size: 3905970176 sectors
mode: read/write
flags: discards no_read_workqueue no_write_workqueue
$ systemctl cat /
# /run/systemd/generator/-.mount
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-mapper-root.target
[Mount]
What=/dev/mapper/root
Where=/
Type=btrfs
Options=rw,noatime,space_cache=v2,subvol=/subroot
Debug log
Full debug output for the last case, --key-slot=0, wrong fido2 key, finally unlocks with tpm2 in keyslot 2:
$ sudo cryptsetup --verbose open --type=luks2 --test-passphrase --key-slot=0 --debug /dev/nvme1n1p2
# cryptsetup 2.5.0 processing "cryptsetup --verbose open --type=luks2 --test-passphrase --key-slot=0 --debug /dev/nvme1n1p2"
# Verifying parameters for command open.
# Running command open.
# Locking memory.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Allocating context for crypt device /dev/nvme1n1p2.
# Trying to open and read device /dev/nvme1n1p2 with direct-io.
# Initialising device-mapper backend library.
# Trying to load LUKS2 crypt type from device /dev/nvme1n1p2.
# Crypto backend (OpenSSL 3.0.7 1 Nov 2022 [default][legacy]) initialized in cryptsetup library version 2.5.0.
# Detected kernel Linux 6.0.8-arch1-1 x86_64.
# Loading LUKS2 header (repair disabled).
# Acquiring read lock for device /dev/nvme1n1p2.
# Opening lock resource file /run/cryptsetup/L_259:2
# Verifying lock handle for /dev/nvme1n1p2.
# Device /dev/nvme1n1p2 READ lock taken.
# Trying to read primary LUKS2 header at offset 0x0.
# Opening locked device /dev/nvme1n1p2
# Verifying locked device handle (bdev)
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:ce7e8e208bec4a0daf401e1fccb8ae80378b2ee1d5032d6fa4d9293be26a826c (on-disk)
# Checksum:ce7e8e208bec4a0daf401e1fccb8ae80378b2ee1d5032d6fa4d9293be26a826c (in-memory)
# Trying to read secondary LUKS2 header at offset 0x4000.
# Reusing open ro fd on device /dev/nvme1n1p2
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:40a3e37b885284a9950dbeb651dc33ccd02691a965324b9983d880aefcd045da (on-disk)
# Checksum:40a3e37b885284a9950dbeb651dc33ccd02691a965324b9983d880aefcd045da (in-memory)
# Device size 1999873507328, offset 16777216.
# Device /dev/nvme1n1p2 READ lock released.
# PBKDF argon2id, time_ms 2000 (iterations 0), max_memory_kb 1048576, parallel_threads 4.
# Checking volume passphrase using token (any type) -1.
# Token 0 unusable for segment -1 with desired keyslot priority 2.
# Token 1 unusable for segment -1 with desired keyslot priority 2.
# Trying to load /usr/lib/cryptsetup/libcryptsetup-token-systemd-fido2.so.
# Loading symbol cryptsetup_token_open@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_buffer_free@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_validate@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_dump@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_open_pin@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_version@CRYPTSETUP_TOKEN_1.0.
# Token handler systemd-fido2-1.0 systemd-v252 (252.1-1-arch) loaded successfully.
# Requesting JSON for token 0.
Asking FIDO2 token for authentication.
👆 Please confirm presence on security token to unlock.
Wrong security token; needed credentials not present on token.
# Token 0 (systemd-fido2) open failed with -11.
# Trying to load /usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so.
# Loading symbol cryptsetup_token_open@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_buffer_free@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_validate@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_dump@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_open_pin@CRYPTSETUP_TOKEN_1.0.
# Loading symbol cryptsetup_token_version@CRYPTSETUP_TOKEN_1.0.
# Token handler systemd-tpm2-1.0 systemd-v252 (252.1-1-arch) loaded successfully.
# Requesting JSON for token 1.
# Trying to open keyslot 2 with token 1 (type systemd-tpm2).
# Trying to open LUKS2 keyslot 2.
# Running keyslot key derivation.
# Reading keyslot area [0x86000].
# Acquiring read lock for device /dev/nvme1n1p2.
# Opening lock resource file /run/cryptsetup/L_259:2
# Verifying lock handle for /dev/nvme1n1p2.
# Device /dev/nvme1n1p2 READ lock taken.
# Reusing open ro fd on device /dev/nvme1n1p2
# Device /dev/nvme1n1p2 READ lock released.
# Verifying key from keyslot 2, digest 0.
# dm version [ opencount flush ] [16384] (*1)
# dm versions [ opencount flush ] [16384] (*1)
# Detected dm-ioctl version 4.47.0.
# Detected dm-crypt version 1.24.0.
# Device-mapper backend running with UDEV support enabled.
Key slot 2 unlocked.
# Releasing crypt device /dev/nvme1n1p2 context.
# Releasing device-mapper backend.
# Closing read only fd for /dev/nvme1n1p2.
# Unlocking memory.
Command successful.
# Unloading systemd-tpm2 token handler.
# Unloading systemd-fido2 token handler.