Subject: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support

Attestation is the process used by two un-trusted entities to prove to
each other that it can be trusted. In TDX guest, attestation is mainly
used to verify the trustworthiness of a TD to the 3rd party key
servers.

First step in the attestation process is to generate the TDREPORT data.
This support is added using tdx_mcall_tdreport() API. The second stage
in the attestation process is for the guest to request the VMM generate
and sign a quote based on the TDREPORT acquired earlier. More details
about the steps involved in attestation process can be found in TDX
Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section
titled "TD attestation"

Add tdx_hcall_get_quote() helper function to implement the GetQuote
hypercall.

More details about the GetQuote TDVMCALL are in the Guest-Host
Communication Interface (GHCI) Specification, sec 3.3, titled
"VP.VMCALL<GetQuote>".

This will be used by the TD attestation driver in follow-on patches.

Reviewed-by: Tony Luck <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Acked-by: Kirill A. Shutemov <[email protected]>
Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
---
arch/x86/coco/tdx/tdx.c | 38 ++++++++++++++++++++++++++++++++++++++
arch/x86/include/asm/tdx.h | 2 ++
2 files changed, 40 insertions(+)

diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index 3e409b618d3f..c259d81a5d7f 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -21,6 +21,7 @@

/* TDX hypercall Leaf IDs */
#define TDVMCALL_MAP_GPA 0x10001
+#define TDVMCALL_GET_QUOTE 0x10002

/* MMIO direction */
#define EPT_READ 0
@@ -144,6 +145,43 @@ long tdx_mcall_tdreport(void *data, void *reportdata)
}
EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);

+/*
+ * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
+ *
+ * @data : Address of 8KB GPA memory which contains
+ * TDREPORT_STRUCT.
+ * @len : Length of the GPA in bytes.
+ *
+ * return 0 on success or failure error number.
+ */
+long tdx_hcall_get_quote(void *data, u64 len)
+{
+ u64 ret;
+
+ /*
+ * Use confidential guest TDX check to ensure this API is only
+ * used by TDX guest platforms.
+ */
+ if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return -EINVAL;
+
+ /*
+ * Pass the physical address of tdreport data to the VMM
+ * and trigger the tdquote generation. Quote data will be
+ * stored back in the same physical address space. More info
+ * about ABI can be found in TDX Guest-Host-Communication
+ * Interface (GHCI), sec titled "TDG.VP.VMCALL<GetQuote>".
+ */
+ ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)),
+ len, 0, 0);
+
+ if (ret)
+ return ret;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(tdx_hcall_get_quote);
+
static u64 get_cc_mask(void)
{
struct tdx_module_output out;
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index a151f69dd6ef..014cc6192dc5 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -69,6 +69,8 @@ bool tdx_early_handle_ve(struct pt_regs *regs);

long tdx_mcall_tdreport(void *data, void *reportdata);

+long tdx_hcall_get_quote(void *data, u64 len);
+
#else

static inline void tdx_early_init(void) { };
--
2.25.1


2022-04-19 13:38:29

by Huang, Kai

[permalink] [raw]
Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support

On Mon, 2022-04-18 at 21:04 -0700, Sathyanarayanan Kuppuswamy wrote:
>
> On 4/18/22 7:59 PM, Kai Huang wrote:
> > On Fri, 2022-04-15 at 15:01 -0700, Kuppuswamy Sathyanarayanan wrote:
> > > Attestation is the process used by two un-trusted entities to prove to
> > > each other that it can be trusted.
> > >
> >
> > I don't think this is accurate. TDX attestation is used to attest a TD is
> > genuine and runs on genuine Intel platforms to any challenger who wants to
> > verify this. Theoretically, the TD guest doesn't necessarily need to verify the
> > trustworthiness of the challenger.
>
> Above is a generic explanation for attestation (not TDX specific).

Even for generic, it seems it's not accurate. As I said it's not "two un-
trusted entities to prove to each other".

>
> >
> > > In TDX guest, attestation is mainly
> > > used to verify the trustworthiness of a TD to the 3rd party key
> > > servers.
> >
> > And "key servers" is only one potential use case of using the attestation
> > service. I don't think it's right to say attestation is mainly used for this.
>
> Agree. I will change it to,
>
> Attestation is used to verify the trustworthiness of a TD to the other
> 3rd party entities before exchanging sensitive information.

Fine to me.

>
> >
> > >
> > > First step in the attestation process is to generate the TDREPORT data.
> > > This support is added using tdx_mcall_tdreport() API. The second stage
> > > in the attestation process is for the guest to request the VMM generate
> > > and sign a quote based on the TDREPORT acquired earlier.
> > >
> >
> > This is not accurate. The VMM cannot generate and sign the Quote. Only Quoting
> > enclave (QE) can do that. The VMM is just a bridge which helps to send the
> > TDREPORT to the QE and then give the Quote back to TD guest when it receives it.
> >
> > For instance, theoretically GetQuote TDVMCALL isn't absolutely necessarily for
> > attestation. The TD attestation agent (runs in TD guest userspace) can choose
> > to connect to QE directly if feasible (i.e. via vsock, tcp/ip, ..) and then send
> > the TDREPORT to QE and receive the Quote directly.
>
> Yes, since guest does not get involved with how VMM facilities the
> Quote Generation, I did not elaborate on Quoting Enclave part.
>
> How about following change?
>
> The second stage in the attestation process is for the guest to pass the
> TDREPORT data (generated by TDREPORT TDCALL) to the VMM and
> request it to trigger Quote generation via a Quoting enclave (QE).
>
> Also note that GetQuote is an asynchronous request. So this API does not
> block till Quote is generated. VMM will notify the TD guest about the
> quote generation completion via interrupt (configured by
> SetupEventNotifyInterrupt hypercall). This support will be added by
> follow on patches in this series.

Fine to me.

Btw, if I recall correctly, it seems we don't need to say "xxx will be done in
later patches", etc. I can be wrong. Will leave to others.

[...]


> > > +/*
> > > + * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
> > > + *
> > > + * @data : Address of 8KB GPA memory which contains
> > > + * TDREPORT_STRUCT.
> > > + * @len : Length of the GPA in bytes.
> >
> > It seems GetQuote definitions in public GHCI 1.0 and GHCI 1.5 are different. In
> > GHCI 1.5, R13 is used to specify the shared memory size.
> >
> > I think it is because the public GHCI 1.0 hasn't been updated yet?
>
> Please check the latest 1.0 specification (updated on Feb 2022). It has
> details about R13 register.

Thanks. So it seems GHCI 1.0 has also been updated and it is consistent with
GHCI 1.5 now. In this case, why do we still assume 8K shared memory? Are you
going to update the driver?


2022-04-19 15:36:59

by Huang, Kai

[permalink] [raw]
Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support

On Fri, 2022-04-15 at 15:01 -0700, Kuppuswamy Sathyanarayanan wrote:
> Attestation is the process used by two un-trusted entities to prove to
> each other that it can be trusted. 
>

I don't think this is accurate. TDX attestation is used to attest a TD is
genuine and runs on genuine Intel platforms to any challenger who wants to
verify this. Theoretically, the TD guest doesn't necessarily need to verify the
trustworthiness of the challenger.

> In TDX guest, attestation is mainly
> used to verify the trustworthiness of a TD to the 3rd party key
> servers.

And "key servers" is only one potential use case of using the attestation
service. I don't think it's right to say attestation is mainly used for this.

>
> First step in the attestation process is to generate the TDREPORT data.
> This support is added using tdx_mcall_tdreport() API. The second stage
> in the attestation process is for the guest to request the VMM generate
> and sign a quote based on the TDREPORT acquired earlier. 
>

This is not accurate. The VMM cannot generate and sign the Quote. Only Quoting
enclave (QE) can do that. The VMM is just a bridge which helps to send the
TDREPORT to the QE and then give the Quote back to TD guest when it receives it.

For instance, theoretically GetQuote TDVMCALL isn't absolutely necessarily for
attestation. The TD attestation agent (runs in TD guest userspace) can choose
to connect to QE directly if feasible (i.e. via vsock, tcp/ip, ..) and then send
the TDREPORT to QE and receive the Quote directly.

> More details
> about the steps involved in attestation process can be found in TDX
> Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section
> titled "TD attestation"

See my reply to previous patch. It's mentioned in GHCI 1.0 spec (section 5.4 TD
attestation).

>
> Add tdx_hcall_get_quote() helper function to implement the GetQuote
> hypercall.
>
> More details about the GetQuote TDVMCALL are in the Guest-Host
> Communication Interface (GHCI) Specification, sec 3.3, titled
> "VP.VMCALL<GetQuote>".
>
> This will be used by the TD attestation driver in follow-on patches.
>
> Reviewed-by: Tony Luck <[email protected]>
> Reviewed-by: Andi Kleen <[email protected]>
> Acked-by: Kirill A. Shutemov <[email protected]>
> Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
> ---
> arch/x86/coco/tdx/tdx.c | 38 ++++++++++++++++++++++++++++++++++++++
> arch/x86/include/asm/tdx.h | 2 ++
> 2 files changed, 40 insertions(+)
>
> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
> index 3e409b618d3f..c259d81a5d7f 100644
> --- a/arch/x86/coco/tdx/tdx.c
> +++ b/arch/x86/coco/tdx/tdx.c
> @@ -21,6 +21,7 @@
>
> /* TDX hypercall Leaf IDs */
> #define TDVMCALL_MAP_GPA 0x10001
> +#define TDVMCALL_GET_QUOTE 0x10002
>
> /* MMIO direction */
> #define EPT_READ 0
> @@ -144,6 +145,43 @@ long tdx_mcall_tdreport(void *data, void *reportdata)
> }
> EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);
>
> +/*
> + * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
> + *
> + * @data : Address of 8KB GPA memory which contains
> + * TDREPORT_STRUCT.
> + * @len : Length of the GPA in bytes.

It seems GetQuote definitions in public GHCI 1.0 and GHCI 1.5 are different. In
GHCI 1.5, R13 is used to specify the shared memory size.

I think it is because the public GHCI 1.0 hasn't been updated yet?

> + *
> + * return 0 on success or failure error number.
> + */
> +long tdx_hcall_get_quote(void *data, u64 len)
> +{
> + u64 ret;
> +
> + /*
> + * Use confidential guest TDX check to ensure this API is only
> + * used by TDX guest platforms.
> + */
> + if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
> + return -EINVAL;
> +
> + /*
> + * Pass the physical address of tdreport data to the VMM
> + * and trigger the tdquote generation. Quote data will be
> + * stored back in the same physical address space. More info
> + * about ABI can be found in TDX Guest-Host-Communication
> + * Interface (GHCI), sec titled "TDG.VP.VMCALL<GetQuote>".
> + */
> + ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)),
> + len, 0, 0);

I think this function gives people impression that when this function is done,
the Quote is ready immediately in the shared buffer. But actually GetQuote is
asynchronous. It only means the VMM has accepted this request, but the Quote is
actually only ready when the guest receives the event notification (done in
later patch). So I guess there should be a comment somewhere (or even in commit
message) to explain that?

> +
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(tdx_hcall_get_quote);
> +
> static u64 get_cc_mask(void)
> {
> struct tdx_module_output out;
> diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
> index a151f69dd6ef..014cc6192dc5 100644
> --- a/arch/x86/include/asm/tdx.h
> +++ b/arch/x86/include/asm/tdx.h
> @@ -69,6 +69,8 @@ bool tdx_early_handle_ve(struct pt_regs *regs);
>
> long tdx_mcall_tdreport(void *data, void *reportdata);
>
> +long tdx_hcall_get_quote(void *data, u64 len);
> +
> #else
>
> static inline void tdx_early_init(void) { };

Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support



On 4/18/22 7:59 PM, Kai Huang wrote:
> On Fri, 2022-04-15 at 15:01 -0700, Kuppuswamy Sathyanarayanan wrote:
>> Attestation is the process used by two un-trusted entities to prove to
>> each other that it can be trusted.
>>
>
> I don't think this is accurate. TDX attestation is used to attest a TD is
> genuine and runs on genuine Intel platforms to any challenger who wants to
> verify this. Theoretically, the TD guest doesn't necessarily need to verify the
> trustworthiness of the challenger.

Above is a generic explanation for attestation (not TDX specific).

>
>> In TDX guest, attestation is mainly
>> used to verify the trustworthiness of a TD to the 3rd party key
>> servers.
>
> And "key servers" is only one potential use case of using the attestation
> service. I don't think it's right to say attestation is mainly used for this.

Agree. I will change it to,

Attestation is used to verify the trustworthiness of a TD to the other
3rd party entities before exchanging sensitive information.

>
>>
>> First step in the attestation process is to generate the TDREPORT data.
>> This support is added using tdx_mcall_tdreport() API. The second stage
>> in the attestation process is for the guest to request the VMM generate
>> and sign a quote based on the TDREPORT acquired earlier.
>>
>
> This is not accurate. The VMM cannot generate and sign the Quote. Only Quoting
> enclave (QE) can do that. The VMM is just a bridge which helps to send the
> TDREPORT to the QE and then give the Quote back to TD guest when it receives it.
>
> For instance, theoretically GetQuote TDVMCALL isn't absolutely necessarily for
> attestation. The TD attestation agent (runs in TD guest userspace) can choose
> to connect to QE directly if feasible (i.e. via vsock, tcp/ip, ..) and then send
> the TDREPORT to QE and receive the Quote directly.

Yes, since guest does not get involved with how VMM facilities the
Quote Generation, I did not elaborate on Quoting Enclave part.

How about following change?

The second stage in the attestation process is for the guest to pass the
TDREPORT data (generated by TDREPORT TDCALL) to the VMM and
request it to trigger Quote generation via a Quoting enclave (QE).

Also note that GetQuote is an asynchronous request. So this API does not
block till Quote is generated. VMM will notify the TD guest about the
quote generation completion via interrupt (configured by
SetupEventNotifyInterrupt hypercall). This support will be added by
follow on patches in this series.


>
>> More details
>> about the steps involved in attestation process can be found in TDX
>> Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section
>> titled "TD attestation"
>
> See my reply to previous patch. It's mentioned in GHCI 1.0 spec (section 5.4 TD
> attestation).

Yes. I will change it to 1.0 reference.

>
>>
>> Add tdx_hcall_get_quote() helper function to implement the GetQuote
>> hypercall.
>>
>> More details about the GetQuote TDVMCALL are in the Guest-Host
>> Communication Interface (GHCI) Specification, sec 3.3, titled
>> "VP.VMCALL<GetQuote>".
>>
>> This will be used by the TD attestation driver in follow-on patches.
>>
>> Reviewed-by: Tony Luck <[email protected]>
>> Reviewed-by: Andi Kleen <[email protected]>
>> Acked-by: Kirill A. Shutemov <[email protected]>
>> Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
>> ---
>> arch/x86/coco/tdx/tdx.c | 38 ++++++++++++++++++++++++++++++++++++++
>> arch/x86/include/asm/tdx.h | 2 ++
>> 2 files changed, 40 insertions(+)
>>
>> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
>> index 3e409b618d3f..c259d81a5d7f 100644
>> --- a/arch/x86/coco/tdx/tdx.c
>> +++ b/arch/x86/coco/tdx/tdx.c
>> @@ -21,6 +21,7 @@
>>
>> /* TDX hypercall Leaf IDs */
>> #define TDVMCALL_MAP_GPA 0x10001
>> +#define TDVMCALL_GET_QUOTE 0x10002
>>
>> /* MMIO direction */
>> #define EPT_READ 0
>> @@ -144,6 +145,43 @@ long tdx_mcall_tdreport(void *data, void *reportdata)
>> }
>> EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);
>>
>> +/*
>> + * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
>> + *
>> + * @data : Address of 8KB GPA memory which contains
>> + * TDREPORT_STRUCT.
>> + * @len : Length of the GPA in bytes.
>
> It seems GetQuote definitions in public GHCI 1.0 and GHCI 1.5 are different. In
> GHCI 1.5, R13 is used to specify the shared memory size.
>
> I think it is because the public GHCI 1.0 hasn't been updated yet?

Please check the latest 1.0 specification (updated on Feb 2022). It has
details about R13 register.

>
>> + *
>> + * return 0 on success or failure error number.
>> + */
>> +long tdx_hcall_get_quote(void *data, u64 len)
>> +{
>> + u64 ret;
>> +
>> + /*
>> + * Use confidential guest TDX check to ensure this API is only
>> + * used by TDX guest platforms.
>> + */
>> + if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
>> + return -EINVAL;
>> +
>> + /*
>> + * Pass the physical address of tdreport data to the VMM
>> + * and trigger the tdquote generation. Quote data will be
>> + * stored back in the same physical address space. More info
>> + * about ABI can be found in TDX Guest-Host-Communication
>> + * Interface (GHCI), sec titled "TDG.VP.VMCALL<GetQuote>".
>> + */
>> + ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)),
>> + len, 0, 0);
>
> I think this function gives people impression that when this function is done,
> the Quote is ready immediately in the shared buffer. But actually GetQuote is
> asynchronous. It only means the VMM has accepted this request, but the Quote is
> actually only ready when the guest receives the event notification (done in
> later patch). So I guess there should be a comment somewhere (or even in commit
> message) to explain that?

I will include details about asynchronous request in commit log as
mentioned above.



--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support



On 4/19/22 8:39 PM, Aubrey Li wrote:
> On 2022/4/16 上午6:01, Kuppuswamy Sathyanarayanan wrote:
>> Attestation is the process used by two un-trusted entities to prove to
>> each other that it can be trusted. In TDX guest, attestation is mainly
>> used to verify the trustworthiness of a TD to the 3rd party key
>> servers.
>>
>> First step in the attestation process is to generate the TDREPORT data.
>> This support is added using tdx_mcall_tdreport() API. The second stage
>> in the attestation process is for the guest to request the VMM generate
>> and sign a quote based on the TDREPORT acquired earlier. More details
>> about the steps involved in attestation process can be found in TDX
>> Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section
>> titled "TD attestation"
>>
>> Add tdx_hcall_get_quote() helper function to implement the GetQuote
>> hypercall.
>>
>> More details about the GetQuote TDVMCALL are in the Guest-Host
>> Communication Interface (GHCI) Specification, sec 3.3, titled
>> "VP.VMCALL<GetQuote>".
>>
>> This will be used by the TD attestation driver in follow-on patches.
>>
>> Reviewed-by: Tony Luck <[email protected]>
>> Reviewed-by: Andi Kleen <[email protected]>
>> Acked-by: Kirill A. Shutemov <[email protected]>
>> Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
>> ---
>> arch/x86/coco/tdx/tdx.c | 38 ++++++++++++++++++++++++++++++++++++++
>> arch/x86/include/asm/tdx.h | 2 ++
>> 2 files changed, 40 insertions(+)
>>
>> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
>> index 3e409b618d3f..c259d81a5d7f 100644
>> --- a/arch/x86/coco/tdx/tdx.c
>> +++ b/arch/x86/coco/tdx/tdx.c
>> @@ -21,6 +21,7 @@
>>
>> /* TDX hypercall Leaf IDs */
>> #define TDVMCALL_MAP_GPA 0x10001
>> +#define TDVMCALL_GET_QUOTE 0x10002
>>
>> /* MMIO direction */
>> #define EPT_READ 0
>> @@ -144,6 +145,43 @@ long tdx_mcall_tdreport(void *data, void *reportdata)
>> }
>> EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);
>>
>> +/*
>> + * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
>> + *
>> + * @data : Address of 8KB GPA memory which contains
>> + * TDREPORT_STRUCT.
>> + * @len : Length of the GPA in bytes.
>> + *
>> + * return 0 on success or failure error number.
>> + */
>> +long tdx_hcall_get_quote(void *data, u64 len)
>> +{
>> + u64 ret;
>> +
>> + /*
>> + * Use confidential guest TDX check to ensure this API is only
>> + * used by TDX guest platforms.
>> + */
>> + if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
>> + return -EINVAL;
>> +
>> + /*
>> + * Pass the physical address of tdreport data to the VMM
>> + * and trigger the tdquote generation. Quote data will be
>> + * stored back in the same physical address space. More info
>> + * about ABI can be found in TDX Guest-Host-Communication
>> + * Interface (GHCI), sec titled "TDG.VP.VMCALL<GetQuote>".
>> + */
>> + ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)),
>> + len, 0, 0);
>> +
>
> I commented here in v2 but no response, so let me try again.
>
> IIUC, virt_to_phys(data) (GPA) will be stored in the register when
> TDCALL brings the context back to the VMX root mode, and hypervisor(QEMU)
> will find the mapped host virtual address(HVA) with the GPA in the register,
> and the subsequent ops will be HVA<->HVA in hypervisor, EPT will not be
> involved so no need to cc_mkdec() this GPA.
>
> Please help to correct me if I was wrong.

It was done to meet the expectation from VMM. For shared GPA address,
VMM expects shared bit set. All cc_mkdec() does is to set this bit.

>
> Thanks,
> -Aubrey

--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

2022-04-20 20:49:54

by Huang, Kai

[permalink] [raw]
Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support

On Mon, 2022-04-18 at 22:28 -0700, Sathyanarayanan Kuppuswamy wrote:
>
> On 4/18/22 9:40 PM, Kai Huang wrote:
> > > Please check the latest 1.0 specification (updated on Feb 2022). It has
> > > details about R13 register.
> > Thanks. So it seems GHCI 1.0 has also been updated and it is consistent with
> > GHCI 1.5 now. In this case, why do we still assume 8K shared memory? Are you
> > going to update the driver?
> >
>
> Since the GetQuote spec only requires memory in 4K alignment, we just
> went with 8k constant allocation. Since existing users does not
> require more than 8k, it works. But I agree that this needs to be
> changed.

Quote format can be vendor specific, so there's no guarantee 3rd party won't
have a Quote larger than 8k.

>
> In next version, I will change the driver to choose the allocation size
> based on user space request. Since this change would require us to do
> the memory allocation in IOCTL routine (instead of init code), it will
> make it slower. But I think this is negligible compared to time it takes
> for Quote request. So it should be fine.
>
> >

Yes attestation request should never be something that is very frequent, thus
should never be in a performance critical path.

2022-04-21 00:40:06

by Li, Aubrey

[permalink] [raw]
Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support

On 2022/4/16 上午6:01, Kuppuswamy Sathyanarayanan wrote:
> Attestation is the process used by two un-trusted entities to prove to
> each other that it can be trusted. In TDX guest, attestation is mainly
> used to verify the trustworthiness of a TD to the 3rd party key
> servers.
>
> First step in the attestation process is to generate the TDREPORT data.
> This support is added using tdx_mcall_tdreport() API. The second stage
> in the attestation process is for the guest to request the VMM generate
> and sign a quote based on the TDREPORT acquired earlier. More details
> about the steps involved in attestation process can be found in TDX
> Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section
> titled "TD attestation"
>
> Add tdx_hcall_get_quote() helper function to implement the GetQuote
> hypercall.
>
> More details about the GetQuote TDVMCALL are in the Guest-Host
> Communication Interface (GHCI) Specification, sec 3.3, titled
> "VP.VMCALL<GetQuote>".
>
> This will be used by the TD attestation driver in follow-on patches.
>
> Reviewed-by: Tony Luck <[email protected]>
> Reviewed-by: Andi Kleen <[email protected]>
> Acked-by: Kirill A. Shutemov <[email protected]>
> Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
> ---
> arch/x86/coco/tdx/tdx.c | 38 ++++++++++++++++++++++++++++++++++++++
> arch/x86/include/asm/tdx.h | 2 ++
> 2 files changed, 40 insertions(+)
>
> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
> index 3e409b618d3f..c259d81a5d7f 100644
> --- a/arch/x86/coco/tdx/tdx.c
> +++ b/arch/x86/coco/tdx/tdx.c
> @@ -21,6 +21,7 @@
>
> /* TDX hypercall Leaf IDs */
> #define TDVMCALL_MAP_GPA 0x10001
> +#define TDVMCALL_GET_QUOTE 0x10002
>
> /* MMIO direction */
> #define EPT_READ 0
> @@ -144,6 +145,43 @@ long tdx_mcall_tdreport(void *data, void *reportdata)
> }
> EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);
>
> +/*
> + * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
> + *
> + * @data : Address of 8KB GPA memory which contains
> + * TDREPORT_STRUCT.
> + * @len : Length of the GPA in bytes.
> + *
> + * return 0 on success or failure error number.
> + */
> +long tdx_hcall_get_quote(void *data, u64 len)
> +{
> + u64 ret;
> +
> + /*
> + * Use confidential guest TDX check to ensure this API is only
> + * used by TDX guest platforms.
> + */
> + if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
> + return -EINVAL;
> +
> + /*
> + * Pass the physical address of tdreport data to the VMM
> + * and trigger the tdquote generation. Quote data will be
> + * stored back in the same physical address space. More info
> + * about ABI can be found in TDX Guest-Host-Communication
> + * Interface (GHCI), sec titled "TDG.VP.VMCALL<GetQuote>".
> + */
> + ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)),
> + len, 0, 0);
> +

I commented here in v2 but no response, so let me try again.

IIUC, virt_to_phys(data) (GPA) will be stored in the register when
TDCALL brings the context back to the VMX root mode, and hypervisor(QEMU)
will find the mapped host virtual address(HVA) with the GPA in the register,
and the subsequent ops will be HVA<->HVA in hypervisor, EPT will not be
involved so no need to cc_mkdec() this GPA.

Please help to correct me if I was wrong.

Thanks,
-Aubrey

2022-04-21 08:58:59

by Li, Aubrey

[permalink] [raw]
Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support

On 2022/4/20 下午3:16, Sathyanarayanan Kuppuswamy wrote:
>
>
> On 4/19/22 8:39 PM, Aubrey Li wrote:
>> On 2022/4/16 上午6:01, Kuppuswamy Sathyanarayanan wrote:
>>> Attestation is the process used by two un-trusted entities to prove to
>>> each other that it can be trusted. In TDX guest, attestation is mainly
>>> used to verify the trustworthiness of a TD to the 3rd party key
>>> servers.
>>>
>>> First step in the attestation process is to generate the TDREPORT data.
>>> This support is added using tdx_mcall_tdreport() API. The second stage
>>> in the attestation process is for the guest to request the VMM generate
>>> and sign a quote based on the TDREPORT acquired earlier. More details
>>> about the steps involved in attestation process can be found in TDX
>>> Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section
>>> titled "TD attestation"
>>>
>>> Add tdx_hcall_get_quote() helper function to implement the GetQuote
>>> hypercall.
>>>
>>> More details about the GetQuote TDVMCALL are in the Guest-Host
>>> Communication Interface (GHCI) Specification, sec 3.3, titled
>>> "VP.VMCALL<GetQuote>".
>>>
>>> This will be used by the TD attestation driver in follow-on patches.
>>>
>>> Reviewed-by: Tony Luck <[email protected]>
>>> Reviewed-by: Andi Kleen <[email protected]>
>>> Acked-by: Kirill A. Shutemov <[email protected]>
>>> Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
>>> ---
>>>   arch/x86/coco/tdx/tdx.c    | 38 ++++++++++++++++++++++++++++++++++++++
>>>   arch/x86/include/asm/tdx.h |  2 ++
>>>   2 files changed, 40 insertions(+)
>>>
>>> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
>>> index 3e409b618d3f..c259d81a5d7f 100644
>>> --- a/arch/x86/coco/tdx/tdx.c
>>> +++ b/arch/x86/coco/tdx/tdx.c
>>> @@ -21,6 +21,7 @@
>>>     /* TDX hypercall Leaf IDs */
>>>   #define TDVMCALL_MAP_GPA        0x10001
>>> +#define TDVMCALL_GET_QUOTE        0x10002
>>>     /* MMIO direction */
>>>   #define EPT_READ    0
>>> @@ -144,6 +145,43 @@ long tdx_mcall_tdreport(void *data, void *reportdata)
>>>   }
>>>   EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);
>>>   +/*
>>> + * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
>>> + *
>>> + * @data        : Address of 8KB GPA memory which contains
>>> + *                TDREPORT_STRUCT.
>>> + * @len        : Length of the GPA in bytes.
>>> + *
>>> + * return 0 on success or failure error number.
>>> + */
>>> +long tdx_hcall_get_quote(void *data, u64 len)
>>> +{
>>> +    u64 ret;
>>> +
>>> +    /*
>>> +     * Use confidential guest TDX check to ensure this API is only
>>> +     * used by TDX guest platforms.
>>> +     */
>>> +    if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
>>> +        return -EINVAL;
>>> +
>>> +    /*
>>> +     * Pass the physical address of tdreport data to the VMM
>>> +     * and trigger the tdquote generation. Quote data will be
>>> +     * stored back in the same physical address space. More info
>>> +     * about ABI can be found in TDX Guest-Host-Communication
>>> +     * Interface (GHCI), sec titled "TDG.VP.VMCALL<GetQuote>".
>>> +     */
>>> +    ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)),
>>> +                 len, 0, 0);
>>> +
>>
>> I commented here in v2 but no response, so let me try again.
>>
>> IIUC, virt_to_phys(data) (GPA) will be stored in the register when
>> TDCALL brings the context back to the VMX root mode, and hypervisor(QEMU)
>> will find the mapped host virtual address(HVA) with the GPA in the register,
>> and the subsequent ops will be HVA<->HVA in hypervisor, EPT will not be
>> involved so no need to cc_mkdec() this GPA.
>>
>> Please help to correct me if I was wrong.
>
> It was done to meet the expectation from VMM. For shared GPA address,
> VMM expects shared bit set. All cc_mkdec() does is to set this bit.
>

It seems not a good idea to make the guest aware of the shared bit IMHO.
I didn't see it specified in GHCI, there should be at least a comment here
to explain this behavior.

Thanks,
-Aubrey


Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support



On 4/18/22 9:40 PM, Kai Huang wrote:
>> Please check the latest 1.0 specification (updated on Feb 2022). It has
>> details about R13 register.
> Thanks. So it seems GHCI 1.0 has also been updated and it is consistent with
> GHCI 1.5 now. In this case, why do we still assume 8K shared memory? Are you
> going to update the driver?
>

Since the GetQuote spec only requires memory in 4K alignment, we just
went with 8k constant allocation. Since existing users does not
require more than 8k, it works. But I agree that this needs to be
changed.

In next version, I will change the driver to choose the allocation size
based on user space request. Since this change would require us to do
the memory allocation in IOCTL routine (instead of init code), it will
make it slower. But I think this is negligible compared to time it takes
for Quote request. So it should be fine.

>

--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

2022-04-22 22:27:34

by Isaku Yamahata

[permalink] [raw]
Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support

On Wed, Apr 20, 2022 at 12:16:04AM -0700,
Sathyanarayanan Kuppuswamy <[email protected]> wrote:

>
>
> On 4/19/22 8:39 PM, Aubrey Li wrote:
> > On 2022/4/16 上午6:01, Kuppuswamy Sathyanarayanan wrote:
> > > Attestation is the process used by two un-trusted entities to prove to
> > > each other that it can be trusted. In TDX guest, attestation is mainly
> > > used to verify the trustworthiness of a TD to the 3rd party key
> > > servers.
> > >
> > > First step in the attestation process is to generate the TDREPORT data.
> > > This support is added using tdx_mcall_tdreport() API. The second stage
> > > in the attestation process is for the guest to request the VMM generate
> > > and sign a quote based on the TDREPORT acquired earlier. More details
> > > about the steps involved in attestation process can be found in TDX
> > > Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section
> > > titled "TD attestation"
> > >
> > > Add tdx_hcall_get_quote() helper function to implement the GetQuote
> > > hypercall.
> > >
> > > More details about the GetQuote TDVMCALL are in the Guest-Host
> > > Communication Interface (GHCI) Specification, sec 3.3, titled
> > > "VP.VMCALL<GetQuote>".
> > >
> > > This will be used by the TD attestation driver in follow-on patches.
> > >
> > > Reviewed-by: Tony Luck <[email protected]>
> > > Reviewed-by: Andi Kleen <[email protected]>
> > > Acked-by: Kirill A. Shutemov <[email protected]>
> > > Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
> > > ---
> > > arch/x86/coco/tdx/tdx.c | 38 ++++++++++++++++++++++++++++++++++++++
> > > arch/x86/include/asm/tdx.h | 2 ++
> > > 2 files changed, 40 insertions(+)
> > >
> > > diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
> > > index 3e409b618d3f..c259d81a5d7f 100644
> > > --- a/arch/x86/coco/tdx/tdx.c
> > > +++ b/arch/x86/coco/tdx/tdx.c
> > > @@ -21,6 +21,7 @@
> > > /* TDX hypercall Leaf IDs */
> > > #define TDVMCALL_MAP_GPA 0x10001
> > > +#define TDVMCALL_GET_QUOTE 0x10002
> > > /* MMIO direction */
> > > #define EPT_READ 0
> > > @@ -144,6 +145,43 @@ long tdx_mcall_tdreport(void *data, void *reportdata)
> > > }
> > > EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);
> > > +/*
> > > + * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
> > > + *
> > > + * @data : Address of 8KB GPA memory which contains
> > > + * TDREPORT_STRUCT.
> > > + * @len : Length of the GPA in bytes.
> > > + *
> > > + * return 0 on success or failure error number.
> > > + */
> > > +long tdx_hcall_get_quote(void *data, u64 len)
> > > +{
> > > + u64 ret;
> > > +
> > > + /*
> > > + * Use confidential guest TDX check to ensure this API is only
> > > + * used by TDX guest platforms.
> > > + */
> > > + if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
> > > + return -EINVAL;
> > > +
> > > + /*
> > > + * Pass the physical address of tdreport data to the VMM
> > > + * and trigger the tdquote generation. Quote data will be
> > > + * stored back in the same physical address space. More info
> > > + * about ABI can be found in TDX Guest-Host-Communication
> > > + * Interface (GHCI), sec titled "TDG.VP.VMCALL<GetQuote>".
> > > + */
> > > + ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)),
> > > + len, 0, 0);
> > > +
> >
> > I commented here in v2 but no response, so let me try again.
> >
> > IIUC, virt_to_phys(data) (GPA) will be stored in the register when
> > TDCALL brings the context back to the VMX root mode, and hypervisor(QEMU)
> > will find the mapped host virtual address(HVA) with the GPA in the register,
> > and the subsequent ops will be HVA<->HVA in hypervisor, EPT will not be
> > involved so no need to cc_mkdec() this GPA.
> >
> > Please help to correct me if I was wrong.
>
> It was done to meet the expectation from VMM. For shared GPA address,
> VMM expects shared bit set. All cc_mkdec() does is to set this bit.

This is to conform to the guest-host communicate interface(GHCI) spec.
The input value is defined as "shared GPA as input". Shared GPA is GPA with
shared bit set.

table TDG.VP.VMCALL<GetQuote> - Input Operands
R12 Shared GPA as input – the memory contains a TDREPORT_STRUCT.
The same buffer is used as output – the memory contains a TD Quote.


Userspace VMM(qemu) can be implemented to accept GPA with shared bit set or not.
It's not a big issue.
--
Isaku Yamahata <[email protected]>

2022-04-25 09:53:50

by Li, Aubrey

[permalink] [raw]
Subject: Re: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support

On 2022/4/23 上午1:24, Isaku Yamahata wrote:
> On Wed, Apr 20, 2022 at 12:16:04AM -0700,
> Sathyanarayanan Kuppuswamy <[email protected]> wrote:
>
>>
>>
>> On 4/19/22 8:39 PM, Aubrey Li wrote:
>>> On 2022/4/16 上午6:01, Kuppuswamy Sathyanarayanan wrote:
>>>> Attestation is the process used by two un-trusted entities to prove to
>>>> each other that it can be trusted. In TDX guest, attestation is mainly
>>>> used to verify the trustworthiness of a TD to the 3rd party key
>>>> servers.
>>>>
>>>> First step in the attestation process is to generate the TDREPORT data.
>>>> This support is added using tdx_mcall_tdreport() API. The second stage
>>>> in the attestation process is for the guest to request the VMM generate
>>>> and sign a quote based on the TDREPORT acquired earlier. More details
>>>> about the steps involved in attestation process can be found in TDX
>>>> Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section
>>>> titled "TD attestation"
>>>>
>>>> Add tdx_hcall_get_quote() helper function to implement the GetQuote
>>>> hypercall.
>>>>
>>>> More details about the GetQuote TDVMCALL are in the Guest-Host
>>>> Communication Interface (GHCI) Specification, sec 3.3, titled
>>>> "VP.VMCALL<GetQuote>".
>>>>
>>>> This will be used by the TD attestation driver in follow-on patches.
>>>>
>>>> Reviewed-by: Tony Luck <[email protected]>
>>>> Reviewed-by: Andi Kleen <[email protected]>
>>>> Acked-by: Kirill A. Shutemov <[email protected]>
>>>> Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
>>>> ---
>>>> arch/x86/coco/tdx/tdx.c | 38 ++++++++++++++++++++++++++++++++++++++
>>>> arch/x86/include/asm/tdx.h | 2 ++
>>>> 2 files changed, 40 insertions(+)
>>>>
>>>> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
>>>> index 3e409b618d3f..c259d81a5d7f 100644
>>>> --- a/arch/x86/coco/tdx/tdx.c
>>>> +++ b/arch/x86/coco/tdx/tdx.c
>>>> @@ -21,6 +21,7 @@
>>>> /* TDX hypercall Leaf IDs */
>>>> #define TDVMCALL_MAP_GPA 0x10001
>>>> +#define TDVMCALL_GET_QUOTE 0x10002
>>>> /* MMIO direction */
>>>> #define EPT_READ 0
>>>> @@ -144,6 +145,43 @@ long tdx_mcall_tdreport(void *data, void *reportdata)
>>>> }
>>>> EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);
>>>> +/*
>>>> + * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
>>>> + *
>>>> + * @data : Address of 8KB GPA memory which contains
>>>> + * TDREPORT_STRUCT.
>>>> + * @len : Length of the GPA in bytes.
>>>> + *
>>>> + * return 0 on success or failure error number.
>>>> + */
>>>> +long tdx_hcall_get_quote(void *data, u64 len)
>>>> +{
>>>> + u64 ret;
>>>> +
>>>> + /*
>>>> + * Use confidential guest TDX check to ensure this API is only
>>>> + * used by TDX guest platforms.
>>>> + */
>>>> + if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
>>>> + return -EINVAL;
>>>> +
>>>> + /*
>>>> + * Pass the physical address of tdreport data to the VMM
>>>> + * and trigger the tdquote generation. Quote data will be
>>>> + * stored back in the same physical address space. More info
>>>> + * about ABI can be found in TDX Guest-Host-Communication
>>>> + * Interface (GHCI), sec titled "TDG.VP.VMCALL<GetQuote>".
>>>> + */
>>>> + ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)),
>>>> + len, 0, 0);
>>>> +
>>>
>>> I commented here in v2 but no response, so let me try again.
>>>
>>> IIUC, virt_to_phys(data) (GPA) will be stored in the register when
>>> TDCALL brings the context back to the VMX root mode, and hypervisor(QEMU)
>>> will find the mapped host virtual address(HVA) with the GPA in the register,
>>> and the subsequent ops will be HVA<->HVA in hypervisor, EPT will not be
>>> involved so no need to cc_mkdec() this GPA.
>>>
>>> Please help to correct me if I was wrong.
>>
>> It was done to meet the expectation from VMM. For shared GPA address,
>> VMM expects shared bit set. All cc_mkdec() does is to set this bit.
>
> This is to conform to the guest-host communicate interface(GHCI) spec.
> The input value is defined as "shared GPA as input". Shared GPA is GPA with
> shared bit set.
>
> table TDG.VP.VMCALL<GetQuote> - Input Operands
> R12 Shared GPA as input – the memory contains a TDREPORT_STRUCT.
> The same buffer is used as output – the memory contains a TD Quote.
>
>
> Userspace VMM(qemu) can be implemented to accept GPA with shared bit set or not.
> It's not a big issue.
>

OK, I checked other TDCALL like TDG.VP.VMCALL<MapGPA>, the GPA parameter also has
shared bit set. So the behavior is consistent.

Thanks for the explanation.
-Aubrey