From patchwork Thu Oct 20 04:58:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 5975 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp67508wrs; Wed, 19 Oct 2022 22:05:40 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4QR4eyvUBYSvCy3CZkWKuck59pXNMZB7zCQGL05IgdR4rpvcUayJHX8klzteoITNfu1e+a X-Received: by 2002:a17:902:e88b:b0:17f:8514:cf5f with SMTP id w11-20020a170902e88b00b0017f8514cf5fmr12071477plg.163.1666242340538; Wed, 19 Oct 2022 22:05:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666242340; cv=none; d=google.com; s=arc-20160816; b=xxxJYQrZONl0SFYS+1df5uWB8NnbvfbfaTNQin3TFaT8qMmymjtJScw27srp1rw0tR JngBsUTn6gcuTc+aEw6dEs02U0XL6SeYjKg81STCouwxq7QS+czg5p/9U9Pcdbdl6oQW LeHD+iqlpppD662IIkcVH41YfetT3oqE7KLXdx3QvlFUR7E3zujHAakkiSlltfoQJQVp rYm/0mFUJiv8ar85DHadZFIXc0XzXuRYn2P+U0yJ8HISyEBbPQs2TcFtnY6xlaL/bpCv CLhtTrfZ6ZlgruyqsMewd2NR/cTUncyUhDjNmA3NT70eMaRKg19vXsZimcG1Hyt2unDF KlaQ== 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=lcyc3wEqCVVbLy3n5rCQT9S5rjAqJZzI7Jaj0AkfdV4=; b=bBMPI1RTwDnHcOfnj8Pg5FEr9pHu16q0FN9TNx1kugFWxxiyg+m6ohrN8x7hYTUTXP EhQB5A17GKJHUUZcTLEwOTMhFriqHC4WgmZBnhL+xn0+1apOZHY+wjEGbz751VyrVXlO uwBBSBn8OW5BH7U9AnNJA0TONT5B5bbH9Oul0De72+pna0gwaSzq3/+TzQ9aKzy7wINd ywekCrZ2MI6aYtYMNveQS2WUlcA2p7sjZRCupfWEdpVOep+wmRNJVSNlEtFQ+OtYvXi8 6rgKAw/GvkNd4nD+EhaLYjqUx7TClvBGdoP2WMGz4YD2lzKLnYE6HmxvXhcWFS0y9TIV rAvw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=UgcR+Hmw; 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: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m21-20020a637d55000000b0045c39503df3si19970665pgn.451.2022.10.19.22.05.26; Wed, 19 Oct 2022 22:05:40 -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=UgcR+Hmw; 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 S229892AbiJTE75 (ORCPT + 99 others); Thu, 20 Oct 2022 00:59:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229769AbiJTE7o (ORCPT ); Thu, 20 Oct 2022 00:59:44 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D4B282792A; Wed, 19 Oct 2022 21:59:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1666241981; x=1697777981; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=p+sUnn7KTIQ8XWNxIf5VmU2ElbLpb0lVdDmjgaFJsp0=; b=UgcR+HmwCky28abvmQ7MU5PEkrqFz8o25EV0kR5N/nDWTi1qmo9yJrx1 T5b/KhZFkr+WKNoE9JDir5GZycAg3UOF3bSA9YH3+Cyt4LMeDYV2r916T PIpQuKFQm4TIgTwn0Wml6kmCTxW/tkkPFB94boNkLo5nbF7TWbE6fWfpQ sjeQNLQt2uW/7doB6mzev/OAYD5vNH//IHDEi0gaPFSAFyOWo4KFYyq05 iN9LCE1QOatVWLPZhmifx3utklLr39H1VfqPBYcHFU26bRQkMdNHoZqUO G14xnpEixI3tTA+zJEQ2MSuVLxArFkM46GW7xgVwC4CXFsrM4Y6Unvo86 g==; X-IronPort-AV: E=McAfee;i="6500,9779,10505"; a="293997454" X-IronPort-AV: E=Sophos;i="5.95,198,1661842800"; d="scan'208";a="293997454" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Oct 2022 21:59:32 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10505"; a="660690262" X-IronPort-AV: E=Sophos;i="5.95,198,1661842800"; d="scan'208";a="660690262" Received: from srnaisha-mobl.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.209.25.189]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Oct 2022 21:59:31 -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 v15 3/3] selftests: tdx: Test TDX attestation GetReport support Date: Wed, 19 Oct 2022 21:58:28 -0700 Message-Id: <20221020045828.2354731-4-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221020045828.2354731-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20221020045828.2354731-1-sathyanarayanan.kuppuswamy@linux.intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE, URIBL_BLOCKED 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 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747181728620120703?= X-GMAIL-MSGID: =?utf-8?q?1747181728620120703?= 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 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..19fdb0a89bad --- /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. All rights reserved. + * + * 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