All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v12 0/3] Add TDX Guest Attestation support
@ 2022-09-08  0:27 Kuppuswamy Sathyanarayanan
  2022-09-08  0:27 ` [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver Kuppuswamy Sathyanarayanan
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2022-09-08  0:27 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kuppuswamy Sathyanarayanan,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, 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 the commit log of Patch 1/3 or in Documentation/x86/tdx.rst (added
by patch 3/3).

Following are the details of the patch set:

Patch 1/3 -> Adds TDREPORT support.
Patch 2/3 -> Adds selftest support for TDREPORT feature.
Patch 3/3 -> Add attestation related documentation.

Commit log history is maintained in the individual patches.

Kuppuswamy Sathyanarayanan (3):
  x86/tdx: Add TDX Guest attestation interface driver
  selftests: tdx: Test TDX attestation GetReport support
  Documentation/x86: Document TDX attestation process

 Documentation/x86/tdx.rst                     |  75 +++++++++
 arch/x86/coco/tdx/tdx.c                       | 112 +++++++++++++
 arch/x86/include/uapi/asm/tdx.h               |  54 ++++++
 tools/arch/x86/include/uapi/asm/tdx.h         |  54 ++++++
 tools/testing/selftests/Makefile              |   1 +
 tools/testing/selftests/tdx/Makefile          |  11 ++
 tools/testing/selftests/tdx/config            |   1 +
 tools/testing/selftests/tdx/tdx_attest_test.c | 155 ++++++++++++++++++
 8 files changed, 463 insertions(+)
 create mode 100644 arch/x86/include/uapi/asm/tdx.h
 create mode 100644 tools/arch/x86/include/uapi/asm/tdx.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_attest_test.c

-- 
2.34.1


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

* [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver
  2022-09-08  0:27 [PATCH v12 0/3] Add TDX Guest Attestation support Kuppuswamy Sathyanarayanan
@ 2022-09-08  0:27 ` Kuppuswamy Sathyanarayanan
  2022-09-08  5:31   ` Greg Kroah-Hartman
  2022-09-08  0:27 ` [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support Kuppuswamy Sathyanarayanan
  2022-09-08  0:27 ` [PATCH v12 3/3] Documentation/x86: Document TDX attestation process Kuppuswamy Sathyanarayanan
  2 siblings, 1 reply; 20+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2022-09-08  0:27 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kuppuswamy Sathyanarayanan,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, 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 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.

During the TDX guest launch, the initial contents (including the
firmware image) and configuration of the guest are recorded by the
Intel TDX module in build time measurement register (MRTD). After TDX
guest is created, run-time measurement registers (RTMRs) can be used by
the guest software to extend the measurements. TDX supports 4 RTMR
registers, and TDG.MR.RTMR.EXTEND TDCALL is used to update the RTMR
registers securely. RTMRs are mainly used to record measurements
related to sections like the kernel image, command line parameters,
initrd, ACPI tables, firmware data, configuration firmware volume (CFV)
of TDVF, etc. For complete details, please refer to TDX Virtual
Firmware design specification, sec titled "TD Measurement".

At TDX guest runtime, the Intel TDX module reuses the Intel SGX
attestation infrastructure to provide support for attesting to these
measurements as described below.

The attestation process consists of two steps: TDREPORT generation and
Quote generation.

TDREPORT (TDREPORT_STRUCT) 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. The guest kernel uses
TDCALL[TDG.MR.REPORT] to get the TDREPORT from the TDX module. 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".

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 Quote Enclave (QE) to verify
the TDREPORT locally and convert it to a remote verifiable Quote.

After getting the TDREPORT, the second step of the attestation process
is to send it to the QE to generate the Quote. TDX doesn't support SGX
inside the guest, so the QE can be deployed in the host, or in another
legacy VM with SGX support. QE checks the integrity of TDREPORT and if
it is valid, a certified quote signing key is used to sign the Quote.
How to send the TDREPORT to QE and receive the Quote is implementation
and deployment specific.

Implement a basic guest misc driver to allow userspace to get the
TDREPORT. After getting TDREPORT, the userspace attestation software
can choose whatever communication channel available (i.e. vsock or
hypercall) to send the TDREPORT to QE and receive the Quote.

Also note that explicit access permissions are not enforced in this
driver because the quote and measurements are not a secret. However
the access permissions of the device node can be used to set any
desired access policy. The udev default is usually root access
only.

Operations like getting TDREPORT or Quote generation 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. This is similar to AMD
SEV platform, which also uses IOCTL interface to support attestation.

Any distribution enabling TDX is also expected to need attestation. So
enable it by default with TDX guest support.

Reviewed-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Kai Huang <kai.huang@intel.com>
Acked-by: Wander Lairson Costa <wander@redhat.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---

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/

 arch/x86/coco/tdx/tdx.c         | 112 ++++++++++++++++++++++++++++++++
 arch/x86/include/uapi/asm/tdx.h |  54 +++++++++++++++
 2 files changed, 166 insertions(+)
 create mode 100644 arch/x86/include/uapi/asm/tdx.h

diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index 928dcf7a20d9..d1ea7dae3f20 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -5,16 +5,21 @@
 #define pr_fmt(fmt)     "tdx: " fmt
 
 #include <linux/cpufeature.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/io.h>
 #include <asm/coco.h>
 #include <asm/tdx.h>
 #include <asm/vmx.h>
 #include <asm/insn.h>
 #include <asm/insn-eval.h>
 #include <asm/pgtable.h>
+#include <uapi/asm/tdx.h>
 
 /* 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 */
@@ -775,3 +780,110 @@ void __init tdx_early_init(void)
 
 	pr_info("Guest detected\n");
 }
+
+static long tdx_get_report(void __user *argp)
+{
+	u8 *reportdata, *tdreport;
+	struct tdx_report_req req;
+	long ret;
+
+	if (copy_from_user(&req, argp, sizeof(req)))
+		return -EFAULT;
+
+	/*
+	 * Per TDX Module 1.0 specification, section titled
+	 * "TDG.MR.REPORT", REPORTDATA length is fixed as
+	 * TDX_REPORTDATA_LEN, TDREPORT length is fixed as
+	 * TDX_REPORT_LEN, and TDREPORT subtype is fixed as
+	 * 0. Also check for valid user pointers.
+	 */
+	if (!req.reportdata || !req.tdreport || req.subtype ||
+		req.rpd_len != TDX_REPORTDATA_LEN ||
+		req.tdr_len != TDX_REPORT_LEN)
+		return -EINVAL;
+
+	reportdata = kmalloc(req.rpd_len, GFP_KERNEL);
+	if (!reportdata)
+		return -ENOMEM;
+
+	tdreport = kzalloc(req.tdr_len, GFP_KERNEL);
+	if (!tdreport) {
+		kfree(reportdata);
+		return -ENOMEM;
+	}
+
+	if (copy_from_user(reportdata, u64_to_user_ptr(req.reportdata),
+			   req.rpd_len)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	/*
+	 * Generate TDREPORT using "TDG.MR.REPORT" TDCALL.
+	 *
+	 * Get the TDREPORT using REPORTDATA as input. Refer to
+	 * section 22.3.3 TDG.MR.REPORT leaf in the TDX Module 1.0
+	 * Specification for detailed information.
+	 */
+	ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(tdreport),
+				virt_to_phys(reportdata), req.subtype,
+				0, NULL);
+	if (ret) {
+		ret = -EIO;
+		goto out;
+	}
+
+	if (copy_to_user(u64_to_user_ptr(req.tdreport), tdreport, req.tdr_len))
+		ret = -EFAULT;
+
+out:
+	kfree(reportdata);
+	kfree(tdreport);
+	return ret;
+}
+static long tdx_guest_ioctl(struct file *file, unsigned int cmd,
+			    unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	long ret = -ENOTTY;
+
+	switch (cmd) {
+	case TDX_CMD_GET_REPORT:
+		ret = tdx_get_report(argp);
+		break;
+	default:
+		pr_debug("cmd %d not supported\n", cmd);
+		break;
+	}
+
+	return ret;
+}
+
+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           = TDX_GUEST_DEVICE,
+	.minor          = MISC_DYNAMIC_MINOR,
+	.fops           = &tdx_guest_fops,
+};
+
+static int __init tdx_guest_init(void)
+{
+	int ret;
+
+	if (!cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return -EIO;
+
+	ret = misc_register(&tdx_misc_dev);
+	if (ret) {
+		pr_err("misc device registration failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+device_initcall(tdx_guest_init)
diff --git a/arch/x86/include/uapi/asm/tdx.h b/arch/x86/include/uapi/asm/tdx.h
new file mode 100644
index 000000000000..29d8e38f226a
--- /dev/null
+++ b/arch/x86/include/uapi/asm/tdx.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_ASM_X86_TDX_H
+#define _UAPI_ASM_X86_TDX_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define TDX_GUEST_DEVICE		"tdx-guest"
+
+/* 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: Get TDREPORT using REPORTDATA as input.
+ *
+ * @reportdata     : User-defined 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       : TDREPORT output from TDCALL[TDG.MR.REPORT].
+ * @rpd_len        : Length of the REPORTDATA (fixed as 64 bytes by
+ *                   the TDX Module specification, but parameter is
+ *                   added to handle future extension).
+ * @tdr_len        : Length of the TDREPORT (fixed as 1024 bytes by
+ *                   the TDX Module specification, but a parameter
+ *                   is added to accommodate future extension).
+ * @subtype        : Subtype of TDREPORT (fixed as 0 by TDX Module
+ *                   specification, but added a parameter to handle
+ *                   future extension).
+ *
+ * Used in TDX_CMD_GET_REPORT IOCTL request.
+ */
+struct tdx_report_req {
+	__u64 reportdata;
+	__u64 tdreport;
+	__u32 rpd_len;
+	__u32 tdr_len;
+	__u8  subtype;
+	__u8 reserved[7];
+};
+
+/*
+ * 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', 0x01, __u64)
+
+#endif /* _UAPI_ASM_X86_TDX_H */
-- 
2.34.1


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

* [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support
  2022-09-08  0:27 [PATCH v12 0/3] Add TDX Guest Attestation support Kuppuswamy Sathyanarayanan
  2022-09-08  0:27 ` [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver Kuppuswamy Sathyanarayanan
@ 2022-09-08  0:27 ` Kuppuswamy Sathyanarayanan
  2022-09-08 14:16   ` Wander Lairson Costa
  2022-09-09  3:48   ` Huang, Kai
  2022-09-08  0:27 ` [PATCH v12 3/3] Documentation/x86: Document TDX attestation process Kuppuswamy Sathyanarayanan
  2 siblings, 2 replies; 20+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2022-09-08  0:27 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kuppuswamy Sathyanarayanan,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, 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, 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 TDX guest runtime, Intel SGX attestation
infrastructure is re-used to attest to these measurement data.

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 to protect the
integerity 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
get the TDREPORT from the user space.

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

Reviewed-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---

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/arch/x86/include/uapi/asm/tdx.h         |  54 ++++++
 tools/testing/selftests/Makefile              |   1 +
 tools/testing/selftests/tdx/Makefile          |  11 ++
 tools/testing/selftests/tdx/config            |   1 +
 tools/testing/selftests/tdx/tdx_attest_test.c | 155 ++++++++++++++++++
 5 files changed, 222 insertions(+)
 create mode 100644 tools/arch/x86/include/uapi/asm/tdx.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_attest_test.c

diff --git a/tools/arch/x86/include/uapi/asm/tdx.h b/tools/arch/x86/include/uapi/asm/tdx.h
new file mode 100644
index 000000000000..29d8e38f226a
--- /dev/null
+++ b/tools/arch/x86/include/uapi/asm/tdx.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_ASM_X86_TDX_H
+#define _UAPI_ASM_X86_TDX_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define TDX_GUEST_DEVICE		"tdx-guest"
+
+/* 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: Get TDREPORT using REPORTDATA as input.
+ *
+ * @reportdata     : User-defined 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       : TDREPORT output from TDCALL[TDG.MR.REPORT].
+ * @rpd_len        : Length of the REPORTDATA (fixed as 64 bytes by
+ *                   the TDX Module specification, but parameter is
+ *                   added to handle future extension).
+ * @tdr_len        : Length of the TDREPORT (fixed as 1024 bytes by
+ *                   the TDX Module specification, but a parameter
+ *                   is added to accommodate future extension).
+ * @subtype        : Subtype of TDREPORT (fixed as 0 by TDX Module
+ *                   specification, but added a parameter to handle
+ *                   future extension).
+ *
+ * Used in TDX_CMD_GET_REPORT IOCTL request.
+ */
+struct tdx_report_req {
+	__u64 reportdata;
+	__u64 tdreport;
+	__u32 rpd_len;
+	__u32 tdr_len;
+	__u8  subtype;
+	__u8 reserved[7];
+};
+
+/*
+ * 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', 0x01, __u64)
+
+#endif /* _UAPI_ASM_X86_TDX_H */
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 10b34bb03bc1..22bdb3d848f5 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -70,6 +70,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..014795420184
--- /dev/null
+++ b/tools/testing/selftests/tdx/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+
+top_srcdir = ../../../..
+
+LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include
+
+CFLAGS += -O3 -Wl,-no-as-needed -Wall -static -I$(LINUX_TOOL_ARCH_INCLUDE)
+
+TEST_GEN_PROGS := tdx_attest_test
+
+include ../lib.mk
diff --git a/tools/testing/selftests/tdx/config b/tools/testing/selftests/tdx/config
new file mode 100644
index 000000000000..1340073a4abf
--- /dev/null
+++ b/tools/testing/selftests/tdx/config
@@ -0,0 +1 @@
+CONFIG_INTEL_TDX_GUEST=y
diff --git a/tools/testing/selftests/tdx/tdx_attest_test.c b/tools/testing/selftests/tdx/tdx_attest_test.c
new file mode 100644
index 000000000000..b7974050e3cf
--- /dev/null
+++ b/tools/testing/selftests/tdx/tdx_attest_test.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test TDX attestation
+ *
+ * Copyright (C) 2022 Intel Corporation. All rights reserved.
+ *
+ * Author: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <uapi/asm/tdx.h>
+
+#include "../kselftest_harness.h"
+
+#define TDX_GUEST_DEVNAME "/dev/"TDX_GUEST_DEVICE
+#define HEX_DUMP_SIZE	8
+#define __packed       __attribute__((packed))
+
+/*
+ * Trusted Execution Environment (TEE) report (TDREPORT_STRUCT) type,
+ * sub type and version. More details can be found in TDX v1.0 Module
+ * specification, sec titled "REPORTTYPE".
+ */
+struct tdreport_type {
+	/* 0 - SGX, 81 -TDX, rest are reserved */
+	__u8 type;
+	/* Default value is 0 */
+	__u8 sub_type;
+	/* Default value is 0 */
+	__u8 version;
+	__u8 reserved;
+}  __packed;
+
+/*
+ * struct reportmac - First field in the TRDREPORT_STRUCT. It is common
+ * to Intel’s TEE's e.g., SGX and TDX. It is MAC-protected and contains
+ * hashes of the remainder of the report structure which includes the
+ * TEE’s measurements, and where applicable, the measurements of additional
+ * TCB elements not reflected in CPUSVN – e.g., a SEAM’s measurements.
+ * More details can be found in TDX v1.0 Module specification, sec titled
+ * "REPORTMACSTRUCT"
+ */
+struct reportmac {
+	struct tdreport_type type;
+	__u8 reserved1[12];
+	/* CPU security version */
+	__u8 cpu_svn[16];
+	/* SHA384 hash of TEE TCB INFO */
+	__u8 tee_tcb_info_hash[48];
+	/* SHA384 hash of TDINFO_STRUCT */
+	__u8 tee_td_info_hash[48];
+	/* User defined unique data passed in TDG.MR.REPORT request */
+	__u8 reportdata[64];
+	__u8 reserved2[32];
+	__u8 mac[32];
+}  __packed;
+
+/*
+ * struct td_info - 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. These values are copied from
+ * the TDCS by the TDG.MR.REPORT function. More details can be found in
+ * TDX v1.0 Module specification, sec titled "TDINFO_STRUCT".
+ */
+struct td_info {
+	/* TDX Guest attributes (like debug, spet_disable, etc) */
+	__u8 attr[8];
+	__u64 xfam;
+	/* Measurement registers */
+	__u64 mrtd[6];
+	__u64 mrconfigid[6];
+	__u64 mrowner[6];
+	__u64 mrownerconfig[6];
+	/* Runtime measurement registers */
+	__u64 rtmr[24];
+	__u64 reserved[14];
+} __packed;
+
+struct tdreport {
+	/* Common to TDX/SGX of size 256 bytes */
+	struct reportmac reportmac;
+	__u8 tee_tcb_info[239];
+	__u8 reserved[17];
+	/* Measurements and configuration data of size 512 byes */
+	struct td_info tdinfo;
+}  __packed;
+
+#ifdef DEBUG
+static void print_array_hex(const char *title, const char *prefix_str,
+		const void *buf, int len)
+{
+	const __u8 *ptr = buf;
+	int i, rowsize = HEX_DUMP_SIZE;
+
+	if (!len || !buf)
+		return;
+
+	printf("\t\t%s", title);
+
+	for (i = 0; i < len; i++) {
+		if (!(i % rowsize))
+			printf("\n%s%.8x:", prefix_str, i);
+		printf(" %.2x", ptr[i]);
+	}
+
+	printf("\n");
+}
+#endif
+
+TEST(verify_report)
+{
+	__u8 reportdata[TDX_REPORTDATA_LEN];
+	struct tdreport tdreport;
+	struct tdx_report_req req;
+	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++)
+		reportdata[i] = i;
+
+	/* Initialize IOCTL request */
+	req.subtype     = 0;
+	req.reportdata  = (__u64)reportdata;
+	req.rpd_len     = TDX_REPORTDATA_LEN;
+	req.tdreport    = (__u64)&tdreport;
+	req.tdr_len     = sizeof(tdreport);
+
+	/* Get TDREPORT */
+	ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req));
+
+#ifdef DEBUG
+	print_array_hex("\n\t\tTDX report data\n", "",
+			reportdata, sizeof(reportdata));
+
+	print_array_hex("\n\t\tTDX tdreport data\n", "",
+			&tdreport, sizeof(tdreport));
+#endif
+
+	/* Make sure TDREPORT data includes the REPORTDATA passed */
+	ASSERT_EQ(0, memcmp(&tdreport.reportmac.reportdata[0],
+			    reportdata, sizeof(reportdata)));
+
+	ASSERT_EQ(0, close(devfd));
+}
+
+TEST_HARNESS_MAIN
-- 
2.34.1


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

* [PATCH v12 3/3] Documentation/x86: Document TDX attestation process
  2022-09-08  0:27 [PATCH v12 0/3] Add TDX Guest Attestation support Kuppuswamy Sathyanarayanan
  2022-09-08  0:27 ` [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver Kuppuswamy Sathyanarayanan
  2022-09-08  0:27 ` [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support Kuppuswamy Sathyanarayanan
@ 2022-09-08  0:27 ` Kuppuswamy Sathyanarayanan
  2022-09-08  9:10   ` Bagas Sanjaya
  2 siblings, 1 reply; 20+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2022-09-08  0:27 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan
  Cc: H . Peter Anvin, Greg Kroah-Hartman, Kuppuswamy Sathyanarayanan,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, Kai Huang,
	Wander Lairson Costa, Isaku Yamahata, marcelo.cerri, tim.gardner,
	khalid.elmously, philip.cox, linux-kernel, linux-kselftest,
	linux-doc

Document details about TDX attestation process and related user API
support.

Attestation details can be found in Guest-Host-Communication Interface
(GHCI) for Intel Trust Domain Extensions (TDX), section titled "TD
attestation".

[Bagas Sanjaya fixed htmldocs warning]
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---

Changes since v11:
 * Fixed htmldocs warnings.

 Documentation/x86/tdx.rst | 75 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/Documentation/x86/tdx.rst b/Documentation/x86/tdx.rst
index b8fa4329e1a5..c9e3ecf86e0b 100644
--- a/Documentation/x86/tdx.rst
+++ b/Documentation/x86/tdx.rst
@@ -210,6 +210,81 @@ 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 request for attestation before releasing the encryption keys
+to mount the encrypted rootfs or secondary drive.
+
+TDX module records the state of the TDX guest in various stages of guest
+boot process using build time measurement register (MRTD) and runtime
+measurement registers (RTMR). Measurements related to guest initial
+configuration and firmware image is 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, please refer to TDX Virtual Firmware design
+specification, sec titled "TD Measurement".
+
+At TDX guest runtime, the Intel TDX module reuses the Intel SGX attestation
+infrastructure to provide support for attesting to these measurements as
+described below.
+
+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.
+
+After getting the TDREPORT, the second step of the attestation process
+is to send it to the QE to generate the Quote. TDREPORT by design can only
+be verified on local platform as the MAC key is bound to the platform. To
+support remote verification of the TDREPORT, TDX leverages Intel SGX Quote
+Enclave (QE) to verify the TDREPORT locally and convert it to a remote
+verifiable Quote. Method of sending TDREPORT to QE is implemenentation
+specific. Attestation software can choose whatever communication channel
+available (i.e. vsock or hypercall) to send the TDREPORT to QE and receive
+the Quote.
+
+To allow userspace attestation agent get the TDREPORT, TDX guest driver
+exposes an IOCTL (TDX_CMD_GET_REPORT) interface via /dev/tdx-guest misc
+device.
+
+TDX Guest driver
+================
+
+The TDX guest driver exposes IOCTL interfaces via /dev/tdx-guest misc
+device to allow user space to get certain TDX guest specific details
+(like attestation report, attestation quote or storage keys, etc).
+
+In this section, for each supported IOCTL, following information is
+provided along with 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).
+
+TDX_CMD_GET_REPORT
+------------------
+
+:Input parameters: struct tdx_report_req
+:Output: Upon successful execution, TDREPORT data is copied to
+         tdx_report_req.tdreport and returns 0 or returns
+         -EIO on TDCALL failure and standard error number on
+         other common failures.
+
+The TDX_CMD_GET_REPORT IOCTL can be used by the attestation software to
+get the TDX guest measurements data (with few other info) in the format
+of TDREPORT_STRUCT. It uses TDCALL[TDG.MR.REPORT] to get the TDREPORT
+from the TDX Module.
+
+Format of TDREPORT_STRUCT can be found in TDX 1.0 Module specification,
+sec titled "TDREPORT_STRUCT".
+
 References
 ==========
 
-- 
2.34.1


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

* Re: [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver
  2022-09-08  0:27 ` [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver Kuppuswamy Sathyanarayanan
@ 2022-09-08  5:31   ` Greg Kroah-Hartman
  2022-09-08 19:07     ` Sathyanarayanan Kuppuswamy
  2022-09-08 23:53     ` Sathyanarayanan Kuppuswamy
  0 siblings, 2 replies; 20+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-08  5:31 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Kirill A . Shutemov, Tony Luck,
	Andi Kleen, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

On Wed, Sep 07, 2022 at 05:27:20PM -0700, Kuppuswamy Sathyanarayanan wrote:
> +	/*
> +	 * Per TDX Module 1.0 specification, section titled
> +	 * "TDG.MR.REPORT", REPORTDATA length is fixed as
> +	 * TDX_REPORTDATA_LEN, TDREPORT length is fixed as
> +	 * TDX_REPORT_LEN, and TDREPORT subtype is fixed as
> +	 * 0. Also check for valid user pointers.
> +	 */
> +	if (!req.reportdata || !req.tdreport || req.subtype ||
> +		req.rpd_len != TDX_REPORTDATA_LEN ||
> +		req.tdr_len != TDX_REPORT_LEN)
> +		return -EINVAL;

You never verify that your reserved[7] fields are actually set to 0,
which means you can never use them in the future :(

Please fix that up, thanks.

greg k-h

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

* Re: [PATCH v12 3/3] Documentation/x86: Document TDX attestation process
  2022-09-08  0:27 ` [PATCH v12 3/3] Documentation/x86: Document TDX attestation process Kuppuswamy Sathyanarayanan
@ 2022-09-08  9:10   ` Bagas Sanjaya
  0 siblings, 0 replies; 20+ messages in thread
From: Bagas Sanjaya @ 2022-09-08  9:10 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, Kai Huang,
	Wander Lairson Costa, Isaku Yamahata, marcelo.cerri, tim.gardner,
	khalid.elmously, philip.cox, linux-kernel, linux-kselftest,
	linux-doc

[-- Attachment #1: Type: text/plain, Size: 469 bytes --]

On Wed, Sep 07, 2022 at 05:27:22PM -0700, Kuppuswamy Sathyanarayanan wrote:
> Document details about TDX attestation process and related user API
> support.
> 
> Attestation details can be found in Guest-Host-Communication Interface
> (GHCI) for Intel Trust Domain Extensions (TDX), section titled "TD
> attestation".
> 

The doc LGTM, thanks.

Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com>

-- 
An old man doll... just what I always wanted! - Clara

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support
  2022-09-08  0:27 ` [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support Kuppuswamy Sathyanarayanan
@ 2022-09-08 14:16   ` Wander Lairson Costa
  2022-09-08 23:45     ` Sathyanarayanan Kuppuswamy
  2022-09-09  1:55     ` Sathyanarayanan Kuppuswamy
  2022-09-09  3:48   ` Huang, Kai
  1 sibling, 2 replies; 20+ messages in thread
From: Wander Lairson Costa @ 2022-09-08 14:16 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, Kai Huang,
	Isaku Yamahata, marcelo.cerri, tim.gardner, khalid.elmously,
	philip.cox, linux-kernel, linux-kselftest, linux-doc

On Wed, Sep 07, 2022 at 05:27:21PM -0700, Kuppuswamy Sathyanarayanan wrote:
> Attestation is used to verify the trustworthiness of a TDX guest.
> During the guest bring-up, 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 TDX guest runtime, Intel SGX attestation
> infrastructure is re-used to attest to these measurement data.
> 
> 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 to protect the
> integerity 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
> get the TDREPORT from the user space.
> 
> Add a kernel selftest module to test this ABI and verify the validity
> of generated TDREPORT.
> 
> Reviewed-by: Tony Luck <tony.luck@intel.com>
> Reviewed-by: Andi Kleen <ak@linux.intel.com>
> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> ---
> 
> 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/arch/x86/include/uapi/asm/tdx.h         |  54 ++++++
>  tools/testing/selftests/Makefile              |   1 +
>  tools/testing/selftests/tdx/Makefile          |  11 ++
>  tools/testing/selftests/tdx/config            |   1 +
>  tools/testing/selftests/tdx/tdx_attest_test.c | 155 ++++++++++++++++++
>  5 files changed, 222 insertions(+)
>  create mode 100644 tools/arch/x86/include/uapi/asm/tdx.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_attest_test.c
> 
> diff --git a/tools/arch/x86/include/uapi/asm/tdx.h b/tools/arch/x86/include/uapi/asm/tdx.h
> new file mode 100644
> index 000000000000..29d8e38f226a
> --- /dev/null
> +++ b/tools/arch/x86/include/uapi/asm/tdx.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _UAPI_ASM_X86_TDX_H
> +#define _UAPI_ASM_X86_TDX_H
> +
> +#include <linux/types.h>
> +#include <linux/ioctl.h>
> +
> +#define TDX_GUEST_DEVICE		"tdx-guest"
> +
> +/* 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: Get TDREPORT using REPORTDATA as input.
> + *
> + * @reportdata     : User-defined 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       : TDREPORT output from TDCALL[TDG.MR.REPORT].
> + * @rpd_len        : Length of the REPORTDATA (fixed as 64 bytes by
> + *                   the TDX Module specification, but parameter is
> + *                   added to handle future extension).
> + * @tdr_len        : Length of the TDREPORT (fixed as 1024 bytes by
> + *                   the TDX Module specification, but a parameter
> + *                   is added to accommodate future extension).
> + * @subtype        : Subtype of TDREPORT (fixed as 0 by TDX Module
> + *                   specification, but added a parameter to handle
> + *                   future extension).
> + *
> + * Used in TDX_CMD_GET_REPORT IOCTL request.
> + */
> +struct tdx_report_req {
> +	__u64 reportdata;
> +	__u64 tdreport;
> +	__u32 rpd_len;
> +	__u32 tdr_len;
> +	__u8  subtype;
> +	__u8 reserved[7];
> +};
> +
> +/*
> + * 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', 0x01, __u64)
> +
> +#endif /* _UAPI_ASM_X86_TDX_H */
> diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
> index 10b34bb03bc1..22bdb3d848f5 100644
> --- a/tools/testing/selftests/Makefile
> +++ b/tools/testing/selftests/Makefile
> @@ -70,6 +70,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..014795420184
> --- /dev/null
> +++ b/tools/testing/selftests/tdx/Makefile
> @@ -0,0 +1,11 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +top_srcdir = ../../../..
> +
> +LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include
> +
> +CFLAGS += -O3 -Wl,-no-as-needed -Wall -static -I$(LINUX_TOOL_ARCH_INCLUDE)
> +
> +TEST_GEN_PROGS := tdx_attest_test
> +
> +include ../lib.mk
> diff --git a/tools/testing/selftests/tdx/config b/tools/testing/selftests/tdx/config
> new file mode 100644
> index 000000000000..1340073a4abf
> --- /dev/null
> +++ b/tools/testing/selftests/tdx/config
> @@ -0,0 +1 @@
> +CONFIG_INTEL_TDX_GUEST=y
> diff --git a/tools/testing/selftests/tdx/tdx_attest_test.c b/tools/testing/selftests/tdx/tdx_attest_test.c
> new file mode 100644
> index 000000000000..b7974050e3cf
> --- /dev/null
> +++ b/tools/testing/selftests/tdx/tdx_attest_test.c
> @@ -0,0 +1,155 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Test TDX attestation
> + *
> + * Copyright (C) 2022 Intel Corporation. All rights reserved.
> + *
> + * Author: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> + */
> +
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/ioctl.h>
> +#include <sys/types.h>
> +#include <uapi/asm/tdx.h>
> +
> +#include "../kselftest_harness.h"
> +
> +#define TDX_GUEST_DEVNAME "/dev/"TDX_GUEST_DEVICE
> +#define HEX_DUMP_SIZE	8
> +#define __packed       __attribute__((packed))
> +
> +/*
> + * Trusted Execution Environment (TEE) report (TDREPORT_STRUCT) type,
> + * sub type and version. More details can be found in TDX v1.0 Module
> + * specification, sec titled "REPORTTYPE".
> + */
> +struct tdreport_type {
> +	/* 0 - SGX, 81 -TDX, rest are reserved */
> +	__u8 type;
> +	/* Default value is 0 */
> +	__u8 sub_type;
> +	/* Default value is 0 */
> +	__u8 version;
> +	__u8 reserved;
> +}  __packed;
> +
> +/*
> + * struct reportmac - First field in the TRDREPORT_STRUCT. It is common
> + * to Intel’s TEE's e.g., SGX and TDX. It is MAC-protected and contains
> + * hashes of the remainder of the report structure which includes the
> + * TEE’s measurements, and where applicable, the measurements of additional
> + * TCB elements not reflected in CPUSVN – e.g., a SEAM’s measurements.
> + * More details can be found in TDX v1.0 Module specification, sec titled
> + * "REPORTMACSTRUCT"
> + */
> +struct reportmac {
> +	struct tdreport_type type;
> +	__u8 reserved1[12];
> +	/* CPU security version */
> +	__u8 cpu_svn[16];
> +	/* SHA384 hash of TEE TCB INFO */
> +	__u8 tee_tcb_info_hash[48];
> +	/* SHA384 hash of TDINFO_STRUCT */
> +	__u8 tee_td_info_hash[48];
> +	/* User defined unique data passed in TDG.MR.REPORT request */
> +	__u8 reportdata[64];
> +	__u8 reserved2[32];
> +	__u8 mac[32];
> +}  __packed;
> +
> +/*
> + * struct td_info - 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. These values are copied from
> + * the TDCS by the TDG.MR.REPORT function. More details can be found in
> + * TDX v1.0 Module specification, sec titled "TDINFO_STRUCT".
> + */
> +struct td_info {
> +	/* TDX Guest attributes (like debug, spet_disable, etc) */
> +	__u8 attr[8];
> +	__u64 xfam;
> +	/* Measurement registers */
> +	__u64 mrtd[6];
> +	__u64 mrconfigid[6];
> +	__u64 mrowner[6];
> +	__u64 mrownerconfig[6];
> +	/* Runtime measurement registers */
> +	__u64 rtmr[24];
> +	__u64 reserved[14];
> +} __packed;
> +
> +struct tdreport {
> +	/* Common to TDX/SGX of size 256 bytes */
> +	struct reportmac reportmac;
> +	__u8 tee_tcb_info[239];
> +	__u8 reserved[17];
> +	/* Measurements and configuration data of size 512 byes */
> +	struct td_info tdinfo;
> +}  __packed;
> +
> +#ifdef DEBUG
> +static void print_array_hex(const char *title, const char *prefix_str,
> +		const void *buf, int len)
> +{
> +	const __u8 *ptr = buf;
> +	int i, rowsize = HEX_DUMP_SIZE;
> +
> +	if (!len || !buf)
> +		return;
> +
> +	printf("\t\t%s", title);
> +
> +	for (i = 0; i < len; i++) {
> +		if (!(i % rowsize))
> +			printf("\n%s%.8x:", prefix_str, i);
> +		printf(" %.2x", ptr[i]);
> +	}
> +
> +	printf("\n");
> +}
> +#endif
> +
> +TEST(verify_report)
> +{
> +	__u8 reportdata[TDX_REPORTDATA_LEN];
> +	struct tdreport tdreport;
> +	struct tdx_report_req req;
> +	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++)
> +		reportdata[i] = i;
> +
> +	/* Initialize IOCTL request */
> +	req.subtype     = 0;
> +	req.reportdata  = (__u64)reportdata;
> +	req.rpd_len     = TDX_REPORTDATA_LEN;
> +	req.tdreport    = (__u64)&tdreport;
> +	req.tdr_len     = sizeof(tdreport);
> +
> +	/* Get TDREPORT */
> +	ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req));
> +
> +#ifdef DEBUG
> +	print_array_hex("\n\t\tTDX report data\n", "",
> +			reportdata, sizeof(reportdata));
> +
> +	print_array_hex("\n\t\tTDX tdreport data\n", "",
> +			&tdreport, sizeof(tdreport));
> +#endif

You can unconditionally define print_array_hex, and
use `if (DEBUG)` instead of #ifdef `DEBUG here`. The compiler
will get rid of the unused code when DEBUG is not defined
as expected, but you get the parser to validate it
independent of the definition of DEBUG.

> +
> +	/* Make sure TDREPORT data includes the REPORTDATA passed */
> +	ASSERT_EQ(0, memcmp(&tdreport.reportmac.reportdata[0],
> +			    reportdata, sizeof(reportdata)));
> +
> +	ASSERT_EQ(0, close(devfd));
> +}
> +
> +TEST_HARNESS_MAIN
> -- 
> 2.34.1
> 
> 


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

* Re: [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver
  2022-09-08  5:31   ` Greg Kroah-Hartman
@ 2022-09-08 19:07     ` Sathyanarayanan Kuppuswamy
  2022-09-08 20:36       ` Dave Hansen
  2022-09-08 23:53     ` Sathyanarayanan Kuppuswamy
  1 sibling, 1 reply; 20+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-09-08 19:07 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Kirill A . Shutemov, Tony Luck,
	Andi Kleen, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

Hi,

On 9/7/22 10:31 PM, Greg Kroah-Hartman wrote:
> On Wed, Sep 07, 2022 at 05:27:20PM -0700, Kuppuswamy Sathyanarayanan wrote:
>> +	/*
>> +	 * Per TDX Module 1.0 specification, section titled
>> +	 * "TDG.MR.REPORT", REPORTDATA length is fixed as
>> +	 * TDX_REPORTDATA_LEN, TDREPORT length is fixed as
>> +	 * TDX_REPORT_LEN, and TDREPORT subtype is fixed as
>> +	 * 0. Also check for valid user pointers.
>> +	 */
>> +	if (!req.reportdata || !req.tdreport || req.subtype ||
>> +		req.rpd_len != TDX_REPORTDATA_LEN ||
>> +		req.tdr_len != TDX_REPORT_LEN)
>> +		return -EINVAL;
> 
> You never verify that your reserved[7] fields are actually set to 0,
> which means you can never use them in the future :(

Currently, we don't use those fields in our code. Why do we have to
make sure they are set to zero? Can't we add checks when we really use
them in future?

If your suggestion is to define allowed values of these fields for user,
we can add some help in structure definition of "tdx_report_req" in
arch/x86/include/uapi/asm/tdx.h

> 
> Please fix that up, thanks.
> 
> greg k-h

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

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

* Re: [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver
  2022-09-08 19:07     ` Sathyanarayanan Kuppuswamy
@ 2022-09-08 20:36       ` Dave Hansen
  2022-09-08 20:45         ` Sathyanarayanan Kuppuswamy
  2022-09-09  5:26         ` Greg Kroah-Hartman
  0 siblings, 2 replies; 20+ messages in thread
From: Dave Hansen @ 2022-09-08 20:36 UTC (permalink / raw)
  To: Sathyanarayanan Kuppuswamy, Greg Kroah-Hartman
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Kirill A . Shutemov, Tony Luck,
	Andi Kleen, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

On 9/8/22 12:07, Sathyanarayanan Kuppuswamy wrote:
> On 9/7/22 10:31 PM, Greg Kroah-Hartman wrote:
>> On Wed, Sep 07, 2022 at 05:27:20PM -0700, Kuppuswamy Sathyanarayanan wrote:
>>> +	/*
>>> +	 * Per TDX Module 1.0 specification, section titled
>>> +	 * "TDG.MR.REPORT", REPORTDATA length is fixed as
>>> +	 * TDX_REPORTDATA_LEN, TDREPORT length is fixed as
>>> +	 * TDX_REPORT_LEN, and TDREPORT subtype is fixed as
>>> +	 * 0. Also check for valid user pointers.
>>> +	 */
>>> +	if (!req.reportdata || !req.tdreport || req.subtype ||
>>> +		req.rpd_len != TDX_REPORTDATA_LEN ||
>>> +		req.tdr_len != TDX_REPORT_LEN)
>>> +		return -EINVAL;
>> You never verify that your reserved[7] fields are actually set to 0,
>> which means you can never use them in the future :(
> Currently, we don't use those fields in our code. Why do we have to
> make sure they are set to zero?

Yes.

> Can't we add checks when we really use them in future?

No.

This has been a hard learned lesson both by people writing software and
designing hardware interfaces: if you _let_ folks pass garbage you have
to _keep_ letting them pass garbage forever.  It becomes part of the ABI.

I'm sorry you missed the memo on this one.  But, this is one million
percent a best practice across the industry.  Please do it.

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

* Re: [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver
  2022-09-08 20:36       ` Dave Hansen
@ 2022-09-08 20:45         ` Sathyanarayanan Kuppuswamy
  2022-09-09  5:26         ` Greg Kroah-Hartman
  1 sibling, 0 replies; 20+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-09-08 20:45 UTC (permalink / raw)
  To: Dave Hansen, Greg Kroah-Hartman
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Kirill A . Shutemov, Tony Luck,
	Andi Kleen, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc



On 9/8/22 1:36 PM, Dave Hansen wrote:
> On 9/8/22 12:07, Sathyanarayanan Kuppuswamy wrote:
>> On 9/7/22 10:31 PM, Greg Kroah-Hartman wrote:
>>> On Wed, Sep 07, 2022 at 05:27:20PM -0700, Kuppuswamy Sathyanarayanan wrote:
>>>> +	/*
>>>> +	 * Per TDX Module 1.0 specification, section titled
>>>> +	 * "TDG.MR.REPORT", REPORTDATA length is fixed as
>>>> +	 * TDX_REPORTDATA_LEN, TDREPORT length is fixed as
>>>> +	 * TDX_REPORT_LEN, and TDREPORT subtype is fixed as
>>>> +	 * 0. Also check for valid user pointers.
>>>> +	 */
>>>> +	if (!req.reportdata || !req.tdreport || req.subtype ||
>>>> +		req.rpd_len != TDX_REPORTDATA_LEN ||
>>>> +		req.tdr_len != TDX_REPORT_LEN)
>>>> +		return -EINVAL;
>>> You never verify that your reserved[7] fields are actually set to 0,
>>> which means you can never use them in the future :(
>> Currently, we don't use those fields in our code. Why do we have to
>> make sure they are set to zero?
> 
> Yes.
> 
>> Can't we add checks when we really use them in future?
> 
> No.
> 
> This has been a hard learned lesson both by people writing software and
> designing hardware interfaces: if you _let_ folks pass garbage you have
> to _keep_ letting them pass garbage forever.  It becomes part of the ABI.
> 
> I'm sorry you missed the memo on this one.  But, this is one million
> percent a best practice across the industry.  Please do it.

Ok. Thanks for clarifying it. I will fix it in next version.

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

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

* Re: [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support
  2022-09-08 14:16   ` Wander Lairson Costa
@ 2022-09-08 23:45     ` Sathyanarayanan Kuppuswamy
  2022-09-09 13:36       ` Wander Lairson Costa
  2022-09-09  1:55     ` Sathyanarayanan Kuppuswamy
  1 sibling, 1 reply; 20+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-09-08 23:45 UTC (permalink / raw)
  To: Wander Lairson Costa
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, Kai Huang,
	Isaku Yamahata, marcelo.cerri, tim.gardner, khalid.elmously,
	philip.cox, linux-kernel, linux-kselftest, linux-doc



On 9/8/22 7:16 AM, Wander Lairson Costa wrote:
>> +#ifdef DEBUG
>> +static void print_array_hex(const char *title, const char *prefix_str,
>> +		const void *buf, int len)
>> +{
>> +	const __u8 *ptr = buf;
>> +	int i, rowsize = HEX_DUMP_SIZE;
>> +
>> +	if (!len || !buf)
>> +		return;
>> +
>> +	printf("\t\t%s", title);
>> +
>> +	for (i = 0; i < len; i++) {
>> +		if (!(i % rowsize))
>> +			printf("\n%s%.8x:", prefix_str, i);
>> +		printf(" %.2x", ptr[i]);
>> +	}
>> +
>> +	printf("\n");
>> +}
>> +#endif
>> +
>> +TEST(verify_report)
>> +{
>> +	__u8 reportdata[TDX_REPORTDATA_LEN];
>> +	struct tdreport tdreport;
>> +	struct tdx_report_req req;
>> +	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++)
>> +		reportdata[i] = i;
>> +
>> +	/* Initialize IOCTL request */
>> +	req.subtype     = 0;
>> +	req.reportdata  = (__u64)reportdata;
>> +	req.rpd_len     = TDX_REPORTDATA_LEN;
>> +	req.tdreport    = (__u64)&tdreport;
>> +	req.tdr_len     = sizeof(tdreport);
>> +
>> +	/* Get TDREPORT */
>> +	ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req));
>> +
>> +#ifdef DEBUG
>> +	print_array_hex("\n\t\tTDX report data\n", "",
>> +			reportdata, sizeof(reportdata));
>> +
>> +	print_array_hex("\n\t\tTDX tdreport data\n", "",
>> +			&tdreport, sizeof(tdreport));
>> +#endif
> You can unconditionally define print_array_hex, and
> use `if (DEBUG)` instead of #ifdef `DEBUG here`. The compiler
> will get rid of the unused code when DEBUG is not defined
> as expected, but you get the parser to validate it
> independent of the definition of DEBUG.

Currently, DEBUG is a macro, so we cannot use if (DEBUG) directly.
You are suggesting to change DEBUG to a variable? Any reason to
make this change? I think both changes are functionally similar.
So I am wondering why to make this change?

> 

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

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

* Re: [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver
  2022-09-08  5:31   ` Greg Kroah-Hartman
  2022-09-08 19:07     ` Sathyanarayanan Kuppuswamy
@ 2022-09-08 23:53     ` Sathyanarayanan Kuppuswamy
  2022-09-09  5:25       ` Greg Kroah-Hartman
  1 sibling, 1 reply; 20+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-09-08 23:53 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Kirill A . Shutemov, Tony Luck,
	Andi Kleen, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

Hi Dave/Greg,

On 9/7/22 10:31 PM, Greg Kroah-Hartman wrote:
> On Wed, Sep 07, 2022 at 05:27:20PM -0700, Kuppuswamy Sathyanarayanan wrote:
>> +	/*
>> +	 * Per TDX Module 1.0 specification, section titled
>> +	 * "TDG.MR.REPORT", REPORTDATA length is fixed as
>> +	 * TDX_REPORTDATA_LEN, TDREPORT length is fixed as
>> +	 * TDX_REPORT_LEN, and TDREPORT subtype is fixed as
>> +	 * 0. Also check for valid user pointers.
>> +	 */
>> +	if (!req.reportdata || !req.tdreport || req.subtype ||
>> +		req.rpd_len != TDX_REPORTDATA_LEN ||
>> +		req.tdr_len != TDX_REPORT_LEN)
>> +		return -EINVAL;
> 
> You never verify that your reserved[7] fields are actually set to 0,
> which means you can never use them in the future :(
> 
> Please fix that up, thanks.

Would you prefer a new posting (v12.1 or v13) with this change, or do you
want to continue the review in the same version?

> 
> greg k-h

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

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

* Re: [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support
  2022-09-08 14:16   ` Wander Lairson Costa
  2022-09-08 23:45     ` Sathyanarayanan Kuppuswamy
@ 2022-09-09  1:55     ` Sathyanarayanan Kuppuswamy
  2022-09-09 13:49       ` Dave Hansen
  1 sibling, 1 reply; 20+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-09-09  1:55 UTC (permalink / raw)
  To: Wander Lairson Costa
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, Kai Huang,
	Isaku Yamahata, marcelo.cerri, tim.gardner, khalid.elmously,
	philip.cox, linux-kernel, linux-kselftest, linux-doc



On 9/8/22 7:16 AM, Wander Lairson Costa wrote:
> You can unconditionally define print_array_hex, and
> use `if (DEBUG)` instead of #ifdef `DEBUG here`. The compiler
> will get rid of the unused code when DEBUG is not defined
> as expected, but you get the parser to validate it
> independent of the definition of DEBUG.

To avoid #ifdef DEBUG in multiple places, we can try following
change. Let me know your comments.

--- a/tools/testing/selftests/tdx/tdx_attest_test.c

+++ b/tools/testing/selftests/tdx/tdx_attest_test.c

@@ -21,6 +21,14 @@

 #define HEX_DUMP_SIZE  8

 #define __packed       __attribute__((packed))

 

+static inline int _no_printf(const char *format, ...) { return 0; }

+

+#ifdef DEBUG

+#define pr_debug(...) printf(__VA_ARGS__)

+#else

+#define pr_debug(...) _no_printf(__VA_ARGS__)

+#endif

+

 /*

  * Trusted Execution Environment (TEE) report (TDREPORT_STRUCT) type,

  * sub type and version. More details can be found in TDX v1.0 Module

@@ -90,7 +98,6 @@ struct tdreport {

        struct td_info tdinfo;

 }  __packed;

 

-#ifdef DEBUG

 static void print_array_hex(const char *title, const char *prefix_str,

                const void *buf, int len)

 {

@@ -100,17 +107,16 @@ static void print_array_hex(const char *title, const char *prefix_str,

        if (!len || !buf)

                return;

 

-       printf("\t\t%s", title);

+       pr_debug("\t\t%s", title);

 

        for (i = 0; i < len; i++) {

                if (!(i % rowsize))

-                       printf("\n%s%.8x:", prefix_str, i);

-               printf(" %.2x", ptr[i]);

+                       pr_debug("\n%s%.8x:", prefix_str, i);

+               pr_debug(" %.2x", ptr[i]);

        }

 

-       printf("\n");

+       pr_debug("\n");

 }

-#endif

 

 TEST(verify_report)

 {

@@ -139,13 +145,11 @@ TEST(verify_report)

        /* Get TDREPORT */

        ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req));

 

-#ifdef DEBUG

        print_array_hex("\n\t\tTDX report data\n", "",

                        reportdata, sizeof(reportdata));

 

        print_array_hex("\n\t\tTDX tdreport data\n", "",

                        &tdreport, sizeof(tdreport));

-#endif

 

        /* Make sure TDREPORT data includes the REPORTDATA passed */

        ASSERT_EQ(0, memcmp(&tdreport.reportmac.reportdata[0],



-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

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

* Re: [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support
  2022-09-08  0:27 ` [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support Kuppuswamy Sathyanarayanan
  2022-09-08 14:16   ` Wander Lairson Costa
@ 2022-09-09  3:48   ` Huang, Kai
  2022-09-09  5:08     ` Sathyanarayanan Kuppuswamy
  1 sibling, 1 reply; 20+ messages in thread
From: Huang, Kai @ 2022-09-09  3:48 UTC (permalink / raw)
  To: sathyanarayanan.kuppuswamy, tglx, mingo, shuah, x86, bp, dave.hansen
  Cc: linux-kernel, ak, gregkh, wander, tim.gardner, hpa,
	isaku.yamahata, kirill.shutemov, Luck, Tony, khalid.elmously,
	marcelo.cerri, Cox, Philip, linux-doc, linux-kselftest

On Wed, 2022-09-07 at 17:27 -0700, Kuppuswamy Sathyanarayanan wrote:
> +TEST(verify_report)
> +{
> +	__u8 reportdata[TDX_REPORTDATA_LEN];
> +	struct tdreport tdreport;
> +	struct tdx_report_req req;
> +	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++)
> +		reportdata[i] = i;
> +
> +	/* Initialize IOCTL request */
> +	req.subtype     = 0;
> +	req.reportdata  = (__u64)reportdata;
> +	req.rpd_len     = TDX_REPORTDATA_LEN;
> +	req.tdreport    = (__u64)&tdreport;
> +	req.tdr_len     = sizeof(tdreport);
> +

'req' is a local variable, which isn't guaranteed to be zero. Looks you need to
explicitly clear 'req' otherwise the req.reserved[7] may not be zero.

-- 
Thanks,
-Kai



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

* Re: [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support
  2022-09-09  3:48   ` Huang, Kai
@ 2022-09-09  5:08     ` Sathyanarayanan Kuppuswamy
  0 siblings, 0 replies; 20+ messages in thread
From: Sathyanarayanan Kuppuswamy @ 2022-09-09  5:08 UTC (permalink / raw)
  To: Huang, Kai, tglx, mingo, shuah, x86, bp, dave.hansen
  Cc: linux-kernel, ak, gregkh, wander, tim.gardner, hpa,
	isaku.yamahata, kirill.shutemov, Luck, Tony, khalid.elmously,
	marcelo.cerri, Cox, Philip, linux-doc, linux-kselftest



On 9/8/22 8:48 PM, Huang, Kai wrote:
> On Wed, 2022-09-07 at 17:27 -0700, Kuppuswamy Sathyanarayanan wrote:
>> +TEST(verify_report)
>> +{
>> +	__u8 reportdata[TDX_REPORTDATA_LEN];
>> +	struct tdreport tdreport;
>> +	struct tdx_report_req req;
>> +	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++)
>> +		reportdata[i] = i;
>> +
>> +	/* Initialize IOCTL request */
>> +	req.subtype     = 0;
>> +	req.reportdata  = (__u64)reportdata;
>> +	req.rpd_len     = TDX_REPORTDATA_LEN;
>> +	req.tdreport    = (__u64)&tdreport;
>> +	req.tdr_len     = sizeof(tdreport);
>> +
> 
> 'req' is a local variable, which isn't guaranteed to be zero. Looks you need to
> explicitly clear 'req' otherwise the req.reserved[7] may not be zero.

In the next version, I explicitly set it to 0. I could initialize the struct to
0. But doing it explicitly will show the expected values clearly.

memset(req.reserved, 0, sizeof(req.reserved));

> 

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

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

* Re: [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver
  2022-09-08 23:53     ` Sathyanarayanan Kuppuswamy
@ 2022-09-09  5:25       ` Greg Kroah-Hartman
  0 siblings, 0 replies; 20+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-09  5:25 UTC (permalink / raw)
  To: Sathyanarayanan Kuppuswamy
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Kirill A . Shutemov, Tony Luck,
	Andi Kleen, Kai Huang, Wander Lairson Costa, Isaku Yamahata,
	marcelo.cerri, tim.gardner, khalid.elmously, philip.cox,
	linux-kernel, linux-kselftest, linux-doc

On Thu, Sep 08, 2022 at 04:53:18PM -0700, Sathyanarayanan Kuppuswamy wrote:
> Hi Dave/Greg,
> 
> On 9/7/22 10:31 PM, Greg Kroah-Hartman wrote:
> > On Wed, Sep 07, 2022 at 05:27:20PM -0700, Kuppuswamy Sathyanarayanan wrote:
> >> +	/*
> >> +	 * Per TDX Module 1.0 specification, section titled
> >> +	 * "TDG.MR.REPORT", REPORTDATA length is fixed as
> >> +	 * TDX_REPORTDATA_LEN, TDREPORT length is fixed as
> >> +	 * TDX_REPORT_LEN, and TDREPORT subtype is fixed as
> >> +	 * 0. Also check for valid user pointers.
> >> +	 */
> >> +	if (!req.reportdata || !req.tdreport || req.subtype ||
> >> +		req.rpd_len != TDX_REPORTDATA_LEN ||
> >> +		req.tdr_len != TDX_REPORT_LEN)
> >> +		return -EINVAL;
> > 
> > You never verify that your reserved[7] fields are actually set to 0,
> > which means you can never use them in the future :(
> > 
> > Please fix that up, thanks.
> 
> Would you prefer a new posting (v12.1 or v13) with this change, or do you
> want to continue the review in the same version?

What would you want to see happen if you were a reviewer?

(hint, new version...)

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

* Re: [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver
  2022-09-08 20:36       ` Dave Hansen
  2022-09-08 20:45         ` Sathyanarayanan Kuppuswamy
@ 2022-09-09  5:26         ` Greg Kroah-Hartman
  1 sibling, 0 replies; 20+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-09  5:26 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Sathyanarayanan Kuppuswamy, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, Shuah Khan, H . Peter Anvin,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, Kai Huang,
	Wander Lairson Costa, Isaku Yamahata, marcelo.cerri, tim.gardner,
	khalid.elmously, philip.cox, linux-kernel, linux-kselftest,
	linux-doc

On Thu, Sep 08, 2022 at 01:36:00PM -0700, Dave Hansen wrote:
> On 9/8/22 12:07, Sathyanarayanan Kuppuswamy wrote:
> > On 9/7/22 10:31 PM, Greg Kroah-Hartman wrote:
> >> On Wed, Sep 07, 2022 at 05:27:20PM -0700, Kuppuswamy Sathyanarayanan wrote:
> >>> +	/*
> >>> +	 * Per TDX Module 1.0 specification, section titled
> >>> +	 * "TDG.MR.REPORT", REPORTDATA length is fixed as
> >>> +	 * TDX_REPORTDATA_LEN, TDREPORT length is fixed as
> >>> +	 * TDX_REPORT_LEN, and TDREPORT subtype is fixed as
> >>> +	 * 0. Also check for valid user pointers.
> >>> +	 */
> >>> +	if (!req.reportdata || !req.tdreport || req.subtype ||
> >>> +		req.rpd_len != TDX_REPORTDATA_LEN ||
> >>> +		req.tdr_len != TDX_REPORT_LEN)
> >>> +		return -EINVAL;
> >> You never verify that your reserved[7] fields are actually set to 0,
> >> which means you can never use them in the future :(
> > Currently, we don't use those fields in our code. Why do we have to
> > make sure they are set to zero?
> 
> Yes.
> 
> > Can't we add checks when we really use them in future?
> 
> No.
> 
> This has been a hard learned lesson both by people writing software and
> designing hardware interfaces: if you _let_ folks pass garbage you have
> to _keep_ letting them pass garbage forever.  It becomes part of the ABI.
> 
> I'm sorry you missed the memo on this one.  But, this is one million
> percent a best practice across the industry.  Please do it.

And it's documented in the Documentation/ directory as a requirement to
do as well, the memo shouldn't have been missed :(

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

* Re: [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support
  2022-09-08 23:45     ` Sathyanarayanan Kuppuswamy
@ 2022-09-09 13:36       ` Wander Lairson Costa
  2022-09-09 18:40         ` Sathyanarayanan Kuppuswamy
  0 siblings, 1 reply; 20+ messages in thread
From: Wander Lairson Costa @ 2022-09-09 13:36 UTC (permalink / raw)
  To: Sathyanarayanan Kuppuswamy
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	Shuah Khan, H . Peter Anvin, Greg Kroah-Hartman,
	Kirill A . Shutemov, Tony Luck, Andi Kleen, Kai Huang,
	Isaku Yamahata, marcelo.cerri, tim.gardner, khalid.elmously,
	philip.cox, linux-kernel, linux-kselftest, linux-doc

On Thu, Sep 8, 2022 at 8:45 PM Sathyanarayanan Kuppuswamy
<sathyanarayanan.kuppuswamy@linux.intel.com> wrote:
>
>
>
> On 9/8/22 7:16 AM, Wander Lairson Costa wrote:
> >> +#ifdef DEBUG
> >> +static void print_array_hex(const char *title, const char *prefix_str,
> >> +            const void *buf, int len)
> >> +{
> >> +    const __u8 *ptr = buf;
> >> +    int i, rowsize = HEX_DUMP_SIZE;
> >> +
> >> +    if (!len || !buf)
> >> +            return;
> >> +
> >> +    printf("\t\t%s", title);
> >> +
> >> +    for (i = 0; i < len; i++) {
> >> +            if (!(i % rowsize))
> >> +                    printf("\n%s%.8x:", prefix_str, i);
> >> +            printf(" %.2x", ptr[i]);
> >> +    }
> >> +
> >> +    printf("\n");
> >> +}
> >> +#endif
> >> +
> >> +TEST(verify_report)
> >> +{
> >> +    __u8 reportdata[TDX_REPORTDATA_LEN];
> >> +    struct tdreport tdreport;
> >> +    struct tdx_report_req req;
> >> +    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++)
> >> +            reportdata[i] = i;
> >> +
> >> +    /* Initialize IOCTL request */
> >> +    req.subtype     = 0;
> >> +    req.reportdata  = (__u64)reportdata;
> >> +    req.rpd_len     = TDX_REPORTDATA_LEN;
> >> +    req.tdreport    = (__u64)&tdreport;
> >> +    req.tdr_len     = sizeof(tdreport);
> >> +
> >> +    /* Get TDREPORT */
> >> +    ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req));
> >> +
> >> +#ifdef DEBUG
> >> +    print_array_hex("\n\t\tTDX report data\n", "",
> >> +                    reportdata, sizeof(reportdata));
> >> +
> >> +    print_array_hex("\n\t\tTDX tdreport data\n", "",
> >> +                    &tdreport, sizeof(tdreport));
> >> +#endif
> > You can unconditionally define print_array_hex, and
> > use `if (DEBUG)` instead of #ifdef `DEBUG here`. The compiler
> > will get rid of the unused code when DEBUG is not defined
> > as expected, but you get the parser to validate it
> > independent of the definition of DEBUG.
>
> Currently, DEBUG is a macro, so we cannot use if (DEBUG) directly.
> You are suggesting to change DEBUG to a variable? Any reason to
> make this change? I think both changes are functionally similar.
> So I am wondering why to make this change?
>

My thought is always to define DEBUG. If in debug mode it is defined
to 1; otherwise to 0.
Then, you can use `if (DEBUG)` instead of `#ifdef DEBUG`. But the
former will always check the syntax of the debug code,
independent of the value of DEBUG, and the compiler will generate the
same code. The GNU coding standard [1] explains that
better than I do.

[1] https://www.gnu.org/prep/standards/standards.html#Conditional-Compilation

> >
>
> --
> Sathyanarayanan Kuppuswamy
> Linux Kernel Developer
>


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

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

On 9/8/22 18:55, Sathyanarayanan Kuppuswamy wrote:
> +#ifdef DEBUG
> +#define pr_debug(...) printf(__VA_ARGS__)
> +#else
> +#define pr_debug(...) _no_printf(__VA_ARGS__)
> +#endif

If you're going this way, please put this in common selftest code.
Don't force every single test to duplicate it.

But, seriously, this is all insanity.  Fixing the whole "oh, but DEBUG
might not be defined" thing is not exactly rocket science.  Just do this
in your test header or .c file:

#ifndef DEBUG
#define DEBUG 0
#endif

Then you can do:

	if (DEBUG)
		foo();

all day long.

Or, not.  I honestly don't think this is worth even mucking with in the
first place.

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

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



On 9/9/22 6:36 AM, Wander Lairson Costa wrote:
> On Thu, Sep 8, 2022 at 8:45 PM Sathyanarayanan Kuppuswamy
> <sathyanarayanan.kuppuswamy@linux.intel.com> wrote:
>>
>>
>>
>> On 9/8/22 7:16 AM, Wander Lairson Costa wrote:
>>>> +#ifdef DEBUG
>>>> +static void print_array_hex(const char *title, const char *prefix_str,
>>>> +            const void *buf, int len)
>>>> +{
>>>> +    const __u8 *ptr = buf;
>>>> +    int i, rowsize = HEX_DUMP_SIZE;
>>>> +
>>>> +    if (!len || !buf)
>>>> +            return;
>>>> +
>>>> +    printf("\t\t%s", title);
>>>> +
>>>> +    for (i = 0; i < len; i++) {
>>>> +            if (!(i % rowsize))
>>>> +                    printf("\n%s%.8x:", prefix_str, i);
>>>> +            printf(" %.2x", ptr[i]);
>>>> +    }
>>>> +
>>>> +    printf("\n");
>>>> +}
>>>> +#endif
>>>> +
>>>> +TEST(verify_report)
>>>> +{
>>>> +    __u8 reportdata[TDX_REPORTDATA_LEN];
>>>> +    struct tdreport tdreport;
>>>> +    struct tdx_report_req req;
>>>> +    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++)
>>>> +            reportdata[i] = i;
>>>> +
>>>> +    /* Initialize IOCTL request */
>>>> +    req.subtype     = 0;
>>>> +    req.reportdata  = (__u64)reportdata;
>>>> +    req.rpd_len     = TDX_REPORTDATA_LEN;
>>>> +    req.tdreport    = (__u64)&tdreport;
>>>> +    req.tdr_len     = sizeof(tdreport);
>>>> +
>>>> +    /* Get TDREPORT */
>>>> +    ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req));
>>>> +
>>>> +#ifdef DEBUG
>>>> +    print_array_hex("\n\t\tTDX report data\n", "",
>>>> +                    reportdata, sizeof(reportdata));
>>>> +
>>>> +    print_array_hex("\n\t\tTDX tdreport data\n", "",
>>>> +                    &tdreport, sizeof(tdreport));
>>>> +#endif
>>> You can unconditionally define print_array_hex, and
>>> use `if (DEBUG)` instead of #ifdef `DEBUG here`. The compiler
>>> will get rid of the unused code when DEBUG is not defined
>>> as expected, but you get the parser to validate it
>>> independent of the definition of DEBUG.
>>
>> Currently, DEBUG is a macro, so we cannot use if (DEBUG) directly.
>> You are suggesting to change DEBUG to a variable? Any reason to
>> make this change? I think both changes are functionally similar.
>> So I am wondering why to make this change?
>>
> 
> My thought is always to define DEBUG. If in debug mode it is defined
> to 1; otherwise to 0.
> Then, you can use `if (DEBUG)` instead of `#ifdef DEBUG`. But the
> former will always check the syntax of the debug code,
> independent of the value of DEBUG, and the compiler will generate the
> same code. The GNU coding standard [1] explains that
> better than I do.
> 
> [1] https://www.gnu.org/prep/standards/standards.html#Conditional-Compilation

Got it. I will use if (DEBUG).

> 
>>>
>>
>> --
>> Sathyanarayanan Kuppuswamy
>> Linux Kernel Developer
>>
> 

-- 
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

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

end of thread, other threads:[~2022-09-09 18:40 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-08  0:27 [PATCH v12 0/3] Add TDX Guest Attestation support Kuppuswamy Sathyanarayanan
2022-09-08  0:27 ` [PATCH v12 1/3] x86/tdx: Add TDX Guest attestation interface driver Kuppuswamy Sathyanarayanan
2022-09-08  5:31   ` Greg Kroah-Hartman
2022-09-08 19:07     ` Sathyanarayanan Kuppuswamy
2022-09-08 20:36       ` Dave Hansen
2022-09-08 20:45         ` Sathyanarayanan Kuppuswamy
2022-09-09  5:26         ` Greg Kroah-Hartman
2022-09-08 23:53     ` Sathyanarayanan Kuppuswamy
2022-09-09  5:25       ` Greg Kroah-Hartman
2022-09-08  0:27 ` [PATCH v12 2/3] selftests: tdx: Test TDX attestation GetReport support Kuppuswamy Sathyanarayanan
2022-09-08 14:16   ` Wander Lairson Costa
2022-09-08 23:45     ` Sathyanarayanan Kuppuswamy
2022-09-09 13:36       ` Wander Lairson Costa
2022-09-09 18:40         ` Sathyanarayanan Kuppuswamy
2022-09-09  1:55     ` Sathyanarayanan Kuppuswamy
2022-09-09 13:49       ` Dave Hansen
2022-09-09  3:48   ` Huang, Kai
2022-09-09  5:08     ` Sathyanarayanan Kuppuswamy
2022-09-08  0:27 ` [PATCH v12 3/3] Documentation/x86: Document TDX attestation process Kuppuswamy Sathyanarayanan
2022-09-08  9:10   ` Bagas Sanjaya

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.