Received: by 2002:a05:6358:1087:b0:cb:c9d3:cd90 with SMTP id j7csp1529233rwi; Thu, 27 Oct 2022 17:31:24 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5m8ZWhN0C1ePt9uaB/g+UTXMi0arxuJyqXn0Jp2isKHoBLQUx5CJEhSQckHP+lQg1dxlNt X-Received: by 2002:a05:6402:1cca:b0:460:7d72:8f2 with SMTP id ds10-20020a0564021cca00b004607d7208f2mr38863049edb.205.1666917084469; Thu, 27 Oct 2022 17:31:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666917084; cv=none; d=google.com; s=arc-20160816; b=bftqvNLsII1P8ZCdMRV/ZIUsuJLUEgVxFrWqAyAY12X6Q686fo+A0pFJfAlkRrMNkQ AUjtQsLruwjXW8eVCbvNZEg2icrd6F3czpy6Lx+g+w0AZTOYpJc0PFSTR6VPccD6pfvw AIwxp9I5ZHuR4lH6PbV6Uz8pOniY1B65z1HqgtAj+p22ZmEBWcuqdC5y78DGhTmwGqhh rhsZxuR1livBJYRT4hdPcT80ykyLl6l8auniXqgFSAzQ7nSvi6szzr1DNisawS+0jfpA pStYNkV3Djsd7xnyRtHK0nmYSB0TaOIJITQyguiGVxTG4lP7L4C/XFhfny7wHa75qpju hZFg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=HJuu7vYvWL3zTLldUJXO7eBnVb6hxUom0z064QvbzWg=; b=y+H97V5IpukymbmndBQXMEPOFdtwZG8eHUrM3yvM7B8Of3WMsNsg9AgCJKhpzCUNye 0ywga1TeqckQ16s4KbnRmdv9UlRA9ODiFJ+kr5kssd4CjnisQONq18SpZazTfKISBrmE ++mRa384VdsIxapl5MSfbJjVhGc7kKI0kyLtklMrAoZ0+PHgsb33PrMOr3XuvkPWaeAb waYNao2AT+T3sRTqG3hPBJCkC2EuwkjqO0IUZWWY5BOQT5BJiCtcTcmaw6B3JoSQr2fA 52+f8qL4hpFJ15GNPZGAbUXSP054LXgAf1YRbJwmA3ZELQhxeaP+gfyggvy9OPz02t/C 6O9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=VvgBZcXE; 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 nc32-20020a1709071c2000b00791bcf8aa5esi3310151ejc.739.2022.10.27.17.30.59; Thu, 27 Oct 2022 17:31:24 -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=VvgBZcXE; 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 S235425AbiJ1A3C (ORCPT + 99 others); Thu, 27 Oct 2022 20:29:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235235AbiJ1A2v (ORCPT ); Thu, 27 Oct 2022 20:28:51 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61151A23E1; Thu, 27 Oct 2022 17:28:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1666916930; x=1698452930; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=o9ufgY6oX5/hDJiwAZcmwIPdCN+KFFWxhYHkn/fr9bY=; b=VvgBZcXE54VwdVIkZCeC8zGJ7QNJUZCkqChGG8MnEi8YOfDE/KMduMXr gPLvtODT8EiObV0lQrESBf98k62GT3Vb53yvZOV7UyqqrfEsF5GMc4JG0 bl5ZyYDiGhZgp6wjmuoytg3NdYzFrAWx4jY3V/6EFIbT6FzqAN5maQa5y Qwgs/Yjevz/yZd1KuOyoyN0VoiygsNAks5w2sJdaDpUp7o0bM0ayx8K1l 6QAOs0sacXI1XyXJSoOTt2+lf1RiVehKye/O/zJMcYHahn45VoAVtNwck YDnOrPUPEpbmYFCc9/dCHLw0/q48tcHL7bQLAXn5JK6gzYMJwrBF062aM g==; X-IronPort-AV: E=McAfee;i="6500,9779,10513"; a="288091265" X-IronPort-AV: E=Sophos;i="5.95,219,1661842800"; d="scan'208";a="288091265" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2022 17:28:49 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10513"; a="627356163" X-IronPort-AV: E=Sophos;i="5.95,219,1661842800"; d="scan'208";a="627356163" Received: from ortizseb-mobl.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.212.153.115]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2022 17:28:49 -0700 From: Kuppuswamy Sathyanarayanan To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Shuah Khan , Jonathan Corbet Cc: "H . Peter Anvin" , Greg Kroah-Hartman , Kuppuswamy Sathyanarayanan , "Kirill A . Shutemov" , Tony Luck , Kai Huang , 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, linux-kselftest@vger.kernel.org, linux-doc@vger.kernel.org Subject: [PATCH v16 3/3] selftests: tdx: Test TDX attestation GetReport support Date: Thu, 27 Oct 2022 17:28:20 -0700 Message-Id: <20221028002820.3303030-4-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221028002820.3303030-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20221028002820.3303030-1-sathyanarayanan.kuppuswamy@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_PASS, 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 Attestation is used to verify the trustworthiness of a TDX guest. During the guest bring-up, the 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 guest runtime, the attestation process is used to attest to these measurements. The 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 ID to protect the integrity 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 enable guest userspace to get the TDREPORT. Add a kernel self test module to test this ABI and verify the validity of the generated TDREPORT. Reviewed-by: Tony Luck Reviewed-by: Mika Westerberg Acked-by: Kai Huang Acked-by: Kirill A. Shutemov Signed-off-by: Kuppuswamy Sathyanarayanan --- Changes since v15: * None Changes since v14: * Fixed format issue in struct comments. * Rebased on top of v6.1-rc1 Changes since v13: * Removed __packed from TDREPORT structs. * Since the guest driver is moved to drivers/virt/coco, removed tools/arch/x86/include header folder usage. * Fixed struct comments to match kernel-doc format. * Fixed commit log as per review comments. * Fixed some format issues in the code. Changes since v12: * Changed #ifdef DEBUG usage with if (DEBUG). * Initialized reserved entries values to zero. 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/testing/selftests/Makefile | 1 + tools/testing/selftests/tdx/Makefile | 7 + tools/testing/selftests/tdx/config | 1 + tools/testing/selftests/tdx/tdx_guest_test.c | 175 +++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 tools/testing/selftests/tdx/Makefile create mode 100644 tools/testing/selftests/tdx/config create mode 100644 tools/testing/selftests/tdx/tdx_guest_test.c diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 0464b2c6c1e4..f60e14d16bfd 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -73,6 +73,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..8dd43517cd55 --- /dev/null +++ b/tools/testing/selftests/tdx/Makefile @@ -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 diff --git a/tools/testing/selftests/tdx/config b/tools/testing/selftests/tdx/config new file mode 100644 index 000000000000..aa1edc829ab6 --- /dev/null +++ b/tools/testing/selftests/tdx/config @@ -0,0 +1 @@ +CONFIG_TDX_GUEST_DRIVER=y diff --git a/tools/testing/selftests/tdx/tdx_guest_test.c b/tools/testing/selftests/tdx/tdx_guest_test.c new file mode 100644 index 000000000000..a5c243f73adc --- /dev/null +++ b/tools/testing/selftests/tdx/tdx_guest_test.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test TDX guest features + * + * Copyright (C) 2022 Intel Corporation. + * + * Author: Kuppuswamy Sathyanarayanan + */ + +#include + +#include +#include + +#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; + + if (!len || !buf) + return; + + 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) +{ + __u8 reportdata[TDX_REPORTDATA_LEN]; + 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++) + 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); + + memset(req.reserved, 0, sizeof(req.reserved)); + + /* Get TDREPORT */ + ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT, &req)); + + if (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)); + } + + /* 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