You are not logged in.

#1 Today 13:43:57

5hridhyan
Member
Registered: 2025-12-25
Posts: 1,070
Website

TPM PCR15 for LUKS2 setup...

Hey guys, out of blue I thought of having TPM enrolled to LUKS2 disk, which I got success with, and was enjoying "passwordless" booting with PCR11 TPM policy

[shridhyan@atrnxa ~]$ sudo cryptsetup luksDump /dev/nvme0n1p2
[sudo] password for shridhyan: 
LUKS header information
Version:       	2
Epoch:         	5
Metadata area: 	16384 [bytes]
Keyslots area: 	16744448 [bytes]
UUID:          	cdeccdfc-d361-4faa-a30a-6a31142afdb2
Label:         	(no label)
Subsystem:     	(no subsystem)
Flags:       	(no flags)

Data segments:
  0: crypt
	offset: 16777216 [bytes]
	length: (whole device)
	cipher: aes-xts-plain64
	sector: 512 [bytes]

Keyslots:
  0: luks2
	Key:        512 bits
	Priority:   normal
	Cipher:     aes-xts-plain64
	Cipher key: 512 bits
	PBKDF:      argon2id
	Time cost:  29
	Memory:     1048576
	Threads:    4
	Salt:       33 7a 1f 4b 2b 80 3c ea 30 a5 d8 0e 61 2e 4b b4 
	           fa 14 60 af 4c 90 35 b4 cf 8e df 5e 07 f2 d9 03 
	AF stripes: 4000
	AF hash:    sha512
	Area offset:32768 [bytes]
	Area length:258048 [bytes]
	Digest ID:  0
  1: luks2
	Key:        512 bits
	Priority:   normal
	Cipher:     aes-xts-plain64
	Cipher key: 512 bits
	PBKDF:      pbkdf2
	Hash:       sha512
	Iterations: 1000
	Salt:       75 1e df 58 80 ee 74 aa 15 d0 2c 20 c3 eb 91 d9 
	           3c 26 7a f4 d1 cb 7f b9 e8 fc 7b 7a 96 7f b3 9b 
	AF stripes: 4000
	AF hash:    sha512
	Area offset:290816 [bytes]
	Area length:258048 [bytes]
	Digest ID:  0
Tokens:
  0: systemd-tpm2
	tpm2-hash-pcrs:   
	tpm2-pcr-bank:    sha256
	tpm2-pubkey:
	           2d 2d 2d 2d 2d 42 45 47 49 4e 20 50 55 42 4c 49
	           43 20 4b 45 59 2d 2d 2d 2d 2d 0a 4d 49 49 42 49
	           6a 41 4e 42 67 6b 71 68 6b 69 47 39 77 30 42 41
	           51 45 46 41 41 4f 43 41 51 38 41 4d 49 49 42 43
	           67 4b 43 41 51 45 41 6f 49 6a 73 6d 77 72 70 73
	           77 42 4a 70 35 41 62 63 79 39 79 0a 48 37 7a 57
	           7a 33 2f 54 4b 47 5a 7a 4c 45 48 38 6c 48 6d 67
	           65 73 36 56 41 6c 61 6f 59 31 4a 61 32 65 78 6d
	           44 31 67 4a 57 50 32 35 46 44 39 2f 6e 73 62 56
	           6f 76 6b 37 4e 42 69 78 6e 77 32 76 0a 51 53 45
	           78 43 79 70 6d 67 50 41 35 5a 33 43 34 52 6a 59
	           70 4b 34 43 44 37 47 73 6f 4d 31 6b 30 57 35 44
	           4b 51 4e 77 68 4e 6b 6a 4c 55 61 58 46 4a 41 41
	           43 53 75 56 72 34 54 67 6b 37 48 34 2f 0a 5a 78
	           6d 48 61 42 70 61 38 43 71 4a 72 33 79 4c 44 61
	           52 6f 6d 71 77 31 6b 78 6d 67 4d 48 73 72 4a 36
	           68 2f 38 4a 67 71 54 6c 6d 77 62 6d 42 6a 37 44
	           41 69 51 32 4c 32 61 49 45 35 76 72 4b 52 0a 31
	           71 38 74 54 78 68 30 6d 6c 76 32 61 6d 54 78 39
	           34 61 49 6e 45 33 73 5a 56 2b 58 33 52 77 7a 6c
	           4f 46 4b 68 44 64 65 56 78 2b 45 45 4b 72 6b 4c
	           4e 37 6d 4d 6e 2b 65 2f 68 57 57 50 6a 36 64 0a
	           6b 5a 57 6f 49 35 46 44 77 7a 58 4b 56 37 34 61
	           37 71 4f 70 4a 4c 4c 33 73 6c 6f 49 53 37 6a 6b
	           44 45 56 5a 33 4f 47 6c 5a 59 63 66 34 43 63 4d
	           56 6d 5a 42 6d 6e 37 61 68 7a 4a 72 52 65 61 74
	           0a 76 77 49 44 41 51 41 42 0a 2d 2d 2d 2d 2d 45
	           4e 44 20 50 55 42 4c 49 43 20 4b 45 59 2d 2d 2d
	           2d 2d 0a
	tpm2-pubkey-ref:  (null)
	tpm2-pubkey-pcrs: 11
	tpm2-primary-alg: rsa
	tpm2-pin:         false
	tpm2-pcrlock:     false
	tpm2-argon2id:    false
	tpm2-salt:        false
	tpm2-srk:         true
	tpm2-pcrlock-nv:  false
	tpm2-policy-hash:
	           a5 a9 43 18 f3 00 6a 16 e2 4f 01 3c d1 78 8e 62
	           d8 e3 df 50 3f d8 36 38 7d be 09 3a 54 2d 2d 14
	tpm2-blob:  00 9e 00 20 a2 bd 4a 30 54 70 bd 6b 83 98 fd d0
	           bf 84 18 01 5c aa 17 b4 38 c2 4d 35 a5 cb 18 49
	           78 c1 2a b6 00 10 2c 06 23 5f 6e 1e dd a7 73 8d
	           45 87 62 fb 26 08 a0 f3 b2 4d 2c 27 32 b3 63 3f
	           d2 25 48 9f 10 c1 75 dc e9 32 43 8e 49 a6 7c 98
	           f4 af a3 50 9f 80 7d 58 71 96 08 f7 77 3e 7e dd
	           a6 c9 93 9a eb 9b 89 e9 2f 4e fa e5 e9 e2 94 33
	           16 0f ed b0 fb ba 0f 0a 19 7f 7c a4 65 fd 8b 18
	           8d f7 8f d4 b0 60 7f 82 7e d4 a3 a3 00 9f 50 e2
	           6d f9 52 4b 21 dc ad 25 0f 13 7c 7a 09 4b 4a b7
	           00 4e 00 08 00 0b 00 00 04 12 00 20 a5 a9 43 18
	           f3 00 6a 16 e2 4f 01 3c d1 78 8e 62 d8 e3 df 50
	           3f d8 36 38 7d be 09 3a 54 2d 2d 14 00 10 00 20
	           b6 20 9a eb e2 31 df a6 5d ad 02 59 50 2d 54 0f
	           39 af a2 ba ab 45 77 97 aa 48 33 13 60 c3 70 04
	Keyslot:    1
Digests:
  0: pbkdf2
	Hash:       sha512
	Iterations: 201030
	Salt:       
36 
70 
fc 
4e 
e5 
94 
a5 
93 
da 
c0 
41 
b8 
19 
6c 
fc 
e2 
	           
02 
2b 
ed 
af 
1f 
c2 
a3 
a7 
58 
02 
cd 
a2 
ba 
17 
2b 
7d 
	Digest:     
68 
de 
db 
20 
b4 
7c 
9c 
d4 
ea 
59 
96 
9d 
f6 
31 
cd 
43 
	           
57 
af 
d0 
da 
2e 
ec 
fd 
be 
76 
fe 
8f 
8b 
4d 
5f 
cc 
d3 
	           
30 
05 
ad 
11 
a5 
b2 
03 
4a 
1f 
65 
ea 
19 
49 
08 
84 
70 
	           
ec 
51 
33 
37 
cb 
1e 
c0 
96 
77 
ad 
73 
08 
d9 
73 
93 
05 
Command successful.

and my current cmdline

[shridhyan@atrnxa ~]$ cat /etc/kernel/cmdline
rd.luks.name=cdeccdfc-d361-4faa-a30a-6a31142afdb2=root root=/dev/mapper/root zswap.enabled=0 rootflags=subvol=@ rw rootfstype=btrfs lsm=landlock,lockdown,yama,integrity,apparmor,bpf lockdown=confidentiality rd.luks.options=cdeccdfc-d361-4faa-a30a-6a31142afdb2=tpm2-device=auto

its fairly a new installation after a previous disaster and this is an UKI based setup, and also with BTRFS

[shridhyan@atrnxa ~]$ lsblk -f
NAME        FSTYPE      FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
zram0       swap        1     zram0 bd22e9c3-129f-44c6-8f17-edb471c69361                [SWAP]
nvme0n1                                                                                 
├─nvme0n1p1 vfat        FAT32       69DE-EF2D                             729.8M    29% /boot
└─nvme0n1p2 crypto_LUKS 2           cdeccdfc-d361-4faa-a30a-6a31142afdb2                
  └─root    btrfs                   e3b0cf88-3856-44f7-8860-66c746fb7c08  325.9G     5% /var/log
                                                                                        /var/cache/pacman/pkg
                                                                                        /home
                                                                                        /

So, I'm actually trying to implement the systemd TPM2/LUKS setup where the LUKS volume key is measured into PCR 15, and eventually use fixate-volume-key= to bind the expected volume key to the encrypted volume...

I also want the TPM measurement to distinguish the originally enrolled encrypted volume from a different LUKS volume that happens to have the same filesystem/root configuration.
My understanding is that systemd supports this through tpm2-measure-pcr= and fixate-volume-key=. The systemd TPM2 PCR documentation describes systemd-cryptsetup measuring a value derived from the LUKS volume key into PCR 15. fixate-volume-key= is then intended to verify the expected volume-key ID when activating the volume.

First, I appended "tpm2-measure-pcr=yes" in my /etc/kernel/cmdline, and after rebuilding the UKI and rebooting, PCR 15 remained unchanged.
the journal said

[shridhyan@atrnxa ~]$ sudo journalctl -b -1 -u systemd-cryptsetup@root.service --no-pager -o cat
Starting Cryptography Setup for root...
Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/disk/by-uuid/cdeccdfc-d361-4faa-a30a-6a31142afdb2.
Automatically discovered security TPM2 token unlocks volume.
Could not extend PCR: No such file or directory
Finished Cryptography Setup for root.

So it appears that the TPM2 unlock itself succeeds, and tpm2-measure-pcr=yes reaches systemd-cryptsetup, but the actual PCR extension fails with ENOENT.
The same boot also contains:

systemd-tpm2-setup[140]: 4 NvPCRs initialized.

and later:

systemd-pcrextend[345]: Extended NvPCR index 'hardware' with 'product-id:...'.
systemd-pcrextend[341]: Extended PCR index 15 with 'machine-id:...' (banks sha256).

So TPM2/NvPCR/PCR functionality is not globally unavailable...

so is there smtg missing from my initramfs/configuration that prevents systemd-cryptsetup from extending PCR 15 during LUKS activation?
If this mechanism is expected to work, I'd also like to know the correct way to obtain the fixate-volume-key= value for an existing LUKS volume after successfully measuring it...
like I am not trying to put PCR 15 itself into the TPM2 unlock policy, my understanding is that PCR 15 is extended as part of the LUKS activation, so it cannot be used that way as a prerequisite for the same activation.
The desired flow is:
TPM2 unlock => activate known LUKS volume => measure its derived volume-key identity into PCR 15 => optionally enforce that identity with fixate-volume-key=
...

oh yeah, if someone needs to know what's in my mkinitcpio.conf

[shridhyan@atrnxa ~]$ cat /etc/mkinitcpio.conf
# vim:set ft=sh:
# MODULES
# The following modules are loaded before any boot hooks are
# run.  Advanced users may wish to specify all system modules
# in this array.  For instance:
#     MODULES=(usbhid xhci_hcd)
MODULES=()

# BINARIES
# This setting includes any additional binaries a given user may
# wish into the CPIO image.  This is run last, so it may be used to
# override the actual binaries included by a given hook
# BINARIES are dependency parsed, so you may safely ignore libraries
BINARIES=(/usr/lib/systemd/systemd-tpm2-setup)

# FILES
# This setting is similar to BINARIES above, however, files are added
# as-is and are not parsed in any way.  This is useful for config files.
# FILES=()
FILES=(
  /usr/lib/systemd/system/systemd-tpm2-setup-early.service /usr/lib/systemd/system/sysinit.target.wants/systemd-tpm2-setup-early.service)

# HOOKS
# This is the most important setting in this file.  The HOOKS control the
# modules and scripts added to the image, and what happens at boot time.
# Order is important, and it is recommended that you do not change the
# order in which HOOKS are added.  Run 'mkinitcpio -H <hook name>' for
# help on a given hook.
# 'base' is _required_ unless you know precisely what you are doing.
# 'udev' is _required_ in order to automatically load modules
# 'filesystems' is _required_ unless you specify your fs modules in MODULES
# Examples:
##   This setup specifies all modules in the MODULES setting above.
##   No RAID, lvm2, or encrypted root is needed.
#    HOOKS=(base)
#
##   This setup will autodetect all modules for your system and should
##   work as a sane default
#    HOOKS=(base udev autodetect microcode modconf block filesystems fsck)
#
##   This setup will generate a 'full' image which supports most systems.
##   No autodetection is done.
#    HOOKS=(base udev microcode modconf block filesystems fsck)
#
##   This setup assembles a mdadm array with an encrypted root file system.
##   Note: See 'mkinitcpio -H mdadm_udev' for more information on RAID devices.
#    HOOKS=(base udev microcode modconf keyboard keymap consolefont block mdadm_udev encrypt filesystems fsck)
#
##   This setup loads an lvm2 volume group.
#    HOOKS=(base udev microcode modconf block lvm2 filesystems fsck)
#
##   This will create a systemd based initramfs which loads an encrypted root filesystem.
#    HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)
#
##   NOTE: If you have /usr on a separate partition, you MUST include the
#    usr and fsck hooks.
#HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)
#HOOKS=(base autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)
HOOKS=(base autodetect systemd microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)
# COMPRESSION
# Use this to compress the initramfs image. By default, zstd compression
# is used for Linux ≥ 5.9 and gzip compression is used for Linux < 5.9.
# Use 'cat' to create an uncompressed image.
#COMPRESSION="zstd"
#COMPRESSION="gzip"
#COMPRESSION="bzip2"
#COMPRESSION="lzma"
#COMPRESSION="xz"
#COMPRESSION="lzop"
#COMPRESSION="lz4"

# COMPRESSION_OPTIONS
# Additional options for the compressor
#COMPRESSION_OPTIONS=()

# MODULES_DECOMPRESS
# Decompress loadable kernel modules and their firmware during initramfs
# creation. Switch (yes/no).
# Enable to allow further decreasing image size when using high compression
# (e.g. xz -9e or zstd --long --ultra -22) at the expense of increased RAM usage
# at early boot.
# Note that any compressed files will be placed in the uncompressed early CPIO
# to avoid double compression.
#MODULES_DECOMPRESS="no"

Last edited by 5hridhyan (Today 13:59:19)

Offline

#2 Today 20:34:32

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,979

Offline

Board footer

Powered by FluxBB