On 2025-03-08 18:52, Diorcet Yann wrote:
But in the case of multiple partitions unlocked by the initrd, I can't
figure why an attacker couldn't succeed to :
- Clone the original disk (notably ESP)
- Replace root partition by a malicious one
- Fake the second (using UUID/PARTLABEL/...) but using LUKS partition
from the "good" root partition
This is done by "systemd-pcrfs[-root]". The attacker needs to have
access to the system (as a normal user to use something like lsblk)
tpm2-measure-pcr take the LUKS2 volume key (cryptsetup luksDump
--dump-master-key), and this requires the effective unlock of the device
(via TPM2 or passphrase)
- Boot the machine
- The initrd will try unlocks the malicious partition as root. As the
TPM token will not work, the attacker will use the password of his
malicious LUKS
- Make the update of the PCR due to the measuring of the malicious
partition fails
As commented, using tpm2-measure-pcr, PCR15 will be extended with
HMAC("cryptsetup:$name:$uuid", vk), and vk cannot be impersonated.
- Initrd will try to unlock the second partition, which is the "good"
root partition, and it will succeed, allowing the attacker to finally
access all data from the partition.
Yes, this partition can be unlocked using a policy that uses PCR0..9 for
TPM2 (without PIN). But not necessarily means that the attacker has any
access yet, at least not while we are in the initrd.
With measured boot, the previous stage measure something of the next
stage before delegating. The initrd needs to measure something from the
device to continue the chain of trust. IIRC in the image-based proposal
that was the dm-verity root key. If dm-verity is not used, then
something else needs to be measured. The volume key seems a good
replacement.
The main point here is to "Make the update of the PCR due to the
measuring of the malicious partition fails".
I think that there is a more simple model, that was described in a nice
blog post some months ago. The idea is to never leave the initrd if the
expected value of PCR15 is not meet.
In this model PCR15 does not participate in the unseal of any secret.
Instead you need to mark the encrypted partitions as tpm2-measure-pcr
that are unlocked early in the initrd (root, swap, and the ones with
x-initrd.attach).
Maybe using a generator, we need to order how systemd-cryptsetup will
access those devices. This is optional, but will simplify a lot how to
make predictions for PCR15.
The last step is to have a service in the initrd that is executed after
systemd-cryptsetup@.service, but before the switch root, it will compare
the current PCR15 value with the expected one, and if it fails it will
halt the system.
With something like this an attacker cannot replace any of the disk that
belong to the OS without being detected. This would require the
alteration of initrd in the UKI or on the ESP, that is covered by the
measured boot policy.
There is some code here:
* A generator that order the PCR15 extensions
https://github.com/openSUSE/sdbootutil/blob/main/measure-pcr-generator.sh
* A predictor for PCR15
https://github.com/openSUSE/sdbootutil/blob/main/sdbootutil#L2210
* A validator service that stop the boot process if the expected value
did not match
(also validate the signature of the file that contains the prediction)
https://github.com/openSUSE/sdbootutil/blob/main/measure-pcr-validator.sh
* (Only for non-UKIs) A service that import into the initrd the
prediction
https://github.com/aplanas/dracut-pcr-signature/blob/main/pcr-signature.sh