From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web10.860.1573108700153983091 for ; Wed, 06 Nov 2019 22:38:20 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.88, mailfrom: ray.ni@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Nov 2019 22:38:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,277,1569308400"; d="scan'208";a="377327810" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by orsmga005.jf.intel.com with ESMTP; 06 Nov 2019 22:38:18 -0800 Received: from fmsmsx113.amr.corp.intel.com (10.18.116.7) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 6 Nov 2019 22:38:18 -0800 Received: from shsmsx105.ccr.corp.intel.com (10.239.4.158) by FMSMSX113.amr.corp.intel.com (10.18.116.7) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 6 Nov 2019 22:38:18 -0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.127]) by SHSMSX105.ccr.corp.intel.com ([169.254.11.225]) with mapi id 14.03.0439.000; Thu, 7 Nov 2019 14:38:15 +0800 From: "Ni, Ray" To: "Yao, Jiewen" , "devel@edk2.groups.io" CC: "Chaganty, Rangasai V" , "Lou, Yun" Subject: Re: [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity. Thread-Topic: [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity. Thread-Index: AQHVj+ctCxwFyeTmi0ujvLYGeHzbDKd/RbIA Date: Thu, 7 Nov 2019 06:38:15 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C352E68@SHSMSX104.ccr.corp.intel.com> References: <20191031123127.10900-1-jiewen.yao@intel.com> <20191031123127.10900-5-jiewen.yao@intel.com> In-Reply-To: <20191031123127.10900-5-jiewen.yao@intel.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: ray.ni@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable 1. Can you make the macro short? EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED -> EDKII_DEVICE_MEASUREMENT_RE= QUIRED EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED -> EDKII_DEVICE_AUTHENTICAT= ION_REQUIRED 2. It looks a bit strange to me that DeviceSecurityPolicy protocol not only= contains API to return the platform policy for each device but also saves the security state for each device. "Sec= urity state" is not a policy but a state. I went back to check the design foils @ https://edk2.groups.io/g/devel/= files/Designs/2019/1018/EDKII-Device%20Firmware%20Security.pdf Now I understand the SetDeviceState() is used to give platform a chance= to disable the device in a platform specific way. Then how about rename the API to NotifyDeviceState? But I still don't understand why the device state needs to be passed in= to the SetDeviceState() by reference. Do you expect platform to change the device state? I thought making it = read-only to platform is easy to understand. Looking deep to the code and I guess you expect the EDKII_DEVICE_SECURI= TY_STATE_ERROR_UEFI_UNSUPPORTED is passed to platform and platform can reset this status to 0 to inform= this driver ignore such error. Can you please add comments to patch 2/6 to explain clearly what SetDev= iceState() needs to do? 3. Can you refine below debug message so that platform developers when they= see these debug messages can easily understand these debug messages are for device security features? I suggest you co= mbine them into one line and with "DeviceSecurity" keyword in the beginning of the message. "one line" is just a recommend= ation but "DeviceSecurity" keyword is what I really need. With that, debug messages are also helpful to platform developers, not = just helpful to feature developers. DEBUG((DEBUG_INFO, " CapId - 0x%04x\n", DvSecHdr.CapId)); DEBUG((DEBUG_INFO, " CapVersion - 0x%01x\n", DvSecHdr.CapVersion)); DEBUG((DEBUG_INFO, " NextOffset - 0x%03x\n", DvSecHdr.NextOffset)); DEBUG((DEBUG_INFO, " DvSecVendorId - 0x%04x\n", DvSecHdr.DvSecVendorId))= ; DEBUG((DEBUG_INFO, " DvSecRevision - 0x%01x\n", DvSecHdr.DvSecRevision))= ; DEBUG((DEBUG_INFO, " DvSecLength - 0x%03x\n", DvSecHdr.DvSecLength)); DEBUG((DEBUG_INFO, " DvSecId - 0x%04x\n", DvSecHdr.DvSecId)); > -----Original Message----- > From: Yao, Jiewen > Sent: Thursday, October 31, 2019 8:31 PM > To: devel@edk2.groups.io > Cc: Ni, Ray ; Chaganty, Rangasai V > ; Lou, Yun > Subject: [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add > PciSecurity. >=20 > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2303 >=20 > This driver is to do the PCI device authentication based upon Intel PCIe > Security Specification. >=20 > Cc: Ray Ni > Cc: Rangasai V Chaganty > Cc: Yun Lou > Signed-off-by: Jiewen Yao > Signed-off-by: Yun Lou > --- >=20 > Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurity= Dxe > /IntelPciDeviceSecurityDxe.c | 701 ++++++++++++++++++++ >=20 > Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurity= Dxe > /IntelPciDeviceSecurityDxe.inf | 45 ++ >=20 > Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurity= Dxe > /TcgDeviceEvent.h | 193 ++++++ > 3 files changed, 939 insertions(+) >=20 > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecuri= tyDx > e/IntelPciDeviceSecurityDxe.c > b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecuri= tyD > xe/IntelPciDeviceSecurityDxe.c > new file mode 100644 > index 0000000000..f1859c2715 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceS > +++ ecurityDxe/IntelPciDeviceSecurityDxe.c > @@ -0,0 +1,701 @@ > +/** @file > + EDKII Device Security library for PCI device. > + It follows the Intel PCIe Security Specification. > + > +Copyright (c) 2019, 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 "TcgDeviceEvent.h" > + > +typedef struct { > + UINT8 Measurement[SHA512_D= IGEST_SIZE]; > +} EDKII_DEVICE_SECURITY_EVENT_MEASUREMENT_CONTENT_MAX_HASH; > + > +typedef struct { > + UINTN Signature; > + LIST_ENTRY Link; > + UINTN PciSegment; > + UINTN PciBus; > + UINTN PciDevice; > + UINTN PciFunction; > +} PCI_DEVICE_INSTANCE; > + > +#define PCI_DEVICE_INSTANCE_SIGNATURE SIGNATURE_32 ('P', 'D', 'I', > +'S') #define PCI_DEVICE_INSTANCE_FROM_LINK(a) CR (a, > +PCI_DEVICE_INSTANCE, Link, PCI_DEVICE_INSTANCE_SIGNATURE) > + > +LIST_ENTRY mSecurityEventMeasurementDeviceList =3D > +INITIALIZE_LIST_HEAD_VARIABLE(mSecurityEventMeasurementDeviceList) > ;; > +EDKII_DEVICE_SECURITY_POLICY_PROTOCOL *mDeviceSecurityPolicy; > + > +/** > + Record a PCI device into device list. > + > + @param PciIo PciIo instance of the device > + @param PciDeviceList The list to record the the device > +**/ > +VOID > +RecordPciDeviceInList( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN LIST_ENTRY *PciDeviceList > + ) > +{ > + UINTN PciSegment; > + UINTN PciBus; > + UINTN PciDevice; > + UINTN PciFunction; > + EFI_STATUS Status; > + PCI_DEVICE_INSTANCE *NewPciDevice; > + > + Status =3D PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice= , > + &PciFunction); ASSERT_EFI_ERROR(Status); > + > + NewPciDevice =3D AllocateZeroPool(sizeof(*NewPciDevice)); > + ASSERT_EFI_ERROR(NewPciDevice !=3D NULL); > + > + NewPciDevice->Signature =3D PCI_DEVICE_INSTANCE_SIGNATURE; > + NewPciDevice->PciSegment =3D PciSegment; > + NewPciDevice->PciBus =3D PciBus; > + NewPciDevice->PciDevice =3D PciDevice; > + NewPciDevice->PciFunction =3D PciFunction; > + > + InsertTailList(PciDeviceList, &NewPciDevice->Link); } > + > +/** > + Check if a PCI device is recorded in device list. > + > + @param PciIo PciIo instance of the device > + @param PciDeviceList The list to record the the device > + > + @retval TRUE The PCI device is in the list. > + @retval FALSE The PCI device is NOT in the list. > +**/ > +BOOLEAN > +IsPciDeviceInList( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN LIST_ENTRY *PciDeviceList > + ) > +{ > + UINTN PciSegment; > + UINTN PciBus; > + UINTN PciDevice; > + UINTN PciFunction; > + EFI_STATUS Status; > + LIST_ENTRY *Link; > + PCI_DEVICE_INSTANCE *CurrentPciDevice; > + > + Status =3D PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice= , > + &PciFunction); ASSERT_EFI_ERROR(Status); > + > + Link =3D GetFirstNode(PciDeviceList); > + while (!IsNull(PciDeviceList, Link)) { > + CurrentPciDevice =3D PCI_DEVICE_INSTANCE_FROM_LINK(Link); > + > + if (CurrentPciDevice->PciSegment =3D=3D PciSegment && CurrentPciDevi= ce- > >PciBus =3D=3D PciBus && > + CurrentPciDevice->PciDevice =3D=3D PciDevice && CurrentPciDevice= - > >PciFunction =3D=3D PciFunction) { > + DEBUG((DEBUG_INFO, "PCI device duplicated (Loc - > %04x:%02x:%02x:%02x)\n", PciSegment, PciBus, PciDevice, PciFunction)); > + return TRUE; > + } > + > + Link =3D GetNextNode(PciDeviceList, Link); } > + > + return FALSE; > +} > + > +/* > + return Offset of the PCI Cap ID. > + > + @param PciIo PciIo instance of the device > + @param CapId The Capability ID of the Pci device > + > + @return The PCI Capability ID Offset > +*/ > +UINT32 > +GetPciCapId ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT8 CapId > + ) > +{ > + EFI_PCI_CAPABILITY_HDR PciCapIdHdr; > + UINT32 PciCapIdOffset; > + EFI_STATUS Status; > + > + PciCapIdHdr.CapabilityID =3D ~CapId; > + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, > + PCI_CAPBILITY_POINTER_OFFSET, 1, &PciCapIdHdr.NextItemPtr); > + ASSERT_EFI_ERROR(Status); if (PciCapIdHdr.NextItemPtr =3D=3D 0 || > PciCapIdHdr.NextItemPtr =3D=3D 0xFF) { > + return 0; > + } > + PciCapIdOffset =3D 0; > + do { > + if (PciCapIdHdr.CapabilityID =3D=3D CapId) { > + break; > + } > + PciCapIdOffset =3D PciCapIdHdr.NextItemPtr; > + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PciCapIdOffs= et, 1, > &PciCapIdHdr); > + ASSERT_EFI_ERROR(Status); > + } while (PciCapIdHdr.NextItemPtr !=3D 0 && PciCapIdHdr.NextItemPtr != =3D > + 0xFF); > + > + if (PciCapIdHdr.CapabilityID =3D=3D CapId) { > + return PciCapIdOffset; > + } else { > + return 0; > + } > +} > + > +/* > + return Offset of the PCIe Ext Cap ID. > + > + @param PciIo PciIo instance of the device > + @param CapId The Ext Capability ID of the Pci device > + > + @return The PCIe Ext Capability ID Offset */ > +UINT32 > +GetPciExpressExtCapId ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT16 CapId > + ) > +{ > + UINT32 PcieCapIdOffset; > + PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER PciExpressExtCapIdHdr; > + EFI_STATUS Status; > + > + PcieCapIdOffset =3D GetPciCapId (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP); > + if (PcieCapIdOffset =3D=3D 0) { > + return 0; > + } > + > + PciExpressExtCapIdHdr.CapabilityId =3D ~CapId; > + PciExpressExtCapIdHdr.CapabilityVersion =3D 0xF; > + PciExpressExtCapIdHdr.NextCapabilityOffset =3D 0x100; PcieCapIdOffset = =3D > + 0; do { > + if (PciExpressExtCapIdHdr.CapabilityId =3D=3D CapId) { > + break; > + } > + PcieCapIdOffset =3D PciExpressExtCapIdHdr.NextCapabilityOffset; > + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, PcieCapIdOff= set, 1, > &PciExpressExtCapIdHdr); > + ASSERT_EFI_ERROR(Status); > + } while (PciExpressExtCapIdHdr.NextCapabilityOffset !=3D 0 && > + PciExpressExtCapIdHdr.NextCapabilityOffset !=3D 0xFFF); > + > + if (PciExpressExtCapIdHdr.CapabilityId =3D=3D CapId) { > + return PcieCapIdOffset; > + } else { > + return 0; > + } > +} > + > +/** > + Read byte of the PCI device configuration space. > + > + @param PciIo PciIo instance of the device > + @param Offset The offset of the Pci device configuration spa= ce > + > + @return Byte value of the PCI device configuration space. > +**/ > +UINT8 > +DvSecPciRead8 ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT32 Offset > + ) > +{ > + EFI_STATUS Status; > + UINT8 Data; > + > + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, Offset, 1, > + &Data); ASSERT_EFI_ERROR(Status); > + > + return Data; > +} > + > +/** > + Write byte of the PCI device configuration space. > + > + @param PciIo PciIo instance of the device > + @param Offset The offset of the Pci device configuration spa= ce > + @param Data Byte value of the PCI device configuration spa= ce. > +**/ > +VOID > +DvSecPciWrite8 ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT32 Offset, > + IN UINT8 Data > + ) > +{ > + EFI_STATUS Status; > + > + Status =3D PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, Offset, 1, > +&Data); > + ASSERT_EFI_ERROR(Status); > +} > + > +/** > + Get the Digest size from the TCG hash Algorithm ID. > + > + @param TcgAlgId TCG hash Algorithm ID > + > + @return Digest size of the TCG hash Algorithm ID **/ UINTN > +DigestSizeFromTcgAlgId ( > + IN UINT16 TcgAlgId > + ) > +{ > + switch (TcgAlgId) { > + case TPM_ALG_SHA256: > + return SHA256_DIGEST_SIZE; > + case TPM_ALG_SHA384: > + return SHA384_DIGEST_SIZE; > + case TPM_ALG_SHA512: > + return SHA512_DIGEST_SIZE; > + case TPM_ALG_SM3_256: > + default: > + break; > + } > + return 0; > +} > + > +/** > + Convert the SPDM hash algo ID from the TCG hash Algorithm ID. > + > + @param TcgAlgId TCG hash Algorithm ID > + > + @return SPDM hash algo ID > +**/ > +UINT8 > +TcgAlgIdToSpdmHashAlgo ( > + IN UINT16 TcgAlgId > + ) > +{ > + switch (TcgAlgId) { > + case TPM_ALG_SHA256: > + return SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA2_256; > + case TPM_ALG_SHA384: > + return SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA2_384; > + case TPM_ALG_SHA512: > + return SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA2_512; > + case TPM_ALG_SM3_256: > + default: > + break; > + } > + return 0; > +} > + > +/** > + This function extend the PCI digest from the DvSec register. > + > + @param[in] PciIo The PciIo of the device. > + @param[in] DeviceSecurityPolicy The Device Security Policy associat= ed > with the device. > + @param[in] TcgAlgId TCG hash Algorithm ID > + @param[in] DigestSel The digest selector > + @param[in] Digest The digest buffer > + @param[out] DeviceSecurityState The Device Security state associate= d > with the device. > +**/ > +VOID > +ExtendDigestRegister ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN EDKII_DEVICE_SECURITY_POLICY *DeviceSecurityPolicy, > + IN UINT16 TcgAlgId, > + IN UINT8 DigestSel, > + IN UINT8 *Digest, > + OUT EDKII_DEVICE_SECURITY_STATE *DeviceSecurityState > + ) > +{ > + UINT32 PcrIndex; > + UINT32 EventType; > + EDKII_DEVICE_SECURITY_PCI_EVENT_DATA EventLog; > + EDKII_DEVICE_SECURITY_EVENT_MEASUREMENT_CONTENT_MAX_HASH > HashData; > + UINT64 HashDataLen; > + UINTN DigestSize; > + EFI_STATUS Status; > + PCI_TYPE00 PciData; > + > + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, > + sizeof(PciData), &PciData); ASSERT_EFI_ERROR(Status); > + > + PcrIndex =3D EDKII_DEVICE_MEASUREMENT_COMPONENT_PCR_INDEX; > + EventType =3D EDKII_DEVICE_MEASUREMENT_COMPONENT_EVENT_TYPE; > + > + CopyMem (EventLog.EventData.Signature, > EDKII_DEVICE_SECURITY_EVENT_DATA_SIGNATURE, > sizeof(EventLog.EventData.Signature)); > + EventLog.EventData.Version =3D > EDKII_DEVICE_SECURITY_EVENT_DATA_VERSION; > + EventLog.EventData.Length =3D > sizeof(EDKII_DEVICE_SECURITY_PCI_EVENT_DATA); > + EventLog.EventData.SpdmMeasurementBlock.Index =3D D= igestSel; > + EventLog.EventData.SpdmMeasurementBlock.MeasurementType =3D > SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWA > RE; > + EventLog.EventData.SpdmMeasurementBlock.MeasurementSpecification > =3D 0xFF; > + EventLog.EventData.SpdmMeasurementBlock.Reserved =3D 0= ; > + EventLog.EventData.SpdmHashAlgo =3D TcgAlgIdToSpdmHashAlgo > (TcgAlgId); > + EventLog.EventData.DeviceType =3D > EDKII_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI; > + ZeroMem (EventLog.EventData.Reserved, > sizeof(EventLog.EventData.Reserved)); > + EventLog.PciContext.Version =3D > EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION; > + EventLog.PciContext.Length =3D > sizeof(EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT); > + EventLog.PciContext.VendorId =3D PciData.Hdr.VendorId; > + EventLog.PciContext.DeviceId =3D PciData.Hdr.DeviceId; > + EventLog.PciContext.RevisionID =3D PciData.Hdr.RevisionID; > + EventLog.PciContext.ClassCode[0] =3D PciData.Hdr.ClassCode[0]; > + EventLog.PciContext.ClassCode[1] =3D PciData.Hdr.ClassCode[1]; > + EventLog.PciContext.ClassCode[2] =3D PciData.Hdr.ClassCode[2]; > + if ((PciData.Hdr.HeaderType & HEADER_LAYOUT_CODE) =3D=3D > HEADER_TYPE_DEVICE) { > + EventLog.PciContext.SubsystemVendorID =3D > PciData.Device.SubsystemVendorID; > + EventLog.PciContext.SubsystemID =3D PciData.Device.SubsystemID= ; > + } else { > + EventLog.PciContext.SubsystemVendorID =3D 0; > + EventLog.PciContext.SubsystemID =3D 0; > + } > + > + DigestSize =3D DigestSizeFromTcgAlgId (TcgAlgId); CopyMem > + (&HashData.Measurement, Digest, DigestSize); > + > + HashDataLen =3D DigestSize; > + Status =3D TpmMeasureAndLogData ( > + PcrIndex, > + EventType, > + &EventLog, > + EventLog.EventData.Length, > + &HashData, > + HashDataLen > + ); > + DEBUG((DEBUG_INFO, "TpmMeasureAndLogData - %r\n", Status)); > + if (EFI_ERROR(Status)) { > + DeviceSecurityState->MeasurementState =3D > +EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR; > + } else { > + RecordPciDeviceInList (PciIo, > +&mSecurityEventMeasurementDeviceList); > + } > +} > + > +/** > + This function reads the PCI digest from the DvSec register and extend = to > TPM. > + > + @param[in] PciIo The PciIo of the device. > + @param[in] DvSecOffset The DvSec register offset of the de= vice. > + @param[in] DeviceSecurityPolicy The Device Security Policy associat= ed > with the device. > + @param[out] DeviceSecurityState The Device Security state associate= d > with the device. > +**/ > +VOID > +DoMeasurementsFromDigestRegister ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT32 DvSecOffset, > + IN EDKII_DEVICE_SECURITY_POLICY *DeviceSecurityPolicy, > + OUT EDKII_DEVICE_SECURITY_STATE *DeviceSecurityState > + ) > +{ > + UINT8 Modified; > + UINT8 Valid; > + UINT16 TcgAlgId; > + UINT8 NumDigest; > + UINT8 DigestSel; > + UINT8 Digest[SHA512_DIGEST_SIZE]; > + UINTN DigestSize; > + EFI_STATUS Status; > + > + TcgAlgId =3D DvSecPciRead8 ( > + PciIo, > + DvSecOffset + sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEADER) = + > OFFSET_OF(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE, TcgAlgId) > + ); > + DEBUG((DEBUG_INFO, " TcgAlgId - 0x%04x\n", TcgAlgId)); > + DigestSize =3D DigestSizeFromTcgAlgId (TcgAlgId); if (DigestSize =3D= =3D 0) > + { > + DEBUG((DEBUG_INFO, "Unsupported Algorithm - 0x%04x\n", TcgAlgId)); > + DeviceSecurityState->MeasurementState =3D > EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES; > + return ; > + } > + DEBUG((DEBUG_INFO, " (DigestSize: 0x%x)\n", DigestSize)); > + > + DeviceSecurityState->MeasurementState =3D > + EDKII_DEVICE_SECURITY_STATE_SUCCESS; > + > + NumDigest =3D DvSecPciRead8 ( > + PciIo, > + DvSecOffset + sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEADER)= + > OFFSET_OF(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE, FirmwareID) > + ); > + DEBUG((DEBUG_INFO, " NumDigest - 0x%02x\n", NumDigest)); > + > + Valid =3D DvSecPciRead8 ( > + PciIo, > + DvSecOffset + sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEADER) + > OFFSET_OF(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE, Valid) > + ); > + DEBUG((DEBUG_INFO, " Valid - 0x%02x\n", Valid)); > + > + // > + // Only 2 are supported as maximum. > + // But hardware may report 3. > + // > + if (NumDigest > 2) { > + NumDigest =3D 2; > + } > + > + for (DigestSel =3D 0; DigestSel < NumDigest; DigestSel++) { > + DEBUG((DEBUG_INFO, " DigestSel - 0x%02x\n", DigestSel)); > + if ((DigestSel =3D=3D 0) && ((Valid & INTEL_PCI_DIGEST_0_VALID) =3D= =3D 0)) { > + continue; > + } > + if ((DigestSel =3D=3D 1) && ((Valid & INTEL_PCI_DIGEST_1_VALID) =3D= =3D 0)) { > + continue; > + } > + while (TRUE) { > + // > + // Host MUST clear DIGEST_MODIFIED before read DIGEST. > + // > + DvSecPciWrite8 ( > + PciIo, > + DvSecOffset + sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEADER) + > OFFSET_OF(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE, Modified), > + INTEL_PCI_DIGEST_MODIFIED > + ); > + > + Status =3D PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint8, > + (UINT32)(DvSecOffset + > sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEADER) + > sizeof(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE) + DigestSize * DigestSel), > + DigestSize, > + Digest > + ); > + ASSERT_EFI_ERROR(Status); > + > + // > + // After read DIGEST, Host MUST consult DIGEST_MODIFIED. > + // > + Modified =3D DvSecPciRead8 ( > + PciIo, > + DvSecOffset + sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEAD= ER) + > OFFSET_OF(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE, Modified) > + ); > + if ((Modified & INTEL_PCI_DIGEST_MODIFIED) =3D=3D 0) { > + break; > + } > + } > + > + // > + // Dump Digest > + // > + { > + UINTN Index; > + DEBUG((DEBUG_INFO, " Digest - ")); > + for (Index =3D 0; Index < DigestSize; Index++) { > + DEBUG((DEBUG_INFO, "%02x", *(Digest + Index))); > + } > + DEBUG((DEBUG_INFO, "\n")); > + } > + > + DEBUG((DEBUG_INFO, "ExtendDigestRegister...\n", > ExtendDigestRegister)); > + ExtendDigestRegister (PciIo, DeviceSecurityPolicy, TcgAlgId, > +DigestSel, Digest, DeviceSecurityState); > + } > +} > + > +/** > + The device driver uses this service to measure a PCI device. > + > + @param[in] PciIo The PciIo of the device. > + @param[in] DeviceSecurityPolicy The Device Security Policy associat= ed > with the device. > + @param[out] DeviceSecurityState The Device Security state associate= d > with the device. > +**/ > +VOID > +DoDeviceMeasurement ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN EDKII_DEVICE_SECURITY_POLICY *DeviceSecurityPolicy, > + OUT EDKII_DEVICE_SECURITY_STATE *DeviceSecurityState > + ) > +{ > + UINT32 DvSecOffset; > + INTEL_PCI_DIGEST_CAPABILITY_HEADER DvSecHdr; > + EFI_STATUS Status; > + > + if (IsPciDeviceInList (PciIo, &mSecurityEventMeasurementDeviceList)) { > + DeviceSecurityState->MeasurementState =3D > EDKII_DEVICE_SECURITY_STATE_SUCCESS; > + return ; > + } > + > + DvSecOffset =3D GetPciExpressExtCapId (PciIo, INTEL_PCI_CAPID_DVSEC); > + DEBUG((DEBUG_INFO, "DvSecOffset - 0x%x\n", DvSecOffset)); if > + (DvSecOffset =3D=3D 0) { > + DeviceSecurityState->MeasurementState =3D > EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES; > + return ; > + } > + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, DvSecOffset, > + sizeof(DvSecHdr)/sizeof(UINT16), &DvSecHdr); > ASSERT_EFI_ERROR(Status); > + DEBUG((DEBUG_INFO, " CapId - 0x%04x\n", DvSecHdr.CapId)); > + DEBUG((DEBUG_INFO, " CapVersion - 0x%01x\n", > DvSecHdr.CapVersion)); > + DEBUG((DEBUG_INFO, " NextOffset - 0x%03x\n", > DvSecHdr.NextOffset)); > + DEBUG((DEBUG_INFO, " DvSecVendorId - 0x%04x\n", > + DvSecHdr.DvSecVendorId)); DEBUG((DEBUG_INFO, " DvSecRevision - > 0x%01x\n", DvSecHdr.DvSecRevision)); > + DEBUG((DEBUG_INFO, " DvSecLength - 0x%03x\n", > DvSecHdr.DvSecLength)); > + DEBUG((DEBUG_INFO, " DvSecId - 0x%04x\n", DvSecHdr.DvSecId)); > + if ((DvSecHdr.DvSecVendorId !=3D INTEL_PCI_DVSEC_VENDORID_INTEL) && > + (DvSecHdr.DvSecId !=3D INTEL_PCI_DVSEC_DVSECID_MEASUREMENT)) { > + DeviceSecurityState->MeasurementState =3D > EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES; > + return ; > + } > + > + DoMeasurementsFromDigestRegister (PciIo, DvSecOffset, > +DeviceSecurityPolicy, DeviceSecurityState); } > + > +/** > + The device driver uses this service to verify a PCI device. > + > + @param[in] PciIo The PciIo of the device. > + @param[in] DeviceSecurityPolicy The Device Security Policy associat= ed > with the device. > + @param[out] DeviceSecurityState The Device Security state associate= d > with the device. > +**/ > +VOID > +DoDeviceAuthentication ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN EDKII_DEVICE_SECURITY_POLICY *DeviceSecurityPolicy, > + OUT EDKII_DEVICE_SECURITY_STATE *DeviceSecurityState > + ) > +{ > + DeviceSecurityState->AuthenticationState =3D > +EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED; > +} > + > +/** > + The device driver uses this service to measure and/or verify a device. > + > + The flow in device driver is: > + 1) Device driver discovers a new device. > + 2) Device driver creates an EFI_DEVICE_PATH_PROTOCOL. > + 3) Device driver creates a device access protocol. e.g. > + EFI_PCI_IO_PROTOCOL for PCI device. > + EFI_USB_IO_PROTOCOL for USB device. > + EFI_EXT_SCSI_PASS_THRU_PROTOCOL for SCSI device. > + EFI_ATA_PASS_THRU_PROTOCOL for ATA device. > + EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL for NVMe device. > + EFI_SD_MMC_PASS_THRU_PROTOCOL for SD/MMC device. > + 4) Device driver installs the EFI_DEVICE_PATH_PROTOCOL with > EFI_DEVICE_PATH_PROTOCOL_GUID, > + and the device access protocol with > EDKII_DEVICE_IDENTIFIER_TYPE_xxx_GUID. > + Once it is done, a DeviceHandle is returned. > + 5) Device driver creates EDKII_DEVICE_IDENTIFIER with > EDKII_DEVICE_IDENTIFIER_TYPE_xxx_GUID > + and the DeviceHandle. > + 6) Device driver calls DeviceAuthenticate(). > + 7) If DeviceAuthenticate() returns EFI_SECURITY_VIOLATION, the device > driver uninstalls > + all protocols on this handle. > + 8) If DeviceAuthenticate() returns EFI_SUCCESS, the device driver inst= alls > the device access > + protocol with a real protocol GUID. e.g. > + EFI_PCI_IO_PROTOCOL with EFI_PCI_IO_PROTOCOL_GUID. > + EFI_USB_IO_PROTOCOL with EFI_USB_IO_PROTOCOL_GUID. > + > + @param[in] This The protocol instance pointer. > + @param[in] DeviceId The Identifier for the device. > + > + @retval EFI_SUCCESS The device specified by the DeviceId = passed > the measurement > + and/or authentication based upon the = platform policy. > + If TCG measurement is required, the m= easurement is > extended to TPM PCR. > + @retval EFI_SECURITY_VIOLATION The device fails to return the > measurement data. > + @retval EFI_SECURITY_VIOLATION The device fails to response the > authentication request. > + @retval EFI_SECURITY_VIOLATION The system fails to verify the device > based upon the authentication response. > + @retval EFI_SECURITY_VIOLATION The system fails to extend the > measurement to TPM PCR. > +**/ > +EFI_STATUS > +EFIAPI > +DeviceAuthentication ( > + IN EDKII_DEVICE_SECURITY_PROTOCOL *This, > + IN EDKII_DEVICE_IDENTIFIER *DeviceId > + ) > +{ > + EDKII_DEVICE_SECURITY_POLICY *DeviceSecurityPolicy; > + EDKII_DEVICE_SECURITY_STATE DeviceSecurityState; > + EFI_PCI_IO_PROTOCOL *PciIo; > + EFI_STATUS Status; > + > + if (mDeviceSecurityPolicy =3D=3D NULL) { > + return EFI_SUCCESS; > + } > + > + if (!CompareGuid (&DeviceId->DeviceType, > &gEdkiiDeviceIdentifierTypePciGuid)) { > + return EFI_SUCCESS; > + } > + > + Status =3D gBS->HandleProtocol ( > + DeviceId->DeviceHandle, > + &gEdkiiDeviceIdentifierTypePciGuid, > + (VOID **)&PciIo > + ); > + if (EFI_ERROR(Status)) { > + DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n", > Status)); > + return EFI_SUCCESS; > + } > + > + DeviceSecurityState.Version =3D 0x1; > + DeviceSecurityState.MeasurementState =3D 0x0; > + DeviceSecurityState.AuthenticationState =3D 0x0; > + > + Status =3D mDeviceSecurityPolicy->GetDevicePolicy > + (mDeviceSecurityPolicy, DeviceId, &DeviceSecurityPolicy); if > (EFI_ERROR(Status)) { > + DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->GetDevicePolicy - > %r\n", Status)); > + DeviceSecurityState.MeasurementState =3D > EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL; > + DeviceSecurityState.AuthenticationState =3D > + EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL; > + } else { > + if ((DeviceSecurityPolicy->MeasurementPolicy & > EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED) !=3D 0) { > + DoDeviceMeasurement (PciIo, DeviceSecurityPolicy, > &DeviceSecurityState); > + DEBUG((DEBUG_ERROR, "MeasurementState - 0x%08x\n", > DeviceSecurityState.MeasurementState)); > + } > + if ((DeviceSecurityPolicy->AuthenticationPolicy & > EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED) !=3D 0) { > + DoDeviceAuthentication (PciIo, DeviceSecurityPolicy, > &DeviceSecurityState); > + DEBUG((DEBUG_ERROR, "AuthenticationState - 0x%08x\n", > DeviceSecurityState.AuthenticationState)); > + } > + } > + > + Status =3D mDeviceSecurityPolicy->SetDeviceState > + (mDeviceSecurityPolicy, DeviceId, &DeviceSecurityState); if > (EFI_ERROR(Status)) { > + DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->SetDeviceState - %r\n", > + Status)); } > + > + if ((DeviceSecurityState.MeasurementState =3D=3D 0) && > + (DeviceSecurityState.AuthenticationState =3D=3D 0)) { > + return EFI_SUCCESS; > + } else { > + return EFI_SECURITY_VIOLATION; > + } > +} > + > +EDKII_DEVICE_SECURITY_PROTOCOL mDeviceSecurity =3D { > + EDKII_DEVICE_SECURITY_PROTOCOL_REVISION, > + DeviceAuthentication > +}; > + > +/** > + Entrypoint of the device security driver. > + > + @param[in] ImageHandle ImageHandle of the loaded driver @param[in] > + SystemTable Pointer to the System Table > + > + @retval EFI_SUCCESS The Protocol is installed. > + @retval EFI_OUT_OF_RESOURCES Not enough resources available to > initialize driver. > + @retval EFI_DEVICE_ERROR A device error occurred attempting to > initialize the driver. > + > +**/ > +EFI_STATUS > +EFIAPI > +MainEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_HANDLE Handle; > + EFI_STATUS Status; > + > + Status =3D gBS->LocateProtocol > + (&gEdkiiDeviceSecurityPolicyProtocolGuid, NULL, (VOID > + **)&mDeviceSecurityPolicy); ASSERT_EFI_ERROR(Status); > + > + Handle =3D NULL; > + Status =3D gBS->InstallProtocolInterface ( > + &Handle, > + &gEdkiiDeviceSecurityProtocolGuid, > + EFI_NATIVE_INTERFACE, > + (VOID **)&mDeviceSecurity > + ); > + ASSERT_EFI_ERROR(Status); > + > + return Status; > +} > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecuri= tyDx > e/IntelPciDeviceSecurityDxe.inf > b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecuri= tyD > xe/IntelPciDeviceSecurityDxe.inf > new file mode 100644 > index 0000000000..89a4c8fadd > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceS > +++ ecurityDxe/IntelPciDeviceSecurityDxe.inf > @@ -0,0 +1,45 @@ > +## @file > +# EDKII Device Security library for PCI device # # Copyright (c) 2019, > +Intel Corporation. All rights reserved.
# SPDX-License-Identifier: > +BSD-2-Clause-Patent # ## > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D IntelPciDeviceSecurityDxe > + FILE_GUID =3D D9569195-ED94-47D2-9523-38BF2D20137= 1 > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + ENTRY_POINT =3D MainEntryPoint > + > +[Sources] > + IntelPciDeviceSecurityDxe.c > + TcgDeviceEvent.h > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + IntelSiliconPkg/IntelSiliconPkg.dec > + > +[LibraryClasses] > + UefiRuntimeServicesTableLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + MemoryAllocationLib > + DevicePathLib > + BaseMemoryLib > + PrintLib > + DebugLib > + UefiLib > + PcdLib > + TpmMeasurementLib > + > +[Protocols] > + gEdkiiDeviceSecurityPolicyProtocolGuid ## CONSUMES > + gEdkiiDeviceSecurityProtocolGuid ## PRODUCES > + gEdkiiDeviceIdentifierTypePciGuid ## COMSUMES > + > +[Depex] > + gEdkiiDeviceSecurityPolicyProtocolGuid > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecuri= tyDx > e/TcgDeviceEvent.h > b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecuri= tyD > xe/TcgDeviceEvent.h > new file mode 100644 > index 0000000000..8b1227dace > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceS > +++ ecurityDxe/TcgDeviceEvent.h > @@ -0,0 +1,193 @@ > +/** @file > + TCG Device Event data structure > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent **/ > + > + > +#ifndef __TCG_EVENT_DATA_H__ > +#define __TCG_EVENT_DATA_H__ > + > +#include > + > +#pragma pack(1) > + > +// ------------------------------------------- > +// TCG Measurement for SPDM Device Measurement // > +------------------------------------------- > + > +// > +// Device Firmware Component (including immutable ROM or mutable > +firmware) // > +#define EDKII_DEVICE_MEASUREMENT_COMPONENT_PCR_INDEX 2 > +#define EDKII_DEVICE_MEASUREMENT_COMPONENT_EVENT_TYPE > 0x800000E1 > +// > +// Device Firmware Configuration (including hardware configuration or > +firmware configuration) // > +#define EDKII_DEVICE_MEASUREMENT_CONFIGURATION_PCR_INDEX 4 > +#define EDKII_DEVICE_MEASUREMENT_CONFIGURATION_EVENT_TYPE > 0x800000E2 > + > +// > +// Device Firmware Measurement Measurement Data // The measurement > data > +is the device firmware measurement. > +// > +// TBD: Open: > +// In order to support crypto agile, the firmware will hash the > DeviceMeasurement again. > +// As such the device measurement algo might be different with host > firmware measurement algo. > +// > + > +// > +// Device Firmware Measurement Event Data // #define > +EDKII_DEVICE_SECURITY_EVENT_DATA_SIGNATURE "SPDM Device Sec\0" > +#define EDKII_DEVICE_SECURITY_EVENT_DATA_VERSION 0 > + > +// > +// Device Type > +// 0x03 ~ 0xDF reserved by TCG. > +// 0xE0 ~ 0xFF reserved by OEM. > +// > +#define EDKII_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_NULL 0 > +#define EDKII_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI 1 > +#define EDKII_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_USB 2 > + > +// > +// Device Firmware Measurement Event Data Common Part // The device > +specific part should follow this data structure. > +// > +typedef struct { > + // > + // It must be EDKII_DEVICE_SECURITY_EVENT_DATA_SIGNATURE. > + // > + UINT8 Signature[16]; > + // > + // It must be EDKII_DEVICE_SECURITY_EVENT_DATA_VERSION. > + // > + UINT16 Version; > + // > + // The length of whole data structure, including Device Context. > + // > + UINT16 Length; > + // > + // The SPDM measurement block header. > + // > + SPDM_MEASUREMENT_BLOCK_HEADER SpdmMeasurementBlock; > + // > + // The SpdmHashAlgo > + // > + UINT8 SpdmHashAlgo; > + // > + // The type of device. This field is to determine the Device Context > followed by. > + // > + UINT8 DeviceType; > + // > + // reserved. Make UINT64 aligned. > + // > + UINT8 Reserved[6]; > +} EDKII_DEVICE_SECURITY_EVENT_DATA_HEADER; > + > +// > +// PCI device specific context > +// > +#define EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION 0 > typedef > +struct { > + UINT16 Version; > + UINT16 Length; > + UINT16 VendorId; > + UINT16 DeviceId; > + UINT8 RevisionID; > + UINT8 ClassCode[3]; > + UINT16 SubsystemVendorID; > + UINT16 SubsystemID; > +} EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT; > + > +typedef struct { > + EDKII_DEVICE_SECURITY_EVENT_DATA_HEADER EventData; > + EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT PciContext; } > +EDKII_DEVICE_SECURITY_PCI_EVENT_DATA; > + > +// > +// USB device specific context > +// > +#define EDKII_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT_VERSION > 0 typedef > +struct { > + UINT16 Version; > + UINT16 Length; > +//UINT8 DeviceDescriptor[DescLen]; > +//UINT8 BodDescriptor[DescLen]; > +//UINT8 ConfigurationDescriptor[DescLen][NumOfConfiguration]; > +} EDKII_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT; > + > +typedef struct { > + EDKII_DEVICE_SECURITY_EVENT_DATA_HEADER EventData; > + EDKII_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT PciContext; } > +EDKII_DEVICE_SECURITY_USB_EVENT_DATA; > + > +// ---------------------------------------------- > +// TCG Measurement for SPDM Device Authentication // > +---------------------------------------------- > + > +// > +// Device Root cert is stored into a UEFI authenticated variable. > +// It is non-volatile, boot service, runtime service, and time based > authenticated variable. > +// The "devdb" includes a list of allowed device root cert. > +// The "devdbx" includes a list of forbidden device root cert. > +// The usage of "devdb" and "devdbx" is same as "db" and "dbx" in UEFI > secure boot. > +// > +// NOTE: We choose not to mix "db"/"dbx" for better management > purpose. > +// > + > +#define EDKII_DEVICE_ROOT_CERT_VARAIBLE_NAME L"devdb" > +#define EDKII_DEVICE_ROOT_CERT_VARAIBLE2_NAME L"devdbx" > + > +#define EDKII_DEVICE_SIGNATURE_DATABASE_GUID \ > + {0xb9c2b4f4, 0xbf5f, 0x462d, 0x8a, 0xdf, 0xc5, 0xc7, 0xa, 0xc3, 0x5d, > +0xad} > + > +// > +// Platform Firmware adhering to the policy MUST therefore measure the > following values into PCR[7]: > +// 1. The content of the > EDKII_DEVICE_SIGNATURE_DATABASE_GUID/EDKII_DEVICE_ROOT_CERT_V > ARAIBLE_NAME variable. > +// 2. The content of the > EDKII_DEVICE_SIGNATURE_DATABASE_GUID/EDKII_DEVICE_ROOT_CERT_V > ARAIBLE2_NAME variable. > +// 3. Entries in the > EDKII_DEVICE_SIGNATURE_DATABASE_GUID/EDKII_DEVICE_ROOT_CERT_V > ARAIBLE_NAME variable to > +// authenticate the device. > +// > +// For all UEFI variable value events, the eventType SHALL be > +EV_EFI_VARIABLE_DRIVER_CONFIG and the Event // value SHALL be the > value of the UEFI_VARIABLE_DATA structure (this structure SHALL be > considered byte-aligned). > +// The measurement digest MUST be tagged Hash for each supported PCR > +bank of the event data which is the // UEFI_VARIABLE_DATA structure. > +The UEFI_VARIABLE_DATA.UnicodeNameLength value is the number of > CHAR16 // characters (not the number of bytes). The > UEFI_VARIABLE_DATA.UnicodeName contents MUST NOT include a NUL. > +// If reading a UEFI variable returns UEFI_NOT_FOUND, the > +UEFI_VARIABLE_DATA.VariableDataLength field MUST // be set to zero and > UEFI_VARIABLE_DATA.VariableData field will have a size of zero. > +// > + > +// > +// Entities that MUST be measured if the TPM is enabled: > +// 1. Before executing any code not cryptographically authenticated as > being provided by the Platform Manufacturer, > +// the Platform Manufacturer firmware MUST measure the following > values, in the order listed using the > +// EV_EFI_VARIABLE_DRIVER_CONFIG event type to PCR[7]: > +// a) The content of the EDKII_DEVICE_SIGNATURE_DATABASE_GUID/ > EDKII_DEVICE_ROOT_CERT_VARAIBLE_NAME variable. > +// b) The content of the EDKII_DEVICE_SIGNATURE_DATABASE_GUID/ > EDKII_DEVICE_ROOT_CERT_VARAIBLE2_NAME variable. > +// 2. If the platform supports changing any of the following UEFI policy > variables after they are initially measured > +// in PCR[7] and before ExitBootServices() has completed, the platfor= m > MAY be restarted OR the variables MUST be > +// remeasured into PCR[7]. Additionally the normal update process for > setting any of the UEFI variables below SHOULD > +// occur before the initial measurement in PCR[7] or after the call t= o > ExitBootServices() has completed. > +// a) The content of the EDKII_DEVICE_SIGNATURE_DATABASE_GUID/ > EDKII_DEVICE_ROOT_CERT_VARAIBLE_NAME variable. > +// b) The content of the EDKII_DEVICE_SIGNATURE_DATABASE_GUID/ > EDKII_DEVICE_ROOT_CERT_VARAIBLE2_NAME variable. > +// 3. The system SHALL measure the EV_SEPARATOR event in PCR[7]. (This > occurs at the same time the separator is > +// measured to PCR[0-7].) > +// Before setting up a device, the UEFI firmware SHALL determine if t= he > entry in the > +// EDKII_DEVICE_SIGNATURE_DATABASE_GUID/ > EDKII_DEVICE_ROOT_CERT_VARAIBLE_NAME variable that was used to > validate > +// the device has previously been measured in PCR[7]. If it has not b= een, it > MUST be measured into PCR[7] as follows. > +// If it has been measured previously, it MUST NOT be measured again. > The measurement SHALL occur in conjunction > +// with device setup. > +// a) The eventType SHALL be EV_EFI_VARIABLE_AUTHORITY. > +// b) The event value SHALL be the value of the UEFI_VARIABLE_DATA > structure. > +// i. The UEFI_VARIABLE_DATA.VariableData value SHALL be the > UEFI_SIGNATURE_DATA value from the > +// UEFI_SIGNATURE_LIST that contained the authority that was = used > to validate the image. > +// ii. The UEFI_VARIABLE_DATA.VariableName SHALL be set to > UEFI_IMAGE_SECURITY_DATABASE_GUID. > +// iii. The UEFI_VARIABLE_DATA.UnicodeName SHALL be set to the val= ue > of UEFI_IMAGE_SECURITY_DATABASE. > +// The value MUST NOT include the terminating NUL. > +// > + > +#pragma pack() > + > +#endif > -- > 2.19.2.windows.1