Unlocking of LUKS-encrypted volumes by using TPM 2.0

I’m testing MicroOS and I still don’t really know what I can do and what I can’t.
I would like to be able to unlock my LUKS volumes on boot using TPM 2.0 and thus not have to enter the password manually. There are 2 methods to do this: systemd-cryptenroll and clevis.

  • systemd-cryptenroll requires to modify /etc/crypttab. I think it is not possible to modify this file using MicroOS. Does anyone know how to do it?

  • Clevis uses commands similar to these:

sudo clevis luks bind -d /dev/sda2 tpm2 '{"hash":"sha256","key":"rsa","pcr_bank":"sha256","pcr_ids":"0,1"}'
sudo dracut -fv --regenerate-all

I think the clevis method could work. Someone has tried? I’m thinking of doing it in a virtual machine.

PS: I know that MicroOS implements remote attestation, but I would like to make it local, and without relying on third parties.

References:
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/configuring-automated-unlocking-of-encrypted-volumes-using-policy-based-decryption_security-hardening#configuring-manual-enrollment-of-volumes-using-tpm2_configuring-automated-unlocking-of-encrypted-volumes-using-policy-based-decryption
https://kowalski7cc.xyz/blog/luks2-tpm2-clevis-fedora31
https://wiki.archlinux.org/title/Trusted_Platform_Module
http://0pointer.net/blog/unlocking-luks2-volumes-with-tpm2-fido2-pkcs11-security-hardware-on-systemd-248.html

1 Like

I have managed to install clevis-luks. I’ve downloaded the following rpm’s:
libjose0
libluksmeta0
libtss2-rc0
libtss2-tctildr0
jose
luksmeta
libtss2-fapi1
tpm2.0-tools
clevis
clevis-luks

Then:

sudo transactional-update pkg install libjose0* libluksmeta0* libtss2-rc0 libtss2-tctildr0 jose* luksmeta* libtss2-fapi1 tpm2.0-tools clevis* clevis-luks*

The problem:

$ sudo tpm2_pcrread
ERROR:tcti:src/tss2-tcti/tctildr-dl.c:254:tctildr_get_default() No standard TCTI could be loaded 
ERROR:tcti:src/tss2-tcti/tctildr.c:428:Tss2_TctiLdr_Initialize_Ex() Failed to instantiate TCTI 
ERROR: Could not load tcti, got: "(null)"

$ sudo clevis-luks-bind -d /dev/nvme0n1p2 tpm2 '{"hash":"sha256","key":"rsa","pcr_bank":"sha256","pcr_ids":"0,7"}'
Enter existing LUKS password: 
You are about to initialize a LUKS device for metadata storage.
Attempting to initialize it may result in data loss if data was
already written into the LUKS header gap in a different format.
A backup is advised before initialization is performed.

Do you wish to initialize /dev/nvme0n1p2? [yn] y
Warning: Value 512 is outside of the allowed entropy range, adjusting it.
ERROR:tcti:src/tss2-tcti/tctildr.c:428:Tss2_TctiLdr_Initialize_Ex() Failed to instantiate TCTI 
ERROR: Could not load tcti, got: "device:/dev/tpmrm0"
Creating TPM2 primary key failed!
Error reading from standard input
Error saving metadata to LUKSMeta slot 1 from /dev/nvme0n1p2
Unable to update metadata; operation cancelled
Error adding new binding to /dev/nvme0n1p2

I don’t know if it’s because I’m using a Virtualbox virtual machine.

Additional info:

$ dmesg | grep -i tpm
     0.000000] efi: ACPI=0xdef7e000 ACPI 2.0=0xdef7e014  TPMFinalLog=0xdefd6000 SMBIOS=0xdefd5000 MOKvar=0xdd925000  TPMEventLog=0xdd7ce018 
    0.020801] ACPI: TPM2 0x00000000DEF77000 000034 (v04 VBOX   VBOXTPM2 00000001 ASL  00000061)
    0.020802] ACPI: SSDT 0x00000000DEF76000 000124 (v01 VBOX   VBOXTPMT 00000002 INTL 20200925)
    0.020810] ACPI: Reserving TPM2 table memory at [mem 0xdef77000-0xdef77033]
    0.344718] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0x0, rev-id 1)
     0.710131] systemd[1]: systemd 252.2+suse.29.ge7e931b07e running in  system mode (+PAM +AUDIT +SELINUX +APPARMOR -IMA -SMACK +SECCOMP +GCRYPT  +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC  +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2  +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT  default-hierarchy=unified)
    4.763768] systemd[1]: systemd  252.2+suse.29.ge7e931b07e running in system mode (+PAM +AUDIT +SELINUX  +APPARMOR -IMA -SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID  +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK  +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD  +BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT  default-hierarchy=unified)
$ cat /sys/class/tpm/tpm*/tpm_version_major
2
$ sudo journalctl -k --grep=tpm
dic 06 20:16:06 MicroOS-1 kernel: efi: ACPI=0xdef7e000 ACPI 2.0=0xdef7e014 TPMFinalLog=0xdefd6000 SMBIOS=0xdefd5000 MOKvar=0xdd925000 TPMEventLog=0xdd7ce018 
dic 06 20:16:06 MicroOS-1 kernel: ACPI: TPM2 0x00000000DEF77000 000034 (v04 VBOX   VBOXTPM2 00000001 ASL  00000061)
dic 06 20:16:06 MicroOS-1 kernel: ACPI: SSDT 0x00000000DEF76000 000124 (v01 VBOX   VBOXTPMT 00000002 INTL 20200925)
dic 06 20:16:06 MicroOS-1 kernel: ACPI: Reserving TPM2 table memory at [mem 0xdef77000-0xdef77033]
dic 06 20:16:06 MicroOS-1 kernel: tpm_tis MSFT0101:00: 2.0 TPM (device-id 0x0, rev-id 1)
dic 06 20:16:06 MicroOS-1 systemd[1]: systemd 252.2+suse.29.ge7e931b07e running in system mode (+PAM +AUDIT +SELINUX +APPARMOR -IMA -SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
dic 06 20:16:11 MicroOS-1 systemd[1]: systemd 252.2+suse.29.ge7e931b07e running in system mode (+PAM +AUDIT +SELINUX +APPARMOR -IMA -SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
$ sudo systemd-cryptenroll --tpm2-device=list
PATH        DEVICE      DRIVER 
/dev/tpmrm0 MSFT0101:00 tpm_tis

I have made progress. The error was because I needed to install a package.

sudo transactional-update pkg install libtss2-tcti-device0
$ sudo tpm2_pcrread  sha1:
    0 : 0x0DFF02BF3D69516D6454741DBA43045A3E4B51EC
    1 : 0x225A50B3AF2591AC789F30C9F5AAF83BA21B18EB
    2 : 0xB2A83B0EBF2F8374299A5B2BDFC31EA955AD7236
    3 : 0xB2A83B0EBF2F8374299A5B2BDFC31EA955AD7236
    4 : 0x7D6FB2B2DBE24EAA03F922701B6B0FDC45CD9A2A
    5 : 0x34A4956683FA134CA242F6E885C58CD7BFF70944
    6 : 0xB2A83B0EBF2F8374299A5B2BDFC31EA955AD7236
    7 : 0xB6E0E51FB9078FFCCBB06EC47AAC58E199C15069
    8 : 0x8D5FF7A6F31336B1BE2C165E45FF0AFF7B7D36EE
    9 : 0x21ACFDBB2F9C70DB72D211E61A3D3F246462656B
    10: 0x15AF12C0DB16B4B310D80BC80EE6BBB994C66FF2
    11: 0x0000000000000000000000000000000000000000
    12: 0x0000000000000000000000000000000000000000
    13: 0x0000000000000000000000000000000000000000
    14: 0x96C4C89B9D431EC7A2FDE1FE5DCF91C53B2A2EBC
    15: 0x0000000000000000000000000000000000000000
    16: 0x0000000000000000000000000000000000000000
    17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    23: 0x0000000000000000000000000000000000000000
$ sudo clevis-luks-bind -d /dev/nvme0n1p2 tpm2 '{"hash":"sha256","key":"rsa","pcr_bank":"sha256","pcr_ids":"0,7"}'Enter existing LUKS password: 
Warning: Value 512 is outside of the allowed entropy range, adjusting it.
$ sudo clevis-luks-list -d /dev/nvme0n1p2
1: tpm2 '{"hash":"sha256","key":"rsa","pcr_bank":"sha256","pcr_ids":"0,7"}'
$ sudo clevis-luks-list -d /dev/nvme0n1p3
1: tpm2 '{"hash":"sha256","key":"rsa","pcr_bank":"sha256","pcr_ids":"0,7"}'
sudo dracut -fv --regenerate-alldracut: Executing: /usr/bin/dracut --kver=6.0.10-1-default -fv
dracut: No permission to write to /boot.
sudo transactional-update run dracut -fv --regenerate-all

I no longer have any errors. However, it keeps asking for the 2 passwords on boot.

There is no need to use bold. Besides it is absolutely unclear what you expected - no questions, one question, three questions? Are “two passwords” for the same encrypted device or for different devices? You show some commands without explaining your overall configuration, so it is impossible to understand what these commands are supposed to achieve, nor do you explain what you expect from these commands.

I have used bold because it is the summary of the whole thread. I have been putting commands and their outputs in case someone was encouraged to help me, that he had enough information and thus save time. I make a summary of what I have done so far.

  1. I download the 6 packages that are not in the official repository:
    libjose0
    libluksmeta0
    jose
    luksmeta
    clevis
    clevis-luks
  2. I’ve installed the necessary packages without errors:
sudo transactional-update pkg install libtss2-rc0 libtss2-tctildr0 libtss2-fapi1 tpm2.0-tools libtss2-tcti-device0 libjose0* libluksmeta0* jose* luksmeta* clevis* clevis-luks*

→ Reboot

  1. I run the clevis commands:
sudo clevis-luks-bind -d /dev/nvme0n1p2 tpm2 '{"hash":"sha256","key":"rsa","pcr_bank":"sha256","pcr_ids":"0,7"}
sudo clevis-luks-bind -d /dev/nvme0n1p3 tpm2 '{"hash":"sha256","key":"rsa","pcr_bank":"sha256","pcr_ids":"0,7"}
  1. I verify that they have been executed correctly:
sudo clevis-luks-list -d /dev/nvme0n1p2
sudo clevis-luks-list -d /dev/nvme0n1p3
  1. I regenerate the linux boot image:
sudo transactional-update run dracut -fv --regenerate-all

–> Reboot

So far, apparently everything is correct and without errors. However, I have not achieved my goal, which was to have the encrypted partitions automatically unlocked by TPM2.0. When booting it keeps asking for a password before grub and another after grub.

I had only tried the method with Clevis so far. I’ve tried the systemd-cryptenroll method now and got to a point where I don’t know how to continue.

According to the arch wiki, tpm2-tss must be installed:

sudo transactional-update pkg install tpm2-0-tss

Some tweaks need to be made to the initramfs, dracut users may enable the tpm2-tss module:

sudo transactional-update --continue run vim /etc/dracut.conf.d/myflags.conf
add_dracutmodules+=" tpm2-tss "

Commands for binds the key to PCRs 0 and 7 (the system firmware and Secure Boot state):

sudo transactional-update --continue run systemd-cryptenroll --tpm2-device=/dev/tpmrm0 --tpm2-pcrs=0+7 /dev/nvme0n1p2
sudo transactional-update --continue run systemd-cryptenroll --tpm2-device=/dev/tpmrm0 --tpm2-pcrs=0+7 /dev/nvme0n1p3

I edit /etc/crypttab

sudo transactional-update --continue run vim /etc/crypttab
cr_root  UUID=4add01e2-df1d-4d19-86cb-7284a4702847  none  x-initrd.attach,tpm2-device=/dev/tpmrm0
cr_home  UUID=d9dd6a80-c94b-4ee9-94e5-fe5d24f711f4

According to the arch wiki:

If the volume you wish to unlock contains your root file system, you must take the following additional steps:


  - Ensure you are using systemd and sd-encrypt in the HOOKS array of /etc/mkinitcpio.conf
  - Configure your initramfs to unlock the root volume with one of the following methods:
[LIST]
  - Specifying the root volume using the configuration outlined above in /etc/crypttab.initramfs (see tip at the top of [dm-crypt/System configuration#Using systemd-cryptsetup-generator](https://wiki.archlinux.org/title/Dm-crypt/System_configuration#Using_systemd-cryptsetup-generator))
  - Setting rd.luks.options=*XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX*
=tpm2-device=auto in addition to rd.luks.uuid or rd.luks.name in the kernel command line

[/LIST]

I can’t find the file /etc/mkinitcpio.conf and I don’t know how to configure your initramfs to unlock the root volume.
Maybe that’s why it doesn’t work for me:

https://i.imgur.com/1QtcjpS.png

https://i.imgur.com/JOvhqcE.png

https://i.imgur.com/XzqWy8m.png

I’m still trying to understand the sense of it all.
What is the use of encrypting the disk and than decrypting it automatically for everyone,
who is able to press the “Power On” button?

The meaning is that if you boot from a live USB you can’t access my data because it’s encrypted, and if you boot from MicroOS, it will ask you for the user password and you won’t be able to access it either. So the files are not accessible, am I wrong?

1 Like

Thanks. Understood the use cases.

Hi
Is/can the /etc/crypttab manually created? If so then you could use ignition to create on install of MicroOS.

You do not explain anything by repeatedly posting the same information over and over again.

Anyway - clevis plugs into systemd password agent framework. There could be any number of password agents and all of them will process the same password request concurrently. By default either tty password agent or plymouth password agent are started on boot and they will display password prompt. Clevis will also act on the same password request and unlock device without user interaction. Even if password request is answered by clevis, password request on plain console can no more be erased. And Plymouth continues to display passphrase request even though it is already answered. I do not know whether this is systemd bug (password request is not deleted) or Plymouth bug. If you are concerned, debug, find out, file bug report.

For this to work you need clevis systemd units which are packaged separately in clevis-systemd. And of course if you want to unlock root filesystem you need dracut integration which again is packaged separately as clevis-dracut.

  1. Data at rest encryption - if you return HDD for RMA, nobody can read data on it (hopefully).
  2. Evil maid aversion - if someone boots your notebook with USB key, it will not be decrypted. If you bind LUKS key to TPM registers that depend on it.
    In this particular example PCR registers 0 and 7 only reflect BIOS state (basically, sort of BIOS guard) and do not protect against this threat.

And if you just switch on you won’t have any environment to access data - you will need to log in first. Hopefully you do not use auto-logon with disk encryption.

How is it relevant to the question?

You forgot to explain what exactly is wrong on this pictures or what you expected.

For a few days I had not been able to enter this thread.
I made a summary of what I have done, in case someone can help me that person can see what I have done. I try to provide a history.
I had already tried installing the clevis-dracut, clevis-systemd and clevis-systemd-ask-password-plymouth packages. The problem remains the same. At system startup, luks volumes are not unlocked automatically. I have tried with clevis and systemd-cryptenroll.
I’m not a computer scientist, if I don’t even know enough to make it work, it’s impossible for me to debug code. I don’t know how to report bugs, nor do I feel qualified to do so because I don’t know if it’s a bug or that I make a mistake in the process (that’s why I put the history of what I’ve done :slight_smile: ).
If someone could install MicroOS in a virtual machine with the encrypted ROOT unit and try to decrypt the encrypted volume using some automatic method, it would help me to know if I’m alone in this or if it happens to more people.

What PCR registers would you use?

In the screenshots I show how the boot process is. It asks me for 1 password, goes to grub and then asks me for the password again. That is, it does not unlock automatically and, to top it off, it asks me for the password 2 times.

And I tested clevis and at system startup volumes that I configured are unlocked automatically. This “my is bigger than yours” can go on indefinitely until you provide more detailed description - what volumes are configured, what filesystem is on these volumes, what happens during boot, at which stage you get password prompt, etc.

I tested also systemd-cryptenroll with TPM and it works. You still did not explain what was wrong on screenshots you posted. You have two LUKS volumes, one is configured to use TPM, another is not. You get password prompt for the latter volume. Where is the problem?

openSUSE does not support it using standard installer/tools. Bootloader needs to read kernel, which is on encrypted device, so bootloader needs to unlock it. grub to my best knowledge does not support TPM for automatic unlock (there were patches, but I do not know if they are accepted). What SUSE supports, is passing passphrase from bootloader to Linux kernel, so you need to enter passphrase only once.

systemd-boot sidesteps this because it can only read from ESP, so kernel and initrd must be located on ESP which cannot be encrypted.

And /boot as separate unencrypted filesystem is probably not supported by MicroOS anyway.

This depends on your goals and software you use.

I have succeeded, at the moment I have only encrypted root filesystem, now I am going to try to encrypt /home as well. I found an official information of OpenSUSE working on MicroOS last night: SDB:LUKS2, TPM2 and FIDO2 - openSUSE Wiki
The trick is to have the /boot partition separate and unencrypted.

The instructions for systemd-cryptenroll say:

My installation is going to be on a server that I won’t have access to on a daily basis. I need that if it updates and restarts automatically, it will be able to turn itself on. Would it be possible to create a script that reads the used PCR registers at startup and, if those registers have been modified due to an update, it does the re-enroll when the equipment is turning off?

If these registers changed on startup, then unlocking fails. That is the very reason for using TPM - to verify that your environment did not change. You must update TPM before you reboot or unlock using some other means (passphrase) and then update TPM. But changing it before is probably not really possible.

PCR2 records any additional boot code that may have been loaded during boot. E.g., extension ROM from the cards you plugged in. As you cannot know them in advance, you will always have to use passphrase to unlock after adding additional card.

PCR4 measures where you (tried to) boot from. Should not change normally unless something fails.

PCR8 and PCR9 are used by applications. If you are using grub, then grub will measure everything executed from configuration file, any file read during boot as well as kernel command line (GNU GRUB Manual 2.12: Measured Boot). So, measurements change after you updated grub, after you updated/reconfigured kernel or even after you manually changed kernel command line (like selecting failsafe menu entry). It is impossible (well, extremely hard and fragile) to predict the final value.

As usual, you trade security for convenience. You must be prepared to have access to console and manually unlock your partition every time you reboot.