#1109055 clevis-initramfs: Possible LUKS2 passphrase lockout if clevis token is not bound to a keyslot

Package:
clevis-initramfs
Source:
clevis-initramfs
Description:
Clevis initramfs integration
Submitter:
Wolfgang Zarre
Date:
2025-07-11 12:27:02 UTC
Severity:
normal
Tags:
#1109055#5
Date:
2025-07-10 13:59:28 UTC
From:
To:
Dear Maintainer,

I discovered, that clevis LUKS2 decrypt will block the possibility to enter a passphrase
if a clevis token is not bound to a LUKS2 keyslot.

After several decryption retries it will end up at the initramfs prompt.

The root cause is that in the initrd script scripts/local-top/clevis in function
luks2_decrypt existing unbound clevis tokens are not filtered but then decrypted
and passed to PASSFIFO.

It is reproducible with clevis luks bind, e.g.:
clevis luks bind -f -y -k <our-keyfile> -d <root_device> tpm2 <PCR_bind>

Then removing the keyslot of a token/keyslot pair with:
cryptsetup luksKillSlot <root_device>  <keyslot number>

With cryptsetup luksDump <root_device> you would see then e.g.:
...
Tokens:
   0: clevis
Digests:
...

After a reboot obviously clevis cannot decrypt but furthermore, it is impossible
to enter the passphrase.


Suggestion to fix:
---------------------------------------------------------------
--- /usr/share/initramfs-tools/scripts/local-top/clevis
+++ /usr/share/initramfs-tools/scripts/local-top/clevis
@@ -78,7 +78,8 @@ luks1_decrypt() {
  luks2_decrypt() {
      local CRYPTTAB_SOURCE=$1
      local PASSFIFO=$2
-    cryptsetup luksDump "$CRYPTTAB_SOURCE" | sed -rn 's|^\s+([0-9]+): clevis|\1|p' | while read -r
id; do
+    # Just utilise keyslot assigned token
+    cryptsetup luksDump "$CRYPTTAB_SOURCE" | awk '{ if( $1 == "Keyslot:" && token == "clevis" && id
 >= 0 && $2 >= 0 ) {printf( "%d\n", id);}; id = $1; token = $2 ;}' | while read -r id ; do
          # jose jwe fmt -c outputs extra \n, so clean it up
          cte=$(cryptsetup token export --token-id "$id" "$CRYPTTAB_SOURCE")
          [ $? -eq 0 ] || continue
---------------------------------------------------------------

This could be also fixed with a bash loop without awk or sed if a newer bash syntax would be ok.


Cheers,
Wolf

#1109055#10
Date:
2025-07-10 20:41:11 UTC
From:
To:
Wolfgang Zarre wrote...

Thanks for catching this, I brought the issue to upstream.

    Christoph

#1109055#19
Date:
2025-07-11 12:25:23 UTC
From:
To:
Hi,

[src:cryptsetup co-maintainer here, thanks Christoph for bringing this
issue to my attention.]

`cryptsetup luksDump` output has been rather stable in practice, but
AFAIK upstream provides no guaranty about stability and machine-readable
output.  If support for cryptsetup <2.4.0 (released Aug 2021) is not
needed I'd suggest to use the `--dump-json-metadata` flag to dump the
header JSON metadata area, and massage the JSON output instead.  (Note
that the command fails on LUKS1 devices though.)

Schema for the LUKS2 header JSON metadata area is documented in §2.2 of
the LUKS2 specification: https://gitlab.com/cryptsetup/LUKS2-docs .