diff mbox series

[RFC,v2,4/4] tsm: Allow for extending and reading configured RTMRs

Message ID 20240128212532.2754325-5-sameo@rivosinc.com (mailing list archive)
State New, archived
Headers show
Series tsm: Runtime measurement registers ABI | expand

Commit Message

Samuel Ortiz Jan. 28, 2024, 9:25 p.m. UTC
The whole purpose of TSM supported RTMRs is for userspace to extend them
with runtime measurements and to read them back.

This can be done through a binary configfs attribute for each RTMR:

rtmr0=/sys/kernel/config/tsm/rtmrs/rtmr0
mkdir $rtmr0
echo 0 > $rtmr0/index
dd if=software_layer_digest > $rtmr0/digest
hexdump $rtmr0/digest

An RTMR digest can not be extended or read before the RTMR is configured
by assigning it an index.

Signed-off-by: Samuel Ortiz <sameo@rivosinc.com>
---
 Documentation/ABI/testing/configfs-tsm | 11 +++++
 drivers/virt/coco/Kconfig              |  1 +
 drivers/virt/coco/tsm.c                | 58 ++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)

Comments

James Bottomley May 11, 2024, 2:57 a.m. UTC | #1
I'm not really sure where to hang this, since there's no posted agenda
or materials for the CCC meeting today.  I'm afraid I also don't have a
copy of the presentation to point people who weren't at the meeting to.
However, it struck me you missed a third option: use the ima log
format.  This has the advantage that we can define additional events
and have them published with a kernel patch (the IMA log format is
defined in the kernel).  Thanks to the TCG, it's also CEL compatible
but doesn't require any sort of TCG blessing of the events.  Plus we
also have existing kernel infrastructure to log to that format.

Regards,

James
Samuel Ortiz May 13, 2024, 10:16 a.m. UTC | #2
On Fri, May 10, 2024 at 10:57:37PM -0400, James Bottomley wrote:
> I'm not really sure where to hang this, since there's no posted agenda
> or materials for the CCC meeting today.

The agenda was posted on the linux-coco ml [1]. I sent a link to the
presentation slides [2] to the thread.

> However, it struck me you missed a third option: use the ima log
> format.  This has the advantage that we can define additional events
> and have them published with a kernel patch (the IMA log format is
> defined in the kernel).  Thanks to the TCG, it's also CEL compatible
> but doesn't require any sort of TCG blessing of the events.  Plus we
> also have existing kernel infrastructure to log to that format.

That's an interesting idea. It may avoid having to extend the CEL spec
with a new Content Type, but otoh the current spec defines which IMA
events are supported. So adding new ones may require to also eventually
extend the spec. But I guess since IMA is a Linux kernel subsystem,
changing the kernel code and ABI would de-facto extend the TCG CEL IMA
spec.

Here I assume you're talking about the IMA_TEMPLATE CEL specified
format, which is designed to accomodate for the current kernel IMA log
format. The main drawback of this format is that the digest does not
include the whole content event, making the CEL content type, the IMA
tag name and both lengths (for the content event and the IMA content)
untrusted for event log verifiers.

CEL defines another IMA format (IMA_TLV), that hashes the whole event
content. I think we should at least use that format as our output ABI,
if we want to use a TCG specified IMA content type.

Cheers,
Samuel.

[1] https://lore.kernel.org/linux-coco/61b65115-5945-4e27-89e4-bb6cba657f7f@linux.intel.com/
[2] https://docs.google.com/presentation/d/1qMk-8TiMigVmVAEDWXqPu9Jd7OJ8AGvCR34Lp2WunhU/edit?usp=sharing

> Regards,
> 
> James
>
James Bottomley May 13, 2024, 2:03 p.m. UTC | #3
On Mon, 2024-05-13 at 12:16 +0200, Samuel Ortiz wrote:
> On Fri, May 10, 2024 at 10:57:37PM -0400, James Bottomley wrote:
> > I'm not really sure where to hang this, since there's no posted
> > agenda
> > or materials for the CCC meeting today.
> 
> The agenda was posted on the linux-coco ml [1]. I sent a link to the
> presentation slides [2] to the thread.

That's great, thanks.

> > However, it struck me you missed a third option: use the ima log
> > format.  This has the advantage that we can define additional
> > events and have them published with a kernel patch (the IMA log
> > format is defined in the kernel).  Thanks to the TCG, it's also CEL
> > compatible but doesn't require any sort of TCG blessing of the
> > events.  Plus we also have existing kernel infrastructure to log to
> > that format.
> 
> That's an interesting idea. It may avoid having to extend the CEL
> spec with a new Content Type, but otoh the current spec defines which
> IMA events are supported. So adding new ones may require to also
> eventually extend the spec. But I guess since IMA is a Linux kernel
> subsystem, changing the kernel code and ABI would de-facto extend the
> TCG CEL IMA spec.

That's what I was assuming since the TCG is currently deferring to IMA
in that regard.

> Here I assume you're talking about the IMA_TEMPLATE CEL specified
> format, which is designed to accomodate for the current kernel IMA
> log format. The main drawback of this format is that the digest does
> not include the whole content event, making the CEL content type, the
> IMA tag name and both lengths (for the content event and the IMA
> content) untrusted for event log verifiers.

That's only because IMA doesn't yet have such an event.  If we're
assuming effectively designing an IMA log format for non repudiation of
external events, one can be added.  Although I wouldn't want to be
hasty: one of the big problems of all options is that no existing log
format really covers the measure container use case and we're not
completely sure what other use cases will arise (the firewall rules
measurements was one that regulated cloud providers seem to think would
be important ... and that has a periodic rush of events, but there will
be others).

However, the current IMA templates (event descriptions) are known by an
ASCII prefix (they all begin ima-):

https://docs.kernel.org/security/IMA-templates.html#supported-template-fields-and-descriptors

So it would be easy to add more with a non ima- prefix.  Note that this
doc is out of date an IMA does support hashes all the way to SHA256
although SHA384 isn't currently listed.

The current record fields are defined in

security/integrity/ima/ima_template.c

> CEL defines another IMA format (IMA_TLV), that hashes the whole event
> content. I think we should at least use that format as our output
> ABI, if we want to use a TCG specified IMA content type.

Possibly.  Although avoiding double hashing may be a useful performance
measure (not really sure how fast records will come in yet).

James
Samuel Ortiz May 14, 2024, 5:08 a.m. UTC | #4
On Mon, May 13, 2024 at 08:03:53AM -0600, James Bottomley wrote:
> On Mon, 2024-05-13 at 12:16 +0200, Samuel Ortiz wrote:
> > > However, it struck me you missed a third option: use the ima log
> > > format.  This has the advantage that we can define additional
> > > events and have them published with a kernel patch (the IMA log
> > > format is defined in the kernel).  Thanks to the TCG, it's also CEL
> > > compatible but doesn't require any sort of TCG blessing of the
> > > events.  Plus we also have existing kernel infrastructure to log to
> > > that format.
> > 
> > That's an interesting idea. It may avoid having to extend the CEL
> > spec with a new Content Type, but otoh the current spec defines which
> > IMA events are supported. So adding new ones may require to also
> > eventually extend the spec. But I guess since IMA is a Linux kernel
> > subsystem, changing the kernel code and ABI would de-facto extend the
> > TCG CEL IMA spec.
> 
> That's what I was assuming since the TCG is currently deferring to IMA
> in that regard.
> 
> > Here I assume you're talking about the IMA_TEMPLATE CEL specified
> > format, which is designed to accomodate for the current kernel IMA
> > log format. The main drawback of this format is that the digest does
> > not include the whole content event, making the CEL content type, the
> > IMA tag name and both lengths (for the content event and the IMA
> > content) untrusted for event log verifiers.
> 
> That's only because IMA doesn't yet have such an event.  If we're
> assuming effectively designing an IMA log format for non repudiation of
> external events, one can be added. 

If we were to follow the IMA_TEMPLATE format as our output RTMR ABI for
the event log, adding one or more IMA events would not change the fact
that the event and content type would not be hashed into the extended
digest. Unless we want to specify a different behaviour for each IMA
event, and then verifiers would have interpret the digest construction
differently depending on the IMA_TEMPLATE nested event type. And that's
not pretty IMHO.

Using the IMA_TLV content type would make that cut cleaner at least. A
digest is built on the whole content event, for all event types. And the
content and event types are trusted, i.e. the verifier can securely map
events to the reported event types.

> Although I wouldn't want to be
> hasty: one of the big problems of all options is that no existing log
> format really covers the measure container use case and we're not
> completely sure what other use cases will arise (the firewall rules
> measurements was one that regulated cloud providers seem to think would
> be important ... and that has a periodic rush of events, but there will
> be others).

Right. A new CEL content type would give us more freedom in that regard,
as it would allow us to define our own event content value in a more
flexible way. Instead of the nested TLV approach that IMA_TLV follows,
having one where the T would be a max length string defining the creator
of the event (a.k.a. the attester), would avoid having to formally
define each and every new event. That's where option #2 in the
presentation was heading to.

Cheers,
Samuel.
>
Xing, Cedric May 16, 2024, 8:33 a.m. UTC | #5
On 5/13/2024 10:08 PM, Samuel Ortiz wrote:
> On Mon, May 13, 2024 at 08:03:53AM -0600, James Bottomley wrote:
>> On Mon, 2024-05-13 at 12:16 +0200, Samuel Ortiz wrote:
>>>> However, it struck me you missed a third option: use the ima log
>>>> format.  This has the advantage that we can define additional
>>>> events and have them published with a kernel patch (the IMA log
>>>> format is defined in the kernel).  Thanks to the TCG, it's also CEL
>>>> compatible but doesn't require any sort of TCG blessing of the
>>>> events.  Plus we also have existing kernel infrastructure to log to
>>>> that format.
>>>
>>> That's an interesting idea. It may avoid having to extend the CEL
>>> spec with a new Content Type, but otoh the current spec defines which
>>> IMA events are supported. So adding new ones may require to also
>>> eventually extend the spec. But I guess since IMA is a Linux kernel
>>> subsystem, changing the kernel code and ABI would de-facto extend the
>>> TCG CEL IMA spec.
>>
>> That's what I was assuming since the TCG is currently deferring to IMA
>> in that regard.
>>
>>> Here I assume you're talking about the IMA_TEMPLATE CEL specified
>>> format, which is designed to accomodate for the current kernel IMA
>>> log format. The main drawback of this format is that the digest does
>>> not include the whole content event, making the CEL content type, the
>>> IMA tag name and both lengths (for the content event and the IMA
>>> content) untrusted for event log verifiers.
>>
>> That's only because IMA doesn't yet have such an event.  If we're
>> assuming effectively designing an IMA log format for non repudiation of
>> external events, one can be added.
> 
> If we were to follow the IMA_TEMPLATE format as our output RTMR ABI for
> the event log, adding one or more IMA events would not change the fact
> that the event and content type would not be hashed into the extended
> digest. Unless we want to specify a different behaviour for each IMA
> event, and then verifiers would have interpret the digest construction
> differently depending on the IMA_TEMPLATE nested event type. And that's
> not pretty IMHO.
> 
Agreed. This misses the design objective of separating storage from 
semantics of event records.

> Using the IMA_TLV content type would make that cut cleaner at least. A
> digest is built on the whole content event, for all event types. And the
> content and event types are trusted, i.e. the verifier can securely map
> events to the reported event types.
> 
The numerical T would need to be allocated/tracked by a central 
registry. This won't work for applications designed/developed outside of 
the kernel community, as they won't have a reliable way to avoid 
conflicts with each other. Thus, T needs to be a string, but that 
violates IMA_TLV definition. This is kinda fitting a square peg into a 
round hole IMHO.

>> Although I wouldn't want to be
>> hasty: one of the big problems of all options is that no existing log
>> format really covers the measure container use case and we're not
>> completely sure what other use cases will arise (the firewall rules
>> measurements was one that regulated cloud providers seem to think would
>> be important ... and that has a periodic rush of events, but there will
>> be others).
> 
> Right. A new CEL content type would give us more freedom in that regard,
> as it would allow us to define our own event content value in a more
> flexible way. Instead of the nested TLV approach that IMA_TLV follows,
> having one where the T would be a max length string defining the creator
> of the event (a.k.a. the attester), would avoid having to formally
> define each and every new event. That's where option #2 in the
> presentation was heading to.
> 
Agreed. In fact, the 2 primary design objectives of this event log are 
(1) to separate storage from semantics of event records and (2) to allow 
applications to define custom events and avoid conflicts with each other 
reliably. IMA_TLV meets the 1st objective but misses the 2nd; while 
IMA_TEMPLATE meets the 2nd but misses the 1st. And that's how we came to 
this Option #2.

-Cedric
diff mbox series

Patch

diff --git a/Documentation/ABI/testing/configfs-tsm b/Documentation/ABI/testing/configfs-tsm
index 5d20a872475e..dc5c68a49625 100644
--- a/Documentation/ABI/testing/configfs-tsm
+++ b/Documentation/ABI/testing/configfs-tsm
@@ -81,6 +81,17 @@  Description:
 		(RO) Indicates the minimum permissible value that can be written
 		to @privlevel.
 
+What:		/sys/kernel/config/tsm/rtmrs/$name/digest
+Date:		January, 2024
+KernelVersion:	v6.8
+Contact:	linux-coco@lists.linux.dev
+Description:
+		(RW) The value in this attribute is the Runtime Measurement
+		Register (RTMR) digest. Callers can extend this digest with
+		additional hashes by writing into it. Binary blobs written to
+		this attribute must be of the exact length used by the hash
+		algorithm for this RTMR.
+
 What:		/sys/kernel/config/tsm/rtmrs/$name/index
 Date:		January, 2024
 KernelVersion:	v6.8
diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig
index 87d142c1f932..5d924bae1ed8 100644
--- a/drivers/virt/coco/Kconfig
+++ b/drivers/virt/coco/Kconfig
@@ -5,6 +5,7 @@ 
 
 config TSM_REPORTS
 	select CONFIGFS_FS
+	select CRYPTO_HASH_INFO
 	tristate
 
 source "drivers/virt/coco/efi_secret/Kconfig"
diff --git a/drivers/virt/coco/tsm.c b/drivers/virt/coco/tsm.c
index d03cf5173bc9..b4f8cf6ca149 100644
--- a/drivers/virt/coco/tsm.c
+++ b/drivers/virt/coco/tsm.c
@@ -551,6 +551,63 @@  static struct configfs_attribute *tsm_rtmr_attrs[] = {
 	NULL,
 };
 
+static ssize_t tsm_rtmr_digest_read(struct config_item *cfg, void *buf,
+				    size_t count)
+{
+	struct tsm_rtmr_state *rtmr_state = to_tsm_rtmr_state(cfg);
+	int rc, digest_size = hash_digest_size[rtmr_state->alg];
+
+	/* configfs is asking for the digest size */
+	if (!buf)
+		return digest_size;
+
+	if (!is_rtmr_configured(rtmr_state))
+		return -ENXIO;
+
+	if (count > TSM_DIGEST_MAX || count < digest_size)
+		return -EINVAL;
+
+	/* Read from the cached digest */
+	if (rtmr_state->cached_digest) {
+		memcpy(buf, rtmr_state->digest, count);
+		return digest_size;
+	}
+
+	/* Slow path, this RTMR got extended */
+	guard(rwsem_write)(&tsm_rwsem);
+	rc = tsm_rtmr_read(&provider, rtmr_state->index, buf, count);
+	if (rc < 0)
+		return rc;
+
+	/* Update the cached digest */
+	memcpy(rtmr_state->digest, buf, count);
+	rtmr_state->cached_digest = true;
+
+	return rc;
+}
+
+static ssize_t tsm_rtmr_digest_write(struct config_item *cfg,
+				     const void *buf, size_t count)
+{
+	struct tsm_rtmr_state *rtmr_state = to_tsm_rtmr_state(cfg);
+
+	if (!is_rtmr_configured(rtmr_state))
+		return -ENXIO;
+
+	if (count > TSM_DIGEST_MAX || count < hash_digest_size[rtmr_state->alg])
+		return -EINVAL;
+
+	guard(rwsem_write)(&tsm_rwsem);
+	rtmr_state->cached_digest = false;
+	return tsm_rtmr_extend(&provider, rtmr_state->index, buf, count);
+}
+CONFIGFS_BIN_ATTR(tsm_rtmr_, digest, NULL, TSM_DIGEST_MAX);
+
+static struct configfs_bin_attribute *tsm_rtmr_bin_attrs[] = {
+	&tsm_rtmr_attr_digest,
+	NULL,
+};
+
 static void tsm_rtmr_item_release(struct config_item *cfg)
 {
 	struct tsm_rtmr_state *state = to_tsm_rtmr_state(cfg);
@@ -564,6 +621,7 @@  static struct configfs_item_operations tsm_rtmr_item_ops = {
 
 const struct config_item_type tsm_rtmr_type = {
 	.ct_owner = THIS_MODULE,
+	.ct_bin_attrs = tsm_rtmr_bin_attrs,
 	.ct_attrs = tsm_rtmr_attrs,
 	.ct_item_ops = &tsm_rtmr_item_ops,
 };