Received: by 2002:ac0:e34a:0:0:0:0:0 with SMTP id g10csp389314imn; Thu, 28 Jul 2022 04:03:51 -0700 (PDT) X-Google-Smtp-Source: AGRyM1ua2766DUzCq1EO0GUiBEHUEcTf4xEQHnJuTvBgFLp87vghLijQEABPIf/s+jmcHs5tVfjc X-Received: by 2002:aa7:d0c8:0:b0:43c:f071:992a with SMTP id u8-20020aa7d0c8000000b0043cf071992amr1599159edo.418.1659006231391; Thu, 28 Jul 2022 04:03:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659006231; cv=none; d=google.com; s=arc-20160816; b=VnlAWKuUi48DPfzadFrsNTzxB2OCt7ohBCIWjYmchZxjJ+omvcsxKSIydZ6sRoNqOm wJXzOcWATXWkQIMfQ3nXLf8YkajokmCM3MIyUOvqHvQdCvqayzFpSNOz6HBarbGg6zIM 8SjxV6AVMTLKlV32cNhS8BeZsEcViBCFRia1kExEa8BcCkfjIJps2qkyKa/6S+IPLbY0 bQEwGQmhYSAKKZ4zYQf0Rot4U3NguM7A3YtCOUTE6YP/V5LDkQoqAj5JeuOHHEb0tEeZ eWBSrpYhvN4fz3iPpmpB7Gg2mY2YO5YR8N+MdYMxESN3l9iUdzaWIbsAxycbmbtTp2u2 npnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:user-agent :content-transfer-encoding:references:in-reply-to:date:cc:to:from :subject:message-id:dkim-signature; bh=U7Ud7dg5+me48U0htjYzzT4Qicy0qTHdDwNJigtm5Bs=; b=pLDj3R588jbD7M+zFvYr4UAU91MqXJqq8ShC6+7q57EjkaLImjVY+MxATnPSJELG5B VHMluajrh6m886mNDY5IVvPa6Nygnggd3laHmdVvuQzloiYVojG9cdJAL7lQekMKQImf 9TUqDfjZ9UjIdb5JQv5Xc/mdzJQYSmoxrEGar1iiR05sOqLJNrw6FTPeFv9hdCHDUkRF mtWycMUOC6g2MWPOkl+QxJ9K8IlI+Oaak3FYQKC6+Q1jceYDY4wAQLQm/wDBPhJ4PNYf SqHd9t5ZQIE3/1q0Icp5Iej5ptRgmJy50QR2RGqzcA33ngmrCP60NvssJTDRF7SGf70w 1xEg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=HHj4Wtiz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r12-20020a17090638cc00b00711f55a31casi429994ejd.775.2022.07.28.04.03.26; Thu, 28 Jul 2022 04:03:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=HHj4Wtiz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235968AbiG1Kcr (ORCPT + 99 others); Thu, 28 Jul 2022 06:32:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235965AbiG1Kco (ORCPT ); Thu, 28 Jul 2022 06:32:44 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 60926422E6 for ; Thu, 28 Jul 2022 03:32:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1659004362; x=1690540362; h=message-id:subject:from:to:cc:date:in-reply-to: references:content-transfer-encoding:mime-version; bh=4g8gzDAmV6rhsRG6mHh43CHff7QEagwSp34J8Gn4xuM=; b=HHj4WtizoeQ5sLqffgVhSzY32P8WCH6Kbjdg8bAcHIV3mKhY5zsg/9rF JnoIMsbNfjV7Bb86uGNb/15AFI0Eh/lEWnMQYp2NgMpXStSUUmEqOkKi/ /uyo35FlbkGASJ7SwOJwSg4TCvx3n65IivG0vas5tACjwFFX6ohGYmo09 aMWa9kWJ6zAaNB76BJNDDA6VjBRIPJe9nchiofwo+UHWmujLCRs1dg6vO dzXA6GL2cA0qDRGvGavMMFM0U26WFl/lRH6JOjypWv5oFg70yjse9ezfC OpviCnHNLB4Ixzy97INVJcZQjt8nUxg311c4eu+bGqM7TS5gKRB/roDvm Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10421"; a="314267031" X-IronPort-AV: E=Sophos;i="5.93,196,1654585200"; d="scan'208";a="314267031" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2022 03:32:41 -0700 X-IronPort-AV: E=Sophos;i="5.93,196,1654585200"; d="scan'208";a="659661892" Received: from byeongky-mobl.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.209.170.137]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2022 03:32:34 -0700 Message-ID: <03c6c9cecd281d64d0efd48cb40135092dc2d0df.camel@intel.com> Subject: Re: [PATCH v9 2/6] selftests: tdx: Test GetReport TDX attestation feature From: Kai Huang To: Kuppuswamy Sathyanarayanan , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org Cc: "H . Peter Anvin" , "Kirill A . Shutemov" , Tony Luck , Andi Kleen , Wander Lairson Costa , Isaku Yamahata , marcelo.cerri@canonical.com, tim.gardner@canonical.com, khalid.elmously@canonical.com, philip.cox@canonical.com, linux-kernel@vger.kernel.org Date: Thu, 28 Jul 2022 22:32:32 +1200 In-Reply-To: <20220728034420.648314-3-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20220728034420.648314-1-sathyanarayanan.kuppuswamy@linux.intel.com> <20220728034420.648314-3-sathyanarayanan.kuppuswamy@linux.intel.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.44.3 (3.44.3-1.fc36) MIME-Version: 1.0 X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 2022-07-27 at 20:44 -0700, Kuppuswamy Sathyanarayanan wrote: > In TDX guest, attestation is used to verify the trustworthiness of a > TD. During the TD bring-up, Intel TDX module measures and records the > initial contents and configuration of TD, and at runtime, TD software > uses runtime measurement registers (RMTRs) to measure and record > details related to kernel image, command line params, ACPI tables, > initrd, etc. At TD runtime, Intel SGX attestation infrastructure is > re-used to attest to these measurement data. >=20 > First step in the TDX attestation process is to get the TDREPORT data. > It is 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. >=20 > Intel's TDX guest driver exposes TDX_CMD_GET_REPORT IOCTL interface to > get the TDREPORT from the user space. >=20 > Add a kernel selftest module to test this ABI and verify the validity > of generated TDREPORT. >=20 > Reviewed-by: Tony Luck > Reviewed-by: Andi Kleen > Acked-by: Kirill A. Shutemov > Signed-off-by: Kuppuswamy Sathyanarayanan > --- > tools/testing/selftests/Makefile | 1 + > tools/testing/selftests/tdx/Makefile | 7 + > tools/testing/selftests/tdx/tdx_attest_test.c | 160 ++++++++++++++++++ > 3 files changed, 168 insertions(+) > create mode 100644 tools/testing/selftests/tdx/Makefile > create mode 100644 tools/testing/selftests/tdx/tdx_attest_test.c >=20 > diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/M= akefile > index de11992dc577..807a839d69c4 100644 > --- a/tools/testing/selftests/Makefile > +++ b/tools/testing/selftests/Makefile > @@ -69,6 +69,7 @@ TARGETS +=3D sync > TARGETS +=3D syscall_user_dispatch > TARGETS +=3D sysctl > TARGETS +=3D tc-testing > +TARGETS +=3D tdx > TARGETS +=3D timens > ifneq (1, $(quicktest)) > TARGETS +=3D timers > diff --git a/tools/testing/selftests/tdx/Makefile b/tools/testing/selftes= ts/tdx/Makefile > new file mode 100644 > index 000000000000..281db209f9d6 > --- /dev/null > +++ b/tools/testing/selftests/tdx/Makefile > @@ -0,0 +1,7 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +CFLAGS +=3D -O3 -Wl,-no-as-needed -Wall -static > + > +TEST_GEN_PROGS :=3D tdx_attest_test > + > +include ../lib.mk > diff --git a/tools/testing/selftests/tdx/tdx_attest_test.c b/tools/testin= g/selftests/tdx/tdx_attest_test.c > new file mode 100644 > index 000000000000..7155cc751eaa > --- /dev/null > +++ b/tools/testing/selftests/tdx/tdx_attest_test.c > @@ -0,0 +1,160 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Test TDX attestation feature > + * > + * Copyright (C) 2022 Intel Corporation. All rights reserved. > + * > + * Author: Kuppuswamy Sathyanarayanan > + */ > + > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "../kselftest_harness.h" > +#include "../../../../arch/x86/include/uapi/asm/tdx.h" > + > +#define devname "/dev/tdx-guest" > +#define HEX_DUMP_SIZE 8 > + > +/* > + * struct td_info - It contains the measurements and initial configurati= on of > + * the TD 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. > + */ > +struct td_info { > + /* TD 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]; > +}; > + > +/* > + * Trusted Execution Environment (TEE) report (TDREPORT_STRUCT) type, > + * sub type and version.. > + */ > +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; > +}; > + > +/* > + * struct reportmac - First field in the TEE report structure > + * (TRDREPORT_STRUCT). It is common to Intel=E2=80=99s TEE's e.g., SGX a= nd TDX. > + * It is MAC-protected and contains hashes of the remainder of the repor= t > + * structure which includes the TEE=E2=80=99s measurements, and where ap= plicable, > + * the measurements of additional TCB elements not reflected in CPUSVN = =E2=80=93 > + * e.g., a SEAM=E2=80=99s measurements. > + */ > +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]; > +}; > + > +struct tee_tcb_info { > + __u8 data[239]; > +}; > + > +struct tdreport_data { > + struct reportmac _reportmac; > + struct tee_tcb_info _tcb_info; > + __u8 reserved[17]; > + struct td_info _tdinfo; > +}; I think 'struct tdreport' is enough. The _data postfix only causes it to b= e more confusing. Btw, as it appears you only verified reportdata below, is it worth to have = all those data structures (and they are used by hardware but not __packed)? Pe= rhaps a macro to define REPORTDATA offset in TDREPORT is good enough? Or maybe I= am missing something. > + > +#ifdef DEBUG > +static void print_array_hex(const char *title, const char *prefix_str, > + const void *buf, int len) > +{ > + const __u8 *ptr =3D buf; > + int i, rowsize =3D HEX_DUMP_SIZE; > + > + if (!len || !buf) > + return; > + > + printf("\t\t%s", title); > + > + for (i =3D 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_data *tdr_data; > + __u8 tdreport[TDX_REPORT_LEN]; > + struct tdx_report_req req; > + int devfd, i; > + > + devfd =3D open(devname, O_RDWR | O_SYNC); > + > + ASSERT_LT(0, devfd); > + > + /* Generate sample report data */ > + for (i =3D 0; i < TDX_REPORTDATA_LEN; i++) > + reportdata[i] =3D i; > + > + /* Initialize IOCTL request */ > + req.subtype =3D 0; > + req.reportdata =3D (__u64)reportdata; > + req.rpd_len =3D TDX_REPORTDATA_LEN; > + req.tdreport =3D (__u64)tdreport; > + req.tdr_len =3D TDX_REPORT_LEN; > + > + /* Get TDREPORT */ > + ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req)); > + > + tdr_data =3D (struct tdreport_data *)tdreport; > + > +#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(&tdr_data->_reportmac.reportdata[0], reportdata, > + sizeof(reportdata))); > + > + ASSERT_EQ(0, close(devfd)); > +} > + > +TEST_HARNESS_MAIN