From nobody Wed Apr 24 20:16:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+80627+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+80627+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1631584664; cv=none; d=zohomail.com; s=zohoarc; b=J/a2oquaVm3u4vGo3fpwGfj77C+8A2padPhO1L3UALxtTLxEo05sXrkbYikzIT0FVrWn9fuwMHAYSIJwyOcOZVLjqsjoH+CmxGSA4jKsMMbP8p9QxPsGghvX9BCF8C09CNohkGs9/dYsAFfcl9MOulLvY4xzzeV53TVpOgZt/K4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1631584664; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=cM6dMfhj/GH1Rw9OtxwIW0D0ta6zVYvy1/7zKKJlDL8=; b=ErnQaXaKNneyVbCMgYVa/f3NFWLks2CYiaXiT3Oa2oMjAElAc5SVolO47RIXqf4SbOomw/Gtqj8yZyoBPOkeyPYZ8X2ZvQKY9Hy/FR7id+VG3svPNa1ilU+gNlEhw9vfFfabifGplTvKxyjwvokZSo7edYw2BrI+clxU8YwQj+8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+80627+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 16315846642271013.221511106925; Mon, 13 Sep 2021 18:57:44 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id uGBhYY1788612xt9SyjfOyvy; Mon, 13 Sep 2021 18:57:43 -0700 X-Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web09.4269.1631584662538995448 for ; Mon, 13 Sep 2021 18:57:43 -0700 X-IronPort-AV: E=McAfee;i="6200,9189,10106"; a="285538711" X-IronPort-AV: E=Sophos;i="5.85,291,1624345200"; d="scan'208";a="285538711" X-Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2021 18:57:42 -0700 X-IronPort-AV: E=Sophos;i="5.85,291,1624345200"; d="scan'208";a="552035349" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.249.169.243]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2021 18:57:39 -0700 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Michael D Kinney , Liming Gao , Zhiguang Liu , Jiewen Yao , Jian J Wang , Ken Lu Subject: [edk2-devel] [PATCH 1/2] MdePkg: Introduce TdProtocol for TD-Guest firmware Date: Tue, 14 Sep 2021 09:57:19 +0800 Message-Id: <29ffecfbc2a4076d9cb9fc40238548ab637c5f19.1631583583.git.min.m.xu@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: BAWKQypZlpM3Lw9X5KM2kkTBx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1631584663; bh=S4aEyXob0lqHBHbTG1n5+i/sFBOnRnQYI7hc/w071W4=; h=Cc:Date:From:Reply-To:Subject:To; b=sQwynVUskBNrzZ2zwQH0/bfFDqvao0m+NdeqvnmkhJXqSDUjEEf3WAP5CQUtuW0D+mP kUQ/HTDNXMdCKK90tJs1gO/rWloRyW1LvS9A1mimnjtYmDAA7z9TFID0RqgqJZ0bV56mr jyLn+JqDkrZeM2N7RHCsiJ9aSo00zsP8giw= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1631584665155100003 Content-Type: text/plain; charset="utf-8" BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3625 If TD-Guest firmware supports measurement and an event is created, TD-Guest firmware is designed to report the event log with the same data structure in TCG-Platform-Firmware-Profile specification with EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 format. The TD-Guest firmware supports measurement, the TD Guest Firmware is designed to produce EFI_TD_PROTOCOL with new GUID EFI_TD_PROTOCOL_GUID to report event log and provides hash capability. Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Jiewen Yao Cc: Jian J Wang Cc: Ken Lu Signed-off-by: Min Xu --- MdePkg/Include/Protocol/TdProtocol.h | 305 +++++++++++++++++++++++++++ MdePkg/MdePkg.dec | 3 + 2 files changed, 308 insertions(+) create mode 100644 MdePkg/Include/Protocol/TdProtocol.h diff --git a/MdePkg/Include/Protocol/TdProtocol.h b/MdePkg/Include/Protocol= /TdProtocol.h new file mode 100644 index 000000000000..5a015fca0079 --- /dev/null +++ b/MdePkg/Include/Protocol/TdProtocol.h @@ -0,0 +1,305 @@ +/** @file + If TD-Guest firmware supports measurement and an event is created, TD-Gu= est + firmware is designed to report the event log with the same data structure + in TCG-Platform-Firmware-Profile specification with + EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 format. + + The TD-Guest firmware supports measurement, the TD Guest Firmware is des= igned + to produce EFI_TD_PROTOCOL with new GUID EFI_TD_PROTOCOL_GUID to report + event log and provides hash capability. + +Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#ifndef TD_PROTOCOL_H_ +#define TD_PROTOCOL_H_ + +#include +#include +#include + + +#define EFI_TD_PROTOCOL_GUID \ + { 0x96751a3d, 0x72f4, 0x41a6, { 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae= , 0x6b }} +extern EFI_GUID gEfiTdProtocolGuid; + +typedef struct _EFI_TD_PROTOCOL EFI_TD_PROTOCOL; + +typedef struct { + UINT8 Major; + UINT8 Minor; +} EFI_TD_VERSION; + +typedef UINT32 EFI_TD_EVENT_LOG_BITMAP; +typedef UINT32 EFI_TD_EVENT_LOG_FORMAT; +typedef UINT32 EFI_TD_EVENT_ALGORITHM_BITMAP; +typedef UINT32 EFI_TD_MR_INDEX; + +#define EFI_TD_EVENT_LOG_FORMAT_TCG_2 0x00000002 +#define EFI_TD_BOOT_HASH_ALG_SHA384 0x00000004 + +// +// This bit is shall be set when an event shall be extended but not logged. +// +#define EFI_TD_FLAG_EXTEND_ONLY 0x0000000000000001 +// +// This bit shall be set when the intent is to measure a PE/COFF image. +// +#define EFI_TD_FLAG_PE_COFF_IMAGE 0x0000000000000010 + +#define MR_INDEX_MRTD 0 +#define MR_INDEX_RTMR0 1 +#define MR_INDEX_RTMR1 2 +#define MR_INDEX_RTMR2 3 +#define MR_INDEX_RTMR3 4 + +// +// This bit shall be set when the intent is to measure a PE/COFF image. +// +#define PE_COFF_IMAGE 0x0000000000000010 + +#pragma pack (1) + +#define EFI_TD_EVENT_HEADER_VERSION 1 + +typedef struct { + // + // Size of the event header itself (sizeof(EFI_TD_EVENT_HEADER)). + // + UINT32 HeaderSize; + // + // Header version. For this version of this specification, the value sha= ll be 1. + // + UINT16 HeaderVersion; + // + // Index of the MR that shall be extended. + // + EFI_TD_MR_INDEX MrIndex; + // + // Type of the event that shall be extended (and optionally logged). + // + UINT32 EventType; +} EFI_TD_EVENT_HEADER; + +typedef struct { + // + // Total size of the event including the Size component, the header and = the Event data. + // + UINT32 Size; + EFI_TD_EVENT_HEADER Header; + UINT8 Event[1]; +} EFI_TD_EVENT; + +#pragma pack() + + +typedef struct { + // + // Allocated size of the structure + // + UINT8 Size; + // + // Version of the EFI_TD_BOOT_SERVICE_CAPABILITY structure itself. + // For this version of the protocol, the Major version shall be set to 1 + // and the Minor version shall be set to 1. + // + EFI_TD_VERSION StructureVersion; + // + // Version of the EFI TD protocol. + // For this version of the protocol, the Major version shall be set to 1 + // and the Minor version shall be set to 1. + // + EFI_TD_VERSION ProtocolVersion; + // + // Supported hash algorithms + // + EFI_TD_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap; + // + // Bitmap of supported event log formats + // + EFI_TD_EVENT_LOG_BITMAP SupportedEventLogs; + + // + // False =3D TD not present + // + BOOLEAN TdPresentFlag; +} EFI_TD_BOOT_SERVICE_CAPABILITY; + +/** + The EFI_TD_PROTOCOL GetCapability function call provides protocol + capability information and state information. + + @param[in] This Indicates the calling context + @param[in, out] ProtocolCapability The caller allocates memory for a EFI= _TD_BOOT_SERVICE_CAPABILITY + structure and sets the size field to = the size of the structure allocated. + The callee fills in the fields with t= he EFI protocol capability information + and the current EFI TD state informat= ion up to the number of fields which + fit within the size of the structure = passed in. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_DEVICE_ERROR The command was unsuccessful. + The ProtocolCapability variable will not = be populated. + @retval EFI_INVALID_PARAMETER One or more of the parameters are incorre= ct. + The ProtocolCapability variable will not = be populated. + @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too sm= all to hold the full response. + It will be partially populated (required = Size field will be set). +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TD_GET_CAPABILITY) ( + IN EFI_TD_PROTOCOL *This, + IN OUT EFI_TD_BOOT_SERVICE_CAPABILITY *ProtocolCapability + ); + +/** + The EFI_TD_PROTOCOL Get Event Log function call allows a caller to + retrieve the address of a given event log and its last entry. + + @param[in] This Indicates the calling context + @param[in] EventLogFormat The type of the event log for which the i= nformation is requested. + @param[out] EventLogLocation A pointer to the memory address of the ev= ent log. + @param[out] EventLogLastEntry If the Event Log contains more than one e= ntry, this is a pointer to the + address of the start of the last entry in= the event log in memory. + @param[out] EventLogTruncated If the Event Log is missing at least one = entry because an event would + have exceeded the area allocated for even= ts, this value is set to TRUE. + Otherwise, the value will be FALSE and th= e Event Log will be complete. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_INVALID_PARAMETER One or more of the parameters are incorre= ct + (e.g. asking for an event log whose forma= t is not supported). +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TD_GET_EVENT_LOG) ( + IN EFI_TD_PROTOCOL *This, + IN EFI_TD_EVENT_LOG_FORMAT EventLogFormat, + OUT EFI_PHYSICAL_ADDRESS *EventLogLocation, + OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry, + OUT BOOLEAN *EventLogTruncated + ); + +/** + The EFI_TD_PROTOCOL HashLogExtendEvent function call provides callers wi= th + an opportunity to extend and optionally log events without requiring + knowledge of actual TD commands. + The extend operation will occur even if this function cannot create an e= vent + log entry (e.g. due to the event log being full). + + @param[in] This Indicates the calling context + @param[in] Flags Bitmap providing additional information. + @param[in] DataToHash Physical address of the start of the data= buffer to be hashed. + @param[in] DataToHashLen The length in bytes of the buffer referen= ced by DataToHash. + @param[in] EfiTdEvent Pointer to data buffer containing informa= tion about the event. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_DEVICE_ERROR The command was unsuccessful. + @retval EFI_VOLUME_FULL The extend operation occurred, but the ev= ent could not be written to one or more event logs. + @retval EFI_INVALID_PARAMETER One or more of the parameters are incorre= ct. + @retval EFI_UNSUPPORTED The PE/COFF image type is not supported. +**/ +typedef +EFI_STATUS +(EFIAPI * EFI_TD_HASH_LOG_EXTEND_EVENT) ( + IN EFI_TD_PROTOCOL *This, + IN UINT64 Flags, + IN EFI_PHYSICAL_ADDRESS DataToHash, + IN UINT64 DataToHashLen, + IN EFI_TD_EVENT *EfiTdEvent + ); + +/** + The EFI_TD_PROTOCOL MapPcrToMrIndex function call provides callers + the info on TPM PCR<-> measurement register mapping information. + + In current version, we use below mapping: + PCR0 -> MRTD (Index 0) + PCR1 -> RTMR0 (Index 1) + PCR2~6 -> RTMR1 (Index 2) + PCR7 -> RTMR0 (Index 1) + PCR8~15 -> RTMR2 (Index 3) + + @param[in] This Indicates the calling context + @param[in] PcrIndex TPM PCR index. + @param[out] MrIndex Measurement register index. + + @retval EFI_SUCCESS The MR index is returned. + @retval EFI_INVALID_PARAMETER The MrIndex is NULL. + @retval EFI_UNSUPPORTED The PcrIndex is invalid. +**/ +typedef +EFI_STATUS +(EFIAPI * EFI_TD_MAP_PCR_TO_MR_INDEX) ( + IN EFI_TD_PROTOCOL *This, + IN TCG_PCRINDEX PcrIndex, + OUT EFI_TD_MR_INDEX *MrIndex + ); + +struct _EFI_TD_PROTOCOL { + EFI_TD_GET_CAPABILITY GetCapability; + EFI_TD_GET_EVENT_LOG GetEventLog; + EFI_TD_HASH_LOG_EXTEND_EVENT HashLogExtendEvent; + EFI_TD_MAP_PCR_TO_MR_INDEX MapPcrToMrIndex; +}; + + +// +// TD event log +// + +#pragma pack(1) + +// +// Crypto Agile Log Entry Format. +// It is similar with TCG_PCR_EVENT2 except the field of MrIndex and PCRIn= dex. +// +typedef struct { + EFI_TD_MR_INDEX MrIndex; + UINT32 EventType; + TPML_DIGEST_VALUES Digests; + UINT32 EventSize; + UINT8 Event[1]; +} TD_EVENT; + +// +// EFI TD Event Header +// It is similar with TCG_PCR_EVENT2_HDR except the field of MrIndex and P= CRIndex +// +typedef struct { + EFI_TD_MR_INDEX MrIndex; + UINT32 EventType; + TPML_DIGEST_VALUES Digests; + UINT32 EventSize; +} TD_EVENT_HDR; + +#pragma pack() + +// +// Log entries after Get Event Log service +// + + +typedef struct { + // + // The version of this structure. It shall be set ot 1. + // + UINT64 Version; + // + // Number of events recorded after invocation of GetEventLog API + // + UINT64 NumberOfEvents; + // + // List of events of type TCG_TD_EVENT. + // + //TD_EVENT Event[1]; +} EFI_TD_FINAL_EVENTS_TABLE; + + +#define EFI_TD_FINAL_EVENTS_TABLE_GUID \ + {0xdd4a4648, 0x2de7, 0x4665, {0x96, 0x4d, 0x21, 0xd9, 0xef, 0x5f, 0xb4, = 0x46}} + +extern EFI_GUID gEfiTdFinalEventsTableGuid; + +#endif diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index a28a2daaffa8..2f48f6c40c1e 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -1008,6 +1008,9 @@ ## Include/Protocol/PcdInfo.h gGetPcdInfoProtocolGuid =3D { 0x5be40f57, 0xfa68, 0x4610, { 0xbb,= 0xbf, 0xe9, 0xc5, 0xfc, 0xda, 0xd3, 0x65 } } =20 + ## Include/Protocol/TdProtocol.h + gEfiTdProtocolGuid =3D { 0x96751a3d, 0x72f4, 0x41a6, { 0xa7,= 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b }} + # # Protocols defined in PI1.0. # --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#80627): https://edk2.groups.io/g/devel/message/80627 Mute This Topic: https://groups.io/mt/85592907/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed Apr 24 20:16:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+80628+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+80628+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1631584666; cv=none; d=zohomail.com; s=zohoarc; b=Y5EMahawyCxfwv7AOUUkGx6gcF/LRYHGTdjqALfr5KakgTTqqksuVVzU+rXf/l21z0gMZ6WVC6O+SmBwb+zqsU2uHsg8bhtkHlaJel4v1NkFEcrgBp+LGa3dbc55rISsbibSnxaPyEP97zdvAzlIB1JeQmFHt9LyasrcmD2j/+8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1631584666; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=GuMQbu94glfyce/tFOn8PteDfhujrdcFWyAKx4t5r8A=; b=C4Heyg4P0LOGL3FnfmW0keax7HzQm4j545vs1LyTIOt9/ovrEBetG4xsCNBte6WTqTLS7fj9pgGviaxa3+4HOhiOudlsmHZkPJRI6PdmV5hM+dabHA2p9ys6/B13P6X2wre4zDawyfJtMUzxzTZyzDs/LSUxKNlS1bqOceOHLEk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+80628+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1631584666000198.92866767787314; Mon, 13 Sep 2021 18:57:46 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id S8mgYY1788612xFmLHYXJQnL; Mon, 13 Sep 2021 18:57:45 -0700 X-Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web09.4269.1631584662538995448 for ; Mon, 13 Sep 2021 18:57:45 -0700 X-IronPort-AV: E=McAfee;i="6200,9189,10106"; a="285538720" X-IronPort-AV: E=Sophos;i="5.85,291,1624345200"; d="scan'208";a="285538720" X-Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2021 18:57:44 -0700 X-IronPort-AV: E=Sophos;i="5.85,291,1624345200"; d="scan'208";a="552035360" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.249.169.243]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2021 18:57:42 -0700 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH 2/2] SecurityPkg: Add DxeTdMeasureBootLib for TD measure boot Date: Tue, 14 Sep 2021 09:57:20 +0800 Message-Id: <52fb81451dcd25c3a51edb6306cb76890169b87d.1631583583.git.min.m.xu@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: 282vvcqmVywOuUrl8qDV2LhFx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1631584665; bh=KgZcJH5AOtxjAbOiE54vXfvZgRgVoAzhs4W8X+W3S3Y=; h=Cc:Date:From:Reply-To:Subject:To; b=X6tNlxqQTQ8x8U8TNdUUpF+WvtA2q1mLLjSZRqrhQ1UjxHwGcVYC+iO7tHx8Z6UCMNQ jIYicrm2LuOM93ECQxugjYzbBxlKejGspFu5UnPsV2v0jDyAjgvACadkTKVhLpS/asWRf QC/mPP0DufReTQA4aypqAs+UUwmdBILxxp4= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1631584667277100010 Content-Type: text/plain; charset="utf-8" BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3625 The library instance provides security service of TD measure boot. DxeTdMeasureBootLibImageRead() function will make sure the PE/COFF image co= ntent read is within the image buffer. TdMeasurePeImage() function will accept untrusted PE/COFF image and validat= e its data structure within this image buffer before use. TdMeasureGptTable() function will receive untrusted GPT partition table, an= d parse partition data carefully. Cc: Jiewen Yao Cc: Jian J Wang Signed-off-by: Min Xu --- .../DxeTdMeasureBootLib/DxeTdMeasureBootLib.c | 688 ++++++++++++++++++ .../DxeTdMeasureBootLib.inf | 61 ++ .../DxeTdMeasureBootLib.uni | 21 + SecurityPkg/SecurityPkg.dsc | 5 + 4 files changed, 775 insertions(+) create mode 100644 SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBoo= tLib.c create mode 100644 SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBoo= tLib.inf create mode 100644 SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBoo= tLib.uni diff --git a/SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.c = b/SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.c new file mode 100644 index 000000000000..797925fb6888 --- /dev/null +++ b/SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.c @@ -0,0 +1,688 @@ +/** @file + The library instance provides security service of TD measure boot. + + Caution: This file requires additional review when modified. + This library will have external input - PE/COFF image and GPT partition. + This external input must be validated carefully to avoid security issue = like + buffer overflow, integer overflow. + + DxeTdMeasureBootLibImageRead() function will make sure the PE/COFF image= content + read is within the image buffer. + + TdMeasurePeImage() function will accept untrusted PE/COFF image and vali= date its + data structure within this image buffer before use. + + TdMeasureGptTable() function will receive untrusted GPT partition table,= and parse + partition data carefully. + + Copyright (c) 2021, 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 +#include +#include +#include + +// +// Flag to check GPT partition. It only need be measured once. +// +BOOLEAN mTdMeasureGptTableFlag =3D FALSE; +UINTN mTdMeasureGptCount =3D 0; +VOID *mTdFileBuffer; +UINTN mTdImageSize; +// +// Measured FV handle cache +// +EFI_HANDLE mTdCacheMeasuredHandle =3D NULL; +MEASURED_HOB_DATA *mTdMeasuredHobData =3D NULL; + +/** + Reads contents of a PE/COFF image in memory buffer. + + Caution: This function may receive untrusted input. + PE/COFF image is external input, so this function will make sure the PE/= COFF image content + read is within the image buffer. + + @param FileHandle Pointer to the file handle to read the PE/COFF i= mage. + @param FileOffset Offset into the PE/COFF image to begin the read = operation. + @param ReadSize On input, the size in bytes of the requested rea= d operation. + On output, the number of bytes actually read. + @param Buffer Output buffer that contains the data read from t= he PE/COFF image. + + @retval EFI_SUCCESS The specified portion of the PE/COFF image was r= ead and the size +**/ +EFI_STATUS +EFIAPI +DxeTdMeasureBootLibImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ) +{ + UINTN EndPosition; + + if (FileHandle =3D=3D NULL || ReadSize =3D=3D NULL || Buffer =3D=3D NULL= ) { + return EFI_INVALID_PARAMETER; + } + + if (MAX_ADDRESS - FileOffset < *ReadSize) { + return EFI_INVALID_PARAMETER; + } + + EndPosition =3D FileOffset + *ReadSize; + if (EndPosition > mTdImageSize) { + *ReadSize =3D (UINT32)(mTdImageSize - FileOffset); + } + + if (FileOffset >=3D mTdImageSize) { + *ReadSize =3D 0; + } + + CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize); + + return EFI_SUCCESS; +} + +/** + Measure GPT table data into TD Event log. + + Caution: This function may receive untrusted input. + The GPT partition table is external input, so this function should parse= partition data carefully. + + @param TdProtocol Pointer to the located TD protocol instan= ce. + @param GptHandle Handle that GPT partition was installed. + + @retval EFI_SUCCESS Successfully measure GPT table. + @retval EFI_UNSUPPORTED Not support GPT table on the given handle. + @retval EFI_DEVICE_ERROR Can't get GPT table because device error. + @retval EFI_OUT_OF_RESOURCES No enough resource to measure GPT table. + @retval other error value +**/ +EFI_STATUS +EFIAPI +TdMeasureGptTable ( + IN EFI_TD_PROTOCOL *TdProtocol, + IN EFI_HANDLE GptHandle + ) +{ + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_PARTITION_TABLE_HEADER *PrimaryHeader; + EFI_PARTITION_ENTRY *PartitionEntry; + UINT8 *EntryPtr; + UINTN NumberOfPartition; + UINT32 Index; + EFI_TD_EVENT *TdEvent; + EFI_GPT_DATA *GptData; + UINT32 EventSize; + + if (mTdMeasureGptCount > 0) { + return EFI_SUCCESS; + } + + Status =3D gBS->HandleProtocol (GptHandle, &gEfiBlockIoProtocolGuid, (VO= ID**)&BlockIo); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + Status =3D gBS->HandleProtocol (GptHandle, &gEfiDiskIoProtocolGuid, (VOI= D**)&DiskIo); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + // + // Read the EFI Partition Table Header + // + PrimaryHeader =3D (EFI_PARTITION_TABLE_HEADER *) AllocatePool (BlockIo->= Media->BlockSize); + if (PrimaryHeader =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status =3D DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + 1 * BlockIo->Media->BlockSize, + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to Read Partition Table Header!\n")); + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; + } + // + // Read the partition entry. + // + EntryPtr =3D (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntr= ies * PrimaryHeader->SizeOfPartitionEntry); + if (EntryPtr =3D=3D NULL) { + FreePool (PrimaryHeader); + return EFI_OUT_OF_RESOURCES; + } + Status =3D DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockIo-= >Media->BlockSize), + PrimaryHeader->NumberOfPartitionEntries * PrimaryHead= er->SizeOfPartitionEntry, + EntryPtr + ); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + FreePool (EntryPtr); + return EFI_DEVICE_ERROR; + } + + // + // Count the valid partition + // + PartitionEntry =3D (EFI_PARTITION_ENTRY *)EntryPtr; + NumberOfPartition =3D 0; + for (Index =3D 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index= ++) { + if (!IsZeroGuid (&PartitionEntry->PartitionTypeGUID)) { + NumberOfPartition++; + } + PartitionEntry =3D (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + P= rimaryHeader->SizeOfPartitionEntry); + } + + // + // Prepare Data for Measurement + // + EventSize =3D (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitio= ns) + + NumberOfPartition * PrimaryHeader->SizeOfPartiti= onEntry); + TdEvent =3D (EFI_TD_EVENT *) AllocateZeroPool (EventSize + sizeof (EFI_T= D_EVENT) - sizeof(TdEvent->Event)); + if (TdEvent =3D=3D NULL) { + FreePool (PrimaryHeader); + FreePool (EntryPtr); + return EFI_OUT_OF_RESOURCES; + } + + TdEvent->Size =3D EventSize + sizeof (EFI_TD_EVENT) - sizeof(TdEvent->Ev= ent); + TdEvent->Header.HeaderSize =3D sizeof(EFI_TD_EVENT_HEADER); + TdEvent->Header.HeaderVersion =3D EFI_TD_EVENT_HEADER_VERSION; + TdEvent->Header.MrIndex =3D 1; + TdEvent->Header.EventType =3D EV_EFI_GPT_EVENT; + GptData =3D (EFI_GPT_DATA *) TdEvent->Event; + + // + // Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition + // + CopyMem ((UINT8 *)GptData, (UINT8*)PrimaryHeader, sizeof (EFI_PARTITION_= TABLE_HEADER)); + GptData->NumberOfPartitions =3D NumberOfPartition; + // + // Copy the valid partition entry + // + PartitionEntry =3D (EFI_PARTITION_ENTRY*)EntryPtr; + NumberOfPartition =3D 0; + for (Index =3D 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index= ++) { + if (!IsZeroGuid (&PartitionEntry->PartitionTypeGUID)) { + CopyMem ( + (UINT8 *)&GptData->Partitions + NumberOfPartition * PrimaryHeader-= >SizeOfPartitionEntry, + (UINT8 *)PartitionEntry, + PrimaryHeader->SizeOfPartitionEntry + ); + NumberOfPartition++; + } + PartitionEntry =3D(EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + Pr= imaryHeader->SizeOfPartitionEntry); + } + + // + // Measure the GPT data + // + Status =3D TdProtocol->HashLogExtendEvent ( + TdProtocol, + 0, + (EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) GptData, + (UINT64) EventSize, + TdEvent + ); + if (!EFI_ERROR (Status)) { + mTdMeasureGptCount++; + } + + FreePool (PrimaryHeader); + FreePool (EntryPtr); + FreePool (TdEvent); + + return Status; +} + +/** + Measure PE image into TD log based on the authenticode image hashing in + PE/COFF Specification 8.0 Appendix A. + + Caution: This function may receive untrusted input. + PE/COFF image is external input, so this function will validate its data= structure + within this image buffer before use. + + @param[in] TdProtocol Pointer to the located TD protocol instance. + @param[in] ImageAddress Start address of image buffer. + @param[in] ImageSize Image size + @param[in] LinkTimeBase Address that the image is loaded into memory. + @param[in] ImageType Image subsystem type. + @param[in] FilePath File path is corresponding to the input image. + + @retval EFI_SUCCESS Successfully measure image. + @retval EFI_OUT_OF_RESOURCES No enough resource to measure image. + @retval EFI_UNSUPPORTED ImageType is unsupported or PE image is m= al-format. + @retval other error value + +**/ +EFI_STATUS +EFIAPI +TdMeasurePeImage ( + IN EFI_TD_PROTOCOL *TdProtocol, + IN EFI_PHYSICAL_ADDRESS ImageAddress, + IN UINTN ImageSize, + IN UINTN LinkTimeBase, + IN UINT16 ImageType, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ) +{ + EFI_STATUS Status; + EFI_TD_EVENT *TdEvent; + EFI_IMAGE_LOAD_EVENT *ImageLoad; + UINT32 FilePathSize; + UINT32 EventSize; + + Status =3D EFI_UNSUPPORTED; + ImageLoad =3D NULL; + FilePathSize =3D (UINT32) GetDevicePathSize (FilePath); + + // + // Determine destination PCR by BootPolicy + // + EventSize =3D sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + Fil= ePathSize; + TdEvent =3D AllocateZeroPool (EventSize + sizeof (EFI_TD_EVENT) - sizeof= (TdEvent->Event)); + if (TdEvent =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + TdEvent->Size =3D EventSize + sizeof (EFI_TD_EVENT) - sizeof(TdEvent->Ev= ent); + TdEvent->Header.HeaderSize =3D sizeof(EFI_TD_EVENT_HEADER); + TdEvent->Header.HeaderVersion =3D EFI_TD_EVENT_HEADER_VERSION; + ImageLoad =3D (EFI_IMAGE_LOAD_EVENT *) TdEvent->Event; + + switch (ImageType) { + case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION: + TdEvent->Header.EventType =3D EV_EFI_BOOT_SERVICES_APPLICATION; + TdEvent->Header.MrIndex =3D 1; + break; + case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: + TdEvent->Header.EventType =3D EV_EFI_BOOT_SERVICES_DRIVER; + TdEvent->Header.MrIndex =3D 1; + break; + case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: + TdEvent->Header.EventType =3D EV_EFI_RUNTIME_SERVICES_DRIVER; + TdEvent->Header.MrIndex =3D 1; + break; + default: + DEBUG (( + DEBUG_ERROR, + "TdMeasurePeImage: Unknown subsystem type %d", + ImageType + )); + goto Finish; + } + + ImageLoad->ImageLocationInMemory =3D ImageAddress; + ImageLoad->ImageLengthInMemory =3D ImageSize; + ImageLoad->ImageLinkTimeAddress =3D LinkTimeBase; + ImageLoad->LengthOfDevicePath =3D FilePathSize; + if ((FilePath !=3D NULL) && (FilePathSize !=3D 0)) { + CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize); + } + + // + // Log the PE data + // + Status =3D TdProtocol->HashLogExtendEvent ( + TdProtocol, + PE_COFF_IMAGE, + ImageAddress, + ImageSize, + TdEvent + ); + if (Status =3D=3D EFI_VOLUME_FULL) { + // + // Volume full here means the image is hashed and its result is extend= ed to PCR. + // But the event log can't be saved since log area is full. + // Just return EFI_SUCCESS in order not to block the image load. + // + Status =3D EFI_SUCCESS; + } + +Finish: + FreePool (TdEvent); + + return Status; +} + +/** + The security handler is used to abstract platform-specific policy + from the DXE core response to an attempt to use a file that returns a + given status for the authentication check from the section extraction pr= otocol. + + The possible responses in a given SAP implementation may include locking + flash upon failure to authenticate, attestation logging for all signed d= rivers, + and other exception operations. The File parameter allows for possible = logging + within the SAP of the driver. + + If the file specified by File with an authentication status specified by + AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS i= s returned. + + If the file specified by File with an authentication status specified by + AuthenticationStatus is not safe for the DXE Core to use under any circu= mstances, + then EFI_ACCESS_DENIED is returned. + + If the file specified by File with an authentication status specified by + AuthenticationStatus is not safe for the DXE Core to use right now, but = it + might be possible to use it at a future time, then EFI_SECURITY_VIOLATIO= N is + returned. + + If check image specified by FileBuffer and File is NULL meanwhile, retur= n EFI_ACCESS_DENIED. + + @param[in] AuthenticationStatus This is the authentication status = returned + from the securitymeasurement servi= ces for the + input file. + @param[in] File This is a pointer to the device path of the f= ile that is + being dispatched. This will optionally be use= d for logging. + @param[in] FileBuffer File buffer matches the input file device pat= h. + @param[in] FileSize Size of File buffer matches the input file de= vice path. + @param[in] BootPolicy A boot policy that was used to call LoadImage= () UEFI service. + + @retval EFI_SUCCESS The file specified by DevicePath and non= -NULL + FileBuffer did authenticate, and the pla= tform policy dictates + that the DXE Foundation may use the file. + @retval other error value +**/ +EFI_STATUS +EFIAPI +DxeTdMeasureBootHandler ( + IN UINT32 AuthenticationStatus, + IN CONST EFI_DEVICE_PATH_PROTOCOL *File, OPTIONAL + IN VOID *FileBuffer, + IN UINTN FileSize, + IN BOOLEAN BootPolicy + ) +{ + EFI_TD_PROTOCOL *TdProtocol; + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; + EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode; + EFI_HANDLE Handle; + EFI_HANDLE TempHandle; + BOOLEAN ApplicationRequired; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol; + EFI_PHYSICAL_ADDRESS FvAddress; + UINT32 Index; + + Status =3D gBS->LocateProtocol (&gEfiTdProtocolGuid, NULL, (VOID **) &Td= Protocol); + if (EFI_ERROR (Status)) { + // + // TD protocol is not installed. So, TD is not present. + // Don't do any measurement, and directly return EFI_SUCCESS. + // + DEBUG ((DEBUG_VERBOSE, "DxeTdMeasureBootHandler - TD - %r\n", Status)); + return EFI_SUCCESS; + } + + // + // Copy File Device Path + // + OrigDevicePathNode =3D DuplicateDevicePath (File); + + // + // 1. Check whether this device path support BlockIo protocol. + // Is so, this device path may be a GPT device path. + // + DevicePathNode =3D OrigDevicePathNode; + Status =3D gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathN= ode, &Handle); + if (!EFI_ERROR (Status) && !mTdMeasureGptTableFlag) { + // + // Find the gpt partition on the given devicepath + // + DevicePathNode =3D OrigDevicePathNode; + ASSERT (DevicePathNode !=3D NULL); + while (!IsDevicePathEnd (DevicePathNode)) { + // + // Find the Gpt partition + // + if (DevicePathType (DevicePathNode) =3D=3D MEDIA_DEVICE_PATH && + DevicePathSubType (DevicePathNode) =3D=3D MEDIA_HARDDRIVE_DP) { + // + // Check whether it is a gpt partition or not + // + if (((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->MBRType =3D=3D MBR= _TYPE_EFI_PARTITION_TABLE_HEADER && + ((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->SignatureType =3D= =3D SIGNATURE_TYPE_GUID) { + + // + // Change the partition device path to its parent device path (d= isk) and get the handle. + // + DevicePathNode->Type =3D END_DEVICE_PATH_TYPE; + DevicePathNode->SubType =3D END_ENTIRE_DEVICE_PATH_SUBTYPE; + DevicePathNode =3D OrigDevicePathNode; + Status =3D gBS->LocateDevicePath ( + &gEfiDiskIoProtocolGuid, + &DevicePathNode, + &Handle + ); + if (!EFI_ERROR (Status)) { + // + // Measure GPT disk. + // + Status =3D TdMeasureGptTable (TdProtocol, Handle); + DEBUG ((DEBUG_INFO, "DxeTdMeasureBootHandler - TdMeasureGptTab= le - %r\n", Status)); + if (!EFI_ERROR (Status)) { + // + // GPT disk check done. + // + mTdMeasureGptTableFlag =3D TRUE; + } + } + FreePool (OrigDevicePathNode); + OrigDevicePathNode =3D DuplicateDevicePath (File); + ASSERT (OrigDevicePathNode !=3D NULL); + break; + } + } + DevicePathNode =3D NextDevicePathNode (DevicePathNode); + } + } + + // + // 2. Measure PE image. + // + ApplicationRequired =3D FALSE; + + // + // Check whether this device path support FVB protocol. + // + DevicePathNode =3D OrigDevicePathNode; + Status =3D gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, = &DevicePathNode, &Handle); + if (!EFI_ERROR (Status)) { + // + // Don't check FV image, and directly return EFI_SUCCESS. + // It can be extended to the specific FV authentication according to t= he different requirement. + // + if (IsDevicePathEnd (DevicePathNode)) { + return EFI_SUCCESS; + } + // + // The PE image from unmeasured Firmware volume need be measured + // The PE image from measured Firmware volume will be measured accordi= ng to policy below. + // If it is driver, do not measure + // If it is application, still measure. + // + ApplicationRequired =3D TRUE; + + if (mTdCacheMeasuredHandle !=3D Handle && mTdMeasuredHobData !=3D NULL= ) { + // + // Search for Root FV of this PE image + // + TempHandle =3D Handle; + do { + Status =3D gBS->HandleProtocol( + TempHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID**)&FvbProtocol + ); + TempHandle =3D FvbProtocol->ParentHandle; + } while (!EFI_ERROR(Status) && FvbProtocol->ParentHandle !=3D NULL); + + // + // Search in measured FV Hob + // + Status =3D FvbProtocol->GetPhysicalAddress(FvbProtocol, &FvAddress); + if (EFI_ERROR(Status)){ + return Status; + } + + ApplicationRequired =3D FALSE; + + for (Index =3D 0; Index < mTdMeasuredHobData->Num; Index++) { + if(mTdMeasuredHobData->MeasuredFvBuf[Index].BlobBase =3D=3D FvAddr= ess) { + // + // Cache measured FV for next measurement + // + mTdCacheMeasuredHandle =3D Handle; + ApplicationRequired =3D TRUE; + break; + } + } + } + } + + // + // File is not found. + // + if (FileBuffer =3D=3D NULL) { + Status =3D EFI_SECURITY_VIOLATION; + goto Finish; + } + + mTdImageSize =3D FileSize; + mTdFileBuffer =3D FileBuffer; + + // + // Measure PE Image + // + DevicePathNode =3D OrigDevicePathNode; + ZeroMem (&ImageContext, sizeof (ImageContext)); + ImageContext.Handle =3D (VOID *) FileBuffer; + ImageContext.ImageRead =3D (PE_COFF_LOADER_READ_FILE) DxeTdMeasureBootLi= bImageRead; + + // + // Get information about the image being loaded + // + Status =3D PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + // + // Check for invalid parameters. + // + if (File =3D=3D NULL) { + Status =3D EFI_ACCESS_DENIED; + } + + // + // The information can't be got from the invalid PeImage + // + goto Finish; + } + + // + // Measure only application if Application flag is set + // Measure drivers and applications if Application flag is not set + // + if ((!ApplicationRequired) || + (ApplicationRequired && ImageContext.ImageType =3D=3D EFI_IMAGE_SU= BSYSTEM_EFI_APPLICATION)) { + // + // Print the image path to be measured. + // + DEBUG_CODE_BEGIN (); + CHAR16 *ToText; + ToText =3D ConvertDevicePathToText ( + DevicePathNode, + FALSE, + TRUE + ); + if (ToText !=3D NULL) { + DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText)); + FreePool (ToText); + } + DEBUG_CODE_END (); + + // + // Measure PE image into TD log. + // + Status =3D TdMeasurePeImage ( + TdProtocol, + (EFI_PHYSICAL_ADDRESS) (UINTN) FileBuffer, + FileSize, + (UINTN) ImageContext.ImageAddress, + ImageContext.ImageType, + DevicePathNode + ); + DEBUG ((DEBUG_INFO, "DxeTdMeasureBootHandler - TdMeasurePeImage - %r\n= ", Status)); + } + + // + // Done, free the allocated resource. + // +Finish: + if (OrigDevicePathNode !=3D NULL) { + FreePool (OrigDevicePathNode); + } + + DEBUG ((DEBUG_INFO, "DxeTdMeasureBootHandler - %r\n", Status)); + + return Status; +} + +/** + Register the security handler to provide TD measure boot service. + + @param ImageHandle ImageHandle of the loaded driver. + @param SystemTable Pointer to the EFI System Table. + + @retval EFI_SUCCESS Register successfully. + @retval EFI_OUT_OF_RESOURCES No enough memory to register this handle= r. +**/ +EFI_STATUS +EFIAPI +DxeTdMeasureBootLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob =3D NULL; + + GuidHob =3D GetFirstGuidHob (&gMeasuredFvHobGuid); + + if (GuidHob !=3D NULL) { + mTdMeasuredHobData =3D GET_GUID_HOB_DATA (GuidHob); + } + + return RegisterSecurity2Handler ( + DxeTdMeasureBootHandler, + EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQU= IRED + ); +} diff --git a/SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.in= f b/SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.inf new file mode 100644 index 000000000000..defe2857749d --- /dev/null +++ b/SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.inf @@ -0,0 +1,61 @@ +## @file +# Provides security service for TD measured boot +# +# This library instance hooks LoadImage() API to measure every image that +# is not measured in PEI phase. And, it will also measure GPT partition. +# +# Caution: This module requires additional review when modified. +# This library will have external input - PE/COFF image and GPT partition. +# This external input must be validated carefully to avoid security issue= s such +# as buffer overflow or integer overflow. +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeTdMeasureBootLib + MODULE_UNI_FILE =3D DxeTdMeasureBootLib.uni + FILE_GUID =3D 5ECEEF3F-05ED-4BC8-B027-A6AD182BE2F3 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D NULL|DXE_DRIVER DXE_RUNTIME_DRIVER DX= E_SAL_DRIVER UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR =3D DxeTdMeasureBootLibConstructor + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D X64 +# + +[Sources] + DxeTdMeasureBootLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + CryptoPkg/CryptoPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + MemoryAllocationLib + DevicePathLib + UefiBootServicesTableLib + BaseCryptLib + PeCoffLib + BaseLib + SecurityManagementLib + HobLib + +[Guids] + gMeasuredFvHobGuid ## SOMETIMES_CONSUMES ## HOB + +[Protocols] + gEfiTdProtocolGuid ## SOMETIMES_CONSUMES + gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES diff --git a/SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.un= i b/SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.uni new file mode 100644 index 000000000000..65769e91127c --- /dev/null +++ b/SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.uni @@ -0,0 +1,21 @@ +// /** @file +// Provides security service for TD measured boot +// +// This library instance hooks LoadImage() API to measure every image that +// is not measured in PEI phase. And, it will also measure GPT partition. +// +// Caution: This module requires additional review when modified. +// This library will have external input - PE/COFF image and GPT partition. +// This external input must be validated carefully to avoid security issue= s such +// as buffer overflow or integer overflow. +// +// Copyright (c) 2021, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Provides security= service for TD measured boot" + +#string STR_MODULE_DESCRIPTION #language en-US "This library inst= ance hooks LoadImage() API to measure every image that is not measured in P= EI phase. And, it will also measure GPT partition. Caution: This module req= uires additional review when modified. This library will have external inpu= t - PE/COFF image and GPT partition. This external input must be validated = carefully to avoid security issues such as buffer overflow or integer overf= low." diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index f1f678c492b3..8d8b6a38b1e4 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -218,6 +218,11 @@ SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLi= b.inf SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLi= b.inf =20 + # + # TD + # + SecurityPkg/Library/DxeTdMeasureBootLib/DxeTdMeasureBootLib.inf + SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.i= nf SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.i= nf =20 --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#80628): https://edk2.groups.io/g/devel/message/80628 Mute This Topic: https://groups.io/mt/85592908/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-