Re: [PATCH v8 5/5] x86/tdx: Add Quote generation support

Sathyanarayanan Kuppuswamy
2022-07-21T22:08:53Z

Hi Dave,

On 7/21/22 12:23 PM, Dave Hansen wrote:
> On 7/21/22 11:57, Sathyanarayanan Kuppuswamy wrote:
>>> How does the VMM know how much to read/write? I have a theory: the spec
>>> says that R12 is:
>>>
>>> "Shared 4KB GPA as input – the memory contains a
>>> TDREPORT_STRUCT."
>>>
>>> That's *A* 4KB GPA. The maximum is one 4KB page. That's the only thing
>>> that makes sense because there's no length in the ABI anywhere.
>>>
>>> What am I missing?
>> I think you are looking into the old spec. Please check the version
>> "FEBRUARY 2022"
>>
>> Following are the ABI details:
>>
>> R11 - TDG.VP.VMCALL< GetQuote > sub-function per Table 2-3
>> R12 - Shared GPA as input – the memory contains a TDREPORT_STRUCT. The
>> same buffer is used as output – the memory contains a TD Quote.
>> R13 - Size of shared GPA. The size must be 4KB-aligned.
>
> Yeah, silly me. I assumed the ABI was stable and wouldn't be, you know,
> adding and removing parameters.
>
> I still don't know how this all works. You just said:

At a high level, the quote generation communication flow is as below:

Entities involved are,

Guest TD user app (send TDREPORT) <-> Quoting Enclave (QE) (Sign TDREPORT and send Quote)

Steps involved are,

1. Attestation agent (in TD userspace)  will get the TDREPORT data from
the TDX module.
2. To generate a remotely verifiable Quote, send the TDREPORT data to the
Quoting enclave (QE). QE will verify the integrity of TDREPORT and sign
it with the attestation key.
* QE can be hosted as simple app in the host, or it can be hosted in a special
TD guest.
3. Method of sending TDREPORT to QE depends on the QE requirements. In most
cases, it will support TCP/IP or vsock communication models. So the attestation
agent can easily send the TDREPORT via TCP/IP and get the Quote data.

But for platforms that do not want to support TCP/IP or socket communication,
TDX ABI defines a method of getting Quote using TDVMCALL. It is a less common
case. Our current discussion is related to this approach.

Entities involved in this approach are,

TD Guest user app <-> TD Guest kernel <-> VMM  <-> QE

Communication flow looks like below:

1. Attestation agent (in TD userspace)  will get the TDREPORT data from
the TDX module.
2. Check with QE about the required quote size (it can be some form of
agreement between QE and attestation agent).
3. Allocate space for Quote buffer and update the header details like
mentioned below and send the quote buffer and length details via
IOCTL

+/*
+ * Format of Quote data header. More details can be found in TDX
+ * Guest-Host Communication Interface (GHCI) for Intel TDX 1.0,
+ * section titled "TDG.VP.VMCALL<GetQuote>"
+ */
+struct tdx_quote_hdr {
+       /* Quote version, filled by TD */
+       __u64 version;
+       /* Status code of Quote request, filled by VMM */
+       __u64 status;
+       /* Length of TDREPORT, filled by TD */
+       __u32 in_len;
+       /* Length of Quote, filled by VMM */
+       __u32 out_len;
+       /* Actual Quote data or TDREPORT on input */
+       __u64 data[0];
+};
+
+/* struct tdx_quote_req: Request to generate TD Quote using TDREPORT
+ *
+ * @buf         : Pass user data that includes TDREPORT as input. Upon
+ *                successful completion of IOCTL, output is copied
+ *                back to the same buffer.
+ * @len         : Length of the Quote buffer.
+ */
+struct tdx_quote_req {
+       __u64 buf;
+       __u64 len;
+}

4. Once an IOCTL request is received, the kernel will allocate a Quote buffer
of the requested size, and use GetQuote hypercall to send this request to VMM.

GetQuote (TDVMCALL type, kernel buffer physical addr, length of the buffer).

5. Upon hypercall request, VMM will further send the details to the QE. Once
QE processes this request and generates the Quote, it will update the status
details in the Quote header and copy the Quote back to the guest GPA. After
completing the request, it will also send the IRQ notification to the TD
Guest kernel. Event notification IRQ requirement is due to this step.

6. Once TD Guest kernel receives event notification, it will copy the
contents of the Quote back to the user buffer and complete the IOCTL
request.

>
>> Current ABI allows attestation service and agent to decide the quote size. So
>> we can't make assumptions on what that size will be.
>
> But, the guest *HAS* to make assumptions, right? It's allocating the
> buffer and handing a pointer and size over to the host. It's also guest
> *userspace*. In fact, this implementation *ABSOLUTELY* makes
> assumptions about the buffer size.
>
> If host userspace some day decides it needs 5MB of space, then all the
> guests will just stop working. This implementation is limited by the
> max page allocator size.

Agree. We are assuming that the user agent will not request buffer that
exceeds the limit of the page allocator. But as Isaku mentioned, it is
expected that the Quote size will only be in KBs. I think the main
reason for ABI not limiting the size is, for flexibility and to
support future requirements.

Also, as mentioned above, this approach is not a common case. TCP/IP or
vsock models are generally supported and can be used for Quote generation.

--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer