164 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Test TDX guest features4 *5 * Copyright (C) 2022 Intel Corporation.6 *7 * Author: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>8 */9 10#include <sys/ioctl.h>11 12#include <errno.h>13#include <fcntl.h>14 15#include <linux/tdx-guest.h>16#include "../kselftest_harness.h"17 18#define TDX_GUEST_DEVNAME "/dev/tdx_guest"19#define HEX_DUMP_SIZE 820#define DEBUG 021 22/**23 * struct tdreport_type - Type header of TDREPORT_STRUCT.24 * @type: Type of the TDREPORT (0 - SGX, 81 - TDX, rest are reserved)25 * @sub_type: Subtype of the TDREPORT (Default value is 0).26 * @version: TDREPORT version (Default value is 0).27 * @reserved: Added for future extension.28 *29 * More details can be found in TDX v1.0 module specification, sec30 * titled "REPORTTYPE".31 */32struct tdreport_type {33 __u8 type;34 __u8 sub_type;35 __u8 version;36 __u8 reserved;37};38 39/**40 * struct reportmac - TDX guest report data, MAC and TEE hashes.41 * @type: TDREPORT type header.42 * @reserved1: Reserved for future extension.43 * @cpu_svn: CPU security version.44 * @tee_tcb_info_hash: SHA384 hash of TEE TCB INFO.45 * @tee_td_info_hash: SHA384 hash of TDINFO_STRUCT.46 * @reportdata: User defined unique data passed in TDG.MR.REPORT request.47 * @reserved2: Reserved for future extension.48 * @mac: CPU MAC ID.49 *50 * It is MAC-protected and contains hashes of the remainder of the51 * report structure along with user provided report data. More details can52 * be found in TDX v1.0 Module specification, sec titled "REPORTMACSTRUCT"53 */54struct reportmac {55 struct tdreport_type type;56 __u8 reserved1[12];57 __u8 cpu_svn[16];58 __u8 tee_tcb_info_hash[48];59 __u8 tee_td_info_hash[48];60 __u8 reportdata[64];61 __u8 reserved2[32];62 __u8 mac[32];63};64 65/**66 * struct td_info - TDX guest measurements and configuration.67 * @attr: TDX Guest attributes (like debug, spet_disable, etc).68 * @xfam: Extended features allowed mask.69 * @mrtd: Build time measurement register.70 * @mrconfigid: Software-defined ID for non-owner-defined configuration71 * of the guest - e.g., run-time or OS configuration.72 * @mrowner: Software-defined ID for the guest owner.73 * @mrownerconfig: Software-defined ID for owner-defined configuration of74 * the guest - e.g., specific to the workload.75 * @rtmr: Run time measurement registers.76 * @reserved: Added for future extension.77 *78 * It contains the measurements and initial configuration of the TDX guest79 * that was locked at initialization and a set of measurement registers80 * that are run-time extendable. More details can be found in TDX v1.081 * Module specification, sec titled "TDINFO_STRUCT".82 */83struct td_info {84 __u8 attr[8];85 __u64 xfam;86 __u64 mrtd[6];87 __u64 mrconfigid[6];88 __u64 mrowner[6];89 __u64 mrownerconfig[6];90 __u64 rtmr[24];91 __u64 reserved[14];92};93 94/*95 * struct tdreport - Output of TDCALL[TDG.MR.REPORT].96 * @reportmac: Mac protected header of size 256 bytes.97 * @tee_tcb_info: Additional attestable elements in the TCB are not98 * reflected in the reportmac.99 * @reserved: Added for future extension.100 * @tdinfo: Measurements and configuration data of size 512 bytes.101 *102 * More details can be found in TDX v1.0 Module specification, sec103 * titled "TDREPORT_STRUCT".104 */105struct tdreport {106 struct reportmac reportmac;107 __u8 tee_tcb_info[239];108 __u8 reserved[17];109 struct td_info tdinfo;110};111 112static void print_array_hex(const char *title, const char *prefix_str,113 const void *buf, int len)114{115 int i, j, line_len, rowsize = HEX_DUMP_SIZE;116 const __u8 *ptr = buf;117 118 printf("\t\t%s", title);119 120 for (j = 0; j < len; j += rowsize) {121 line_len = rowsize < (len - j) ? rowsize : (len - j);122 printf("%s%.8x:", prefix_str, j);123 for (i = 0; i < line_len; i++)124 printf(" %.2x", ptr[j + i]);125 printf("\n");126 }127 128 printf("\n");129}130 131TEST(verify_report)132{133 struct tdx_report_req req;134 struct tdreport *tdreport;135 int devfd, i;136 137 devfd = open(TDX_GUEST_DEVNAME, O_RDWR | O_SYNC);138 ASSERT_LT(0, devfd);139 140 /* Generate sample report data */141 for (i = 0; i < TDX_REPORTDATA_LEN; i++)142 req.reportdata[i] = i;143 144 /* Get TDREPORT */145 ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT0, &req));146 147 if (DEBUG) {148 print_array_hex("\n\t\tTDX report data\n", "",149 req.reportdata, sizeof(req.reportdata));150 151 print_array_hex("\n\t\tTDX tdreport data\n", "",152 req.tdreport, sizeof(req.tdreport));153 }154 155 /* Make sure TDREPORT data includes the REPORTDATA passed */156 tdreport = (struct tdreport *)req.tdreport;157 ASSERT_EQ(0, memcmp(&tdreport->reportmac.reportdata[0],158 req.reportdata, sizeof(req.reportdata)));159 160 ASSERT_EQ(0, close(devfd));161}162 163TEST_HARNESS_MAIN164