From: Jason Gunthorpe <jgg@nvidia.com>
To: Dave Jiang <dave.jiang@intel.com>
Cc: "Reshetova, Elena" <elena.reshetova@intel.com>,
Xu Yilun <yilun.xu@linux.intel.com>,
"Aneesh Kumar K.V" <aneesh.kumar@kernel.org>,
"linux-coco@lists.linux.dev" <linux-coco@lists.linux.dev>,
Jiri Pirko <jiri@resnulli.us>,
"Tian, Kevin" <kevin.tian@intel.com>,
Alexey Kardashevskiy <aik@amd.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Steven Price <steven.price@arm.com>,
Kiryl Shutsemau <kas@kernel.org>,
"Edgecombe, Rick P" <rick.p.edgecombe@intel.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
Jonathan Cameron <jic23@kernel.org>,
Bjorn Helgaas <bhelgaas@google.com>,
Ashish Kalra <ashish.kalra@amd.com>,
Tom Lendacky <thomas.lendacky@amd.com>,
John Allen <john.allen@amd.com>, Will Deacon <will@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
"patches@lists.linux.dev" <patches@lists.linux.dev>
Subject: Re: [RFC PATCH v1 10/11] virt: coco: arm-cca-host: Publish slot zero and establish streams after acceptance
Date: Sun, 8 Nov 2026 14:33:37 -0400 [thread overview]
Message-ID: <20261108183337.GL770409@nvidia.com> (raw)
In-Reply-To: <53bc57bf-1ee1-407a-b48b-bc6b2deee12a@intel.com>
On Fri, Nov 06, 2026 at 03:39:56PM -0700, Dave Jiang wrote:
> I think that works for TDX. tdx-host already relays every DOE
> message for the TDX Module, so it can hand them to core SPDM
> code.
Everyone does this right? TDX does, I know ARM does, and AI tells me
AMD does too. So this is universal.
> Only part of the flow is clear text though. With the current
> module I see the VCA, GET_CERTIFICATE for slot 0, and
> KEY_EXCHANGE/KEY_EXCHANGE_RSP in the clear. There's no
> GET_DIGESTS. FINISH, GET_MEASUREMENTS, the reads of slots 1-7 and
> the TDISP messages are all inside the session, so the kernel can't
> decode them.
Yes, but in 1.3 there would be a get digests too.
> So the kernel would get the VCA, slot 0's chain and the KEY_EXCHANGE
> transcript from snooping, and still take MEASUREMENTS from the TDX
> Module's device info. Would that be ok with you?
Yeah, this is what I was thinking about. I think this should be
completly universal and uniform across every implementation.
> I tried disturbing the session from the host with a test hack in
> tdx-host, right before KEY_EXCHANGE. A bare GET_VERSION makes the
> device reject KEY_EXCHANGE. Replaying the VCA with one field changed
> gets a KEY_EXCHANGE_RSP back, but the TDX module rejects it. So
> KEY_EXCHANGE does blow up when the host interferes, as you said in
> the other reply.
Yes, this is a critical security feature.
The host could inject GET_CERTIFICATES on its own right before
KEY_EXCHANGE, and I'm wondering if we end up with this scheme if the
1.3 mode should simply have the host issue GET_CERTIFICATES and the
TSM side just does GET_DIGESTS.
> Seems reasonable. Every TSM gets the same uAPI, and on TDX the host
> already has every message in hand so the driver side should be
> small. It also lets the kernel check the KEY_EXCHANGE_RSP signature
> itself instead of taking TSM's word for it.
Yeah, not sure that has security value, but it is a nice debugging
aide for sure.
> > If you *really* want to do certificate refresh it has to be a
> > dedicated operation, it has to be supported by the TSM, and it has to
> > get back another SIGNED GET_DIGESTS. All that would ideally have to be
> > dumped into the transcript again.
> >
> > I feel it is alot of work and not valuable.
>
> On TDX the re-read of the chains comes with the measurement
> refresh. The kernel doesn't ask for it separately. For option (A) I
> think the kernel can drop the re-read chains and pass up only the
> new MEASUREMENTS. It already has the copy KEY_EXCHANGE signed.
I don't know why you guys do this, I would take it out, IMHO. Just
wastes time. Yes, kernel should forward the chain it collected with
KEY_EXCHANGE, it isn't allowed to change and there is no need to
recollect it.
> > I think any device that can loose its private key while an SPDM
> > session is open (ie with live update or something) is fundamentally
> > broken. If it wants to do this it has to break the SPDM.
>
> On the host side, should we drop the fresh-nonce collection before
> ACCEPT then, or keep it as audit only? I'd rather not carry a uAPI
> for it if nobody needs it. The guest's lock keeps its own
> fresh-nonce recollection, as you asked for earlier.
What does this mean?
Every single call to GET_MEASUREMENTS should come with a user provide
nonce.
You need to provide two flows
1) /dev/attestation/xx on the host does a GET_MEASUREMENTS for the
host's use, with out *any* disruption to *any* guest
2) iommufd command 'get attestation fd for vdev' ends up implementing
the hypevisor side of guest/host channel and does GET_MEASUREMENTS
with whatever anti-tamerping scheme TDX has.
Both of these need to accept a nonce.
No GET_MEASUREMENTS should be issued, and certainly not from accept,
until userspace specifically asks for it with a user provided nonce.
> >> (3) TDH.SPDM.CREATE runs first. The kernel sets CERTIFICATE_SLOT_MASK to
> >> 0x01, so the TSM reads only slot 0's chain. It could also read slots
> >> 1-7 inside the session [GUIDE B.1.1, Table B-1], but no signature
> >> would cover them: KEY_EXCHANGE hashes only the chain of the slot it
> >> names [SPDM 10.18.1]. So (a) doesn't report them.
> >
> > ? this is confusing. KEY_EXCHANGE slot=0 includes the hash of the
> > certificate chain in slot 0. If the TSM doesn't even read that slot
> > during the premable it is impossible to validate the KEY_EXCHANGE.
> >
> > What prupose is there for this configurable "the kernel sets
> > CERTIFICATE_SLOT_MASK to 0x01" ? If the kernel sets for slot 1 then
> > KEY_EXCHANGE must fail?
>
> No, it doesn't fail, and the note was confusing. The mask doesn't
> control slot selection. It only picks which of slots 1-7 the module
> also returns. Slot 0's chain is always read and returned. The module
> reads it in the clear before KEY_EXCHANGE, even with bit 0 clear.
> Slots 1-7 are read inside the session after KEY_EXCHANGE. Setting
> 0x01 just skips reading chains nothing signs.
OK.. Weird, not sure I see that as useful?
> > Yes, but if we do #1 above I would keep it anyhow and optionally give
> > it to the verifier. I agree it is fairly pointless, but it is really
> > cheap to do if you have #1 and simply capturing the *entire* signed
> > transcript is forward looking from an ABI design perspective.
>
> Agreed. With snooping the kernel has them anyway. I'll change (5) to
> keep them and hand them to the verifier.
So what I'm thinking is some kind of little library with a driver
interface like the blow. It would be used instead of the driver just
calling pci_doe() directly and does all the capturing magically and
transparently.
Basically the only thing in the driver will be the communicate loop,
and the little bit ARM needs to get the PUBKEY out.
I've got some AI running through to make a sketch of this to see if it
is a terrible idea.
struct att_spdm_connection; /* opaque */
/*
* Called by the driver (not the TSM core) before the first GET_VERSION is
* issued. @doe_mb is used, not owned; it must outlive the connection.
* Returns ERR_PTR() on failure.
*/
struct att_spdm_connection *
att_spdm_connection_create(struct pci_doe_mb *doe_mb);
/*
* Release all capture storage. Must not race with att_spdm_doe_exchange().
* Sends nothing to the device. Evidence references already taken stay valid.
*/
void att_spdm_connection_destroy(struct att_spdm_connection *conn);
/*
* Forward one firmware-generated request over DOE and capture it.
*
* @doe_type: PCI_DOE_FEATURE_CMA or PCI_DOE_FEATURE_SSESSION, as chosen by
* firmware. Any other value is -EINVAL.
* @req: may point into shared or firmware-owned memory. It is read
* exactly once, into private storage; nothing re-reads it.
*
* Returns 0 when a response is available through att_spdm_response_len() and
* att_spdm_copy_response(). An SPDM ERROR reply (Busy, ResponseNotReady,
* LargeResponse, InvalidRequest, ...) still returns 0: it is a response for
* firmware to handle.
*
* Returns a negative errno when the exchange failed or was refused before
* reaching DOE. The error is latched: every later call returns the same
* value, and the caller must destroy the connection.
* -ECONNRESET GET_VERSION restart, or RequestResynch
* -EPROTO malformed or illegal message for the current state,
* including any plaintext request after KEY_EXCHANGE_RSP
* -EOPNOTSUPP PSK or mutual-authentication flow
* -E2BIG collection budget exhausted
* -ENOMEM allocation failure
* other DOE transport failure
*
* Sleeps. Takes no lock: the TSM core issues SPDM operations to the driver
* one at a time, so calls on a connection are never concurrent.
*/
int att_spdm_doe_exchange(struct att_spdm_connection *conn, u8 doe_type,
const void *req, size_t req_len);
/*
* Size in bytes of the latest raw DOE response, including DOE dword padding
* and any ERROR or chunk envelope. Valid until the next exchange or until
* the connection is destroyed. Returns 0 if no response is available.
*/
size_t att_spdm_response_len(struct att_spdm_connection *conn);
/*
* Copy the latest raw response into @dst. Writes @dst only; never reads it.
* Returns the number of bytes copied, -ENOSPC without copying anything if
* @dst_len is too small, or -ENODATA if no response is available. Never
* truncates. Can be called repeatedly; it does not consume the response.
* An undersized buffer is not latched: how to react is the driver's
* decision.
*/
ssize_t att_spdm_copy_response(struct att_spdm_connection *conn,
void *dst, size_t dst_len);
/*
* The driver calls this once firmware has reported that the SPDM session is
* established and valid, for example when the firmware connect command
* completes successfully. It is the only point where any future kernel-side
* validation of the captured evidence may run, and the only point where such
* validation may fail.
*
* Requires ATT_SPDM_CAPTURED. Calling it in any other state returns -EINVAL
* and latches the error. On success the status moves to
* ATT_SPDM_ESTABLISHED; on failure the error is latched.
*
* Evidence is only made available to attestation consumers after this
* call succeeds.
*/
int att_spdm_session_established(struct att_spdm_connection *conn);
Jason
next prev parent reply other threads:[~2026-11-08 18:33 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 15:26 [RFC PATCH v1 00/11] PCI/TSM: Add CTLV attestation Aneesh Kumar K.V (Arm)
2026-10-28 15:26 ` [RFC PATCH v1 01/11] attestation: Restrict inherited operations per instance Aneesh Kumar K.V (Arm)
2026-10-30 13:29 ` Jiri Pirko
2026-10-28 15:26 ` [RFC PATCH v1 02/11] attestation: Filter evidence objects " Aneesh Kumar K.V (Arm)
2026-10-30 13:44 ` Jiri Pirko
2026-10-31 6:24 ` Aneesh Kumar K.V
2026-11-02 19:14 ` Jiri Pirko
2026-10-28 15:26 ` [RFC PATCH v1 03/11] attestation: Enter secure operation when evidence is accepted Aneesh Kumar K.V (Arm)
2026-10-30 13:51 ` Jiri Pirko
2026-10-30 15:36 ` Jason Gunthorpe
2026-10-31 4:09 ` Aneesh Kumar K.V
2026-11-02 11:28 ` Jiri Pirko
2026-10-28 15:26 ` [RFC PATCH v1 04/11] attestation: Bind object selection to accepted evidence snapshots Aneesh Kumar K.V (Arm)
2026-10-28 15:26 ` [RFC PATCH v1 05/11] attestation: Make the evidence-get challenge attribute optional Aneesh Kumar K.V (Arm)
2026-10-28 15:26 ` [RFC PATCH v1 06/11] PCI/TSM: Describe the PCI attestation control family Aneesh Kumar K.V (Arm)
2026-10-30 14:01 ` Jiri Pirko
2026-10-30 15:43 ` Jason Gunthorpe
2026-11-02 12:45 ` Jiri Pirko
2026-11-03 15:45 ` Jason Gunthorpe
2026-11-04 9:21 ` Jiri Pirko
2026-11-04 14:00 ` Jason Gunthorpe
2026-10-31 4:05 ` Aneesh Kumar K.V
2026-11-02 11:50 ` Jiri Pirko
2026-11-03 15:35 ` Jason Gunthorpe
2026-10-31 4:22 ` Aneesh Kumar K.V
2026-11-02 11:30 ` Jiri Pirko
2026-11-03 15:39 ` Jason Gunthorpe
2026-10-28 15:26 ` [RFC PATCH v1 07/11] attestation: Add attestation helpers for PCI/TSM integration Aneesh Kumar K.V (Arm)
2026-10-28 15:26 ` [RFC PATCH v1 08/11] PCI/TSM: Bind CTLV attestation to connected and locked contexts Aneesh Kumar K.V (Arm)
2026-10-28 22:56 ` Dave Jiang
2026-10-29 5:30 ` Aneesh Kumar K.V
2026-10-29 12:41 ` Jason Gunthorpe
2026-10-30 14:04 ` Jiri Pirko
2026-10-30 14:08 ` Jiri Pirko
2026-10-30 15:39 ` Jason Gunthorpe
2026-11-02 12:11 ` Jiri Pirko
2026-11-03 15:41 ` Jason Gunthorpe
2026-10-28 15:26 ` [RFC PATCH v1 09/11] crypto/ccp: Defer SEV-TIO link setup until evidence acceptance Aneesh Kumar K.V (Arm)
2026-11-06 7:47 ` Alexey Kardashevskiy
2026-11-06 13:14 ` Aneesh Kumar K.V
2026-11-06 14:21 ` Jason Gunthorpe
2026-10-28 15:26 ` [RFC PATCH v1 10/11] virt: coco: arm-cca-host: Publish slot zero and establish streams after acceptance Aneesh Kumar K.V (Arm)
2026-10-29 16:56 ` Dave Jiang
2026-10-29 17:10 ` Jason Gunthorpe
2026-10-30 9:58 ` Reshetova, Elena
2026-10-30 13:15 ` Jason Gunthorpe
2026-10-31 3:47 ` Aneesh Kumar K.V
2026-11-02 10:11 ` Reshetova, Elena
2026-11-02 17:26 ` Jason Gunthorpe
2026-11-03 12:01 ` Reshetova, Elena
2026-11-03 15:16 ` Jason Gunthorpe
2026-11-04 8:03 ` Xu Yilun
2026-11-04 9:49 ` Reshetova, Elena
2026-11-04 13:41 ` Jason Gunthorpe
2026-11-04 16:54 ` Dave Jiang
2026-11-06 15:53 ` Dave Jiang
2026-11-06 19:30 ` Jason Gunthorpe
2026-11-06 22:39 ` Dave Jiang
2026-11-08 18:33 ` Jason Gunthorpe [this message]
2026-11-04 9:03 ` Reshetova, Elena
2026-11-04 13:48 ` Jason Gunthorpe
2026-11-06 8:24 ` Aneesh Kumar K.V
2026-11-06 12:49 ` Reshetova, Elena
2026-11-06 15:53 ` Aneesh Kumar K.V
2026-11-06 18:54 ` Jason Gunthorpe
2026-11-03 16:31 ` Aneesh Kumar K.V
2026-11-03 17:56 ` Jason Gunthorpe
2026-11-02 10:05 ` Reshetova, Elena
2026-11-02 10:22 ` Reshetova, Elena
2026-11-02 17:37 ` Jason Gunthorpe
2026-10-28 15:26 ` [RFC PATCH v1 11/11] virt: coco: arm-cca-guest: Refresh selected evidence against trusted digests Aneesh Kumar K.V (Arm)
2026-10-30 12:34 ` [RFC PATCH v1 00/11] PCI/TSM: Add CTLV attestation Xu Yilun
2026-10-30 15:32 ` Jason Gunthorpe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261108183337.GL770409@nvidia.com \
--to=jgg@nvidia.com \
--cc=aik@amd.com \
--cc=aneesh.kumar@kernel.org \
--cc=ashish.kalra@amd.com \
--cc=bhelgaas@google.com \
--cc=catalin.marinas@arm.com \
--cc=dave.hansen@linux.intel.com \
--cc=dave.jiang@intel.com \
--cc=elena.reshetova@intel.com \
--cc=jic23@kernel.org \
--cc=jiri@resnulli.us \
--cc=john.allen@amd.com \
--cc=kas@kernel.org \
--cc=kevin.tian@intel.com \
--cc=linux-coco@lists.linux.dev \
--cc=mark.rutland@arm.com \
--cc=patches@lists.linux.dev \
--cc=rick.p.edgecombe@intel.com \
--cc=steven.price@arm.com \
--cc=suzuki.poulose@arm.com \
--cc=thomas.lendacky@amd.com \
--cc=will@kernel.org \
--cc=yilun.xu@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.