[systemd-devel] How to tie the unlocking of a LUKS device to multiple PCRs, when one of them is calculated?

Felix Rubio felix at kngnt.org
Sat Jun 24 06:49:07 UTC 2023


Hi everybody,

systemd-cryptenroll can seal/unseal the LUKS key in the TPM predicted to 
the state of some registers, e.g.:
     systemd-cryptenroll --wipe-slot=tpm2 --tpm2-device=auto 
--tpm2-pcrs=7+11+14 <device>

The problem is that this requires, when there are kernel / bootloader / 
... updates, to restart the system, unlock manually and run the command 
again to enroll the new pcr values. As discussed in this mailing list, 
the way to go to ensure that both the kernel and initramfs are checked 
is to use UKI, whose expected PCR 11 state can be calculated by 
systemd-measure (examples from 
https://www.freedesktop.org/software/systemd/man/systemd-measure.html):

   * To generate the signature:
     systemd-measure sign --linux=vmlinux --osrel=os-release.txt 
--cmdline=cmdline.txt \
      --initrd=initrd.cpio --splash=splash.bmp --dtb=devicetree.dtb 
--pcrpkey=tpm2-pcr-public.pem \
      --bank=sha1 --bank=sha256 --private-key=tpm2-pcr-private.pem \
      --public-key=tpm2-pcr-public.pem >tpm2-pcr-signature.json.tmp

   * To embed the signature on the image:
     ukify --output foo.efi --os-release @os-release.txt --cmdline 
@cmdline.txt --splash splash.bmp \
      --devicetree devicetree.dtb --pcr-private-key tpm2-pcr-private.pem 
\
      --pcr-public-key tpm2-pcr-public.pem --pcr-banks sha1,sha256 
vmlinux initrd.cpio

   * To enroll the PCR policy:
     systemd-cryptenroll --tpm2-device=auto 
--tpm2-public-key=tpm2-pcr-public.pem 
--tpm2-signature=tpm2-pcr-signature.json <device>


This process binds the unsealing of the LUKS decryption key to the PCR 
11, but is not clear how (or even if it is possible) to add other PCRs 
to the mix (those being 7 and 14, in my case).

To compare, this is what I was doing when dealing directly with the TPM 
(so, before switching to systemd), creating two policies and combining 
them with a policyor:
     # session for auth based on pcr
     tpm2_startauthsession -S session.ctx
     tpm2_policypcr -S session.ctx -L regular.policy -l sha256:0,1,7,9
     tpm2_policypassword -S session.ctx -L regular.policy
     tpm2_flushcontext session.ctx

     # session for auth based on rescue password
     tpm2_startauthsession -S session.ctx
     tpm2_policysecret -S session.ctx -L rescue.policy -c o 
'<tpm_ownerpass>'
     tpm2_flushcontext session.ctx

     # compound both policies using OR
     tpm2_startauthsession -S session.ctx
     tpm2_policyor -S session.ctx -L compound.policy 
sha256:rescue.policy,regular.policy
     tpm2_flushcontext session.ctx

     # create the seal object
     tpm2_create -C prim.ctx -c key.ctx -u key.pub -r key.priv -L 
compound.policy -i- -p '<disk_unlock_password>' -a 
'fixedtpm|fixedparent'

Is there any way to do something similar with systemd-cryptenroll?

Regards!


-- 
Felix


More information about the systemd-devel mailing list