On 26.03.25 13:27, Gerd Hoffman wrote:
   Hi,

The problem is that add-ons are

   1) Separate binaries. So you need to match multiple files.
   2) In this case, get generated out of the vendor (RH)'s control in a
one-off fashion.

I don't think "signing" is the correct way to address the latter. It's
rather hashing. But I agree with you that it could (should?) be hashing at
the PE loader level similar or identical to Secure Boot rather than a
separate hashing mechanism.
Secure boot offers signing and hashing.  You can add both signing
certificates and authenticode hashes to 'db'.

Not sure I understand the point you are trying to raise.  Add-ons
signatures are checked too.
2 points here here:

   1) With add-ons, there are multiple binaries. We can't only pass a single
one.
Sure.  You'll go need some container, say a cpio archive, but that is
something vmfwupdate loader and loaded firmware have to agree on and not
something we have to worry about too much for the vmfwupdate interface
design.

   2) The security posture of the system may be different between 2 validly
signed images. Think of Daniel's example of verbose kernel output. Maybe I
consider verbose kernel output already inacceptable, while RH thinks it's an
ok posture to have. The user needs to have the chance to differentiate
between a system booted with or without verbose kernel output.
You easily get that by looking at the vTPM measurements.  So not sure
what you are asking for, do you want be able to also do that without a
vTPM?


All of this should work without vTPMs. Why add complexity when you don't need it? The industry is already struggling to deal with TPMs alone. There are way too many potential holes in a solution where you first have to reason about the integrity of your TPM before you can trust it. All of the vTPM in SEV-SNP talk is a house of cards I'm happy to push (blow to keep the analogy?) against as hard as I can.



So we need some equivalent of a hash page.
Ok.  So two opaque blobs, one which is measured into the launch
measurement and one which is not?  That gives you the option to pass
around hashes (or any other data) and leave a trace in the launch
measurement should you need that.
Yes, I think you want to have one or multiple pages with what effectively is
a db append variable update blob.
Makes sense to me.

Or even a full variable store blob.
Hmm, not sure.  I'd rather go for passing efi signature database
appendix, probably for both allow ('db') and deny ('dbx').  That is
going to work better I think, variable store format is an
firmware-internal implementation detail I'd avoid encoding that in
some interface.

The IGVM should dictate the physical location of that blob so that you
can precalculate the launch digest with the blob included.
Hmm, right.  Physical location matters for the launch measurement, so
adding opaque_measured_addr to struct vmfwupdate isn't going to work
very well.

Ukify.py then generates the blob along with the FUKI.
Doesn't fly from a distro point of view.  The UKI is signed, so RH ships
that and the customer can't modify it to update the blob, say with some
additional hashes for 'db'.


I don't follow. Is RH going to ship a UKI or a FUKI? And if RH ships the UKI, ukify could still take a UKI as input and generate a FUKI based on it, no? During that process, it would generate a db which gets put at a fixed location in RAM so the (RH provided) firmware picks it up and validates the UKI it loads is exactly that one UKI.

We can extend that with an additional signature flow, where the ukify generated db contains a signature for the UKI instead. But I would generally advise against optimizing for certificate based flows until revocation is sorted out. And since revocation requires a new dbx in this scheme and that means a different launch digest per revocation, you may as well just directly only use hashes.


Effectively we need something roughly equivalent to shim's MokList.  The
distro ships a default configuration (like the cert compiled into the
shim binary) which works fine for most people.  For IGVM that would be a
default efi variable store compiled into the firmware binary.


This only makes sense in a world where RH ships an SVSM and that's all you want to attest. But that's a different flow from what we describe here. To actually get workload attestation, you need to include your rootfs in the attestation. And the only entity that can do that is the end customer. And they will typically do that through something like dm-verity or fs-verity and a hash provided on the kernel command line.



If you need additional stuff (like the signer cert for the nvidia
driver) there must be some way to add hashes and certificates to db/dbx.

Does it make sense to simply move the firmware update sections from the
main UKI to an add-on?  That would allow customers to easily use their
own if they wish, without breaking the RH signature on the UKI.


I'm still not convinced "RH signature" is a useful marker at execution time of confidential workloads. It may be an interesting one at assembly time, but after that we're folding everything into a single launch digest anyway, for good reasons.



I agree, from a vmfwupdate point of view, we would basically have an IGVM.
The IGVM describes 2 special page (ranges?): One for the CPUID special page,
one for the variable store seed. To precalculate the launch digest you would
need the firmware IGVM, and the seed blob.
Guess we'll have to update the IGVM format spec for that, so we have
page types for 'db' and 'dbx'.  With that it should be possible to load
the igvm, find + update the pages + write it out again.  Then wrap it
into an UKI add-on + copy to ESP.

RH default igvm/add-on would simply have empty 'db' and 'dbx' pages.

Looks workable to me.


I would personally consider the "RH binary adds RH signature into binary by default" a backdoor, but that's you call :).

I agree with the plan to amend the IGVM spec with the UEFI variable update page. I don't think it should be "db" and "dbx" pages. It should be a more generic. In fact, why not make it a loader UEFI (PE) binary? The binary installs the db/dbx updates and chain loads the actual payload UKIs using a file format that's private between the loader binary and the sd-boot stub.



All unauthenticated data, such as locations of the UKI and its add-ons gets
passed as parameter to the firmware IGVM.
i.e. have a IGVM parameter for opaque_addr + opaque_size instead of
placing this in the vmfwupdate struct?


It would be a pretty natural fit for it, no?



take care,
   Gerd

PS: in Berlin tomorrow?


Yup, let's sync up! :)


Alex



Reply via email to