linux-kselftest.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v17 0/3] Add TDX Guest Attestation support
@ 2022-11-04  3:23 Kuppuswamy Sathyanarayanan
  2022-11-04  3:23 ` [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module Kuppuswamy Sathyanarayanan
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2022-11-04  3:23 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kuppuswamy Sathyanarayanan,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Wander Lairson Costa,
	Isaku Yamahata, marcelo.cerri, tim.gardner, khalid.elmously,
	philip.cox, linux-kernel, linux-kselftest, linux-doc

Hi All,

Intel's Trust Domain Extensions (TDX) protect guest VMs from malicious
hosts and some physical attacks. VM guest with TDX support is called
as a TDX Guest.

In TDX guest, attestation process is used to verify the TDX guest
trustworthiness to other entities before provisioning secrets to the
guest. For example, a key server may request for attestation before
releasing the encryption keys to mount the encrypted rootfs or
secondary drive.

This patch set adds attestation support for the TDX guest. Details
about the TDX attestation process and the steps involved are explained
in Documentation/x86/tdx.rst (added by patch 2/3).

Following are the details of the patch set:

Patch 1/3 -> Preparatory patch for adding attestation support.
Patch 2/3 -> Adds user interface driver to support attestation.
Patch 3/3 -> Adds selftest support for TDREPORT feature.

Commit log history is maintained in the individual patches.

Current overall status of this series is, it has no pending issues
and can be considered for the upcoming merge cycle.

Kuppuswamy Sathyanarayanan (3):
  x86/tdx: Add a wrapper to get TDREPORT from the TDX Module
  virt: Add TDX guest driver
  selftests: tdx: Test TDX attestation GetReport support

 Documentation/virt/coco/tdx-guest.rst        |  42 +++++
 Documentation/virt/index.rst                 |   1 +
 Documentation/x86/tdx.rst                    |  43 +++++
 arch/x86/coco/tdx/tdx.c                      |  38 +++++
 arch/x86/include/asm/tdx.h                   |   2 +
 drivers/virt/Kconfig                         |   2 +
 drivers/virt/Makefile                        |   1 +
 drivers/virt/coco/tdx-guest/Kconfig          |  10 ++
 drivers/virt/coco/tdx-guest/Makefile         |   2 +
 drivers/virt/coco/tdx-guest/tdx-guest.c      | 102 ++++++++++++
 include/uapi/linux/tdx-guest.h               |  41 +++++
 tools/testing/selftests/Makefile             |   1 +
 tools/testing/selftests/tdx/Makefile         |   7 +
 tools/testing/selftests/tdx/config           |   1 +
 tools/testing/selftests/tdx/tdx_guest_test.c | 163 +++++++++++++++++++
 15 files changed, 456 insertions(+)
 create mode 100644 Documentation/virt/coco/tdx-guest.rst
 create mode 100644 drivers/virt/coco/tdx-guest/Kconfig
 create mode 100644 drivers/virt/coco/tdx-guest/Makefile
 create mode 100644 drivers/virt/coco/tdx-guest/tdx-guest.c
 create mode 100644 include/uapi/linux/tdx-guest.h
 create mode 100644 tools/testing/selftests/tdx/Makefile
 create mode 100644 tools/testing/selftests/tdx/config
 create mode 100644 tools/testing/selftests/tdx/tdx_guest_test.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module
  2022-11-04  3:23 [PATCH v17 0/3] Add TDX Guest Attestation support Kuppuswamy Sathyanarayanan
@ 2022-11-04  3:23 ` Kuppuswamy Sathyanarayanan
  2022-11-10 15:16   ` Wander Lairson Costa
  2022-11-11 18:35   ` Dave Hansen
  2022-11-04  3:23 ` [PATCH v17 2/3] virt: Add TDX guest driver Kuppuswamy Sathyanarayanan
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 15+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2022-11-04  3:23 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kuppuswamy Sathyanarayanan,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Wander Lairson Costa,
	Isaku Yamahata, marcelo.cerri, tim.gardner, khalid.elmously,
	philip.cox, linux-kernel, linux-kselftest, linux-doc

To support TDX attestation, the TDX guest driver exposes an IOCTL
interface to allow userspace to get the TDREPORT from the TDX module
via TDG.MR.TDREPORT TDCALL.

In order to get the TDREPORT in the TDX guest driver, instead of using
a low level function like __tdx_module_call(), add a
tdx_mcall_get_report() wrapper function to handle it.

This is a preparatory patch for adding attestation support.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---

Changes since v16
 * Added invalid operand error code support.
 * Removed subtype param in tdx_mcall_get_report().

Changes since v15:
 * None

Changes since v14:
 * Instead of exporting __tdx_module_call(), added a new wrapper.
 * Rebased on top of v6.1-rc1

 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 928dcf7a20d9..17cf2e9d5849 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -5,6 +5,8 @@
 #define pr_fmt(fmt)     "tdx: " fmt
 
 #include <linux/cpufeature.h>
+#include <linux/export.h>
+#include <linux/io.h>
 #include <asm/coco.h>
 #include <asm/tdx.h>
 #include <asm/vmx.h>
@@ -15,6 +17,7 @@
 /* TDX module Call Leaf IDs */
 #define TDX_GET_INFO			1
 #define TDX_GET_VEINFO			3
+#define TDX_GET_REPORT			4
 #define TDX_ACCEPT_PAGE			6
 
 /* TDX hypercall Leaf IDs */
@@ -34,6 +37,10 @@
 #define VE_GET_PORT_NUM(e)	((e) >> 16)
 #define VE_IS_IO_STRING(e)	((e) & BIT(4))
 
+/* TDX Module call error codes */
+#define TDCALL_RETURN_CODE(a)	((a) >> 32)
+#define TDCALL_INVALID_OPERAND	0xc0000100
+
 /*
  * Wrapper for standard use of __tdx_hypercall with no output aside from
  * return code.
@@ -98,6 +105,37 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
 		panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
 }
 
+/**
+ * tdx_mcall_get_report() - Wrapper for TDG.MR.REPORT TDCALL.
+ * @reportdata: Address of the input buffer which contains
+ *              user-defined REPORTDATA to be included into
+ *              TDREPORT.
+ * @tdreport: Address of the output buffer to store TDREPORT.
+ *
+ * Generate TDREPORT using "TDG.MR.REPORT" TDCALL. Refer to section
+ * titled "TDG.MR.REPORT leaf" in the TDX Module 1.0 specification
+ * for detailed information. It is used in the TDX guest driver
+ * module to get the TDREPORT.
+ *
+ * Return 0 on success, -EINVAL for invalid operands, or -EIO on
+ * other TDCALL failures.
+ */
+int tdx_mcall_get_report(u8 *reportdata, u8 *tdreport)
+{
+	u64 ret;
+
+	ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(tdreport),
+				virt_to_phys(reportdata), 0, 0, NULL);
+	if (ret) {
+		if (TDCALL_RETURN_CODE(ret) == TDCALL_INVALID_OPERAND)
+			return -EINVAL;
+		return -EIO;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tdx_mcall_get_report);
+
 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 020c81a7c729..eef9c0b7880e 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -67,6 +67,8 @@ void tdx_safe_halt(void);
 
 bool tdx_early_handle_ve(struct pt_regs *regs);
 
+int tdx_mcall_get_report(u8 *reportdata, u8 *tdreport);
+
 #else
 
 static inline void tdx_early_init(void) { };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v17 2/3] virt: Add TDX guest driver
  2022-11-04  3:23 [PATCH v17 0/3] Add TDX Guest Attestation support Kuppuswamy Sathyanarayanan
  2022-11-04  3:23 ` [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module Kuppuswamy Sathyanarayanan
@ 2022-11-04  3:23 ` Kuppuswamy Sathyanarayanan
  2022-11-09 14:24   ` Wander Lairson Costa
  2022-11-10 15:17   ` Wander Lairson Costa
  2022-11-04  3:23 ` [PATCH v17 3/3] selftests: tdx: Test TDX attestation GetReport support Kuppuswamy Sathyanarayanan
  2022-11-10  3:41 ` [PATCH v17 0/3] Add TDX Guest Attestation support Sathyanarayanan Kuppuswamy
  3 siblings, 2 replies; 15+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2022-11-04  3:23 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kuppuswamy Sathyanarayanan,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Wander Lairson Costa,
	Isaku Yamahata, marcelo.cerri, tim.gardner, khalid.elmously,
	philip.cox, linux-kernel, linux-kselftest, linux-doc

TDX guest driver exposes IOCTL interfaces to service TDX guest
user-specific requests. Currently, it is only used to allow the user to
get the TDREPORT to support TDX attestation.

Details about the TDX attestation process are documented in
Documentation/x86/tdx.rst, and the IOCTL details are documented in
Documentation/virt/coco/tdx-guest.rst.

Operations like getting TDREPORT involves sending a blob of data as
input and getting another blob of data as output. It was considered
to use a sysfs interface for this, but it doesn't fit well into the
standard sysfs model for configuring values. It would be possible to
do read/write on files, but it would need multiple file descriptors,
which would be somewhat messy. IOCTLs seems to be the best fitting
and simplest model for this use case. The AMD sev-guest driver also
uses IOCTL interface to support attestation.

[Bagas Sanjaya: Ack is for documentation portion]
Acked-by: Kai Huang <kai.huang@intel.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---

Changes since v16:
 * Removed rpd_len, tdr_len and subtype members from
   struct tdx_report_req.
 * Used fixed size buffers for TDREPORT and REPORTDATA in
   struct tdx_report_req.

Changes since v15:
 * Removed error messages in tdx_get_report() as per Greg's suggestion.
 * Removed #ifdef MODULE usage for MODULE_DEVICE_TABLE.
 * Added copyright info for the header file.

Changes since v14:
 * Used tdx_mcall_get_report() wrapper instead of __tdx_module_call()
   call.
 * Added pr_err() messages for some failure cases in tdx_get_report().
 * Used KBUILD_MODNAME instead of device name.
 * Rebased on top of v6.1-rc1

Changes since v13:
 * Converted the driver from built-in to a driver module
   as per Greg's suggestion.
 * Moved the driver to drivers/virt/coco to match AMD SEV.
 * Added support to autoload the driver based on
   X86_FEATURE_TDX_GUEST CPU feature.
 * Squashed patch titled "Documentation/x86: Document TDX
   attestation process" with this patch.
 * Since the attestation process is already documented in
   Documentation/x86/tdx.rst, remove it from the commit log.
 * Modified the commit log to match the new format.
 * Explicitly included the required header files.
 * Fixed magic number usage in reserved member check.

Changes since v13:
 * Fixed the commit log as per review suggestion.
 * Explicitly included the required header files.
 * Fixed magic number usage in reserved member check.

Changes since v12:
 * Added check to ensure reserved entries are set as 0.

Changes since v11:
 * Renamed DRIVER_NAME to TDX_GUEST_DEVICE and moved it to
   arch/x86/include/uapi/asm/tdx.h.
 * Fixed default error number in tdx_guest_ioctl().
 * Moved tdx_misc_dev definition out of tdx_guest_init() as
   per Greg's suggestion.
 * Reordered struct tdx_report_req to avoid holes and added
   required padding.

Changes since v10:
 * Replaced TD/TD Guest usage with TDX Guest or Guest.
 * Removed unnecessary comments.
 * Added more validation to user input in tdx_get_report().
 * Used u64_to_user_ptr when reading user u64 pointers.
 * Fixed commit log as per review comments.

Changes since v9:
 * Dropped the cover letter. Since this patch set only adds
   TDREPORT support, the commit log itself has all the required details.
 * Dropped the Quote support and event IRQ support as per Dave's
   review suggestion.
 * Dropped attest.c and moved its contents to tdx.c
 * Updated commit log and comments to reflect latest changes.

Changes since v8:
 * Please refer to https://lore.kernel.org/all/ \
   20220728034420.648314-1-sathyanarayanan.kuppuswamy@linux.intel.com/

 Documentation/virt/coco/tdx-guest.rst   |  42 ++++++++++
 Documentation/virt/index.rst            |   1 +
 Documentation/x86/tdx.rst               |  43 ++++++++++
 drivers/virt/Kconfig                    |   2 +
 drivers/virt/Makefile                   |   1 +
 drivers/virt/coco/tdx-guest/Kconfig     |  10 +++
 drivers/virt/coco/tdx-guest/Makefile    |   2 +
 drivers/virt/coco/tdx-guest/tdx-guest.c | 102 ++++++++++++++++++++++++
 include/uapi/linux/tdx-guest.h          |  41 ++++++++++
 9 files changed, 244 insertions(+)
 create mode 100644 Documentation/virt/coco/tdx-guest.rst
 create mode 100644 drivers/virt/coco/tdx-guest/Kconfig
 create mode 100644 drivers/virt/coco/tdx-guest/Makefile
 create mode 100644 drivers/virt/coco/tdx-guest/tdx-guest.c
 create mode 100644 include/uapi/linux/tdx-guest.h

diff --git a/Documentation/virt/coco/tdx-guest.rst b/Documentation/virt/coco/tdx-guest.rst
new file mode 100644
index 000000000000..388d0ffb686b
--- /dev/null
+++ b/Documentation/virt/coco/tdx-guest.rst
@@ -0,0 +1,42 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================================================================
+TDX Guest API Documentation
+===================================================================
+
+1. General description
+======================
+
+The TDX guest driver exposes IOCTL interfaces via /dev/tdx-guest misc
+device to allow userspace to get certain TDX guest specific details.
+
+2. API description
+==================
+
+In this section, for each supported IOCTL, following information is
+provided along with a generic description.
+
+:Input parameters: Parameters passed to the IOCTL and related details.
+:Output: Details about output data and return value (with details about the non
+         common error values).
+
+2.1 TDX_CMD_GET_REPORT
+----------------------
+
+:Input parameters: struct tdx_report_req
+:Output: Upon successful execution, TDREPORT data is copied to
+         tdx_report_req.tdreport and return 0. Return -EINVAL for
+         invalid operands, -EIO on TDCALL failure or standard error
+         number on other common failures.
+
+The TDX_CMD_GET_REPORT IOCTL can be used by the attestation software to
+get the TDREPORT from the TDX module using TDCALL[TDG.MR.REPORT].
+
+Reference
+---------
+
+TDX reference material is collected here:
+
+https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html
+
+The driver is based on TDX module specification v1.0 and TDX GHCI specification v1.0.
diff --git a/Documentation/virt/index.rst b/Documentation/virt/index.rst
index 2f1cffa87b1b..56e003ff28ff 100644
--- a/Documentation/virt/index.rst
+++ b/Documentation/virt/index.rst
@@ -14,6 +14,7 @@ Linux Virtualization Support
    ne_overview
    acrn/index
    coco/sev-guest
+   coco/tdx-guest
    hyperv/index
 
 .. only:: html and subproject
diff --git a/Documentation/x86/tdx.rst b/Documentation/x86/tdx.rst
index b8fa4329e1a5..014b769923a4 100644
--- a/Documentation/x86/tdx.rst
+++ b/Documentation/x86/tdx.rst
@@ -210,6 +210,49 @@ converted to shared on boot.
 For coherent DMA allocation, the DMA buffer gets converted on the
 allocation. Check force_dma_unencrypted() for details.
 
+Attestation
+===========
+
+Attestation is used to verify the TDX guest trustworthiness to other
+entities before provisioning secrets to the guest. For example, a key
+server may want to use attestation to verify that the guest is the
+desired one before releasing the encryption keys to mount the encrypted
+rootfs or secondary drive.
+
+The TDX module records the state of the TDX guest in various stages of
+the guest boot process using build time measurement register (MRTD) and
+runtime measurement registers (RTMR). Measurements related to guest
+initial configuration and firmware image are recorded in the MRTD
+register. Measurements related to initial state, kernel image, firmware
+image, command line options, initrd, ACPI tables, etc are recorded in
+RTMR registers. For more details as an example, please refer to TDX
+Virtual Firmware design specification, sec titled "TD Measurement". At
+TDX guest runtime, the attestation process is used to attest to these
+measurements.
+
+The attestation process consists of two steps: TDREPORT generation and
+Quote generation.
+
+TDX guest uses TDCALL[TDG.MR.REPORT] to get the TDREPORT (TDREPORT_STRUCT)
+from the TDX module. TDREPORT is a fixed-size data structure generated by
+the TDX module which contains guest-specific information (such as build
+and boot measurements), platform security version, and the MAC to protect
+the integrity of the TDREPORT. A user-provided 64-Byte REPORTDATA is used
+as input and included in the TDREPORT. Typically it can be some nonce
+provided by attestation service so the TDREPORT can be verified uniquely.
+More details about the TDREPORT can be found in Intel TDX Module
+specification, section titled "TDG.MR.REPORT Leaf".
+
+After getting the TDREPORT, the second step of the attestation process
+is to send it to the Quoting Enclave (QE) to generate the Quote. TDREPORT
+by design can only be verified on the local platform as the MAC key is
+bound to the platform. To support remote verification of the TDREPORT,
+TDX leverages Intel SGX Quoting Enclave to verify the TDREPORT locally
+and convert it to a remotely verifiable Quote. Method of sending TDREPORT
+to QE is implementation specific. Attestation software can choose
+whatever communication channel available (i.e. vsock or TCP/IP) to
+send the TDREPORT to QE and receive the Quote.
+
 References
 ==========
 
diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
index 87ef258cec64..f79ab13a5c28 100644
--- a/drivers/virt/Kconfig
+++ b/drivers/virt/Kconfig
@@ -52,4 +52,6 @@ source "drivers/virt/coco/efi_secret/Kconfig"
 
 source "drivers/virt/coco/sev-guest/Kconfig"
 
+source "drivers/virt/coco/tdx-guest/Kconfig"
+
 endif
diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile
index 093674e05c40..e9aa6fc96fab 100644
--- a/drivers/virt/Makefile
+++ b/drivers/virt/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_NITRO_ENCLAVES)	+= nitro_enclaves/
 obj-$(CONFIG_ACRN_HSM)		+= acrn/
 obj-$(CONFIG_EFI_SECRET)	+= coco/efi_secret/
 obj-$(CONFIG_SEV_GUEST)		+= coco/sev-guest/
+obj-$(CONFIG_INTEL_TDX_GUEST)	+= coco/tdx-guest/
diff --git a/drivers/virt/coco/tdx-guest/Kconfig b/drivers/virt/coco/tdx-guest/Kconfig
new file mode 100644
index 000000000000..14246fc2fb02
--- /dev/null
+++ b/drivers/virt/coco/tdx-guest/Kconfig
@@ -0,0 +1,10 @@
+config TDX_GUEST_DRIVER
+	tristate "TDX Guest driver"
+	depends on INTEL_TDX_GUEST
+	help
+	  The driver provides userspace interface to communicate with
+	  the TDX module to request the TDX guest details like attestation
+	  report.
+
+	  To compile this driver as module, choose M here. The module will
+	  be called tdx-guest.
diff --git a/drivers/virt/coco/tdx-guest/Makefile b/drivers/virt/coco/tdx-guest/Makefile
new file mode 100644
index 000000000000..775cb463f9c8
--- /dev/null
+++ b/drivers/virt/coco/tdx-guest/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_TDX_GUEST_DRIVER) += tdx-guest.o
diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c
new file mode 100644
index 000000000000..40e7c1881fa9
--- /dev/null
+++ b/drivers/virt/coco/tdx-guest/tdx-guest.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TDX guest user interface driver
+ *
+ * Copyright (C) 2022 Intel Corporation
+ */
+
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+
+#include <uapi/linux/tdx-guest.h>
+
+#include <asm/cpu_device_id.h>
+#include <asm/tdx.h>
+
+static long tdx_get_report(struct tdx_report_req __user *req)
+{
+	u8 *reportdata, *tdreport;
+	long ret;
+
+	reportdata = kmalloc(TDX_REPORTDATA_LEN, GFP_KERNEL);
+	if (!reportdata)
+		return -ENOMEM;
+
+	tdreport = kzalloc(TDX_REPORT_LEN, GFP_KERNEL);
+	if (!tdreport) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (copy_from_user(reportdata, req->reportdata, TDX_REPORTDATA_LEN)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	/* Generate TDREPORT using "TDG.MR.REPORT" TDCALL */
+	ret = tdx_mcall_get_report(reportdata, tdreport);
+	if (ret)
+		goto out;
+
+	if (copy_to_user(req->tdreport, tdreport, TDX_REPORT_LEN))
+		ret = -EFAULT;
+
+out:
+	kfree(reportdata);
+	kfree(tdreport);
+
+	return ret;
+}
+
+static long tdx_guest_ioctl(struct file *file, unsigned int cmd,
+			    unsigned long arg)
+{
+	switch (cmd) {
+	case TDX_CMD_GET_REPORT:
+		return tdx_get_report((struct tdx_report_req __user *)arg);
+	default:
+		return -ENOTTY;
+	}
+}
+
+static const struct file_operations tdx_guest_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = tdx_guest_ioctl,
+	.llseek = no_llseek,
+};
+
+static struct miscdevice tdx_misc_dev = {
+	.name = KBUILD_MODNAME,
+	.minor = MISC_DYNAMIC_MINOR,
+	.fops = &tdx_guest_fops,
+};
+
+static const struct x86_cpu_id tdx_guest_ids[] = {
+	X86_MATCH_FEATURE(X86_FEATURE_TDX_GUEST, NULL),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, tdx_guest_ids);
+
+static int __init tdx_guest_init(void)
+{
+	if (!x86_match_cpu(tdx_guest_ids))
+		return -ENODEV;
+
+	return misc_register(&tdx_misc_dev);
+}
+module_init(tdx_guest_init);
+
+static void __exit tdx_guest_exit(void)
+{
+	misc_deregister(&tdx_misc_dev);
+}
+module_exit(tdx_guest_exit);
+
+MODULE_AUTHOR("Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>");
+MODULE_DESCRIPTION("TDX Guest Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/tdx-guest.h b/include/uapi/linux/tdx-guest.h
new file mode 100644
index 000000000000..c1d52bc3a62e
--- /dev/null
+++ b/include/uapi/linux/tdx-guest.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Userspace interface for TDX guest driver
+ *
+ * Copyright (C) 2022 Intel Corporation
+ */
+
+#ifndef _UAPI_LINUX_TDX_GUEST_H_
+#define _UAPI_LINUX_TDX_GUEST_H_
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/* Length of the REPORTDATA used in TDG.MR.REPORT TDCALL */
+#define TDX_REPORTDATA_LEN              64
+
+/* Length of TDREPORT used in TDG.MR.REPORT TDCALL */
+#define TDX_REPORT_LEN                  1024
+
+/**
+ * struct tdx_report_req - Request struct for TDX_CMD_GET_REPORT IOCTL.
+ *
+ * @reportdata: User buffer with REPORTDATA to be included into TDREPORT.
+ *              Typically it can be some nonce provided by attestation
+ *              service, so the generated TDREPORT can be uniquely verified.
+ * @tdreport: User buffer to store TDREPORT output from TDCALL[TDG.MR.REPORT].
+ */
+struct tdx_report_req {
+	__u8 reportdata[TDX_REPORTDATA_LEN];
+	__u8 tdreport[TDX_REPORT_LEN];
+};
+
+/*
+ * TDX_CMD_GET_REPORT - Get TDREPORT using TDCALL[TDG.MR.REPORT]
+ *
+ * Return 0 on success, -EIO on TDCALL execution failure, and
+ * standard errno on other general error cases.
+ */
+#define TDX_CMD_GET_REPORT              _IOWR('T', 1, struct tdx_report_req)
+
+#endif /* _UAPI_LINUX_TDX_GUEST_H_ */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v17 3/3] selftests: tdx: Test TDX attestation GetReport support
  2022-11-04  3:23 [PATCH v17 0/3] Add TDX Guest Attestation support Kuppuswamy Sathyanarayanan
  2022-11-04  3:23 ` [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module Kuppuswamy Sathyanarayanan
  2022-11-04  3:23 ` [PATCH v17 2/3] virt: Add TDX guest driver Kuppuswamy Sathyanarayanan
@ 2022-11-04  3:23 ` Kuppuswamy Sathyanarayanan
  2022-11-10 15:17   ` Wander Lairson Costa
  2022-11-10  3:41 ` [PATCH v17 0/3] Add TDX Guest Attestation support Sathyanarayanan Kuppuswamy
  3 siblings, 1 reply; 15+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2022-11-04  3:23 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kuppuswamy Sathyanarayanan,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Wander Lairson Costa,
	Isaku Yamahata, marcelo.cerri, tim.gardner, khalid.elmously,
	philip.cox, linux-kernel, linux-kselftest, linux-doc

Attestation is used to verify the trustworthiness of a TDX guest.
During the guest bring-up, the Intel TDX module measures and records
the initial contents and configuration of the guest, and at runtime,
guest software uses runtime measurement registers (RMTRs) to measure
and record details related to kernel image, command line params, ACPI
tables, initrd, etc. At guest runtime, the attestation process is used
to attest to these measurements.

The first step in the TDX attestation process is to get the TDREPORT
data. It is a fixed size data structure generated by the TDX module
which includes the above mentioned measurements data, a MAC ID to
protect the integrity of the TDREPORT, and a 64-Byte of user specified
data passed during TDREPORT request which can uniquely identify the
TDREPORT.

Intel's TDX guest driver exposes TDX_CMD_GET_REPORT IOCTL interface to
enable guest userspace to get the TDREPORT.

Add a kernel self test module to test this ABI and verify the validity
of the generated TDREPORT.

Reviewed-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Kai Huang <kai.huang@intel.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---

Changes since v16:
 * Modified the code to adapt to fixed size reportdata and tdeport
   buffers in struct tdx_report_req.

Changes since v15:
 * None

Changes since v14:
 * Fixed format issue in struct comments.
 * Rebased on top of v6.1-rc1

Changes since v13:
 * Removed __packed from TDREPORT structs.
 * Since the guest driver is moved to drivers/virt/coco, removed
   tools/arch/x86/include header folder usage.
 * Fixed struct comments to match kernel-doc format.
 * Fixed commit log as per review comments.
 * Fixed some format issues in the code.

Changes since v12:
 * Changed #ifdef DEBUG usage with if (DEBUG).
 * Initialized reserved entries values to zero.

Changes since v11:
 * Renamed devname with TDX_GUEST_DEVNAME.

Changes since v10:
 * Replaced TD/TD Guest usage with guest or TDX guest.
 * Reworded the subject line.

Changes since v9:
 * Copied arch/x86/include/uapi/asm/tdx.h to tools/arch/x86/include to
   decouple header dependency between kernel source and tools dir.
 * Fixed Makefile to adapt to above change.
 * Fixed commit log and comments.
 * Added __packed to hardware structs.

Changes since v8:
 * Please refer to https://lore.kernel.org/all/ \
   20220728034420.648314-1-sathyanarayanan.kuppuswamy@linux.intel.com/

 tools/testing/selftests/Makefile             |   1 +
 tools/testing/selftests/tdx/Makefile         |   7 +
 tools/testing/selftests/tdx/config           |   1 +
 tools/testing/selftests/tdx/tdx_guest_test.c | 163 +++++++++++++++++++
 4 files changed, 172 insertions(+)
 create mode 100644 tools/testing/selftests/tdx/Makefile
 create mode 100644 tools/testing/selftests/tdx/config
 create mode 100644 tools/testing/selftests/tdx/tdx_guest_test.c

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 0464b2c6c1e4..f60e14d16bfd 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -73,6 +73,7 @@ TARGETS += sync
 TARGETS += syscall_user_dispatch
 TARGETS += sysctl
 TARGETS += tc-testing
+TARGETS += tdx
 TARGETS += timens
 ifneq (1, $(quicktest))
 TARGETS += timers
diff --git a/tools/testing/selftests/tdx/Makefile b/tools/testing/selftests/tdx/Makefile
new file mode 100644
index 000000000000..8dd43517cd55
--- /dev/null
+++ b/tools/testing/selftests/tdx/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+CFLAGS += -O3 -Wl,-no-as-needed -Wall -static
+
+TEST_GEN_PROGS := tdx_guest_test
+
+include ../lib.mk
diff --git a/tools/testing/selftests/tdx/config b/tools/testing/selftests/tdx/config
new file mode 100644
index 000000000000..aa1edc829ab6
--- /dev/null
+++ b/tools/testing/selftests/tdx/config
@@ -0,0 +1 @@
+CONFIG_TDX_GUEST_DRIVER=y
diff --git a/tools/testing/selftests/tdx/tdx_guest_test.c b/tools/testing/selftests/tdx/tdx_guest_test.c
new file mode 100644
index 000000000000..6f7ab667b8cc
--- /dev/null
+++ b/tools/testing/selftests/tdx/tdx_guest_test.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test TDX guest features
+ *
+ * Copyright (C) 2022 Intel Corporation.
+ *
+ * Author: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+ */
+
+#include <sys/ioctl.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+#include "../kselftest_harness.h"
+#include "../../../../include/uapi/linux/tdx-guest.h"
+
+#define TDX_GUEST_DEVNAME "/dev/tdx_guest"
+#define HEX_DUMP_SIZE 8
+#define DEBUG 0
+
+/**
+ * struct tdreport_type - Type header of TDREPORT_STRUCT.
+ * @type: Type of the TDREPORT (0 - SGX, 81 - TDX, rest are reserved)
+ * @sub_type: Subtype of the TDREPORT (Default value is 0).
+ * @version: TDREPORT version (Default value is 0).
+ * @reserved: Added for future extension.
+ *
+ * More details can be found in TDX v1.0 module specification, sec
+ * titled "REPORTTYPE".
+ */
+struct tdreport_type {
+	__u8 type;
+	__u8 sub_type;
+	__u8 version;
+	__u8 reserved;
+};
+
+/**
+ * struct reportmac - TDX guest report data, MAC and TEE hashes.
+ * @type: TDREPORT type header.
+ * @reserved1: Reserved for future extension.
+ * @cpu_svn: CPU security version.
+ * @tee_tcb_info_hash: SHA384 hash of TEE TCB INFO.
+ * @tee_td_info_hash: SHA384 hash of TDINFO_STRUCT.
+ * @reportdata: User defined unique data passed in TDG.MR.REPORT request.
+ * @reserved2: Reserved for future extension.
+ * @mac: CPU MAC ID.
+ *
+ * It is MAC-protected and contains hashes of the remainder of the
+ * report structure along with user provided report data. More details can
+ * be found in TDX v1.0 Module specification, sec titled "REPORTMACSTRUCT"
+ */
+struct reportmac {
+	struct tdreport_type type;
+	__u8 reserved1[12];
+	__u8 cpu_svn[16];
+	__u8 tee_tcb_info_hash[48];
+	__u8 tee_td_info_hash[48];
+	__u8 reportdata[64];
+	__u8 reserved2[32];
+	__u8 mac[32];
+};
+
+/**
+ * struct td_info - TDX guest measurements and configuration.
+ * @attr: TDX Guest attributes (like debug, spet_disable, etc).
+ * @xfam: Extended features allowed mask.
+ * @mrtd: Build time measurement register.
+ * @mrconfigid: Software-defined ID for non-owner-defined configuration
+ *              of the guest - e.g., run-time or OS configuration.
+ * @mrowner: Software-defined ID for the guest owner.
+ * @mrownerconfig: Software-defined ID for owner-defined configuration of
+ *                 the guest - e.g., specific to the workload.
+ * @rtmr: Run time measurement registers.
+ * @reserved: Added for future extension.
+ *
+ * It contains the measurements and initial configuration of the TDX guest
+ * that was locked at initialization and a set of measurement registers
+ * that are run-time extendable. More details can be found in TDX v1.0
+ * Module specification, sec titled "TDINFO_STRUCT".
+ */
+struct td_info {
+	__u8 attr[8];
+	__u64 xfam;
+	__u64 mrtd[6];
+	__u64 mrconfigid[6];
+	__u64 mrowner[6];
+	__u64 mrownerconfig[6];
+	__u64 rtmr[24];
+	__u64 reserved[14];
+};
+
+/*
+ * struct tdreport - Output of TDCALL[TDG.MR.REPORT].
+ * @reportmac: Mac protected header of size 256 bytes.
+ * @tee_tcb_info: Additional attestable elements in the TCB are not
+ *                reflected in the reportmac.
+ * @reserved: Added for future extension.
+ * @tdinfo: Measurements and configuration data of size 512 bytes.
+ *
+ * More details can be found in TDX v1.0 Module specification, sec
+ * titled "TDREPORT_STRUCT".
+ */
+struct tdreport {
+	struct reportmac reportmac;
+	__u8 tee_tcb_info[239];
+	__u8 reserved[17];
+	struct td_info tdinfo;
+};
+
+static void print_array_hex(const char *title, const char *prefix_str,
+			    const void *buf, int len)
+{
+	int i, j, line_len, rowsize = HEX_DUMP_SIZE;
+	const __u8 *ptr = buf;
+
+	printf("\t\t%s", title);
+
+	for (j = 0; j < len; j += rowsize) {
+		line_len = rowsize < (len - j) ? rowsize : (len - j);
+		printf("%s%.8x:", prefix_str, j);
+		for (i = 0; i < line_len; i++)
+			printf(" %.2x", ptr[j + i]);
+		printf("\n");
+	}
+
+	printf("\n");
+}
+
+TEST(verify_report)
+{
+	struct tdx_report_req req;
+	struct tdreport *tdreport;
+	int devfd, i;
+
+	devfd = open(TDX_GUEST_DEVNAME, O_RDWR | O_SYNC);
+	ASSERT_LT(0, devfd);
+
+	/* Generate sample report data */
+	for (i = 0; i < TDX_REPORTDATA_LEN; i++)
+		req.reportdata[i] = i;
+
+	/* Get TDREPORT */
+	ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req));
+
+	if (DEBUG) {
+		print_array_hex("\n\t\tTDX report data\n", "",
+				req.reportdata, sizeof(req.reportdata));
+
+		print_array_hex("\n\t\tTDX tdreport data\n", "",
+				req.tdreport, sizeof(req.tdreport));
+	}
+
+	/* Make sure TDREPORT data includes the REPORTDATA passed */
+	tdreport = (struct tdreport *)req.tdreport;
+	ASSERT_EQ(0, memcmp(&tdreport->reportmac.reportdata[0],
+			    req.reportdata, sizeof(req.reportdata)));
+
+	ASSERT_EQ(0, close(devfd));
+}
+
+TEST_HARNESS_MAIN
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 2/3] virt: Add TDX guest driver
  2022-11-04  3:23 ` [PATCH v17 2/3] virt: Add TDX guest driver Kuppuswamy Sathyanarayanan
@ 2022-11-09 14:24   ` Wander Lairson Costa
  2022-11-09 15:36     ` Sathyanarayanan Kuppuswamy
  2022-11-10 15:17   ` Wander Lairson Costa
  1 sibling, 1 reply; 15+ messages in thread
From: Wander Lairson Costa @ 2022-11-09 14:24 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

On Thu, Nov 03, 2022 at 08:23:54PM -0700, Kuppuswamy Sathyanarayanan wrote:
> TDX guest driver exposes IOCTL interfaces to service TDX guest
> user-specific requests. Currently, it is only used to allow the user to
> get the TDREPORT to support TDX attestation.
> 
> Details about the TDX attestation process are documented in
> Documentation/x86/tdx.rst, and the IOCTL details are documented in
> Documentation/virt/coco/tdx-guest.rst.
> 
> Operations like getting TDREPORT involves sending a blob of data as
> input and getting another blob of data as output. It was considered
> to use a sysfs interface for this, but it doesn't fit well into the
> standard sysfs model for configuring values. It would be possible to
> do read/write on files, but it would need multiple file descriptors,
> which would be somewhat messy. IOCTLs seems to be the best fitting
> and simplest model for this use case. The AMD sev-guest driver also
> uses IOCTL interface to support attestation.
> 
> [Bagas Sanjaya: Ack is for documentation portion]
> Acked-by: Kai Huang <kai.huang@intel.com>
> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Acked-by: Wander Lairson Costa <wander@redhat.com>
> Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com>
> Reviewed-by: Tony Luck <tony.luck@intel.com>
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> ---
> 
> Changes since v16:
>  * Removed rpd_len, tdr_len and subtype members from
>    struct tdx_report_req.
>  * Used fixed size buffers for TDREPORT and REPORTDATA in
>    struct tdx_report_req.
> 
> Changes since v15:
>  * Removed error messages in tdx_get_report() as per Greg's suggestion.
>  * Removed #ifdef MODULE usage for MODULE_DEVICE_TABLE.
>  * Added copyright info for the header file.
> 
> Changes since v14:
>  * Used tdx_mcall_get_report() wrapper instead of __tdx_module_call()
>    call.
>  * Added pr_err() messages for some failure cases in tdx_get_report().
>  * Used KBUILD_MODNAME instead of device name.
>  * Rebased on top of v6.1-rc1
> 
> Changes since v13:
>  * Converted the driver from built-in to a driver module
>    as per Greg's suggestion.
>  * Moved the driver to drivers/virt/coco to match AMD SEV.
>  * Added support to autoload the driver based on
>    X86_FEATURE_TDX_GUEST CPU feature.
>  * Squashed patch titled "Documentation/x86: Document TDX
>    attestation process" with this patch.
>  * Since the attestation process is already documented in
>    Documentation/x86/tdx.rst, remove it from the commit log.
>  * Modified the commit log to match the new format.
>  * Explicitly included the required header files.
>  * Fixed magic number usage in reserved member check.
> 
> Changes since v13:
>  * Fixed the commit log as per review suggestion.
>  * Explicitly included the required header files.
>  * Fixed magic number usage in reserved member check.
> 
> Changes since v12:
>  * Added check to ensure reserved entries are set as 0.
> 
> Changes since v11:
>  * Renamed DRIVER_NAME to TDX_GUEST_DEVICE and moved it to
>    arch/x86/include/uapi/asm/tdx.h.
>  * Fixed default error number in tdx_guest_ioctl().
>  * Moved tdx_misc_dev definition out of tdx_guest_init() as
>    per Greg's suggestion.
>  * Reordered struct tdx_report_req to avoid holes and added
>    required padding.
> 
> Changes since v10:
>  * Replaced TD/TD Guest usage with TDX Guest or Guest.
>  * Removed unnecessary comments.
>  * Added more validation to user input in tdx_get_report().
>  * Used u64_to_user_ptr when reading user u64 pointers.
>  * Fixed commit log as per review comments.
> 
> Changes since v9:
>  * Dropped the cover letter. Since this patch set only adds
>    TDREPORT support, the commit log itself has all the required details.
>  * Dropped the Quote support and event IRQ support as per Dave's
>    review suggestion.
>  * Dropped attest.c and moved its contents to tdx.c
>  * Updated commit log and comments to reflect latest changes.
> 
> Changes since v8:
>  * Please refer to https://lore.kernel.org/all/ \
>    20220728034420.648314-1-sathyanarayanan.kuppuswamy@linux.intel.com/
> 
>  Documentation/virt/coco/tdx-guest.rst   |  42 ++++++++++
>  Documentation/virt/index.rst            |   1 +
>  Documentation/x86/tdx.rst               |  43 ++++++++++
>  drivers/virt/Kconfig                    |   2 +
>  drivers/virt/Makefile                   |   1 +
>  drivers/virt/coco/tdx-guest/Kconfig     |  10 +++
>  drivers/virt/coco/tdx-guest/Makefile    |   2 +
>  drivers/virt/coco/tdx-guest/tdx-guest.c | 102 ++++++++++++++++++++++++
>  include/uapi/linux/tdx-guest.h          |  41 ++++++++++
>  9 files changed, 244 insertions(+)
>  create mode 100644 Documentation/virt/coco/tdx-guest.rst
>  create mode 100644 drivers/virt/coco/tdx-guest/Kconfig
>  create mode 100644 drivers/virt/coco/tdx-guest/Makefile
>  create mode 100644 drivers/virt/coco/tdx-guest/tdx-guest.c
>  create mode 100644 include/uapi/linux/tdx-guest.h
> 
> diff --git a/Documentation/virt/coco/tdx-guest.rst b/Documentation/virt/coco/tdx-guest.rst
> new file mode 100644
> index 000000000000..388d0ffb686b
> --- /dev/null
> +++ b/Documentation/virt/coco/tdx-guest.rst
> @@ -0,0 +1,42 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +===================================================================
> +TDX Guest API Documentation
> +===================================================================
> +
> +1. General description
> +======================
> +
> +The TDX guest driver exposes IOCTL interfaces via /dev/tdx-guest misc
> +device to allow userspace to get certain TDX guest specific details.
> +
> +2. API description
> +==================
> +
> +In this section, for each supported IOCTL, following information is
> +provided along with a generic description.
> +
> +:Input parameters: Parameters passed to the IOCTL and related details.
> +:Output: Details about output data and return value (with details about the non
> +         common error values).
> +
> +2.1 TDX_CMD_GET_REPORT
> +----------------------
> +
> +:Input parameters: struct tdx_report_req
> +:Output: Upon successful execution, TDREPORT data is copied to
> +         tdx_report_req.tdreport and return 0. Return -EINVAL for
> +         invalid operands, -EIO on TDCALL failure or standard error
> +         number on other common failures.
> +
> +The TDX_CMD_GET_REPORT IOCTL can be used by the attestation software to
> +get the TDREPORT from the TDX module using TDCALL[TDG.MR.REPORT].
> +
> +Reference
> +---------
> +
> +TDX reference material is collected here:
> +
> +https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html
> +
> +The driver is based on TDX module specification v1.0 and TDX GHCI specification v1.0.
> diff --git a/Documentation/virt/index.rst b/Documentation/virt/index.rst
> index 2f1cffa87b1b..56e003ff28ff 100644
> --- a/Documentation/virt/index.rst
> +++ b/Documentation/virt/index.rst
> @@ -14,6 +14,7 @@ Linux Virtualization Support
>     ne_overview
>     acrn/index
>     coco/sev-guest
> +   coco/tdx-guest
>     hyperv/index
>  
>  .. only:: html and subproject
> diff --git a/Documentation/x86/tdx.rst b/Documentation/x86/tdx.rst
> index b8fa4329e1a5..014b769923a4 100644
> --- a/Documentation/x86/tdx.rst
> +++ b/Documentation/x86/tdx.rst
> @@ -210,6 +210,49 @@ converted to shared on boot.
>  For coherent DMA allocation, the DMA buffer gets converted on the
>  allocation. Check force_dma_unencrypted() for details.
>  
> +Attestation
> +===========
> +
> +Attestation is used to verify the TDX guest trustworthiness to other
> +entities before provisioning secrets to the guest. For example, a key
> +server may want to use attestation to verify that the guest is the
> +desired one before releasing the encryption keys to mount the encrypted
> +rootfs or secondary drive.
> +
> +The TDX module records the state of the TDX guest in various stages of
> +the guest boot process using build time measurement register (MRTD) and
> +runtime measurement registers (RTMR). Measurements related to guest
> +initial configuration and firmware image are recorded in the MRTD
> +register. Measurements related to initial state, kernel image, firmware
> +image, command line options, initrd, ACPI tables, etc are recorded in
> +RTMR registers. For more details as an example, please refer to TDX
> +Virtual Firmware design specification, sec titled "TD Measurement". At
> +TDX guest runtime, the attestation process is used to attest to these
> +measurements.
> +
> +The attestation process consists of two steps: TDREPORT generation and
> +Quote generation.
> +
> +TDX guest uses TDCALL[TDG.MR.REPORT] to get the TDREPORT (TDREPORT_STRUCT)
> +from the TDX module. TDREPORT is a fixed-size data structure generated by
> +the TDX module which contains guest-specific information (such as build
> +and boot measurements), platform security version, and the MAC to protect
> +the integrity of the TDREPORT. A user-provided 64-Byte REPORTDATA is used
> +as input and included in the TDREPORT. Typically it can be some nonce
> +provided by attestation service so the TDREPORT can be verified uniquely.
> +More details about the TDREPORT can be found in Intel TDX Module
> +specification, section titled "TDG.MR.REPORT Leaf".
> +
> +After getting the TDREPORT, the second step of the attestation process
> +is to send it to the Quoting Enclave (QE) to generate the Quote. TDREPORT
> +by design can only be verified on the local platform as the MAC key is
> +bound to the platform. To support remote verification of the TDREPORT,
> +TDX leverages Intel SGX Quoting Enclave to verify the TDREPORT locally
> +and convert it to a remotely verifiable Quote. Method of sending TDREPORT
> +to QE is implementation specific. Attestation software can choose
> +whatever communication channel available (i.e. vsock or TCP/IP) to
> +send the TDREPORT to QE and receive the Quote.
> +
>  References
>  ==========
>  
> diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
> index 87ef258cec64..f79ab13a5c28 100644
> --- a/drivers/virt/Kconfig
> +++ b/drivers/virt/Kconfig
> @@ -52,4 +52,6 @@ source "drivers/virt/coco/efi_secret/Kconfig"
>  
>  source "drivers/virt/coco/sev-guest/Kconfig"
>  
> +source "drivers/virt/coco/tdx-guest/Kconfig"
> +
>  endif
> diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile
> index 093674e05c40..e9aa6fc96fab 100644
> --- a/drivers/virt/Makefile
> +++ b/drivers/virt/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_NITRO_ENCLAVES)	+= nitro_enclaves/
>  obj-$(CONFIG_ACRN_HSM)		+= acrn/
>  obj-$(CONFIG_EFI_SECRET)	+= coco/efi_secret/
>  obj-$(CONFIG_SEV_GUEST)		+= coco/sev-guest/
> +obj-$(CONFIG_INTEL_TDX_GUEST)	+= coco/tdx-guest/
> diff --git a/drivers/virt/coco/tdx-guest/Kconfig b/drivers/virt/coco/tdx-guest/Kconfig
> new file mode 100644
> index 000000000000..14246fc2fb02
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-guest/Kconfig
> @@ -0,0 +1,10 @@
> +config TDX_GUEST_DRIVER
> +	tristate "TDX Guest driver"
> +	depends on INTEL_TDX_GUEST
> +	help
> +	  The driver provides userspace interface to communicate with
> +	  the TDX module to request the TDX guest details like attestation
> +	  report.
> +
> +	  To compile this driver as module, choose M here. The module will
> +	  be called tdx-guest.
> diff --git a/drivers/virt/coco/tdx-guest/Makefile b/drivers/virt/coco/tdx-guest/Makefile
> new file mode 100644
> index 000000000000..775cb463f9c8
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-guest/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +obj-$(CONFIG_TDX_GUEST_DRIVER) += tdx-guest.o
> diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c
> new file mode 100644
> index 000000000000..40e7c1881fa9
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-guest/tdx-guest.c
> @@ -0,0 +1,102 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TDX guest user interface driver
> + *
> + * Copyright (C) 2022 Intel Corporation
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/miscdevice.h>
> +#include <linux/mm.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/string.h>
> +#include <linux/uaccess.h>
> +
> +#include <uapi/linux/tdx-guest.h>
> +
> +#include <asm/cpu_device_id.h>
> +#include <asm/tdx.h>
> +
> +static long tdx_get_report(struct tdx_report_req __user *req)
> +{
> +	u8 *reportdata, *tdreport;
> +	long ret;
> +
> +	reportdata = kmalloc(TDX_REPORTDATA_LEN, GFP_KERNEL);
> +	if (!reportdata)
> +		return -ENOMEM;
> +
> +	tdreport = kzalloc(TDX_REPORT_LEN, GFP_KERNEL);
> +	if (!tdreport) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}

Isn't simpler just allocating a struct tdx_report_req? You would save
one allocation and a few lines of code.

> +
> +	if (copy_from_user(reportdata, req->reportdata, TDX_REPORTDATA_LEN)) {
> +		ret = -EFAULT;
> +		goto out;
> +	}
> +
> +	/* Generate TDREPORT using "TDG.MR.REPORT" TDCALL */
> +	ret = tdx_mcall_get_report(reportdata, tdreport);
> +	if (ret)
> +		goto out;
> +
> +	if (copy_to_user(req->tdreport, tdreport, TDX_REPORT_LEN))
> +		ret = -EFAULT;
> +
> +out:
> +	kfree(reportdata);
> +	kfree(tdreport);
> +
> +	return ret;
> +}
> +
> +static long tdx_guest_ioctl(struct file *file, unsigned int cmd,
> +			    unsigned long arg)
> +{
> +	switch (cmd) {
> +	case TDX_CMD_GET_REPORT:
> +		return tdx_get_report((struct tdx_report_req __user *)arg);
> +	default:
> +		return -ENOTTY;
> +	}
> +}
> +
> +static const struct file_operations tdx_guest_fops = {
> +	.owner = THIS_MODULE,
> +	.unlocked_ioctl = tdx_guest_ioctl,
> +	.llseek = no_llseek,
> +};
> +
> +static struct miscdevice tdx_misc_dev = {
> +	.name = KBUILD_MODNAME,
> +	.minor = MISC_DYNAMIC_MINOR,
> +	.fops = &tdx_guest_fops,
> +};
> +
> +static const struct x86_cpu_id tdx_guest_ids[] = {
> +	X86_MATCH_FEATURE(X86_FEATURE_TDX_GUEST, NULL),
> +	{}
> +};
> +MODULE_DEVICE_TABLE(x86cpu, tdx_guest_ids);
> +
> +static int __init tdx_guest_init(void)
> +{
> +	if (!x86_match_cpu(tdx_guest_ids))
> +		return -ENODEV;
> +
> +	return misc_register(&tdx_misc_dev);
> +}
> +module_init(tdx_guest_init);
> +
> +static void __exit tdx_guest_exit(void)
> +{
> +	misc_deregister(&tdx_misc_dev);
> +}
> +module_exit(tdx_guest_exit);
> +
> +MODULE_AUTHOR("Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>");
> +MODULE_DESCRIPTION("TDX Guest Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/uapi/linux/tdx-guest.h b/include/uapi/linux/tdx-guest.h
> new file mode 100644
> index 000000000000..c1d52bc3a62e
> --- /dev/null
> +++ b/include/uapi/linux/tdx-guest.h
> @@ -0,0 +1,41 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/*
> + * Userspace interface for TDX guest driver
> + *
> + * Copyright (C) 2022 Intel Corporation
> + */
> +
> +#ifndef _UAPI_LINUX_TDX_GUEST_H_
> +#define _UAPI_LINUX_TDX_GUEST_H_
> +
> +#include <linux/ioctl.h>
> +#include <linux/types.h>
> +
> +/* Length of the REPORTDATA used in TDG.MR.REPORT TDCALL */
> +#define TDX_REPORTDATA_LEN              64
> +
> +/* Length of TDREPORT used in TDG.MR.REPORT TDCALL */
> +#define TDX_REPORT_LEN                  1024
> +
> +/**
> + * struct tdx_report_req - Request struct for TDX_CMD_GET_REPORT IOCTL.
> + *
> + * @reportdata: User buffer with REPORTDATA to be included into TDREPORT.
> + *              Typically it can be some nonce provided by attestation
> + *              service, so the generated TDREPORT can be uniquely verified.
> + * @tdreport: User buffer to store TDREPORT output from TDCALL[TDG.MR.REPORT].
> + */
> +struct tdx_report_req {
> +	__u8 reportdata[TDX_REPORTDATA_LEN];
> +	__u8 tdreport[TDX_REPORT_LEN];
> +};
> +
> +/*
> + * TDX_CMD_GET_REPORT - Get TDREPORT using TDCALL[TDG.MR.REPORT]
> + *
> + * Return 0 on success, -EIO on TDCALL execution failure, and
> + * standard errno on other general error cases.
> + */
> +#define TDX_CMD_GET_REPORT              _IOWR('T', 1, struct tdx_report_req)
> +
> +#endif /* _UAPI_LINUX_TDX_GUEST_H_ */
> -- 
> 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 2/3] virt: Add TDX guest driver
  2022-11-09 14:24   ` Wander Lairson Costa
@ 2022-11-09 15:36     ` Sathyanarayanan Kuppuswamy
  2022-11-09 15:37       ` Sathyanarayanan Kuppuswamy
  0 siblings, 1 reply; 15+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-11-09 15:36 UTC (permalink / raw)
  To: Wander Lairson Costa
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc



On 11/9/22 6:24 AM, Wander Lairson Costa wrote:
>> +	reportdata = kmalloc(TDX_REPORTDATA_LEN, GFP_KERNEL);
>> +	if (!reportdata)
>> +		return -ENOMEM;
>> +
>> +	tdreport = kzalloc(TDX_REPORT_LEN, GFP_KERNEL);
>> +	if (!tdreport) {
>> +		ret = -ENOMEM;
>> +		goto out;
>> +	}
> Isn't simpler just allocating a struct tdx_report_req? You would save
> one allocation and a few lines of code.
> 

TDG.MR.TDCALL expects reportdata and tdreport buffers to be size aligned. So,
allocating them together with sizeof(struct tdx report req) will not work. We
can get around this by allocating a slightly larger buffer size. However, because
it is not a time-critical path, I believe that allocating two separate buffers
for input/output is simpler.

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 2/3] virt: Add TDX guest driver
  2022-11-09 15:36     ` Sathyanarayanan Kuppuswamy
@ 2022-11-09 15:37       ` Sathyanarayanan Kuppuswamy
  0 siblings, 0 replies; 15+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-11-09 15:37 UTC (permalink / raw)
  To: Wander Lairson Costa
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc



On 11/9/22 7:36 AM, Sathyanarayanan Kuppuswamy wrote:
> TDG.MR.TDCALL expects reportdata and tdreport buffers to be size aligned. So,
> allocating them together with sizeof(struct tdx report req) will not work. We
> can get around this by allocating a slightly larger buffer size. However, because
> it is not a time-critical path, I believe that allocating two separate buffers
> for input/output is simpler.

I mean't TDG.MR.REPORT TDCALL.

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 0/3] Add TDX Guest Attestation support
  2022-11-04  3:23 [PATCH v17 0/3] Add TDX Guest Attestation support Kuppuswamy Sathyanarayanan
                   ` (2 preceding siblings ...)
  2022-11-04  3:23 ` [PATCH v17 3/3] selftests: tdx: Test TDX attestation GetReport support Kuppuswamy Sathyanarayanan
@ 2022-11-10  3:41 ` Sathyanarayanan Kuppuswamy
  3 siblings, 0 replies; 15+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-11-10  3:41 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kirill A . Shutemov,
	Tony Luck, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

Hi Boris/Dave,

On 11/3/22 8:23 PM, Kuppuswamy Sathyanarayanan wrote:
> Hi All,
> 
> Intel's Trust Domain Extensions (TDX) protect guest VMs from malicious
> hosts and some physical attacks. VM guest with TDX support is called
> as a TDX Guest.
> 
> In TDX guest, attestation process is used to verify the TDX guest
> trustworthiness to other entities before provisioning secrets to the
> guest. For example, a key server may request for attestation before
> releasing the encryption keys to mount the encrypted rootfs or
> secondary drive.
> 
> This patch set adds attestation support for the TDX guest. Details
> about the TDX attestation process and the steps involved are explained
> in Documentation/x86/tdx.rst (added by patch 2/3).
> 
> Following are the details of the patch set:
> 
> Patch 1/3 -> Preparatory patch for adding attestation support.
> Patch 2/3 -> Adds user interface driver to support attestation.
> Patch 3/3 -> Adds selftest support for TDREPORT feature.
> 
> Commit log history is maintained in the individual patches.
> 
> Current overall status of this series is, it has no pending issues
> and can be considered for the upcoming merge cycle.
> 

Any comments on this series? If you are fine with the current version,
I'm wondering if this can be considered for the upcoming merge window.
Please let me know what you think.

> Kuppuswamy Sathyanarayanan (3):
>   x86/tdx: Add a wrapper to get TDREPORT from the TDX Module
>   virt: Add TDX guest driver
>   selftests: tdx: Test TDX attestation GetReport support
> 
>  Documentation/virt/coco/tdx-guest.rst        |  42 +++++
>  Documentation/virt/index.rst                 |   1 +
>  Documentation/x86/tdx.rst                    |  43 +++++
>  arch/x86/coco/tdx/tdx.c                      |  38 +++++
>  arch/x86/include/asm/tdx.h                   |   2 +
>  drivers/virt/Kconfig                         |   2 +
>  drivers/virt/Makefile                        |   1 +
>  drivers/virt/coco/tdx-guest/Kconfig          |  10 ++
>  drivers/virt/coco/tdx-guest/Makefile         |   2 +
>  drivers/virt/coco/tdx-guest/tdx-guest.c      | 102 ++++++++++++
>  include/uapi/linux/tdx-guest.h               |  41 +++++
>  tools/testing/selftests/Makefile             |   1 +
>  tools/testing/selftests/tdx/Makefile         |   7 +
>  tools/testing/selftests/tdx/config           |   1 +
>  tools/testing/selftests/tdx/tdx_guest_test.c | 163 +++++++++++++++++++
>  15 files changed, 456 insertions(+)
>  create mode 100644 Documentation/virt/coco/tdx-guest.rst
>  create mode 100644 drivers/virt/coco/tdx-guest/Kconfig
>  create mode 100644 drivers/virt/coco/tdx-guest/Makefile
>  create mode 100644 drivers/virt/coco/tdx-guest/tdx-guest.c
>  create mode 100644 include/uapi/linux/tdx-guest.h
>  create mode 100644 tools/testing/selftests/tdx/Makefile
>  create mode 100644 tools/testing/selftests/tdx/config
>  create mode 100644 tools/testing/selftests/tdx/tdx_guest_test.c
> 

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module
  2022-11-04  3:23 ` [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module Kuppuswamy Sathyanarayanan
@ 2022-11-10 15:16   ` Wander Lairson Costa
  2022-11-11 18:35   ` Dave Hansen
  1 sibling, 0 replies; 15+ messages in thread
From: Wander Lairson Costa @ 2022-11-10 15:16 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

On Thu, Nov 03, 2022 at 08:23:53PM -0700, Kuppuswamy Sathyanarayanan wrote:
> To support TDX attestation, the TDX guest driver exposes an IOCTL
> interface to allow userspace to get the TDREPORT from the TDX module
> via TDG.MR.TDREPORT TDCALL.
> 
> In order to get the TDREPORT in the TDX guest driver, instead of using
> a low level function like __tdx_module_call(), add a
> tdx_mcall_get_report() wrapper function to handle it.
> 
> This is a preparatory patch for adding attestation support.
> 
> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> ---
> 
> Changes since v16
>  * Added invalid operand error code support.
>  * Removed subtype param in tdx_mcall_get_report().
> 
> Changes since v15:
>  * None
> 
> Changes since v14:
>  * Instead of exporting __tdx_module_call(), added a new wrapper.
>  * Rebased on top of v6.1-rc1
> 
>  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 928dcf7a20d9..17cf2e9d5849 100644
> --- a/arch/x86/coco/tdx/tdx.c
> +++ b/arch/x86/coco/tdx/tdx.c
> @@ -5,6 +5,8 @@
>  #define pr_fmt(fmt)     "tdx: " fmt
>  
>  #include <linux/cpufeature.h>
> +#include <linux/export.h>
> +#include <linux/io.h>
>  #include <asm/coco.h>
>  #include <asm/tdx.h>
>  #include <asm/vmx.h>
> @@ -15,6 +17,7 @@
>  /* TDX module Call Leaf IDs */
>  #define TDX_GET_INFO			1
>  #define TDX_GET_VEINFO			3
> +#define TDX_GET_REPORT			4
>  #define TDX_ACCEPT_PAGE			6
>  
>  /* TDX hypercall Leaf IDs */
> @@ -34,6 +37,10 @@
>  #define VE_GET_PORT_NUM(e)	((e) >> 16)
>  #define VE_IS_IO_STRING(e)	((e) & BIT(4))
>  
> +/* TDX Module call error codes */
> +#define TDCALL_RETURN_CODE(a)	((a) >> 32)
> +#define TDCALL_INVALID_OPERAND	0xc0000100
> +
>  /*
>   * Wrapper for standard use of __tdx_hypercall with no output aside from
>   * return code.
> @@ -98,6 +105,37 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
>  		panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
>  }
>  
> +/**
> + * tdx_mcall_get_report() - Wrapper for TDG.MR.REPORT TDCALL.
> + * @reportdata: Address of the input buffer which contains
> + *              user-defined REPORTDATA to be included into
> + *              TDREPORT.
> + * @tdreport: Address of the output buffer to store TDREPORT.
> + *
> + * Generate TDREPORT using "TDG.MR.REPORT" TDCALL. Refer to section
> + * titled "TDG.MR.REPORT leaf" in the TDX Module 1.0 specification
> + * for detailed information. It is used in the TDX guest driver
> + * module to get the TDREPORT.
> + *
> + * Return 0 on success, -EINVAL for invalid operands, or -EIO on
> + * other TDCALL failures.
> + */
> +int tdx_mcall_get_report(u8 *reportdata, u8 *tdreport)
> +{
> +	u64 ret;
> +
> +	ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(tdreport),
> +				virt_to_phys(reportdata), 0, 0, NULL);
> +	if (ret) {
> +		if (TDCALL_RETURN_CODE(ret) == TDCALL_INVALID_OPERAND)
> +			return -EINVAL;
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(tdx_mcall_get_report);
> +
>  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 020c81a7c729..eef9c0b7880e 100644
> --- a/arch/x86/include/asm/tdx.h
> +++ b/arch/x86/include/asm/tdx.h
> @@ -67,6 +67,8 @@ void tdx_safe_halt(void);
>  
>  bool tdx_early_handle_ve(struct pt_regs *regs);
>  
> +int tdx_mcall_get_report(u8 *reportdata, u8 *tdreport);
> +
>  #else
>  
>  static inline void tdx_early_init(void) { };
> -- 
> 2.34.1
> 
> 

Acked-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 2/3] virt: Add TDX guest driver
  2022-11-04  3:23 ` [PATCH v17 2/3] virt: Add TDX guest driver Kuppuswamy Sathyanarayanan
  2022-11-09 14:24   ` Wander Lairson Costa
@ 2022-11-10 15:17   ` Wander Lairson Costa
  1 sibling, 0 replies; 15+ messages in thread
From: Wander Lairson Costa @ 2022-11-10 15:17 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

On Thu, Nov 03, 2022 at 08:23:54PM -0700, Kuppuswamy Sathyanarayanan wrote:
> TDX guest driver exposes IOCTL interfaces to service TDX guest
> user-specific requests. Currently, it is only used to allow the user to
> get the TDREPORT to support TDX attestation.
> 
> Details about the TDX attestation process are documented in
> Documentation/x86/tdx.rst, and the IOCTL details are documented in
> Documentation/virt/coco/tdx-guest.rst.
> 
> Operations like getting TDREPORT involves sending a blob of data as
> input and getting another blob of data as output. It was considered
> to use a sysfs interface for this, but it doesn't fit well into the
> standard sysfs model for configuring values. It would be possible to
> do read/write on files, but it would need multiple file descriptors,
> which would be somewhat messy. IOCTLs seems to be the best fitting
> and simplest model for this use case. The AMD sev-guest driver also
> uses IOCTL interface to support attestation.
> 
> [Bagas Sanjaya: Ack is for documentation portion]
> Acked-by: Kai Huang <kai.huang@intel.com>
> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Acked-by: Wander Lairson Costa <wander@redhat.com>
> Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com>
> Reviewed-by: Tony Luck <tony.luck@intel.com>
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> ---
> 
> Changes since v16:
>  * Removed rpd_len, tdr_len and subtype members from
>    struct tdx_report_req.
>  * Used fixed size buffers for TDREPORT and REPORTDATA in
>    struct tdx_report_req.
> 
> Changes since v15:
>  * Removed error messages in tdx_get_report() as per Greg's suggestion.
>  * Removed #ifdef MODULE usage for MODULE_DEVICE_TABLE.
>  * Added copyright info for the header file.
> 
> Changes since v14:
>  * Used tdx_mcall_get_report() wrapper instead of __tdx_module_call()
>    call.
>  * Added pr_err() messages for some failure cases in tdx_get_report().
>  * Used KBUILD_MODNAME instead of device name.
>  * Rebased on top of v6.1-rc1
> 
> Changes since v13:
>  * Converted the driver from built-in to a driver module
>    as per Greg's suggestion.
>  * Moved the driver to drivers/virt/coco to match AMD SEV.
>  * Added support to autoload the driver based on
>    X86_FEATURE_TDX_GUEST CPU feature.
>  * Squashed patch titled "Documentation/x86: Document TDX
>    attestation process" with this patch.
>  * Since the attestation process is already documented in
>    Documentation/x86/tdx.rst, remove it from the commit log.
>  * Modified the commit log to match the new format.
>  * Explicitly included the required header files.
>  * Fixed magic number usage in reserved member check.
> 
> Changes since v13:
>  * Fixed the commit log as per review suggestion.
>  * Explicitly included the required header files.
>  * Fixed magic number usage in reserved member check.
> 
> Changes since v12:
>  * Added check to ensure reserved entries are set as 0.
> 
> Changes since v11:
>  * Renamed DRIVER_NAME to TDX_GUEST_DEVICE and moved it to
>    arch/x86/include/uapi/asm/tdx.h.
>  * Fixed default error number in tdx_guest_ioctl().
>  * Moved tdx_misc_dev definition out of tdx_guest_init() as
>    per Greg's suggestion.
>  * Reordered struct tdx_report_req to avoid holes and added
>    required padding.
> 
> Changes since v10:
>  * Replaced TD/TD Guest usage with TDX Guest or Guest.
>  * Removed unnecessary comments.
>  * Added more validation to user input in tdx_get_report().
>  * Used u64_to_user_ptr when reading user u64 pointers.
>  * Fixed commit log as per review comments.
> 
> Changes since v9:
>  * Dropped the cover letter. Since this patch set only adds
>    TDREPORT support, the commit log itself has all the required details.
>  * Dropped the Quote support and event IRQ support as per Dave's
>    review suggestion.
>  * Dropped attest.c and moved its contents to tdx.c
>  * Updated commit log and comments to reflect latest changes.
> 
> Changes since v8:
>  * Please refer to https://lore.kernel.org/all/ \
>    20220728034420.648314-1-sathyanarayanan.kuppuswamy@linux.intel.com/
> 
>  Documentation/virt/coco/tdx-guest.rst   |  42 ++++++++++
>  Documentation/virt/index.rst            |   1 +
>  Documentation/x86/tdx.rst               |  43 ++++++++++
>  drivers/virt/Kconfig                    |   2 +
>  drivers/virt/Makefile                   |   1 +
>  drivers/virt/coco/tdx-guest/Kconfig     |  10 +++
>  drivers/virt/coco/tdx-guest/Makefile    |   2 +
>  drivers/virt/coco/tdx-guest/tdx-guest.c | 102 ++++++++++++++++++++++++
>  include/uapi/linux/tdx-guest.h          |  41 ++++++++++
>  9 files changed, 244 insertions(+)
>  create mode 100644 Documentation/virt/coco/tdx-guest.rst
>  create mode 100644 drivers/virt/coco/tdx-guest/Kconfig
>  create mode 100644 drivers/virt/coco/tdx-guest/Makefile
>  create mode 100644 drivers/virt/coco/tdx-guest/tdx-guest.c
>  create mode 100644 include/uapi/linux/tdx-guest.h
> 
> diff --git a/Documentation/virt/coco/tdx-guest.rst b/Documentation/virt/coco/tdx-guest.rst
> new file mode 100644
> index 000000000000..388d0ffb686b
> --- /dev/null
> +++ b/Documentation/virt/coco/tdx-guest.rst
> @@ -0,0 +1,42 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +===================================================================
> +TDX Guest API Documentation
> +===================================================================
> +
> +1. General description
> +======================
> +
> +The TDX guest driver exposes IOCTL interfaces via /dev/tdx-guest misc
> +device to allow userspace to get certain TDX guest specific details.
> +
> +2. API description
> +==================
> +
> +In this section, for each supported IOCTL, following information is
> +provided along with a generic description.
> +
> +:Input parameters: Parameters passed to the IOCTL and related details.
> +:Output: Details about output data and return value (with details about the non
> +         common error values).
> +
> +2.1 TDX_CMD_GET_REPORT
> +----------------------
> +
> +:Input parameters: struct tdx_report_req
> +:Output: Upon successful execution, TDREPORT data is copied to
> +         tdx_report_req.tdreport and return 0. Return -EINVAL for
> +         invalid operands, -EIO on TDCALL failure or standard error
> +         number on other common failures.
> +
> +The TDX_CMD_GET_REPORT IOCTL can be used by the attestation software to
> +get the TDREPORT from the TDX module using TDCALL[TDG.MR.REPORT].
> +
> +Reference
> +---------
> +
> +TDX reference material is collected here:
> +
> +https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html
> +
> +The driver is based on TDX module specification v1.0 and TDX GHCI specification v1.0.
> diff --git a/Documentation/virt/index.rst b/Documentation/virt/index.rst
> index 2f1cffa87b1b..56e003ff28ff 100644
> --- a/Documentation/virt/index.rst
> +++ b/Documentation/virt/index.rst
> @@ -14,6 +14,7 @@ Linux Virtualization Support
>     ne_overview
>     acrn/index
>     coco/sev-guest
> +   coco/tdx-guest
>     hyperv/index
>  
>  .. only:: html and subproject
> diff --git a/Documentation/x86/tdx.rst b/Documentation/x86/tdx.rst
> index b8fa4329e1a5..014b769923a4 100644
> --- a/Documentation/x86/tdx.rst
> +++ b/Documentation/x86/tdx.rst
> @@ -210,6 +210,49 @@ converted to shared on boot.
>  For coherent DMA allocation, the DMA buffer gets converted on the
>  allocation. Check force_dma_unencrypted() for details.
>  
> +Attestation
> +===========
> +
> +Attestation is used to verify the TDX guest trustworthiness to other
> +entities before provisioning secrets to the guest. For example, a key
> +server may want to use attestation to verify that the guest is the
> +desired one before releasing the encryption keys to mount the encrypted
> +rootfs or secondary drive.
> +
> +The TDX module records the state of the TDX guest in various stages of
> +the guest boot process using build time measurement register (MRTD) and
> +runtime measurement registers (RTMR). Measurements related to guest
> +initial configuration and firmware image are recorded in the MRTD
> +register. Measurements related to initial state, kernel image, firmware
> +image, command line options, initrd, ACPI tables, etc are recorded in
> +RTMR registers. For more details as an example, please refer to TDX
> +Virtual Firmware design specification, sec titled "TD Measurement". At
> +TDX guest runtime, the attestation process is used to attest to these
> +measurements.
> +
> +The attestation process consists of two steps: TDREPORT generation and
> +Quote generation.
> +
> +TDX guest uses TDCALL[TDG.MR.REPORT] to get the TDREPORT (TDREPORT_STRUCT)
> +from the TDX module. TDREPORT is a fixed-size data structure generated by
> +the TDX module which contains guest-specific information (such as build
> +and boot measurements), platform security version, and the MAC to protect
> +the integrity of the TDREPORT. A user-provided 64-Byte REPORTDATA is used
> +as input and included in the TDREPORT. Typically it can be some nonce
> +provided by attestation service so the TDREPORT can be verified uniquely.
> +More details about the TDREPORT can be found in Intel TDX Module
> +specification, section titled "TDG.MR.REPORT Leaf".
> +
> +After getting the TDREPORT, the second step of the attestation process
> +is to send it to the Quoting Enclave (QE) to generate the Quote. TDREPORT
> +by design can only be verified on the local platform as the MAC key is
> +bound to the platform. To support remote verification of the TDREPORT,
> +TDX leverages Intel SGX Quoting Enclave to verify the TDREPORT locally
> +and convert it to a remotely verifiable Quote. Method of sending TDREPORT
> +to QE is implementation specific. Attestation software can choose
> +whatever communication channel available (i.e. vsock or TCP/IP) to
> +send the TDREPORT to QE and receive the Quote.
> +
>  References
>  ==========
>  
> diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
> index 87ef258cec64..f79ab13a5c28 100644
> --- a/drivers/virt/Kconfig
> +++ b/drivers/virt/Kconfig
> @@ -52,4 +52,6 @@ source "drivers/virt/coco/efi_secret/Kconfig"
>  
>  source "drivers/virt/coco/sev-guest/Kconfig"
>  
> +source "drivers/virt/coco/tdx-guest/Kconfig"
> +
>  endif
> diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile
> index 093674e05c40..e9aa6fc96fab 100644
> --- a/drivers/virt/Makefile
> +++ b/drivers/virt/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_NITRO_ENCLAVES)	+= nitro_enclaves/
>  obj-$(CONFIG_ACRN_HSM)		+= acrn/
>  obj-$(CONFIG_EFI_SECRET)	+= coco/efi_secret/
>  obj-$(CONFIG_SEV_GUEST)		+= coco/sev-guest/
> +obj-$(CONFIG_INTEL_TDX_GUEST)	+= coco/tdx-guest/
> diff --git a/drivers/virt/coco/tdx-guest/Kconfig b/drivers/virt/coco/tdx-guest/Kconfig
> new file mode 100644
> index 000000000000..14246fc2fb02
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-guest/Kconfig
> @@ -0,0 +1,10 @@
> +config TDX_GUEST_DRIVER
> +	tristate "TDX Guest driver"
> +	depends on INTEL_TDX_GUEST
> +	help
> +	  The driver provides userspace interface to communicate with
> +	  the TDX module to request the TDX guest details like attestation
> +	  report.
> +
> +	  To compile this driver as module, choose M here. The module will
> +	  be called tdx-guest.
> diff --git a/drivers/virt/coco/tdx-guest/Makefile b/drivers/virt/coco/tdx-guest/Makefile
> new file mode 100644
> index 000000000000..775cb463f9c8
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-guest/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +obj-$(CONFIG_TDX_GUEST_DRIVER) += tdx-guest.o
> diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c
> new file mode 100644
> index 000000000000..40e7c1881fa9
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-guest/tdx-guest.c
> @@ -0,0 +1,102 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TDX guest user interface driver
> + *
> + * Copyright (C) 2022 Intel Corporation
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/miscdevice.h>
> +#include <linux/mm.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/string.h>
> +#include <linux/uaccess.h>
> +
> +#include <uapi/linux/tdx-guest.h>
> +
> +#include <asm/cpu_device_id.h>
> +#include <asm/tdx.h>
> +
> +static long tdx_get_report(struct tdx_report_req __user *req)
> +{
> +	u8 *reportdata, *tdreport;
> +	long ret;
> +
> +	reportdata = kmalloc(TDX_REPORTDATA_LEN, GFP_KERNEL);
> +	if (!reportdata)
> +		return -ENOMEM;
> +
> +	tdreport = kzalloc(TDX_REPORT_LEN, GFP_KERNEL);
> +	if (!tdreport) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
> +	if (copy_from_user(reportdata, req->reportdata, TDX_REPORTDATA_LEN)) {
> +		ret = -EFAULT;
> +		goto out;
> +	}
> +
> +	/* Generate TDREPORT using "TDG.MR.REPORT" TDCALL */
> +	ret = tdx_mcall_get_report(reportdata, tdreport);
> +	if (ret)
> +		goto out;
> +
> +	if (copy_to_user(req->tdreport, tdreport, TDX_REPORT_LEN))
> +		ret = -EFAULT;
> +
> +out:
> +	kfree(reportdata);
> +	kfree(tdreport);
> +
> +	return ret;
> +}
> +
> +static long tdx_guest_ioctl(struct file *file, unsigned int cmd,
> +			    unsigned long arg)
> +{
> +	switch (cmd) {
> +	case TDX_CMD_GET_REPORT:
> +		return tdx_get_report((struct tdx_report_req __user *)arg);
> +	default:
> +		return -ENOTTY;
> +	}
> +}
> +
> +static const struct file_operations tdx_guest_fops = {
> +	.owner = THIS_MODULE,
> +	.unlocked_ioctl = tdx_guest_ioctl,
> +	.llseek = no_llseek,
> +};
> +
> +static struct miscdevice tdx_misc_dev = {
> +	.name = KBUILD_MODNAME,
> +	.minor = MISC_DYNAMIC_MINOR,
> +	.fops = &tdx_guest_fops,
> +};
> +
> +static const struct x86_cpu_id tdx_guest_ids[] = {
> +	X86_MATCH_FEATURE(X86_FEATURE_TDX_GUEST, NULL),
> +	{}
> +};
> +MODULE_DEVICE_TABLE(x86cpu, tdx_guest_ids);
> +
> +static int __init tdx_guest_init(void)
> +{
> +	if (!x86_match_cpu(tdx_guest_ids))
> +		return -ENODEV;
> +
> +	return misc_register(&tdx_misc_dev);
> +}
> +module_init(tdx_guest_init);
> +
> +static void __exit tdx_guest_exit(void)
> +{
> +	misc_deregister(&tdx_misc_dev);
> +}
> +module_exit(tdx_guest_exit);
> +
> +MODULE_AUTHOR("Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>");
> +MODULE_DESCRIPTION("TDX Guest Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/uapi/linux/tdx-guest.h b/include/uapi/linux/tdx-guest.h
> new file mode 100644
> index 000000000000..c1d52bc3a62e
> --- /dev/null
> +++ b/include/uapi/linux/tdx-guest.h
> @@ -0,0 +1,41 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/*
> + * Userspace interface for TDX guest driver
> + *
> + * Copyright (C) 2022 Intel Corporation
> + */
> +
> +#ifndef _UAPI_LINUX_TDX_GUEST_H_
> +#define _UAPI_LINUX_TDX_GUEST_H_
> +
> +#include <linux/ioctl.h>
> +#include <linux/types.h>
> +
> +/* Length of the REPORTDATA used in TDG.MR.REPORT TDCALL */
> +#define TDX_REPORTDATA_LEN              64
> +
> +/* Length of TDREPORT used in TDG.MR.REPORT TDCALL */
> +#define TDX_REPORT_LEN                  1024
> +
> +/**
> + * struct tdx_report_req - Request struct for TDX_CMD_GET_REPORT IOCTL.
> + *
> + * @reportdata: User buffer with REPORTDATA to be included into TDREPORT.
> + *              Typically it can be some nonce provided by attestation
> + *              service, so the generated TDREPORT can be uniquely verified.
> + * @tdreport: User buffer to store TDREPORT output from TDCALL[TDG.MR.REPORT].
> + */
> +struct tdx_report_req {
> +	__u8 reportdata[TDX_REPORTDATA_LEN];
> +	__u8 tdreport[TDX_REPORT_LEN];
> +};
> +
> +/*
> + * TDX_CMD_GET_REPORT - Get TDREPORT using TDCALL[TDG.MR.REPORT]
> + *
> + * Return 0 on success, -EIO on TDCALL execution failure, and
> + * standard errno on other general error cases.
> + */
> +#define TDX_CMD_GET_REPORT              _IOWR('T', 1, struct tdx_report_req)
> +
> +#endif /* _UAPI_LINUX_TDX_GUEST_H_ */
> -- 
> 2.34.1
> 
> 

Acked-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 3/3] selftests: tdx: Test TDX attestation GetReport support
  2022-11-04  3:23 ` [PATCH v17 3/3] selftests: tdx: Test TDX attestation GetReport support Kuppuswamy Sathyanarayanan
@ 2022-11-10 15:17   ` Wander Lairson Costa
  0 siblings, 0 replies; 15+ messages in thread
From: Wander Lairson Costa @ 2022-11-10 15:17 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, Jonathan Corbet, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Kai Huang, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

On Thu, Nov 03, 2022 at 08:23:55PM -0700, Kuppuswamy Sathyanarayanan wrote:
> Attestation is used to verify the trustworthiness of a TDX guest.
> During the guest bring-up, the Intel TDX module measures and records
> the initial contents and configuration of the guest, and at runtime,
> guest software uses runtime measurement registers (RMTRs) to measure
> and record details related to kernel image, command line params, ACPI
> tables, initrd, etc. At guest runtime, the attestation process is used
> to attest to these measurements.
> 
> The first step in the TDX attestation process is to get the TDREPORT
> data. It is a fixed size data structure generated by the TDX module
> which includes the above mentioned measurements data, a MAC ID to
> protect the integrity of the TDREPORT, and a 64-Byte of user specified
> data passed during TDREPORT request which can uniquely identify the
> TDREPORT.
> 
> Intel's TDX guest driver exposes TDX_CMD_GET_REPORT IOCTL interface to
> enable guest userspace to get the TDREPORT.
> 
> Add a kernel self test module to test this ABI and verify the validity
> of the generated TDREPORT.
> 
> Reviewed-by: Tony Luck <tony.luck@intel.com>
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Acked-by: Kai Huang <kai.huang@intel.com>
> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> ---
> 
> Changes since v16:
>  * Modified the code to adapt to fixed size reportdata and tdeport
>    buffers in struct tdx_report_req.
> 
> Changes since v15:
>  * None
> 
> Changes since v14:
>  * Fixed format issue in struct comments.
>  * Rebased on top of v6.1-rc1
> 
> Changes since v13:
>  * Removed __packed from TDREPORT structs.
>  * Since the guest driver is moved to drivers/virt/coco, removed
>    tools/arch/x86/include header folder usage.
>  * Fixed struct comments to match kernel-doc format.
>  * Fixed commit log as per review comments.
>  * Fixed some format issues in the code.
> 
> Changes since v12:
>  * Changed #ifdef DEBUG usage with if (DEBUG).
>  * Initialized reserved entries values to zero.
> 
> Changes since v11:
>  * Renamed devname with TDX_GUEST_DEVNAME.
> 
> Changes since v10:
>  * Replaced TD/TD Guest usage with guest or TDX guest.
>  * Reworded the subject line.
> 
> Changes since v9:
>  * Copied arch/x86/include/uapi/asm/tdx.h to tools/arch/x86/include to
>    decouple header dependency between kernel source and tools dir.
>  * Fixed Makefile to adapt to above change.
>  * Fixed commit log and comments.
>  * Added __packed to hardware structs.
> 
> Changes since v8:
>  * Please refer to https://lore.kernel.org/all/ \
>    20220728034420.648314-1-sathyanarayanan.kuppuswamy@linux.intel.com/
> 
>  tools/testing/selftests/Makefile             |   1 +
>  tools/testing/selftests/tdx/Makefile         |   7 +
>  tools/testing/selftests/tdx/config           |   1 +
>  tools/testing/selftests/tdx/tdx_guest_test.c | 163 +++++++++++++++++++
>  4 files changed, 172 insertions(+)
>  create mode 100644 tools/testing/selftests/tdx/Makefile
>  create mode 100644 tools/testing/selftests/tdx/config
>  create mode 100644 tools/testing/selftests/tdx/tdx_guest_test.c
> 
> diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
> index 0464b2c6c1e4..f60e14d16bfd 100644
> --- a/tools/testing/selftests/Makefile
> +++ b/tools/testing/selftests/Makefile
> @@ -73,6 +73,7 @@ TARGETS += sync
>  TARGETS += syscall_user_dispatch
>  TARGETS += sysctl
>  TARGETS += tc-testing
> +TARGETS += tdx
>  TARGETS += timens
>  ifneq (1, $(quicktest))
>  TARGETS += timers
> diff --git a/tools/testing/selftests/tdx/Makefile b/tools/testing/selftests/tdx/Makefile
> new file mode 100644
> index 000000000000..8dd43517cd55
> --- /dev/null
> +++ b/tools/testing/selftests/tdx/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +CFLAGS += -O3 -Wl,-no-as-needed -Wall -static
> +
> +TEST_GEN_PROGS := tdx_guest_test
> +
> +include ../lib.mk
> diff --git a/tools/testing/selftests/tdx/config b/tools/testing/selftests/tdx/config
> new file mode 100644
> index 000000000000..aa1edc829ab6
> --- /dev/null
> +++ b/tools/testing/selftests/tdx/config
> @@ -0,0 +1 @@
> +CONFIG_TDX_GUEST_DRIVER=y
> diff --git a/tools/testing/selftests/tdx/tdx_guest_test.c b/tools/testing/selftests/tdx/tdx_guest_test.c
> new file mode 100644
> index 000000000000..6f7ab667b8cc
> --- /dev/null
> +++ b/tools/testing/selftests/tdx/tdx_guest_test.c
> @@ -0,0 +1,163 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Test TDX guest features
> + *
> + * Copyright (C) 2022 Intel Corporation.
> + *
> + * Author: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> + */
> +
> +#include <sys/ioctl.h>
> +
> +#include <errno.h>
> +#include <fcntl.h>
> +
> +#include "../kselftest_harness.h"
> +#include "../../../../include/uapi/linux/tdx-guest.h"
> +
> +#define TDX_GUEST_DEVNAME "/dev/tdx_guest"
> +#define HEX_DUMP_SIZE 8
> +#define DEBUG 0
> +
> +/**
> + * struct tdreport_type - Type header of TDREPORT_STRUCT.
> + * @type: Type of the TDREPORT (0 - SGX, 81 - TDX, rest are reserved)
> + * @sub_type: Subtype of the TDREPORT (Default value is 0).
> + * @version: TDREPORT version (Default value is 0).
> + * @reserved: Added for future extension.
> + *
> + * More details can be found in TDX v1.0 module specification, sec
> + * titled "REPORTTYPE".
> + */
> +struct tdreport_type {
> +	__u8 type;
> +	__u8 sub_type;
> +	__u8 version;
> +	__u8 reserved;
> +};
> +
> +/**
> + * struct reportmac - TDX guest report data, MAC and TEE hashes.
> + * @type: TDREPORT type header.
> + * @reserved1: Reserved for future extension.
> + * @cpu_svn: CPU security version.
> + * @tee_tcb_info_hash: SHA384 hash of TEE TCB INFO.
> + * @tee_td_info_hash: SHA384 hash of TDINFO_STRUCT.
> + * @reportdata: User defined unique data passed in TDG.MR.REPORT request.
> + * @reserved2: Reserved for future extension.
> + * @mac: CPU MAC ID.
> + *
> + * It is MAC-protected and contains hashes of the remainder of the
> + * report structure along with user provided report data. More details can
> + * be found in TDX v1.0 Module specification, sec titled "REPORTMACSTRUCT"
> + */
> +struct reportmac {
> +	struct tdreport_type type;
> +	__u8 reserved1[12];
> +	__u8 cpu_svn[16];
> +	__u8 tee_tcb_info_hash[48];
> +	__u8 tee_td_info_hash[48];
> +	__u8 reportdata[64];
> +	__u8 reserved2[32];
> +	__u8 mac[32];
> +};
> +
> +/**
> + * struct td_info - TDX guest measurements and configuration.
> + * @attr: TDX Guest attributes (like debug, spet_disable, etc).
> + * @xfam: Extended features allowed mask.
> + * @mrtd: Build time measurement register.
> + * @mrconfigid: Software-defined ID for non-owner-defined configuration
> + *              of the guest - e.g., run-time or OS configuration.
> + * @mrowner: Software-defined ID for the guest owner.
> + * @mrownerconfig: Software-defined ID for owner-defined configuration of
> + *                 the guest - e.g., specific to the workload.
> + * @rtmr: Run time measurement registers.
> + * @reserved: Added for future extension.
> + *
> + * It contains the measurements and initial configuration of the TDX guest
> + * that was locked at initialization and a set of measurement registers
> + * that are run-time extendable. More details can be found in TDX v1.0
> + * Module specification, sec titled "TDINFO_STRUCT".
> + */
> +struct td_info {
> +	__u8 attr[8];
> +	__u64 xfam;
> +	__u64 mrtd[6];
> +	__u64 mrconfigid[6];
> +	__u64 mrowner[6];
> +	__u64 mrownerconfig[6];
> +	__u64 rtmr[24];
> +	__u64 reserved[14];
> +};
> +
> +/*
> + * struct tdreport - Output of TDCALL[TDG.MR.REPORT].
> + * @reportmac: Mac protected header of size 256 bytes.
> + * @tee_tcb_info: Additional attestable elements in the TCB are not
> + *                reflected in the reportmac.
> + * @reserved: Added for future extension.
> + * @tdinfo: Measurements and configuration data of size 512 bytes.
> + *
> + * More details can be found in TDX v1.0 Module specification, sec
> + * titled "TDREPORT_STRUCT".
> + */
> +struct tdreport {
> +	struct reportmac reportmac;
> +	__u8 tee_tcb_info[239];
> +	__u8 reserved[17];
> +	struct td_info tdinfo;
> +};
> +
> +static void print_array_hex(const char *title, const char *prefix_str,
> +			    const void *buf, int len)
> +{
> +	int i, j, line_len, rowsize = HEX_DUMP_SIZE;
> +	const __u8 *ptr = buf;
> +
> +	printf("\t\t%s", title);
> +
> +	for (j = 0; j < len; j += rowsize) {
> +		line_len = rowsize < (len - j) ? rowsize : (len - j);
> +		printf("%s%.8x:", prefix_str, j);
> +		for (i = 0; i < line_len; i++)
> +			printf(" %.2x", ptr[j + i]);
> +		printf("\n");
> +	}
> +
> +	printf("\n");
> +}
> +
> +TEST(verify_report)
> +{
> +	struct tdx_report_req req;
> +	struct tdreport *tdreport;
> +	int devfd, i;
> +
> +	devfd = open(TDX_GUEST_DEVNAME, O_RDWR | O_SYNC);
> +	ASSERT_LT(0, devfd);
> +
> +	/* Generate sample report data */
> +	for (i = 0; i < TDX_REPORTDATA_LEN; i++)
> +		req.reportdata[i] = i;
> +
> +	/* Get TDREPORT */
> +	ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req));
> +
> +	if (DEBUG) {
> +		print_array_hex("\n\t\tTDX report data\n", "",
> +				req.reportdata, sizeof(req.reportdata));
> +
> +		print_array_hex("\n\t\tTDX tdreport data\n", "",
> +				req.tdreport, sizeof(req.tdreport));
> +	}
> +
> +	/* Make sure TDREPORT data includes the REPORTDATA passed */
> +	tdreport = (struct tdreport *)req.tdreport;
> +	ASSERT_EQ(0, memcmp(&tdreport->reportmac.reportdata[0],
> +			    req.reportdata, sizeof(req.reportdata)));
> +
> +	ASSERT_EQ(0, close(devfd));
> +}
> +
> +TEST_HARNESS_MAIN
> -- 
> 2.34.1
> 
> 

Acked-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module
  2022-11-04  3:23 ` [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module Kuppuswamy Sathyanarayanan
  2022-11-10 15:16   ` Wander Lairson Costa
@ 2022-11-11 18:35   ` Dave Hansen
  2022-11-15  0:33     ` Sathyanarayanan Kuppuswamy
  1 sibling, 1 reply; 15+ messages in thread
From: Dave Hansen @ 2022-11-11 18:35 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, Shuah Khan, Jonathan Corbet
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kirill A . Shutemov,
	Tony Luck, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

On 11/3/22 20:23, Kuppuswamy Sathyanarayanan wrote:
> To support TDX attestation, the TDX guest driver exposes an IOCTL
> interface to allow userspace to get the TDREPORT from the TDX module
> via TDG.MR.TDREPORT TDCALL.

This all acts and is named like this is *THE* way to do a TD report.
This is the only type of TD report.

Is it?

If so, why is there a subtype in the TDX module ABI?  It's easy to miss
in the kernel code, btw:

> +int tdx_mcall_get_report(u8 *reportdata, u8 *tdreport)
> +{
> +	u64 ret;
> +
> +	ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(tdreport),
> +				virt_to_phys(reportdata), 0, 0, NULL);

					     subtype here ^

mixed in next to another magic 0.

> +	if (ret) {
> +		if (TDCALL_RETURN_CODE(ret) == TDCALL_INVALID_OPERAND)
> +			return -EINVAL;
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(tdx_mcall_get_report);

What happens to this interface when subtype 1 is added?

TDX_CMD_GET_REPORT can only get subtype 0.  So, we'll have, what, a new
ioctl()?  TDX_CMD_GET_REPORT_SUBTYPE1?

This is why I was pushing for a more generic ABI that would actually
work for more than one subtype.  Other folks thought that was a bad
idea.  I can live with that.  But, what I can't live with is just
pretending that this is the one and only forever "tdreport" interface.

This is *NOT* "a wrapper to get TDREPORT from the TDX Module", this is
at best "a wrapper to get TDREPORT sub type 0 from the TDX Module".

It also occurs to me that "sub type 0" could use an actual name.  Could
we give it one, please?


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module
  2022-11-11 18:35   ` Dave Hansen
@ 2022-11-15  0:33     ` Sathyanarayanan Kuppuswamy
  2022-11-15  0:54       ` Dave Hansen
  0 siblings, 1 reply; 15+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-11-15  0:33 UTC (permalink / raw)
  To: Dave Hansen, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, Shuah Khan, Jonathan Corbet
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kirill A . Shutemov,
	Tony Luck, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

Hi Dave,

On 11/11/22 10:35 AM, Dave Hansen wrote:
> This is *NOT* "a wrapper to get TDREPORT from the TDX Module", this is
> at best "a wrapper to get TDREPORT sub type 0 from the TDX Module".

In both the commit log and the comments, I can highlight the "subtype 0"
information. Will that work for you, or do you prefer that this wrapper
take the "subtype" option as argument and we pass 0 for the subtype value
from the TDX guest driver?

> 
> It also occurs to me that "sub type 0" could use an actual name.  Could
> we give it one, please?

Although the subtype option is mentioned in the TDX Module spec, it is not
currently used (it expects this value to be zero), and the spec also does
not explain why this option is required. According to TDX architects, this
option was primarily added to handle any future requirements that may arise
that require additional information to be added to the TDREPORT. However,
they do not currently have any valid use cases for it. So the current
version can only be described as "Type-0." Once a new use case for Subtype 1
is defined, we may be able to come up with a suitable name. Are you okay
with calling it "Type-0" for the time being?

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module
  2022-11-15  0:33     ` Sathyanarayanan Kuppuswamy
@ 2022-11-15  0:54       ` Dave Hansen
  2022-11-16  6:25         ` Sathyanarayanan Kuppuswamy
  0 siblings, 1 reply; 15+ messages in thread
From: Dave Hansen @ 2022-11-15  0:54 UTC (permalink / raw)
  To: Sathyanarayanan Kuppuswamy, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, Shuah Khan, Jonathan Corbet
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kirill A . Shutemov,
	Tony Luck, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

On 11/14/22 16:33, Sathyanarayanan Kuppuswamy wrote:
> On 11/11/22 10:35 AM, Dave Hansen wrote:
>> This is *NOT* "a wrapper to get TDREPORT from the TDX Module", this is
>> at best "a wrapper to get TDREPORT sub type 0 from the TDX Module".
> 
> In both the commit log and the comments, I can highlight the "subtype 0"
> information. Will that work for you, or do you prefer that this wrapper
> take the "subtype" option as argument and we pass 0 for the subtype value
> from the TDX guest driver?

I actually think it's a *lot* more clear if the User<->Kernel ABI just
takes the subtype.  But, I also heard Greg's concerns about making the
ABI _too_ open-ended.

So, I really don't care.  Just make it clear that, as is, this ABI is
not the "TDREPORT ABI".

>> It also occurs to me that "sub type 0" could use an actual name.  Could
>> we give it one, please?
> 
> Although the subtype option is mentioned in the TDX Module spec, it is not
> currently used (it expects this value to be zero), and the spec also does
> not explain why this option is required. According to TDX architects, this
> option was primarily added to handle any future requirements that may arise
> that require additional information to be added to the TDREPORT. However,
> they do not currently have any valid use cases for it. So the current
> version can only be described as "Type-0." Once a new use case for Subtype 1
> is defined, we may be able to come up with a suitable name. Are you okay
> with calling it "Type-0" for the time being?

That sounds like a cop out to me.  I'd really appreciate some effort on
your part to look deeply into the problem.

The blob that the kernel is passing back and forth here _has_ content.
I guess it's somewhat hard to name because it's got a bunch of inputs
(ATTRIBUTES, XFAM, MRTD, MRCONFIGID, MROWNER, MROWNERCONFIG and RTMRs)
and a fixed hash algorithm (SHA-384).

Any time that those inputs change or, for instance, the hash algorithm
changes, it would need a new subtype.  Right?

I guess we can't call "subtype 0" TDREPORT_SHA384 because "subtype 1"
might still use SHA-384, but have the set of inputs change.

But, it'll also get maddeningly inconsistent if we have a "TDREPORT"
ioctl() that does "subtype 0" and "TDREPORT1" that does "subtype 1".

So, let's at *least* call this thing "TDREPORT0" in the ABI, along with
a description of why we're numbering it that way as opposed to taking
'subtype' as a numeric ioctl() argument.

Any better ideas?

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module
  2022-11-15  0:54       ` Dave Hansen
@ 2022-11-16  6:25         ` Sathyanarayanan Kuppuswamy
  0 siblings, 0 replies; 15+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-11-16  6:25 UTC (permalink / raw)
  To: Dave Hansen, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, Shuah Khan, Jonathan Corbet
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kirill A . Shutemov,
	Tony Luck, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

Hi Dave,

On 11/14/22 4:54 PM, Dave Hansen wrote:
>> In both the commit log and the comments, I can highlight the "subtype 0"
>> information. Will that work for you, or do you prefer that this wrapper
>> take the "subtype" option as argument and we pass 0 for the subtype value
>> from the TDX guest driver?
> I actually think it's a *lot* more clear if the User<->Kernel ABI just
> takes the subtype.  But, I also heard Greg's concerns about making the
> ABI _too_ open-ended.
> 
> So, I really don't care.  Just make it clear that, as is, this ABI is
> not the "TDREPORT ABI".
> 

Are you fine with the following version?

+/* TDX Module call error codes */
+#define TDCALL_RETURN_CODE(a)  ((a) >> 32)
+#define TDCALL_INVALID_OPERAND 0xc0000100
+
+#define TDREPORT_SUBTYPE_0     0
+ 
+/**
+ * tdx_mcall_get_report0() - Wrapper to get TDREPORT0 (a.k.a. TDREPORT
+ *                           subtype 0) using TDG.MR.REPORT TDCALL.
+ * @reportdata: Address of the input buffer which contains user-defined
+ *              REPORTDATA to be included into TDREPORT.
+ * @tdreport: Address of the output buffer to store TDREPORT.
+ *
+ * Refer to section titled "TDG.MR.REPORT leaf" in the TDX Module
+ * v1.0 specification for more information on TDG.MR.REPORT TDCALL.
+ * It is used in the TDX guest driver module to get the TDREPORT0.
+ *
+ * Return 0 on success, -EINVAL for invalid operands, or -EIO on
+ * other TDCALL failures.
+ */
+int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport)
+{
+       u64 ret;
+
+       ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(tdreport),
+                               virt_to_phys(reportdata), TDREPORT_SUBTYPE_0,
+                               0, NULL);
+       if (ret) {
+               if (TDCALL_RETURN_CODE(ret) == TDCALL_INVALID_OPERAND)
+                       return -EINVAL;
+               return -EIO;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tdx_mcall_get_report0);


-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-11-16  6:26 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-04  3:23 [PATCH v17 0/3] Add TDX Guest Attestation support Kuppuswamy Sathyanarayanan
2022-11-04  3:23 ` [PATCH v17 1/3] x86/tdx: Add a wrapper to get TDREPORT from the TDX Module Kuppuswamy Sathyanarayanan
2022-11-10 15:16   ` Wander Lairson Costa
2022-11-11 18:35   ` Dave Hansen
2022-11-15  0:33     ` Sathyanarayanan Kuppuswamy
2022-11-15  0:54       ` Dave Hansen
2022-11-16  6:25         ` Sathyanarayanan Kuppuswamy
2022-11-04  3:23 ` [PATCH v17 2/3] virt: Add TDX guest driver Kuppuswamy Sathyanarayanan
2022-11-09 14:24   ` Wander Lairson Costa
2022-11-09 15:36     ` Sathyanarayanan Kuppuswamy
2022-11-09 15:37       ` Sathyanarayanan Kuppuswamy
2022-11-10 15:17   ` Wander Lairson Costa
2022-11-04  3:23 ` [PATCH v17 3/3] selftests: tdx: Test TDX attestation GetReport support Kuppuswamy Sathyanarayanan
2022-11-10 15:17   ` Wander Lairson Costa
2022-11-10  3:41 ` [PATCH v17 0/3] Add TDX Guest Attestation support Sathyanarayanan Kuppuswamy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).