Re: [PATCH RFC 0/3] tsm: Unified Measurement Register ABI for TVMs

From: Alexander Graf
Date: Wed Sep 11 2024 - 02:57:28 EST



On 11.09.24 06:01, Xing, Cedric wrote:

On 9/10/2024 12:09 PM, Jean-Philippe Brucker wrote:
Hi Cedric,

On Sat, Sep 07, 2024 at 11:56:18PM -0500, Cedric Xing wrote:
Patch 2 introduces event log support for RTMRs, addressing the fact that the
standalone values of RTMRs, which represent the cumulative digests of
sequential events, are not fully informative on their own.

Would each event_log include the events that firmware wrote before Linux?
No. The log format proposed here is textual and incompatible with TCG2
log format.

The proposed log format is based on the CoCo event log -
https://github.com/confidential-containers/guest-components/issues/495.

I'm wondering how this coexists with /sys/firmware/acpi/tables/data/CCEL.
The proposed log will take over after booting to Linux. The `SYNC` line
in the log captures the RTMR value before it, which can be used to
verify CCEL left off by the virtual firmware.

Maybe something like: CCEL only contains pre-Linux events. The TSM driver
parses CCEL (using a format specific to the arch, for example TCG2),
separates the events by MR and produces event_log files in
/sys/kernel/tsm/, possibly in a different format like CEL-TLV. Is that
what you envision for TDX?

CCEL will be pre-Linux only. Given the proposed format is incompatible
with TCG2 format, I don't think those 2 logs will be merged. But if we
get any success in this new log format, we may influence the UEFI/OVMF
community to adopt this new format in future.

We have evaluated both TCG2 and CEL formats but arrived in this new
format because we'd like to support ALL applications. And the only sane
way I could figure out is to separate the log into 2 layers - an
application specific semantics layer (a contract between the application
and the verifier), and an application agnostic storage layer
(implemented by the kernel). The common problem of TCG2 and CEL is that
the event/content tag/type dictates which part of the event data/content
to hash, meaning the kernel must understand an event record before
hashing it. And that has prevented an application agnostic storage design.

Anyway, this new log can be encapsulated in both CEL-JSON (like what
systemd is doing today) and TCG2 (using the EV_ACTION event type)
formats. Please see the CoCo issue (link given above) for more details.

I ask because I've been looking into this interface for Arm CCA, and
having unified event logs available somewhere in /sys/kernel/confg/tsm
would be very convenient for users (avoids having to parse and convert
different /sys/firmware interfaces along with Linux event logs). I would
have put a single event_log in /sys/kernel/config/tsm/report/ but
splitting it by MR should work too.

We have considered one global log vs. per-MR logs. In fact, a global log
is equivalent to the concatenation of all per-MR logs. We've adopted the
per-MR approach to keep the log optional - i.e., an RTMR can be extended
directly (by writing to its `digest` attribute) without a log.

With regard to the location of the MR tree, we picked sysfs because the
MRs (and associated logs) are global and fit more into the semantics of
sysfs than configfs. Dan W. and I are also considering moving both
report/ and measurement/ trees into securityfs. It'll be highly
appreciated if you (and Alex, and everyone) can share your insights.

As Alex I believe we need more similarity between the interfaces of static
and runtime measurements, because verifiers may benefit from an event log
of static measurements. For example Arm could have a configuration like
this:

   struct tsm_measurement_register arm_cca_mrs[] = {
      { MR_(rim) | TSM_MR_F_R | TSM_MR_F_LOG, HA },
      { MR_(rem0) | TSM_MR_F_R | TSM_MR_F_X | TSM_MR_F_LOG, HA },
      ...
      { MR_(rem3) | TSM_MR_F_R | TSM_MR_F_X | TSM_MR_F_LOG, HA },
   };

Here rim is a static measurement of the initial VM state, impossible to
extend but could have an event log. rem0-3 are runtime measurements,
extensible by firmware and then Linux. None of the digests can be written
directly, only extended and read with calls to the upper layer. The tree
would be:

   /sys/kernel/config/tsm/
   ├── rim
   │   ├── digest
   │   ├── event_log
   │   └── hash_algo
   ├── rem0
   │   ├── digest
   │   ├── append_event
   │   ├── event_log
   │   └── hash_algo
   ...
   ├── rem3
   │   ├── digest
   │   ├── append_event
   │   ├── event_log
   │   └── hash_algo
   └── report/$name
       ├── inblob
       └── outblob

I see. The desired/missing feature here I think is to allow a CC guest
driver to supply an "initial log". I can define a LOG bit, which if set,
will make the MR its own dir with `hash_algo` and `event_log`. And if X
is also set, then `append_event` will appear as well. Does this sound
like what Alex and you are looking for?


I don't understand why we want to have 2 separate representations for a "measurement object": flat file as well as directory. Could you please elaborate on the rationale why you think it would be desirable to have a non-directory representation at all? I feel like I'm missing something :)

What if for example next-next-gen SEV-SNP suddenly gains event log support for its launch digest? We would create needless churn on user space to dynamically determine whether it should read things as directory or as file. Or even worse: Newer kernels would simply always set the LOG bit and we suddenly break the user space ABI for existing environments that run on current-gen SEV-SNP.


Alex




Amazon Web Services Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597