Use argon2 for LUKS2 volume with TPM+PIN

Hi there,

I recently decided to switch to EOS as my main distro and it’s been great so far. I’ve enabled full disk encryption during the installation process, but I got tired of typing in my passphrase on every boot, so I looked for a possibility to use the TPM in my laptop in combination with a PIN, similar to Bitlocker with TPM+PIN on Windows. I managed to get it working using the following blogpost (sorry, it’s in german) and the Arch wiki entry for systemd-cryptenroll:

As stated, this works fine, but when I look at the LUKS dump, it shows that the second keyslot, which is the token released by the TPM when the correct PIN is entered, is using pbkdf2 with only 1000 iterations which is, in my understanding, quite low and makes brute forcing the key easier. The first keyslot, which is the passphrase I set up when installing the system, uses argon2id by default, which seems to be widely accepted as the better alternative.

I’d like to know if there’s a possibility to use argon2id instead of pbkdf2 for the TPM token as well and if so, can I just “change” the KDF without issues? Any help would be appreciated.

If there are any important details missing just let me know and I’ll try to provide them.

You seem to understand german. In that I case I suggest to read this article

https://www.heise.de/select/ct/2023/14/2311808433263322621

You can eventually try what they suggest:

sudo cryptsetup luksConvertKey  /dev/DEVICE --pbkdf argon2id

You can read more about this command here: man cryptsetup-luksConvertKey

Thanks for the fast reply! I read the article and two questions came up:

  1. Is this change transparent to the TPM? This seems simple enough for a “normal” passphrase, but since the key in the second keyslot comes from the TPM, will it still work if I just change the KDF? Sorry if this is a stupid question, I’m still trying to figure out how all of this is working together.
  2. The article says when using the luksConvertKey command, you have to enter an existing passphrase which then decides which keyslot will be updated. But since the passphrase for the slot in question comes from the TPM and I don’t actually know it, how can I tell the command which keyslot needs to be updated? The manpage says I can specify the slot with --key-slot, but I’ll still have to enter the passphrase.

While reading more about this topic I wonder if the low iterations is really a problem at all.

Look at this thread:

https://lwn.net/Articles/929343/

Two users are saying the following:

systemd-cryptenroll generates a random key to encrypt the LUKS volume so the KDF function does not matter much. The key is sealed by the TPM and protected with a pin. The TPM limits the number of attempts to get the key to one every 10 minutes or so (it’s configurable), making dictionary or brute-force attacks impractical (as long as the pin is not too short or simple).

and

The KDF doesn’t really matter if the input is already a strong key, such as a truly random recovery key or anything that comes out of FIDO, TPM, etc. You could use these directly as keys, if only cryptsetup let you (t doesn’t, LUKS2 always wants a KDF). If you enroll a passphrase systemd-cryptenroll will pick argon2id, at least in recent versions.