From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web08.3240.1649403844079561158 for ; Fri, 08 Apr 2022 00:44:04 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=f+eGaX1j; spf=pass (domain: intel.com, ip: 192.55.52.136, mailfrom: jiewen.yao@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649403844; x=1680939844; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=we/rz05XPyZ96dMWz4r5Y8EePVJwxpmiiFN9wugjYYc=; b=f+eGaX1jEv/4S4Rxa09LAQORsl2p9KnkkTQhZ46TXIOW0cUTaIvYh3LI hwDlRRHaXyL0rAmCb+6zWjim8KbLUU2OMdKw6uNZc7O8tZVXvVU6BhOM+ HoQG8rOY8lcX2AYkngmq87nUkToEmYQbGNxpEKlbyDGTZ2shX6f9MjtW+ oWBIqs1PPPC8a5p8kk7GibVuYxkb6TWG3u0D/iwm/9Pgt75u3tVERni9m zlX5vIKBJKjZbh4yfrz06ik04xi6oBehD9DWy+7+FXfjRHln8L7O5SCz0 sAWB2sy1wLrYp24CBoIFUk56cagq4AzXyzCni0wi3oJvER5EH5c47hH9A Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="241470237" X-IronPort-AV: E=Sophos;i="5.90,244,1643702400"; d="scan'208";a="241470237" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2022 00:44:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,244,1643702400"; d="scan'208";a="589135705" Received: from orsmsx602.amr.corp.intel.com ([10.22.229.15]) by orsmga001.jf.intel.com with ESMTP; 08 Apr 2022 00:44:02 -0700 Received: from orsmsx601.amr.corp.intel.com (10.22.229.14) by ORSMSX602.amr.corp.intel.com (10.22.229.15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.27; Fri, 8 Apr 2022 00:44:02 -0700 Received: from ORSEDG601.ED.cps.intel.com (10.7.248.6) by orsmsx601.amr.corp.intel.com (10.22.229.14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.27 via Frontend Transport; Fri, 8 Apr 2022 00:44:02 -0700 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (104.47.58.106) by edgegateway.intel.com (134.134.137.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2308.27; Fri, 8 Apr 2022 00:44:02 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LviKxYccLD2P2HbonEHY5xFUJGUHaBoZK77VtE1BNTcoFOAvdCca/57flT9KhS1wxC5TW7oEO7NKnen+tJXFxwEZM9VMxeoiWrvBl+9VPtW+ZzlIvbsSjoPMjWNozPu+WocVQcNoPkUUDHMAbeYbPKWf1KKVuLjFv5M/gUSbZZDZpxRB+P27EEqJPAJ/dOls0SCAALXUQqwwLRG9pIy6AQE+ZqU7nXG0cMsp1UL/5CiyUvIgN/24nZZ7yfY6RcV3dnqCO6mvCHdqDko1HUEio2i3Btr64tPL3KlpHzaadnTK1Z05KWkOezSj1isBB1uN6Ggm3ybOFFdFGi7ZzoAZzA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ohKGTlyyAUN2FZB5BJGGKJY8SWKOsCcguk9qsSD6DtE=; b=hGABnhCPv+xh04FlO0mmudJA2mqM+Of0QrW29U/JULatbuvK4RxVhuFnZI8HO7W0KbJmNPl4ibtiCHTV1SjnSo9VKZMdPZUqwbdFvD+Z8R4M3zUucfG4OMn+YoKwPifi3CshyK8dcKp80KnVEVFPt3rE8Up9yRDZdejUr5F9rDeqTeT/oA/NVuE/YdxyyXXfLRioNMddx48lNcc1v3iOVp6qCdCXlfj0M93qpMYOAx/kE2+iwPXBMsOrTVHaqeSgbbw6kJSO6pnWXJT7FlUgF9XiNlZbmuG+/92vQHhVPot5yfDC+5nK6sJ+IrQPGh2/pgnsbHdjda9Yb8S14mCEIg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from PH0PR11MB5879.namprd11.prod.outlook.com (2603:10b6:510:142::5) by BN6PR11MB1460.namprd11.prod.outlook.com (2603:10b6:405:b::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5144.22; Fri, 8 Apr 2022 07:43:59 +0000 Received: from PH0PR11MB5879.namprd11.prod.outlook.com ([fe80::289d:9245:f6bd:af78]) by PH0PR11MB5879.namprd11.prod.outlook.com ([fe80::289d:9245:f6bd:af78%5]) with mapi id 15.20.5144.022; Fri, 8 Apr 2022 07:43:59 +0000 From: "Yao, Jiewen" To: "Xu, Min M" , "devel@edk2.groups.io" CC: Ard Biesheuvel , "Justen, Jordan L" , Brijesh Singh , "Aktas, Erdem" , James Bottomley , "Tom Lendacky" , Gerd Hoffmann Subject: Re: [PATCH V2 4/8] OvmfPkg/IntelTdx: Measure Td HobList and Configuration FV Thread-Topic: [PATCH V2 4/8] OvmfPkg/IntelTdx: Measure Td HobList and Configuration FV Thread-Index: AQHYSxO7iDBTefZkLUyx2cYCj49Ab6zlonNA Date: Fri, 8 Apr 2022 07:43:58 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.6.401.20 dlp-product: dlpe-windows dlp-reaction: no-action authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 76e13a04-2a39-4e51-e3a8-08da19338ae3 x-ms-traffictypediagnostic: BN6PR11MB1460:EE_ x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-microsoft-antispam-prvs: x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: YsyyFYFDbqw+BYbldgL+KH6aajgVr2uDLhndw2oxMAwPc6YEhQMu0xGVYpsdH5YBn4WVEYYkMXiJ6ZphuQDX4JiYoRZSsdUa8QQvBcdRGCaL8qWncmNmzIe37vhUEb73ykeL4GKWcLMwDAIm2DN6ttnvYcJd279AW86Q0Sp0PjJuoW82cqo+0RqIU+0OZeePwwxHglEgA9vuadsMds+jxM3VNePC7UFwr+8KthKaOo1qRjbVyz4ORoAUq6WE4qHyARgbZBbHAzNIz6KKGTFI3rO9P8PVTJoQc/04U2rEsCgN9oiCp096sjcRcSFYOnJ2RkoyXAwdLd+UofAKDpIy7ojHhBQ0GxJgzvQtsyHGvGxjTQPeuAVLovvkXfT2NerZrP4FWcamTKEnvKU5gjB8w6eoEn49OfmIAy5GdRHT58knnGpH34clEwCO0k9hPOfF/y/DvevSSVEF5gvELOkiGgQnFlT1Xx6IsKsiKPkfSHN/0xrwZ5Oh+o1/glVs3hBFV/ijKcxZ6ycPyJKXg3cfaYTX0WguSaW1IblqBfvqLGDmVSLYFdP3d/L0wp5mjrKYxHqe4ZEHqm/iqiCcPYc835Zjow0Lwa6xcBxJsnFyYnuklmoOUkGkd8OT7pqAhqRB3jhBl/WYXZKM7STBrKOw3fDvhqswWNBinQOQLMtghNi+X0ttBxO6m75Q2477Fh938y+I/DRGv/4pkn0uNlv0kxfXMf81TFKSUZjSMY5iJVOcvvSdJlzfNArQEq+/Ae+yafIAq4jg/1ZORzI6MgEw7o5pu5Lt/L4wuadI2meAYYM= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH0PR11MB5879.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230001)(366004)(66946007)(76116006)(66556008)(86362001)(33656002)(5660300002)(66476007)(64756008)(71200400001)(122000001)(4326008)(8676002)(55016003)(966005)(82960400001)(508600001)(83380400001)(66446008)(38100700002)(316002)(2906002)(110136005)(54906003)(52536014)(7696005)(9686003)(38070700005)(6506007)(19627235002)(53546011)(26005)(186003)(30864003)(8936002)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?6I/wjcIRpSw2anv2oBKpD9XrvweRD0SwgqPqtg76ayt9PLHjIxeX/TWOuNKV?= =?us-ascii?Q?JcVUcXHlzfHK2gdUewDMzNc/4KqZXcVAmeyVVn0T0OEK4plSiRycxPNOSbLG?= =?us-ascii?Q?x0sCYn9v3WYLRzHIFd7eAB+w2//49DpsKeF8DWUgUsxEEYK0A2pYHrNqtQQD?= =?us-ascii?Q?/gNkvXi7oqX4Wma2T6dZFhCw8ewconIVL3G23QRGqyRW8iJ/NqDpgKF61Foh?= =?us-ascii?Q?q9tELrRzNUi4P5eRhkJLCx+Tc2AbozFFLHRMMTUCddRaI8iiyOKFakASymkP?= =?us-ascii?Q?5KCDARIteGgOB45XIRC/ypXTfLdIJf9/PJTOm8rqhILUtwqY/DDYqt5RlOf4?= =?us-ascii?Q?YyDfV2Yqurx0jJekBzruw+kVK5uTMuTYL9eMVxjKBQqYCKVOPpXozB7XMpuv?= =?us-ascii?Q?OGhVfiRzLNpmnUhLozDlqHJYQyq5Rpld9T8GT/UgHjadTsYBAL8b6p7oioXa?= =?us-ascii?Q?+4U5vb8jr5V18lDeKWy8fDJSQpshRsWZSfJRNBfnRSHEimDyv5Kdki8SB0ql?= =?us-ascii?Q?k3qNyf6gdA/U/4Mp5sIvaW/nLv5+v3fxB2xQ4RGqgckvXpvMRQnPh0iTVno4?= =?us-ascii?Q?Jm9rwYhZPKzJ1yuXFjrbOt0iZzXqj8ofgThaszyhynJw0rsjhsee7u+pJXdS?= =?us-ascii?Q?KKUVamNlBqhlz++XZrA/Bb45HCZoHndMiaGyP3UzcDLHLWkoMQbhRs5OZLbV?= =?us-ascii?Q?TGnnhUUOIRfdceLYWYTBzNEKrebJxBylMEHMk64RGOS8tsRYQJhDx0Jvwaay?= =?us-ascii?Q?1Vwgkl46IxIfwrBbwPdIEG7FLOie7At2TLvow21sMDtAnFo8YDrTsC23T8Vz?= =?us-ascii?Q?YeHAhYmv0oXLM/5sak3ZOAG6Rtrp026MS6zrw7Q3aQFyO8SbGwpBSMka5GFb?= =?us-ascii?Q?7j3isCl9CcRPiKVa9TqDpiS4hwxoO7cLFpAmoL20xZKNth3tYM34YKJjAshn?= =?us-ascii?Q?pLstNmeCGE8K4L/FZymFb1NFfwoJ8MCHwD6n11eaf3bu7y0K/YY6OHNv4poH?= =?us-ascii?Q?hIHUzOqFQvLXOiEsTSSXfxHWApU2NvA6pWkwmJn5Z6QxU2BPVkHFhzKay36t?= =?us-ascii?Q?DxjM95Wx8LYK/FWy3Q401LK3FGQ8Mqqq9ZeFJTrCV1MUsJSrEBAdozxiXLqK?= =?us-ascii?Q?4nJMC+WV0cfom0pEdg/RRgXLicBJu4eEO0VPMS9KmofcUX6YRwTjU+rZxcvN?= =?us-ascii?Q?Ztq1I3EyOB9tcpvhsxCA0xpMggGaXvGUpqiH755nvyPxxcBGyT86lcv9dy6T?= =?us-ascii?Q?XW9Ih4U8IRKmCqRtZ0hUv25nGYMf4vOmKA2ReILwcj+Ih7BpfnGOgR8c93dZ?= =?us-ascii?Q?P0HB3m+lWP5mdu0vZYYcpwFInlscZ5LX/yEUCXhbqv/lMCRFM83r/rrgXpVe?= =?us-ascii?Q?3o/ibBiBrU0HN3gpz3AVB+O/G5V2Sz9tKzddT9IDPBczMtHeZfh3cgC2zMoJ?= =?us-ascii?Q?W7/v6YBIoQKO1ufad0dHbRCUmRUeJht5z0OSsOTxzPP2aKiM6BCuC7RxpoMQ?= =?us-ascii?Q?sccHgzSVvQOF06nuD8hQL6NypUN4T9yez0lkpvRre0WqcnVlc9Sed0LsPPYc?= =?us-ascii?Q?FgmtY7rIYmd4vdhciJRSuvxl65EfY7rufNTLG3lPH1MxnLBOmb6z4eMXt0BF?= =?us-ascii?Q?TL/xZ96PVwlB3CHRoRoYibObz/AMnAVr4gq7pYlSHiWV0aAqXbCHaEezS1Vv?= =?us-ascii?Q?gRfgiMYVuSuolGnWipCu78mI3bdhDMni9kT/QK2q+aheN/ePTtarppWZyeXu?= =?us-ascii?Q?h79aR7MHWA=3D=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5879.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 76e13a04-2a39-4e51-e3a8-08da19338ae3 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Apr 2022 07:43:58.9626 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: rHBF5P4/SEV1G7Rdc3jVZbIbd4mSPaS3PJPqHpjWMSemyypht9PmVA5DxCsqbHRU3R6tzr8MklVxlnXnRO7SdA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR11MB1460 Return-Path: jiewen.yao@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Can we use a SecMeasurementLib here? Instead of implementing all things in = Startup. > -----Original Message----- > From: Xu, Min M > Sent: Friday, April 8, 2022 2:39 PM > To: devel@edk2.groups.io > Cc: Xu, Min M ; Ard Biesheuvel > ; Yao, Jiewen ; Justen, > Jordan L ; Brijesh Singh ; > Aktas, Erdem ; James Bottomley > ; Tom Lendacky ; Gerd > Hoffmann > Subject: [PATCH V2 4/8] OvmfPkg/IntelTdx: Measure Td HobList and > Configuration FV >=20 > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3853 >=20 > TdHobList and Configuration FV are external data provided by Host VMM. > These are not trusted in Td guest. So they should be validated , measured > and extended to Td RTMR registers. In the meantime 2 EFI_CC_EVENT_HOB are > created. These 2 GUIDed HOBs carry the hash value of TdHobList and > Configuration FV. In DXE phase EFI_CC_EVENT can be created based on these > 2 GUIDed HOBs. >=20 > Cc: Ard Biesheuvel > Cc: Jiewen Yao > Cc: Jordan Justen > Cc: Brijesh Singh > Cc: Erdem Aktas > Cc: James Bottomley > Cc: Jiewen Yao > Cc: Tom Lendacky > Cc: Gerd Hoffmann > Signed-off-by: Min Xu > --- > OvmfPkg/IntelTdx/IntelTdxX64.dsc | 3 + > OvmfPkg/Library/PeilessStartupLib/IntelTdx.c | 498 ++++++++++++++++++ > .../PeilessStartupLib/PeilessStartup.c | 30 ++ > .../PeilessStartupInternal.h | 57 ++ > .../PeilessStartupLib/PeilessStartupLib.inf | 7 +- > 5 files changed, 593 insertions(+), 2 deletions(-) > create mode 100644 OvmfPkg/Library/PeilessStartupLib/IntelTdx.c >=20 > diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc > b/OvmfPkg/IntelTdx/IntelTdxX64.dsc > index 245155d41b30..caae49d524f9 100644 > --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc > +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc > @@ -520,6 +520,9 @@ > OvmfPkg/IntelTdx/Sec/SecMain.inf { > >=20 > NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecom > pressLib.inf > + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf > + > HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRout > erTdx.inf > + > NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf > } >=20 > # > diff --git a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c > b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c > new file mode 100644 > index 000000000000..bb905cf5cd6a > --- /dev/null > +++ b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c > @@ -0,0 +1,498 @@ > +/** @file > + Copyright (c) 2022, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "PeilessStartupInternal.h" > + > +#pragma pack(1) > + > +typedef struct { > + UINT32 count; > + TPMI_ALG_HASH hashAlg; > + BYTE sha384[SHA384_DIGEST_SIZE]; > +} TDX_DIGEST_VALUE; > + > +#define HANDOFF_TABLE_DESC "TdxTable" > +typedef struct { > + UINT8 TableDescriptionSize; > + UINT8 TableDescription[sizeof (HANDOFF_TABLE_DESC= )]; > + UINT64 NumberOfTables; > + EFI_CONFIGURATION_TABLE TableEntry[1]; > +} TDX_HANDOFF_TABLE_POINTERS2; > + > +#define FV_HANDOFF_TABLE_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX- > XXXXXXXXXXXX)" > +typedef struct { > + UINT8 BlobDescriptionSize; > + UINT8 BlobDescription[sizeof (FV_HANDOFF_TABLE_DESC)= ]; > + EFI_PHYSICAL_ADDRESS BlobBase; > + UINT64 BlobLength; > +} FV_HANDOFF_TABLE_POINTERS2; > + > +#pragma pack() > + > +#define INVALID_PCR2MR_INDEX 0xFF > + > +/** > + RTMR[0] =3D> PCR[1,7] > + RTMR[1] =3D> PCR[2,3,4,5] > + RTMR[2] =3D> PCR[8~15] > + RTMR[3] =3D> NA > + Note: > + PCR[0] is mapped to MRTD and should not appear here. > + PCR[6] is reserved for OEM. It is not used. > +**/ > +UINT8 > +GetMappedRtmrIndex ( > + UINT32 PCRIndex > + ) > +{ > + UINT8 RtmrIndex; > + > + if ((PCRIndex =3D=3D 6) || (PCRIndex =3D=3D 0) || (PCRIndex > 15)) { > + DEBUG ((DEBUG_ERROR, "Invalid PCRIndex(%d) map to MR Index.\n", > PCRIndex)); > + ASSERT (FALSE); > + return INVALID_PCR2MR_INDEX; > + } > + > + RtmrIndex =3D 0; > + if ((PCRIndex =3D=3D 1) || (PCRIndex =3D=3D 7)) { > + RtmrIndex =3D 0; > + } else if ((PCRIndex >=3D 2) && (PCRIndex < 6)) { > + RtmrIndex =3D 1; > + } else if ((PCRIndex >=3D 8) && (PCRIndex <=3D 15)) { > + RtmrIndex =3D 2; > + } > + > + return RtmrIndex; > +} > + > +/** > + Tpm measure and log data, and extend the measurement result into a spe= cific > PCR. > + @param[in] PcrIndex PCR Index. > + @param[in] EventType Event type. > + @param[in] EventLog Measurement event log. > + @param[in] LogLen Event log length in bytes. > + @param[in] HashData The start of the data buffer to be hashed= , > extended. > + @param[in] HashDataLen The length, in bytes, of the buffer refer= enced by > HashData > + @retval EFI_SUCCESS Operation completed successfully. > + @retval EFI_UNSUPPORTED TPM device not available. > + @retval EFI_OUT_OF_RESOURCES Out of memory. > + @retval EFI_DEVICE_ERROR The operation was unsuccessful. > +**/ > +EFI_STATUS > +EFIAPI > +TdxMeasureAndLogData ( > + IN UINT32 PcrIndex, > + IN UINT32 EventType, > + IN VOID *EventLog, > + IN UINT32 LogLen, > + IN VOID *HashData, > + IN UINT64 HashDataLen > + ) > +{ > + EFI_STATUS Status; > + UINT32 RtmrIndex; > + VOID *EventHobData; > + TCG_PCR_EVENT2 *TcgPcrEvent2; > + UINT8 *DigestBuffer; > + TDX_DIGEST_VALUE *TdxDigest; > + TPML_DIGEST_VALUES DigestList; > + UINT8 *Ptr; > + > + RtmrIndex =3D GetMappedRtmrIndex (PcrIndex); > + if (RtmrIndex =3D=3D INVALID_PCR2MR_INDEX) { > + return EFI_INVALID_PARAMETER; > + } > + > + DEBUG ((DEBUG_INFO, "Creating TdTcg2PcrEvent PCR[%d]/RTMR[%d] > EventType 0x%x\n", PcrIndex, RtmrIndex, EventType)); > + > + Status =3D HashAndExtend ( > + RtmrIndex, > + (VOID *)HashData, > + HashDataLen, > + &DigestList > + ); > + > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_INFO, "Failed to HashAndExtend. %r\n", Status)); > + return Status; > + } > + > + // > + // Use TDX_DIGEST_VALUE in the GUID HOB DataLength calculation > + // to reserve enough buffer to hold TPML_DIGEST_VALUES compact binary > + // which is limited to a SHA384 digest list > + // > + EventHobData =3D BuildGuidHob ( > + &gCcEventEntryHobGuid, > + sizeof (TcgPcrEvent2->PCRIndex) + sizeof (TcgPcrEvent= 2->EventType) > + > + sizeof (TDX_DIGEST_VALUE) + > + sizeof (TcgPcrEvent2->EventSize) + LogLen > + ); > + > + if (EventHobData =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + Ptr =3D (UINT8 *)EventHobData; > + // > + // Initialize PcrEvent data now > + // > + RtmrIndex++; > + CopyMem (Ptr, &RtmrIndex, sizeof (UINT32)); > + Ptr +=3D sizeof (UINT32); > + CopyMem (Ptr, &EventType, sizeof (TCG_EVENTTYPE)); > + Ptr +=3D sizeof (TCG_EVENTTYPE); > + > + DigestBuffer =3D Ptr; > + > + TdxDigest =3D (TDX_DIGEST_VALUE *)DigestBuffer; > + TdxDigest->count =3D 1; > + TdxDigest->hashAlg =3D TPM_ALG_SHA384; > + CopyMem ( > + TdxDigest->sha384, > + DigestList.digests[0].digest.sha384, > + SHA384_DIGEST_SIZE > + ); > + > + Ptr +=3D sizeof (TDX_DIGEST_VALUE); > + > + CopyMem (Ptr, &LogLen, sizeof (UINT32)); > + Ptr +=3D sizeof (UINT32); > + CopyMem (Ptr, EventLog, LogLen); > + Ptr +=3D LogLen; > + > + Status =3D EFI_SUCCESS; > + return Status; > +} > + > +/** > + Measure the Hoblist passed from the VMM. > + > + This function will create a unique GUID hob entry will be > + found from the TCG driver building the event log. > + This module will generate the measurement with the data in > + this hob, and log the event. > + > + @param[in] VmmHobList The Hoblist pass the firmware > + > + @retval EFI_SUCCESS Fv image is measured successfully > + or it has been already measured. > + @retval Others Other errors as indicated > +**/ > +EFI_STATUS > +EFIAPI > +MeasureHobList ( > + IN CONST VOID *VmmHobList > + ) > +{ > + EFI_PEI_HOB_POINTERS Hob; > + TDX_HANDOFF_TABLE_POINTERS2 HandoffTables; > + EFI_STATUS Status; > + > + if (!TdIsEnabled ()) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + Hob.Raw =3D (UINT8 *)VmmHobList; > + > + // > + // Parse the HOB list until end of list. > + // > + while (!END_OF_HOB_LIST (Hob)) { > + Hob.Raw =3D GET_NEXT_HOB (Hob); > + } > + > + // > + // Init the log event for HOB measurement > + // > + > + HandoffTables.TableDescriptionSize =3D sizeof > (HandoffTables.TableDescription); > + CopyMem (HandoffTables.TableDescription, HANDOFF_TABLE_DESC, sizeof > (HandoffTables.TableDescription)); > + HandoffTables.NumberOfTables =3D 1; > + CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), > &gUefiOvmfPkgTokenSpaceGuid); > + HandoffTables.TableEntry[0].VendorTable =3D (VOID *)VmmHobList; > + > + Status =3D TdxMeasureAndLogData ( > + 1, // PCRIndex > + EV_EFI_HANDOFF_TABLES2, // EventTyp= e > + (VOID *)&HandoffTables, // EventDat= a > + sizeof (HandoffTables), // EventSiz= e > + (UINT8 *)(UINTN)VmmHobList, // HashData > + (UINTN)((UINT8 *)Hob.Raw - (UINT8 *)VmmHobList) // HashData= Len > + ); > + > + if (EFI_ERROR (Status)) { > + ASSERT (FALSE); > + } > + > + return Status; > +} > + > +/** > + Check padding data all bit should be 1. > + > + @param[in] Buffer - A pointer to buffer header > + @param[in] BufferSize - Buffer size > + > + @retval TRUE - The padding data is valid. > + @retval TRUE - The padding data is invalid. > + > +**/ > +BOOLEAN > +CheckPaddingData ( > + IN UINT8 *Buffer, > + IN UINT32 BufferSize > + ) > +{ > + UINT32 index; > + > + for (index =3D 0; index < BufferSize; index++) { > + if (Buffer[index] !=3D 0xFF) { > + return FALSE; > + } > + } > + > + return TRUE; > +} > + > +/** > + Check the integrity of CFV data. > + > + @param[in] TdxCfvBase - A pointer to CFV header > + @param[in] TdxCfvSize - CFV data size > + > + @retval TRUE - The CFV data is valid. > + @retval FALSE - The CFV data is invalid. > + > +**/ > +BOOLEAN > +EFIAPI > +TdxValidateCfv ( > + IN UINT8 *TdxCfvBase, > + IN UINT32 TdxCfvSize > + ) > +{ > + UINT16 Checksum; > + UINTN VariableBase; > + UINT32 VariableOffset; > + UINT32 VariableOffsetBeforeAlign; > + EFI_FIRMWARE_VOLUME_HEADER *CfvFvHeader; > + VARIABLE_STORE_HEADER *CfvVariableStoreHeader; > + AUTHENTICATED_VARIABLE_HEADER *VariableHeader; > + > + static EFI_GUID FvHdrGUID =3D EFI_SYSTEM_NV_DATA_FV_GUID; > + static EFI_GUID VarStoreHdrGUID =3D EFI_AUTHENTICATED_VARIABLE_GUID; > + > + VariableOffset =3D 0; > + > + if (TdxCfvBase =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "TDX CFV: CFV pointer is NULL\n")); > + return FALSE; > + } > + > + // > + // Verify the header zerovetor, filesystemguid, > + // revision, signature, attributes, fvlength, checksum > + // HeaderLength cannot be an odd number > + // > + CfvFvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)TdxCfvBase; > + > + if ((!IsZeroBuffer (CfvFvHeader->ZeroVector, 16)) || > + (!CompareGuid (&FvHdrGUID, &CfvFvHeader->FileSystemGuid)) || > + (CfvFvHeader->Signature !=3D EFI_FVH_SIGNATURE) || > + (CfvFvHeader->Attributes !=3D 0x4feff) || > + (CfvFvHeader->Revision !=3D EFI_FVH_REVISION) || > + (CfvFvHeader->FvLength !=3D TdxCfvSize) > + ) > + { > + DEBUG ((DEBUG_ERROR, "TDX CFV: Basic FV headers were invalid\n")); > + return FALSE; > + } > + > + // > + // Verify the header checksum > + // > + Checksum =3D CalculateSum16 ((VOID *)CfvFvHeader, CfvFvHeader- > >HeaderLength); > + > + if (Checksum !=3D 0) { > + DEBUG ((DEBUG_ERROR, "TDX CFV: FV checksum was invalid\n")); > + return FALSE; > + } > + > + // > + // Verify the header signature, size, format, state > + // > + CfvVariableStoreHeader =3D (VARIABLE_STORE_HEADER *)(TdxCfvBase + > CfvFvHeader->HeaderLength); > + if ((!CompareGuid (&VarStoreHdrGUID, &CfvVariableStoreHeader->Signatur= e)) > || > + (CfvVariableStoreHeader->Format !=3D VARIABLE_STORE_FORMATTED) || > + (CfvVariableStoreHeader->State !=3D VARIABLE_STORE_HEALTHY) || > + (CfvVariableStoreHeader->Size > (CfvFvHeader->FvLength - CfvFvHead= er- > >HeaderLength)) || > + (CfvVariableStoreHeader->Size < sizeof (VARIABLE_STORE_HEADER)) > + ) > + { > + DEBUG ((DEBUG_ERROR, "TDX CFV: Variable Store header was invalid\n")= ); > + return FALSE; > + } > + > + // > + // Verify the header startId, state > + // Verify data to the end > + // > + VariableBase =3D (UINTN)TdxCfvBase + CfvFvHeader->HeaderLength + sizeo= f > (VARIABLE_STORE_HEADER); > + while (VariableOffset < (CfvVariableStoreHeader->Size - sizeof > (VARIABLE_STORE_HEADER))) { > + VariableHeader =3D (AUTHENTICATED_VARIABLE_HEADER *)(VariableBase + > VariableOffset); > + if (VariableHeader->StartId !=3D VARIABLE_DATA) { > + if (!CheckPaddingData ((UINT8 *)VariableHeader, CfvVariableStoreHe= ader- > >Size - sizeof (VARIABLE_STORE_HEADER) - VariableOffset)) { > + DEBUG ((DEBUG_ERROR, "TDX CFV: Variable header was invalid\n")); > + return FALSE; > + } > + > + VariableOffset =3D CfvVariableStoreHeader->Size - sizeof > (VARIABLE_STORE_HEADER); > + } else { > + if (!((VariableHeader->State =3D=3D VAR_IN_DELETED_TRANSITION) || > + (VariableHeader->State =3D=3D VAR_DELETED) || > + (VariableHeader->State =3D=3D VAR_HEADER_VALID_ONLY) || > + (VariableHeader->State =3D=3D VAR_ADDED))) > + { > + DEBUG ((DEBUG_ERROR, "TDX CFV: Variable header was invalid\n")); > + return FALSE; > + } > + > + VariableOffset +=3D sizeof (AUTHENTICATED_VARIABLE_HEADER) + > VariableHeader->NameSize + VariableHeader->DataSize; > + // Verify VariableOffset should be less than or equal > CfvVariableStoreHeader->Size - sizeof(VARIABLE_STORE_HEADER) > + if (VariableOffset > (CfvVariableStoreHeader->Size - sizeof > (VARIABLE_STORE_HEADER))) { > + DEBUG ((DEBUG_ERROR, "TDX CFV: Variable header was invalid\n")); > + return FALSE; > + } > + > + VariableOffsetBeforeAlign =3D VariableOffset; > + // 4 byte align > + VariableOffset =3D (VariableOffset + 3) & (UINTN)(~3); > + > + if (!CheckPaddingData ((UINT8 *)(VariableBase + VariableOffsetBefo= reAlign), > VariableOffset - VariableOffsetBeforeAlign)) { > + DEBUG ((DEBUG_ERROR, "TDX CFV: Variable header was invalid\n")); > + return FALSE; > + } > + } > + } > + > + return TRUE; > +} > + > +/** > + Get the FvName from the FV header. > + > + Causion: The FV is untrusted input. > + > + @param[in] FvBase Base address of FV image. > + @param[in] FvLength Length of FV image. > + > + @return FvName pointer > + @retval NULL FvName is NOT found > +**/ > +VOID * > +GetFvName ( > + IN EFI_PHYSICAL_ADDRESS FvBase, > + IN UINT64 FvLength > + ) > +{ > + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; > + EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader; > + > + if (FvBase >=3D MAX_ADDRESS) { > + return NULL; > + } > + > + if (FvLength >=3D MAX_ADDRESS - FvBase) { > + return NULL; > + } > + > + if (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) { > + return NULL; > + } > + > + FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase; > + if (FvHeader->ExtHeaderOffset < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) > { > + return NULL; > + } > + > + if (FvHeader->ExtHeaderOffset + sizeof > (EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) { > + return NULL; > + } > + > + FvExtHeader =3D (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + > FvHeader->ExtHeaderOffset); > + > + return &FvExtHeader->FvName; > +} > + > +/** > + Measure FV image. > + Add it into the measured FV list after the FV is measured successfully= . > + > + @param[in] FvBase Base address of FV image. > + @param[in] FvLength Length of FV image. > + @param[in] PcrIndex Index of PCR > + > + @retval EFI_SUCCESS Fv image is measured successfully > + or it has been already measured. > + @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. > + @retval EFI_DEVICE_ERROR The command was unsuccessful. > + > +**/ > +EFI_STATUS > +EFIAPI > +TdxMeasureCfvImage ( > + IN EFI_PHYSICAL_ADDRESS FvBase, > + IN UINT64 FvLength, > + IN UINT8 PcrIndex > + ) > +{ > + EFI_STATUS Status; > + FV_HANDOFF_TABLE_POINTERS2 FvBlob2; > + VOID *FvName; > + > + // > + // Init the log event for FV measurement > + // > + FvBlob2.BlobDescriptionSize =3D sizeof (FvBlob2.BlobDescription); > + CopyMem (FvBlob2.BlobDescription, FV_HANDOFF_TABLE_DESC, sizeof > (FvBlob2.BlobDescription)); > + FvName =3D GetFvName (FvBase, FvLength); > + if (FvName !=3D NULL) { > + AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof > (FvBlob2.BlobDescription), "Fv(%g)", FvName); > + } > + > + FvBlob2.BlobBase =3D FvBase; > + FvBlob2.BlobLength =3D FvLength; > + > + Status =3D TdxMeasureAndLogData ( > + 1, // PCRIndex > + EV_EFI_PLATFORM_FIRMWARE_BLOB2, // EventType > + (VOID *)&FvBlob2, // EventData > + sizeof (FvBlob2), // EventSize > + (UINT8 *)(UINTN)FvBase, // HashData > + (UINTN)(FvLength) // HashDataLen > + ); > + > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "The FV which failed to be measured starts at: > 0x%x\n", FvBase)); > + ASSERT (FALSE); > + } > + > + return Status; > +} > diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c > b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c > index 126eb74048f4..aea7f98da92d 100644 > --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c > +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c > @@ -133,11 +133,13 @@ PeilessStartup ( > UINT32 DxeCodeSize; > TD_RETURN_DATA TdReturnData; > VOID *VmmHobList; > + UINT8 *CfvBase; >=20 > Status =3D EFI_SUCCESS; > BootFv =3D NULL; > VmmHobList =3D NULL; > SecCoreData =3D (EFI_SEC_PEI_HAND_OFF *)Context; > + CfvBase =3D (UINT8 *)(UINTN)FixedPcdGet32 (PcdCfvBase); >=20 > ZeroMem (&PlatformInfoHob, sizeof (PlatformInfoHob)); >=20 > @@ -167,6 +169,34 @@ PeilessStartup ( >=20 > DEBUG ((DEBUG_INFO, "HobList: %p\n", GetHobList ())); >=20 > + if (TdIsEnabled ()) { > + // > + // Measure HobList > + // > + Status =3D MeasureHobList (VmmHobList); > + if (EFI_ERROR (Status)) { > + ASSERT (FALSE); > + CpuDeadLoop (); > + } > + > + // > + // Validate Tdx CFV > + // > + if (!TdxValidateCfv (CfvBase, FixedPcdGet32 (PcdCfvRawDataSize))) { > + ASSERT (FALSE); > + CpuDeadLoop (); > + } > + > + // > + // Measure Tdx CFV > + // > + Status =3D TdxMeasureCfvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)CfvBase, > FixedPcdGet32 (PcdCfvRawDataSize), 1); > + if (EFI_ERROR (Status)) { > + ASSERT (FALSE); > + CpuDeadLoop (); > + } > + } > + > // > // Initialize the Platform > // > diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h > b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h > index 23e9e0be53f1..2a100270ff20 100644 > --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h > +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h > @@ -52,4 +52,61 @@ EFIAPI > ConstructSecHobList ( > ); >=20 > +/** > + Measure the Hoblist passed from the VMM. > + > + This function will create a unique GUID hob entry will be > + found from the TCG driver building the event log. > + This module will generate the measurement with the data in > + this hob, and log the event. > + > + @param[in] VmmHobList The Hoblist pass the firmware > + > + @retval EFI_SUCCESS Fv image is measured successfully > + or it has been already measured. > + @retval Others Other errors as indicated > +**/ > +EFI_STATUS > +EFIAPI > +MeasureHobList ( > + IN CONST VOID *VmmHobList > + ); > + > +/** > + Check the integrity of CFV data. > + > + @param[in] TdxCfvBase - A pointer to CFV header > + @param[in] TdxCfvSize - CFV data size > + > + @retval TRUE - The CFV data is valid. > + @retval FALSE - The CFV data is invalid. > + > +**/ > +BOOLEAN > +EFIAPI > +TdxValidateCfv ( > + IN UINT8 *TdxCfvBase, > + IN UINT32 TdxCfvSize > + ); > + > +/** > + Measure FV image. > + Add it into the measured FV list after the FV is measured successfully= . > + > + @param[in] FvBase Base address of FV image. > + @param[in] FvLength Length of FV image. > + @param[in] PcrIndex Index of PCR > + > + @retval EFI_SUCCESS Fv image is measured successfully > + or it has been already measured. > + @retval Others Other errors as indicated > +**/ > +EFI_STATUS > +EFIAPI > +TdxMeasureCfvImage ( > + IN EFI_PHYSICAL_ADDRESS FvBase, > + IN UINT64 FvLength, > + IN UINT8 PcrIndex > + ); > + > #endif > diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf > b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf > index 8791984586a4..178b4c35d472 100644 > --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf > +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf > @@ -29,8 +29,7 @@ > PeilessStartup.c > Hob.c > DxeLoad.c > - > -[Sources.X64] > + IntelTdx.c > X64/VirtualMemory.c >=20 > [Packages] > @@ -39,6 +38,8 @@ > UefiCpuPkg/UefiCpuPkg.dec > OvmfPkg/OvmfPkg.dec > EmbeddedPkg/EmbeddedPkg.dec > + CryptoPkg/CryptoPkg.dec > + SecurityPkg/SecurityPkg.dec >=20 > [LibraryClasses] > BaseLib > @@ -56,6 +57,7 @@ > PrePiLib > QemuFwCfgLib > PlatformInitLib > + HashLib >=20 > [Guids] > gEfiHobMemoryAllocModuleGuid > @@ -63,6 +65,7 @@ > gUefiOvmfPkgPlatformInfoGuid > gEfiMemoryTypeInformationGuid > gPcdDataBaseHobGuid > + gCcEventEntryHobGuid >=20 > [Pcd] > gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase > -- > 2.29.2.windows.2