Add TDX guest attestation infrastructure and driver
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEV76QKkVc4xCGURexaDWVMHDJkrAFAmOXYmwACgkQaDWVMHDJ krD8hg/+J0hUTfljmlCctwGZyqVR3Y2E722wL9oTvbgYiUAtFrARzfPF0WNwvHi5 Ywvod5hQ4unPoluthdVAD/uJqcPVhjIZ7CvNTGrS8J7ED5x5ydGLNWAL3Rn+9s6O xkz/DsV4zl+cPQ60XLsO+3Mc6RhwVs9DUthpUovl22epmgmRPCovkHWkvQsZajJq ceF/78ThfrkG4dDouaIXi1gsmKLLzU4KdHeBATMg0bgPQXFJZSGBCLaeJXWmLapq 7N3SznUqDMn4Plr/IuP4XuMA6VTVojrakCcBmw5SGVqhkVWGM1/FMg7jHSQS7Z5V 5uG7CkhTBqh17v9xKwDMPh34D51TLtNifA7jbecyL5155czFkj7BoSwEFINU/wCz agUO9NvK9j1chUnA2UGqGQigM3nWGZHMwaQjfgBWyq5gqF8HURUUrjx6XuunOfmB 1byyrDu0g48u/zaQ/RpNfewz1ZY+WylDPcqOhYaVWF1PYThStML/VMBKpdsl1Ovw nytUdQsaBIjFHQdB+snizaF93+/0FG+FTGAlDnHYmey/8plL2LYuzrcDnDYnGEXa tN3HFd2lAi4JBLmvmgF39gH+BLXuKTLweIhwTXZTn91cfire3yxiXAnLd0tuptMP aXFddxKMdMpxTqzy2X+8gJjqCr2lZ9gZkxaPsWwrBM+xrJf0p2w= =JGnq -----END PGP SIGNATURE----- Merge tag 'x86_tdx_for_6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull x86 tdx updates from Dave Hansen: "This includes a single chunk of new functionality for TDX guests which allows them to talk to the trusted TDX module software and obtain an attestation report. This report can then be used to prove the trustworthiness of the guest to a third party and get access to things like storage encryption keys" * tag 'x86_tdx_for_6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: selftests/tdx: Test TDX attestation GetReport support virt: Add TDX guest driver x86/tdx: Add a wrapper to get TDREPORT0 from the TDX Module
This commit is contained in:
commit
a89ef2aa55
52
Documentation/virt/coco/tdx-guest.rst
Normal file
52
Documentation/virt/coco/tdx-guest.rst
Normal file
@ -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.
|
@ -14,6 +14,7 @@ Linux Virtualization Support
|
||||
ne_overview
|
||||
acrn/index
|
||||
coco/sev-guest
|
||||
coco/tdx-guest
|
||||
hyperv/index
|
||||
|
||||
.. only:: html and subproject
|
||||
|
@ -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
|
||||
==========
|
||||
|
||||
|
@ -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 */
|
||||
@ -36,6 +39,12 @@
|
||||
|
||||
#define ATTR_SEPT_VE_DISABLE BIT(28)
|
||||
|
||||
/* TDX Module call error codes */
|
||||
#define TDCALL_RETURN_CODE(a) ((a) >> 32)
|
||||
#define TDCALL_INVALID_OPERAND 0xc0000100
|
||||
|
||||
#define TDREPORT_SUBTYPE_0 0
|
||||
|
||||
/*
|
||||
* Wrapper for standard use of __tdx_hypercall with no output aside from
|
||||
* return code.
|
||||
@ -100,6 +109,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_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);
|
||||
|
||||
static void tdx_parse_tdinfo(u64 *cc_mask)
|
||||
{
|
||||
struct tdx_module_output out;
|
||||
|
@ -67,6 +67,8 @@ void tdx_safe_halt(void);
|
||||
|
||||
bool tdx_early_handle_ve(struct pt_regs *regs);
|
||||
|
||||
int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport);
|
||||
|
||||
#else
|
||||
|
||||
static inline void tdx_early_init(void) { };
|
||||
|
@ -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
|
||||
|
@ -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/
|
||||
|
10
drivers/virt/coco/tdx-guest/Kconfig
Normal file
10
drivers/virt/coco/tdx-guest/Kconfig
Normal file
@ -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.
|
2
drivers/virt/coco/tdx-guest/Makefile
Normal file
2
drivers/virt/coco/tdx-guest/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_TDX_GUEST_DRIVER) += tdx-guest.o
|
102
drivers/virt/coco/tdx-guest/tdx-guest.c
Normal file
102
drivers/virt/coco/tdx-guest/tdx-guest.c
Normal file
@ -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@linux.intel.com>");
|
||||
MODULE_DESCRIPTION("TDX Guest Driver");
|
||||
MODULE_LICENSE("GPL");
|
42
include/uapi/linux/tdx-guest.h
Normal file
42
include/uapi/linux/tdx-guest.h
Normal file
@ -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_ */
|
@ -74,6 +74,7 @@ TARGETS += sync
|
||||
TARGETS += syscall_user_dispatch
|
||||
TARGETS += sysctl
|
||||
TARGETS += tc-testing
|
||||
TARGETS += tdx
|
||||
TARGETS += timens
|
||||
ifneq (1, $(quicktest))
|
||||
TARGETS += timers
|
||||
|
7
tools/testing/selftests/tdx/Makefile
Normal file
7
tools/testing/selftests/tdx/Makefile
Normal file
@ -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
|
1
tools/testing/selftests/tdx/config
Normal file
1
tools/testing/selftests/tdx/config
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_TDX_GUEST_DRIVER=y
|
163
tools/testing/selftests/tdx/tdx_guest_test.c
Normal file
163
tools/testing/selftests/tdx/tdx_guest_test.c
Normal file
@ -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_REPORT0, &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
|
Loading…
Reference in New Issue
Block a user