With the TSM ABI getting merged, I was wondering if the /dev/tdx_guest will stay in the kernel? > On Nov 17, 2022, at 1:43 PM, tip-bot2 for Kuppuswamy Sathyanarayanan <tip-bot2@xxxxxxxxxxxxx> wrote: > > The following commit has been merged into the x86/tdx branch of tip: > > Commit-ID: 6c8c1406a6d6a3f2e61ac590f5c0994231bc6be7 > Gitweb: https://git.kernel.org/tip/6c8c1406a6d6a3f2e61ac590f5c0994231bc6be7 > Author: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@xxxxxxxxxxxxxxx> > AuthorDate: Wed, 16 Nov 2022 14:38:19 -08:00 > Committer: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx> > CommitterDate: Thu, 17 Nov 2022 11:04:23 -08:00 > > virt: Add TDX guest driver > > 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 seem to be the best fitting > and simplest model for this use case. The AMD sev-guest driver also > uses the IOCTL interface to support attestation. > > [Bagas Sanjaya: Ack is for documentation portion] > Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@xxxxxxxxxxxxxxx> > Signed-off-by: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx> > Reviewed-by: Bagas Sanjaya <bagasdotme@xxxxxxxxx> > Reviewed-by: Tony Luck <tony.luck@xxxxxxxxx> > Reviewed-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> > Acked-by: Kai Huang <kai.huang@xxxxxxxxx> > Acked-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> > Acked-by: Wander Lairson Costa <wander@xxxxxxxxxx> > Link: https://lore.kernel.org/all/20221116223820.819090-3-sathyanarayanan.kuppuswamy%40linux.intel.com > --- > Documentation/virt/coco/tdx-guest.rst | 52 ++++++++++++- > 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 | 42 +++++++++- > 9 files changed, 255 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 0000000..46e316d > --- /dev/null > +++ b/Documentation/virt/coco/tdx-guest.rst > @@ -0,0 +1,52 @@ > +.. SPDX-License-Identifier: GPL-2.0 > + > +=================================================================== > +TDX Guest API Documentation > +=================================================================== > + > +1. General description > +====================== > + > +The TDX guest driver exposes IOCTL interfaces via the /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, the 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_REPORT0 > +----------------------- > + > +: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_REPORT0 IOCTL can be used by the attestation software to get > +the TDREPORT0 (a.k.a. TDREPORT subtype 0) from the TDX module using > +TDCALL[TDG.MR.REPORT]. > + > +A subtype index is added at the end of this IOCTL CMD to uniquely identify the > +subtype-specific TDREPORT request. Although the subtype option is mentioned in > +the TDX Module v1.0 specification, section titled "TDG.MR.REPORT", it is not > +currently used, and it expects this value to be 0. So to keep the IOCTL > +implementation simple, the subtype option was not included as part of the input > +ABI. However, in the future, if the TDX Module supports more than one subtype, > +a new IOCTL CMD will be created to handle it. To keep the IOCTL naming > +consistent, a subtype index is added as part of the IOCTL CMD. > + > +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 2f1cffa..56e003f 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 b8fa432..dc8d9fd 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 a secondary drive. > + > +The TDX module records the state of the TDX guest in various stages of > +the guest boot process using the build time measurement register (MRTD) > +and runtime measurement registers (RTMR). Measurements related to the > +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, section 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 87ef258..f79ab13 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 093674e..e9aa6fc 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 0000000..14246fc > --- /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 0000000..775cb46 > --- /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 0000000..5e44a0f > --- /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_report0(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 TDREPORT0 using "TDG.MR.REPORT" TDCALL */ > + ret = tdx_mcall_get_report0(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_REPORT0: > + return tdx_get_report0((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@xxxxxxxxxxxxxxx>"); > +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 0000000..a6a2098 > --- /dev/null > +++ b/include/uapi/linux/tdx-guest.h > @@ -0,0 +1,42 @@ > +/* 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_REPORT0 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_REPORT0 - Get TDREPORT0 (a.k.a. TDREPORT subtype 0) 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_REPORT0 _IOWR('T', 1, struct tdx_report_req) > + > +#endif /* _UAPI_LINUX_TDX_GUEST_H_ */ >