public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH V2 0/6] Add Device Security driver
@ 2019-10-31 12:31 Yao, Jiewen
  2019-10-31 12:31 ` [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition Yao, Jiewen
                   ` (11 more replies)
  0 siblings, 12 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-10-31 12:31 UTC (permalink / raw)
  To: devel

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

This patch series add support for device security based
upon the DMTF SPDM specification.
https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_0.95a.zip

We did design review at 18 Oct, 2019.
https://edk2.groups.io/g/devel/files/Designs/2019/1018
And the feedback from the meeting is addressed.
https://edk2.groups.io/g/devel/files/Designs/2019/1018/EDKII-Device%20Firmware%20Security%20v2.pdf

The Device security protocol is added in EDKII repo.
Here we add the producer what follows Intel PCI security spec
to do the device firmware measurement.
https://www.intel.com/content/www/us/en/io/pci-express/pcie-device-security-enhancements-spec.html

The EDKII repo update is at https://github.com/jyao1/edk2/tree/DeviceSecurityMasterV2
The EDKII platform repo update is at https://github.com/jyao1/edk2-platforms/tree/DeviceSecurityMasterV2

The validation has been done on a Intel internal platform.
The device measurement can be shown in TCG event log.

signed-off-by: Jiewen Yao <jiewen.yao@intel.com>

Jiewen Yao (6):
  IntelSiliconPkg/Include: Add Intel PciSecurity definition.
  IntelSiliconPkg/Include: Add Platform Device Security Policy protocol
  IntelSiliconPkg/dec: Add ProtocolGuid definition.
  IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity.
  IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy.
  IntelSiliconPkg/dsc: Add Device Security component.

 .../IntelPciDeviceSecurityDxe.c               | 701 ++++++++++++++++++
 .../IntelPciDeviceSecurityDxe.inf             |  45 ++
 .../TcgDeviceEvent.h                          | 193 +++++
 .../SamplePlatformDevicePolicyDxe.c           | 189 +++++
 .../SamplePlatformDevicePolicyDxe.inf         |  40 +
 .../IndustryStandard/IntelPciSecurity.h       |  66 ++
 .../Protocol/PlatformDeviceSecurityPolicy.h   |  84 +++
 .../Intel/IntelSiliconPkg/IntelSiliconPkg.dec |   1 +
 .../Intel/IntelSiliconPkg/IntelSiliconPkg.dsc |   3 +
 9 files changed, 1322 insertions(+)
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.c
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.inf
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/TcgDeviceEvent.h
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.c
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.inf
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h

-- 
2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition.
  2019-10-31 12:31 [PATCH V2 0/6] Add Device Security driver Yao, Jiewen
@ 2019-10-31 12:31 ` Yao, Jiewen
  2019-11-06 20:00   ` Chaganty, Rangasai V
  2019-11-07  4:46   ` Ni, Ray
  2019-10-31 12:31 ` [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol Yao, Jiewen
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-10-31 12:31 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Yun Lou

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h | 66 ++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
new file mode 100644
index 0000000000..a8c5483165
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
@@ -0,0 +1,66 @@
+/** @file
+  Intel PCI security data structure
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __INTEL_PCI_SECURITY_H__
+#define __INTEL_PCI_SECURITY_H__
+
+#pragma pack(1)
+
+typedef struct {
+  UINT16  CapId;           // 0x23: DVSEC
+  UINT16  CapVersion:4;    // 1
+  UINT16  NextOffset:12;
+  UINT16  DvSecVendorId;   // 0x8086
+  UINT16  DvSecRevision:4; // 1
+  UINT16  DvSecLength:12;
+  UINT16  DvSecId;         // 0x3E: Measure
+} INTEL_PCI_DIGEST_CAPABILITY_HEADER;
+
+#define INTEL_PCI_CAPID_DVSEC                0x23
+#define INTEL_PCI_DVSEC_VENDORID_INTEL       0x8086
+#define INTEL_PCI_DVSEC_DVSECID_MEASUREMENT  0x3E
+
+typedef union {
+  struct {
+    UINT8   DigestModified:1;         // RW1C
+    UINT8   Reserved0:7;
+  } Bits;
+  UINT8 Data;
+} INTEL_PCI_DIGEST_DATA_MODIFIED;
+
+#define INTEL_PCI_DIGEST_MODIFIED        BIT0
+
+typedef union {
+  struct {
+    UINT8   Digest0Valid:1;          // RO
+    UINT8   Digest0Locked:1;         // RO
+    UINT8   Digest1Valid:1;          // RO
+    UINT8   Digest1Locked:1;         // RO
+    UINT8   Reserved1:4;
+  } Bits;
+  UINT8 Data;
+} INTEL_PCI_DIGEST_DATA_VALID;
+
+#define INTEL_PCI_DIGEST_0_VALID         BIT0
+#define INTEL_PCI_DIGEST_0_LOCKED        BIT1
+#define INTEL_PCI_DIGEST_1_VALID         BIT2
+#define INTEL_PCI_DIGEST_1_LOCKED        BIT3
+
+typedef struct {
+  INTEL_PCI_DIGEST_DATA_MODIFIED   Modified;   // RW1C
+  INTEL_PCI_DIGEST_DATA_VALID      Valid;      // RO
+  UINT16                           TcgAlgId;   // RO
+  UINT8                            FirmwareID; // RO
+  UINT8                            Reserved;
+//UINT8                            Digest[];
+} INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE;
+
+#pragma pack()
+
+#endif
+
-- 
2.19.2.windows.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol
  2019-10-31 12:31 [PATCH V2 0/6] Add Device Security driver Yao, Jiewen
  2019-10-31 12:31 ` [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition Yao, Jiewen
@ 2019-10-31 12:31 ` Yao, Jiewen
  2019-11-06 21:50   ` Chaganty, Rangasai V
  2019-11-07  4:55   ` Ni, Ray
  2019-10-31 12:31 ` [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition Yao, Jiewen
                   ` (9 subsequent siblings)
  11 siblings, 2 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-10-31 12:31 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Yun Lou

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h | 84 ++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
new file mode 100644
index 0000000000..cb5a71ad41
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
@@ -0,0 +1,84 @@
+/** @file
+  Device Security Policy Protocol definition
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
+#define __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
+
+#include <Uefi.h>
+#include <Protocol/DeviceSecurity.h>
+
+typedef struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL EDKII_DEVICE_SECURITY_POLICY_PROTOCOL;
+
+typedef struct {
+  UINT32     Version; // 0x1
+  UINT32     MeasurementPolicy;
+  UINT32     AuthenticationPolicy;
+} EDKII_DEVICE_SECURITY_POLICY;
+
+// BIT0 means if the action is needed or NOT
+#define EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED                 BIT0
+#define EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED              BIT0
+
+typedef struct {
+  UINT32     Version; // 0x1
+  UINT32     MeasurementState;
+  UINT32     AuthenticationState;
+} EDKII_DEVICE_SECURITY_STATE;
+
+// All zero means success
+#define EDKII_DEVICE_SECURITY_STATE_SUCCESS                          0
+#define EDKII_DEVICE_SECURITY_STATE_ERROR                            BIT31
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED           (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x0)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL   (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x1)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES        (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x10)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR         (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x20)
+
+/**
+  This function returns the device security policy associated with the device.
+
+  @param[in]  This                   The protocol instance pointer.
+  @param[in]  DeviceId               The Identifier for the device.
+  @param[out] DeviceSecurityPolicy   The Device Security Policy associated with the device.
+
+  @retval EFI_SUCCESS                The device security policy is returned
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY) (
+  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
+  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
+  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
+  );
+
+/**
+  This function sets the device state based upon the authentication result.
+
+  @param[in]  This                   The protocol instance pointer.
+  @param[in]  DeviceId               The Identifier for the device.
+  @param[in]  DeviceSecurityState    The Device Security state associated with the device.
+
+  @retval EFI_SUCCESS                The device state is set
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_DEVICE_SECURITY_SET_DEVICE_STATE) (
+  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
+  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
+  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
+  );
+
+struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL {
+  UINT32                                   Version; // 0x1
+  EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY  GetDevicePolicy;
+  EDKII_DEVICE_SECURITY_SET_DEVICE_STATE   SetDeviceState;
+};
+
+extern EFI_GUID gEdkiiDeviceSecurityPolicyProtocolGuid;
+
+#endif
-- 
2.19.2.windows.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition.
  2019-10-31 12:31 [PATCH V2 0/6] Add Device Security driver Yao, Jiewen
  2019-10-31 12:31 ` [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition Yao, Jiewen
  2019-10-31 12:31 ` [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol Yao, Jiewen
@ 2019-10-31 12:31 ` Yao, Jiewen
  2019-11-06 22:09   ` Chaganty, Rangasai V
  2019-11-07  6:11   ` Ni, Ray
  2019-10-31 12:31 ` [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity Yao, Jiewen
                   ` (8 subsequent siblings)
  11 siblings, 2 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-10-31 12:31 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Yun Lou

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
index 3079fc2869..8c8cd9f49d 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -53,6 +53,7 @@
 
 [Protocols]
   gEdkiiPlatformVTdPolicyProtocolGuid = { 0x3d17e448, 0x466, 0x4e20, { 0x99, 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 }}
+  gEdkiiDeviceSecurityPolicyProtocolGuid = {0x7ea41a99, 0x5e32, 0x4c97, {0x88, 0xc4, 0xd6, 0xe7, 0x46, 0x84, 0x9, 0xd4}}
 
 [PcdsFixedAtBuild, PcdsPatchableInModule]
   ## Error code for VTd error.<BR><BR>
-- 
2.19.2.windows.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity.
  2019-10-31 12:31 [PATCH V2 0/6] Add Device Security driver Yao, Jiewen
                   ` (2 preceding siblings ...)
  2019-10-31 12:31 ` [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition Yao, Jiewen
@ 2019-10-31 12:31 ` Yao, Jiewen
  2019-11-07  6:38   ` Ni, Ray
  2019-10-31 12:31 ` [PATCH V2 5/6] IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy Yao, Jiewen
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Yao, Jiewen @ 2019-10-31 12:31 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Yun Lou

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

This driver is to do the PCI device authentication
based upon Intel PCIe Security Specification.

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Yun Lou <yun.lou@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.c   | 701 ++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.inf |  45 ++
 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/TcgDeviceEvent.h              | 193 ++++++
 3 files changed, 939 insertions(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.c b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.c
new file mode 100644
index 0000000000..f1859c2715
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/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.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <IndustryStandard/Spdm.h>
+#include <IndustryStandard/IntelPciSecurity.h>
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Tpm20.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/TpmMeasurementLib.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DeviceSecurity.h>
+#include <Protocol/PlatformDeviceSecurityPolicy.h>
+#include "TcgDeviceEvent.h"
+
+typedef struct {
+  UINT8                                             Measurement[SHA512_DIGEST_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 = 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 = PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice, &PciFunction);
+  ASSERT_EFI_ERROR(Status);
+
+  NewPciDevice = AllocateZeroPool(sizeof(*NewPciDevice));
+  ASSERT_EFI_ERROR(NewPciDevice != NULL);
+
+  NewPciDevice->Signature   = PCI_DEVICE_INSTANCE_SIGNATURE;
+  NewPciDevice->PciSegment  = PciSegment;
+  NewPciDevice->PciBus      = PciBus;
+  NewPciDevice->PciDevice   = PciDevice;
+  NewPciDevice->PciFunction = 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 = PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice, &PciFunction);
+  ASSERT_EFI_ERROR(Status);
+
+  Link = GetFirstNode(PciDeviceList);
+  while (!IsNull(PciDeviceList, Link)) {
+    CurrentPciDevice = PCI_DEVICE_INSTANCE_FROM_LINK(Link);
+
+    if (CurrentPciDevice->PciSegment == PciSegment && CurrentPciDevice->PciBus == PciBus &&
+        CurrentPciDevice->PciDevice == PciDevice && CurrentPciDevice->PciFunction == PciFunction) {
+      DEBUG((DEBUG_INFO, "PCI device duplicated (Loc - %04x:%02x:%02x:%02x)\n", PciSegment, PciBus, PciDevice, PciFunction));
+      return TRUE;
+    }
+
+    Link = 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 = ~CapId;
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_CAPBILITY_POINTER_OFFSET, 1, &PciCapIdHdr.NextItemPtr);
+  ASSERT_EFI_ERROR(Status);
+  if (PciCapIdHdr.NextItemPtr == 0 || PciCapIdHdr.NextItemPtr == 0xFF) {
+    return 0;
+  }
+  PciCapIdOffset = 0;
+  do {
+    if (PciCapIdHdr.CapabilityID == CapId) {
+      break;
+    }
+    PciCapIdOffset = PciCapIdHdr.NextItemPtr;
+    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PciCapIdOffset, 1, &PciCapIdHdr);
+    ASSERT_EFI_ERROR(Status);
+  } while (PciCapIdHdr.NextItemPtr != 0 && PciCapIdHdr.NextItemPtr != 0xFF);
+
+  if (PciCapIdHdr.CapabilityID == 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 = GetPciCapId (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP);
+  if (PcieCapIdOffset == 0) {
+    return 0;
+  }
+
+  PciExpressExtCapIdHdr.CapabilityId = ~CapId;
+  PciExpressExtCapIdHdr.CapabilityVersion = 0xF;
+  PciExpressExtCapIdHdr.NextCapabilityOffset = 0x100;
+  PcieCapIdOffset = 0;
+  do {
+    if (PciExpressExtCapIdHdr.CapabilityId == CapId) {
+      break;
+    }
+    PcieCapIdOffset = PciExpressExtCapIdHdr.NextCapabilityOffset;
+    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, PcieCapIdOffset, 1, &PciExpressExtCapIdHdr);
+    ASSERT_EFI_ERROR(Status);
+  } while (PciExpressExtCapIdHdr.NextCapabilityOffset != 0 && PciExpressExtCapIdHdr.NextCapabilityOffset != 0xFFF);
+
+  if (PciExpressExtCapIdHdr.CapabilityId == 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 space
+
+  @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 = 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 space
+  @param Data             Byte value of the PCI device configuration space.
+**/
+VOID
+DvSecPciWrite8 (
+  IN EFI_PCI_IO_PROTOCOL *PciIo,
+  IN UINT32              Offset,
+  IN UINT8               Data
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = 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 associated 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 associated 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 = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof(PciData), &PciData);
+  ASSERT_EFI_ERROR(Status);
+
+  PcrIndex = EDKII_DEVICE_MEASUREMENT_COMPONENT_PCR_INDEX;
+  EventType = EDKII_DEVICE_MEASUREMENT_COMPONENT_EVENT_TYPE;
+
+  CopyMem (EventLog.EventData.Signature, EDKII_DEVICE_SECURITY_EVENT_DATA_SIGNATURE, sizeof(EventLog.EventData.Signature));
+  EventLog.EventData.Version                  = EDKII_DEVICE_SECURITY_EVENT_DATA_VERSION;
+  EventLog.EventData.Length                   = sizeof(EDKII_DEVICE_SECURITY_PCI_EVENT_DATA);
+  EventLog.EventData.SpdmMeasurementBlock.Index                    = DigestSel;
+  EventLog.EventData.SpdmMeasurementBlock.MeasurementType          = SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWARE;
+  EventLog.EventData.SpdmMeasurementBlock.MeasurementSpecification = 0xFF;
+  EventLog.EventData.SpdmMeasurementBlock.Reserved                 = 0;
+  EventLog.EventData.SpdmHashAlgo       = TcgAlgIdToSpdmHashAlgo (TcgAlgId);
+  EventLog.EventData.DeviceType         = EDKII_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI;
+  ZeroMem (EventLog.EventData.Reserved, sizeof(EventLog.EventData.Reserved));
+  EventLog.PciContext.Version           = EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION;
+  EventLog.PciContext.Length            = sizeof(EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT);
+  EventLog.PciContext.VendorId          = PciData.Hdr.VendorId;
+  EventLog.PciContext.DeviceId          = PciData.Hdr.DeviceId;
+  EventLog.PciContext.RevisionID        = PciData.Hdr.RevisionID;
+  EventLog.PciContext.ClassCode[0]      = PciData.Hdr.ClassCode[0];
+  EventLog.PciContext.ClassCode[1]      = PciData.Hdr.ClassCode[1];
+  EventLog.PciContext.ClassCode[2]      = PciData.Hdr.ClassCode[2];
+  if ((PciData.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
+    EventLog.PciContext.SubsystemVendorID = PciData.Device.SubsystemVendorID;
+    EventLog.PciContext.SubsystemID       = PciData.Device.SubsystemID;
+  } else {
+    EventLog.PciContext.SubsystemVendorID = 0;
+    EventLog.PciContext.SubsystemID       = 0;
+  }
+
+  DigestSize = DigestSizeFromTcgAlgId (TcgAlgId);
+  CopyMem (&HashData.Measurement, Digest, DigestSize);
+
+  HashDataLen = DigestSize;
+  Status = TpmMeasureAndLogData (
+             PcrIndex,
+             EventType,
+             &EventLog,
+             EventLog.EventData.Length,
+             &HashData,
+             HashDataLen
+             );
+  DEBUG((DEBUG_INFO, "TpmMeasureAndLogData - %r\n", Status));
+  if (EFI_ERROR(Status)) {
+    DeviceSecurityState->MeasurementState = 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 device.
+  @param[in]  DeviceSecurityPolicy   The Device Security Policy associated with the device.
+  @param[out] DeviceSecurityState    The Device Security state associated 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 = 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 = DigestSizeFromTcgAlgId (TcgAlgId);
+  if (DigestSize == 0) {
+    DEBUG((DEBUG_INFO, "Unsupported Algorithm - 0x%04x\n", TcgAlgId));
+    DeviceSecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES;
+    return ;
+  }
+  DEBUG((DEBUG_INFO, "  (DigestSize: 0x%x)\n", DigestSize));
+
+  DeviceSecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
+
+  NumDigest = 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 = 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 = 2;
+  }
+
+  for (DigestSel = 0; DigestSel < NumDigest; DigestSel++) {
+    DEBUG((DEBUG_INFO, "  DigestSel     - 0x%02x\n", DigestSel));
+    if ((DigestSel == 0) && ((Valid & INTEL_PCI_DIGEST_0_VALID) == 0)) {
+      continue;
+    }
+    if ((DigestSel == 1) && ((Valid & INTEL_PCI_DIGEST_1_VALID) == 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 = 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 = DvSecPciRead8 (
+                   PciIo,
+                   DvSecOffset + sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEADER) + OFFSET_OF(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE, Modified)
+                   );
+      if ((Modified & INTEL_PCI_DIGEST_MODIFIED) == 0) {
+        break;
+      }
+    }
+
+    //
+    // Dump Digest
+    //
+    {
+      UINTN  Index;
+      DEBUG((DEBUG_INFO, "  Digest        - "));
+      for (Index = 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 associated with the device.
+  @param[out] DeviceSecurityState    The Device Security state associated 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 = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
+    return ;
+  }
+
+  DvSecOffset = GetPciExpressExtCapId (PciIo, INTEL_PCI_CAPID_DVSEC);
+  DEBUG((DEBUG_INFO, "DvSecOffset - 0x%x\n", DvSecOffset));
+  if (DvSecOffset == 0) {
+    DeviceSecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES;
+    return ;
+  }
+  Status = 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 != INTEL_PCI_DVSEC_VENDORID_INTEL) &&
+      (DvSecHdr.DvSecId != INTEL_PCI_DVSEC_DVSECID_MEASUREMENT)) {
+    DeviceSecurityState->MeasurementState = 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 associated with the device.
+  @param[out] DeviceSecurityState    The Device Security state associated 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 = 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 installs 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 measurement 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 == NULL) {
+    return EFI_SUCCESS;
+  }
+
+  if (!CompareGuid (&DeviceId->DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
+    return EFI_SUCCESS;
+  }
+
+  Status = gBS->HandleProtocol (
+                  DeviceId->DeviceHandle,
+                  &gEdkiiDeviceIdentifierTypePciGuid,
+                  (VOID **)&PciIo
+                  );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n", Status));
+    return EFI_SUCCESS;
+  }
+
+  DeviceSecurityState.Version = 0x1;
+  DeviceSecurityState.MeasurementState = 0x0;
+  DeviceSecurityState.AuthenticationState = 0x0;
+
+  Status = mDeviceSecurityPolicy->GetDevicePolicy (mDeviceSecurityPolicy, DeviceId, &DeviceSecurityPolicy);
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->GetDevicePolicy - %r\n", Status));
+    DeviceSecurityState.MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL;
+    DeviceSecurityState.AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL;
+  } else {
+    if ((DeviceSecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED) != 0) {
+      DoDeviceMeasurement (PciIo, DeviceSecurityPolicy, &DeviceSecurityState);
+      DEBUG((DEBUG_ERROR, "MeasurementState - 0x%08x\n", DeviceSecurityState.MeasurementState));
+    }
+    if ((DeviceSecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED) != 0) {
+      DoDeviceAuthentication (PciIo, DeviceSecurityPolicy, &DeviceSecurityState);
+      DEBUG((DEBUG_ERROR, "AuthenticationState - 0x%08x\n", DeviceSecurityState.AuthenticationState));
+    }
+  }
+
+  Status = mDeviceSecurityPolicy->SetDeviceState (mDeviceSecurityPolicy, DeviceId, &DeviceSecurityState);
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->SetDeviceState - %r\n", Status));
+  }
+
+  if ((DeviceSecurityState.MeasurementState == 0) &&
+      (DeviceSecurityState.AuthenticationState == 0)) {
+    return EFI_SUCCESS;
+  } else {
+    return EFI_SECURITY_VIOLATION;
+  }
+}
+
+EDKII_DEVICE_SECURITY_PROTOCOL mDeviceSecurity = {
+  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 = gBS->LocateProtocol (&gEdkiiDeviceSecurityPolicyProtocolGuid, NULL, (VOID **)&mDeviceSecurityPolicy);
+  ASSERT_EFI_ERROR(Status);
+
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEdkiiDeviceSecurityProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  (VOID **)&mDeviceSecurity
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.inf b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.inf
new file mode 100644
index 0000000000..89a4c8fadd
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.inf
@@ -0,0 +1,45 @@
+## @file
+#  EDKII Device Security library for PCI device
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = IntelPciDeviceSecurityDxe
+  FILE_GUID                      = D9569195-ED94-47D2-9523-38BF2D201371
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = 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/IntelPciDeviceSecurityDxe/TcgDeviceEvent.h b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/TcgDeviceEvent.h
new file mode 100644
index 0000000000..8b1227dace
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/TcgDeviceEvent.h
@@ -0,0 +1,193 @@
+/** @file
+  TCG Device Event data structure
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+
+#ifndef __TCG_EVENT_DATA_H__
+#define __TCG_EVENT_DATA_H__
+
+#include <IndustryStandard/Spdm.h>
+
+#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_VARAIBLE_NAME variable.
+// 2. The content of the EDKII_DEVICE_SIGNATURE_DATABASE_GUID/EDKII_DEVICE_ROOT_CERT_VARAIBLE2_NAME variable.
+// 3. Entries in the EDKII_DEVICE_SIGNATURE_DATABASE_GUID/EDKII_DEVICE_ROOT_CERT_VARAIBLE_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 platform 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 to 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 the 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 been, 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 value of UEFI_IMAGE_SECURITY_DATABASE.
+//            The value MUST NOT include the terminating NUL.
+//
+
+#pragma pack()
+
+#endif
-- 
2.19.2.windows.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 5/6] IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy.
  2019-10-31 12:31 [PATCH V2 0/6] Add Device Security driver Yao, Jiewen
                   ` (3 preceding siblings ...)
  2019-10-31 12:31 ` [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity Yao, Jiewen
@ 2019-10-31 12:31 ` Yao, Jiewen
  2019-11-07  6:55   ` [edk2-devel] " Ni, Ray
  2019-10-31 12:31 ` [PATCH V2 6/6] IntelSiliconPkg/dsc: Add Device Security component Yao, Jiewen
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Yao, Jiewen @ 2019-10-31 12:31 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Yun Lou

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

This driver provides the platform sample policy to measure
a NVMe card.

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.c   | 189 ++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.inf |  40 +++++
 2 files changed, 229 insertions(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.c b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.c
new file mode 100644
index 0000000000..1f01b961a8
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.c
@@ -0,0 +1,189 @@
+/** @file
+  EDKII Device Security library for PCI device
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <IndustryStandard/Spdm.h>
+#include <IndustryStandard/Pci.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DeviceSecurity.h>
+#include <Protocol/PlatformDeviceSecurityPolicy.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+EDKII_DEVICE_SECURITY_POLICY           mDeviceSecurityPolicyNone = {
+  0x1,
+  0,
+  0,
+};
+EDKII_DEVICE_SECURITY_POLICY           mDeviceSecurityPolicyMeasurement = {
+  0x1,
+  EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED,
+  0,
+};
+
+/**
+  This function returns the device security policy associated with the device.
+
+  @param[in]  This                   The protocol instance pointer.
+  @param[in]  DeviceId               The Identifier for the device.
+  @param[out] DeviceSecurityPolicy   The Device Security Policy associated with the device.
+
+  @retval EFI_SUCCESS                The device security policy is returned
+**/
+EFI_STATUS
+EFIAPI
+GetDevicePolicy (
+  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
+  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
+  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PCI_IO_PROTOCOL         *PciIo;
+  UINT16                      PciVendorId;
+  UINT16                      PciDeviceId;
+
+  *DeviceSecurityPolicy = &mDeviceSecurityPolicyNone;
+
+  DEBUG ((DEBUG_INFO, "GetDevicePolicy - 0x%g\n", &DeviceId->DeviceType));
+
+  if (!CompareGuid (&DeviceId->DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
+    return EFI_SUCCESS;
+  }
+
+  Status = gBS->HandleProtocol (
+                  DeviceId->DeviceHandle,
+                  &gEdkiiDeviceIdentifierTypePciGuid,
+                  (VOID **)&PciIo
+                  );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n", Status));
+    return EFI_SUCCESS;
+  }
+
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET, 1, &PciVendorId);
+  ASSERT_EFI_ERROR(Status);
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET, 1, &PciDeviceId);
+  ASSERT_EFI_ERROR(Status);
+  DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId, PciDeviceId));
+
+  if ((PciVendorId == 0x8086) && (PciDeviceId == 0x0B60)) {
+    *DeviceSecurityPolicy = &mDeviceSecurityPolicyMeasurement;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets the device state based upon the authentication result.
+
+  @param[in]  This                   The protocol instance pointer.
+  @param[in]  DeviceId               The Identifier for the device.
+  @param[in]  DeviceSecurityState    The Device Security state associated with the device.
+
+  @retval EFI_SUCCESS                The device state is set
+**/
+EFI_STATUS
+EFIAPI
+SetDeviceState (
+  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
+  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
+  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PCI_IO_PROTOCOL         *PciIo;
+  UINT16                      PciVendorId;
+  UINT16                      PciDeviceId;
+  UINTN                       Segment;
+  UINTN                       Bus;
+  UINTN                       Device;
+  UINTN                       Function;
+
+  DEBUG ((DEBUG_INFO, "SetDeviceState - 0x%g\n", &DeviceId->DeviceType));
+
+  if (!CompareGuid (&DeviceId->DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
+    return EFI_SUCCESS;
+  }
+
+  Status = gBS->HandleProtocol (
+                  DeviceId->DeviceHandle,
+                  &gEdkiiDeviceIdentifierTypePciGuid,
+                  (VOID **)&PciIo
+                  );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n", Status));
+    return EFI_SUCCESS;
+  }
+
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET, 1, &PciVendorId);
+  ASSERT_EFI_ERROR(Status);
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET, 1, &PciDeviceId);
+  ASSERT_EFI_ERROR(Status);
+  DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId, PciDeviceId));
+
+  Status = PciIo->GetLocation (
+                    PciIo,
+                    &Segment,
+                    &Bus,
+                    &Device,
+                    &Function
+                    );
+  if (!EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_INFO, "PCI Loc - %04x:%02x:%02x:%02x\n",
+      Segment, Bus, Device, Function));
+  }
+
+  DEBUG ((DEBUG_INFO, "State - Measurement - 0x%08x, Authentication - 0x%08x\n",
+    DeviceSecurityState->MeasurementState,
+    DeviceSecurityState->AuthenticationState
+    ));
+
+  return EFI_SUCCESS;
+}
+
+EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  mDeviceSecurityPolicy = {
+  0x1,
+  GetDevicePolicy,
+  SetDeviceState,
+};
+
+/**
+  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;
+
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEdkiiDeviceSecurityPolicyProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mDeviceSecurityPolicy
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.inf b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.inf
new file mode 100644
index 0000000000..a9b77d8371
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.inf
@@ -0,0 +1,40 @@
+## @file
+#  EDKII Device Security library for PCI device
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SamplePlatformDevicePolicyDxe
+  FILE_GUID                      = 7EA7AACF-7ED3-4166-8271-B21156523620
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = MainEntryPoint
+
+[Sources]
+  SamplePlatformDevicePolicyDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+
+[LibraryClasses]
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  DevicePathLib
+  BaseMemoryLib
+  PrintLib
+  DebugLib
+
+[Protocols]
+  gEdkiiDeviceSecurityPolicyProtocolGuid  ## PRODUCES
+  gEdkiiDeviceIdentifierTypePciGuid       ## COMSUMES
+
+[Depex]
+  TRUE
-- 
2.19.2.windows.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 6/6] IntelSiliconPkg/dsc: Add Device Security component.
  2019-10-31 12:31 [PATCH V2 0/6] Add Device Security driver Yao, Jiewen
                   ` (4 preceding siblings ...)
  2019-10-31 12:31 ` [PATCH V2 5/6] IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy Yao, Jiewen
@ 2019-10-31 12:31 ` Yao, Jiewen
       [not found] ` <15D2BB3E562C773B.23805@groups.io>
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-10-31 12:31 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Yun Lou

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
index df8984a606..0a6509d8b3 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
@@ -35,6 +35,7 @@
   CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
   MicrocodeFlashAccessLib|IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf
   PeiGetVtdPmrAlignmentLib|IntelSiliconPkg/Library/PeiGetVtdPmrAlignmentLib/PeiGetVtdPmrAlignmentLib.inf
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
 
 [LibraryClasses.common.PEIM]
   PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
@@ -75,6 +76,8 @@
 
 [Components]
   IntelSiliconPkg/Library/DxeSmbiosDataHobLib/DxeSmbiosDataHobLib.inf
+  IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSecurityDxe.inf
+  IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePlatformDevicePolicyDxe.inf
   IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
   IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
   IntelSiliconPkg/Feature/VTd/PlatformVTdSampleDxe/PlatformVTdSampleDxe.inf
-- 
2.19.2.windows.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [edk2-devel] [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol
       [not found] ` <15D2BB3E562C773B.23805@groups.io>
@ 2019-11-06  6:48   ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-06  6:48 UTC (permalink / raw)
  To: devel@edk2.groups.io, Yao, Jiewen; +Cc: Ni, Ray, Chaganty, Rangasai V, Lou, Yun

Hi Ray/Sai
Would you please review this patch?

We need this feature in next stable tag as planned.

Thank you
Yao Jiewen

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao, Jiewen
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [edk2-devel] [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform
> Device Security Policy protocol
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h |
> 84 ++++++++++++++++++++
>  1 file changed, 84 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
> new file mode 100644
> index 0000000000..cb5a71ad41
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
> @@ -0,0 +1,84 @@
> +/** @file
> +  Device Security Policy Protocol definition
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +
> +#ifndef __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
> +#define __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
> +
> +#include <Uefi.h>
> +#include <Protocol/DeviceSecurity.h>
> +
> +typedef struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL
> EDKII_DEVICE_SECURITY_POLICY_PROTOCOL;
> +
> +typedef struct {
> +  UINT32     Version; // 0x1
> +  UINT32     MeasurementPolicy;
> +  UINT32     AuthenticationPolicy;
> +} EDKII_DEVICE_SECURITY_POLICY;
> +
> +// BIT0 means if the action is needed or NOT
> +#define EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED                 BIT0
> +#define EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED              BIT0
> +
> +typedef struct {
> +  UINT32     Version; // 0x1
> +  UINT32     MeasurementState;
> +  UINT32     AuthenticationState;
> +} EDKII_DEVICE_SECURITY_STATE;
> +
> +// All zero means success
> +#define EDKII_DEVICE_SECURITY_STATE_SUCCESS                          0
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR                            BIT31
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x0)
> +#define
> EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x1)
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x10)
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x20)
> +
> +/**
> +  This function returns the device security policy associated with the device.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[out] DeviceSecurityPolicy   The Device Security Policy associated
> with the device.
> +
> +  @retval EFI_SUCCESS                The device security policy is returned
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY) (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
> +  );
> +
> +/**
> +  This function sets the device state based upon the authentication result.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[in]  DeviceSecurityState    The Device Security state associated with
> the device.
> +
> +  @retval EFI_SUCCESS                The device state is set
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_DEVICE_SECURITY_SET_DEVICE_STATE) (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
> +  );
> +
> +struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL {
> +  UINT32                                   Version; // 0x1
> +  EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY  GetDevicePolicy;
> +  EDKII_DEVICE_SECURITY_SET_DEVICE_STATE   SetDeviceState;
> +};
> +
> +extern EFI_GUID gEdkiiDeviceSecurityPolicyProtocolGuid;
> +
> +#endif
> --
> 2.19.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [edk2-devel] [PATCH V2 5/6] IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy.
       [not found] ` <15D2BB3F6D7204CF.23805@groups.io>
@ 2019-11-06  6:48   ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-06  6:48 UTC (permalink / raw)
  To: devel@edk2.groups.io, Yao, Jiewen; +Cc: Ni, Ray, Chaganty, Rangasai V, Lou, Yun

Hi Ray/Sai
Would you please review this patch?

We need this feature in next stable tag as planned.

Thank you
Yao Jiewen

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao, Jiewen
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [edk2-devel] [PATCH V2 5/6]
> IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> This driver provides the platform sample policy to measure
> a NVMe card.
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyD
> xe/SamplePlatformDevicePolicyDxe.c   | 189 ++++++++++++++++++++
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyD
> xe/SamplePlatformDevicePolicyDxe.inf |  40 +++++
>  2 files changed, 229 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolic
> yDxe/SamplePlatformDevicePolicyDxe.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolic
> yDxe/SamplePlatformDevicePolicyDxe.c
> new file mode 100644
> index 0000000000..1f01b961a8
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolic
> yDxe/SamplePlatformDevicePolicyDxe.c
> @@ -0,0 +1,189 @@
> +/** @file
> +  EDKII Device Security library for PCI device
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <IndustryStandard/Spdm.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/DeviceSecurity.h>
> +#include <Protocol/PlatformDeviceSecurityPolicy.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +EDKII_DEVICE_SECURITY_POLICY           mDeviceSecurityPolicyNone = {
> +  0x1,
> +  0,
> +  0,
> +};
> +EDKII_DEVICE_SECURITY_POLICY           mDeviceSecurityPolicyMeasurement = {
> +  0x1,
> +  EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED,
> +  0,
> +};
> +
> +/**
> +  This function returns the device security policy associated with the device.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[out] DeviceSecurityPolicy   The Device Security Policy associated
> with the device.
> +
> +  @retval EFI_SUCCESS                The device security policy is returned
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDevicePolicy (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PCI_IO_PROTOCOL         *PciIo;
> +  UINT16                      PciVendorId;
> +  UINT16                      PciDeviceId;
> +
> +  *DeviceSecurityPolicy = &mDeviceSecurityPolicyNone;
> +
> +  DEBUG ((DEBUG_INFO, "GetDevicePolicy - 0x%g\n", &DeviceId->DeviceType));
> +
> +  if (!CompareGuid (&DeviceId->DeviceType,
> &gEdkiiDeviceIdentifierTypePciGuid)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = gBS->HandleProtocol (
> +                  DeviceId->DeviceHandle,
> +                  &gEdkiiDeviceIdentifierTypePciGuid,
> +                  (VOID **)&PciIo
> +                  );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n", Status));
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> PCI_VENDOR_ID_OFFSET, 1, &PciVendorId);
> +  ASSERT_EFI_ERROR(Status);
> +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET,
> 1, &PciDeviceId);
> +  ASSERT_EFI_ERROR(Status);
> +  DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId, PciDeviceId));
> +
> +  if ((PciVendorId == 0x8086) && (PciDeviceId == 0x0B60)) {
> +    *DeviceSecurityPolicy = &mDeviceSecurityPolicyMeasurement;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets the device state based upon the authentication result.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[in]  DeviceSecurityState    The Device Security state associated with
> the device.
> +
> +  @retval EFI_SUCCESS                The device state is set
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetDeviceState (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PCI_IO_PROTOCOL         *PciIo;
> +  UINT16                      PciVendorId;
> +  UINT16                      PciDeviceId;
> +  UINTN                       Segment;
> +  UINTN                       Bus;
> +  UINTN                       Device;
> +  UINTN                       Function;
> +
> +  DEBUG ((DEBUG_INFO, "SetDeviceState - 0x%g\n", &DeviceId->DeviceType));
> +
> +  if (!CompareGuid (&DeviceId->DeviceType,
> &gEdkiiDeviceIdentifierTypePciGuid)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = gBS->HandleProtocol (
> +                  DeviceId->DeviceHandle,
> +                  &gEdkiiDeviceIdentifierTypePciGuid,
> +                  (VOID **)&PciIo
> +                  );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n", Status));
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> PCI_VENDOR_ID_OFFSET, 1, &PciVendorId);
> +  ASSERT_EFI_ERROR(Status);
> +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET,
> 1, &PciDeviceId);
> +  ASSERT_EFI_ERROR(Status);
> +  DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId, PciDeviceId));
> +
> +  Status = PciIo->GetLocation (
> +                    PciIo,
> +                    &Segment,
> +                    &Bus,
> +                    &Device,
> +                    &Function
> +                    );
> +  if (!EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_INFO, "PCI Loc - %04x:%02x:%02x:%02x\n",
> +      Segment, Bus, Device, Function));
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "State - Measurement - 0x%08x, Authentication -
> 0x%08x\n",
> +    DeviceSecurityState->MeasurementState,
> +    DeviceSecurityState->AuthenticationState
> +    ));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  mDeviceSecurityPolicy = {
> +  0x1,
> +  GetDevicePolicy,
> +  SetDeviceState,
> +};
> +
> +/**
> +  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;
> +
> +  Handle = NULL;
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gEdkiiDeviceSecurityPolicyProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mDeviceSecurityPolicy
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolic
> yDxe/SamplePlatformDevicePolicyDxe.inf
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolic
> yDxe/SamplePlatformDevicePolicyDxe.inf
> new file mode 100644
> index 0000000000..a9b77d8371
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolic
> yDxe/SamplePlatformDevicePolicyDxe.inf
> @@ -0,0 +1,40 @@
> +## @file
> +#  EDKII Device Security library for PCI device
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SamplePlatformDevicePolicyDxe
> +  FILE_GUID                      = 7EA7AACF-7ED3-4166-8271-B21156523620
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = MainEntryPoint
> +
> +[Sources]
> +  SamplePlatformDevicePolicyDxe.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +[LibraryClasses]
> +  UefiRuntimeServicesTableLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  MemoryAllocationLib
> +  DevicePathLib
> +  BaseMemoryLib
> +  PrintLib
> +  DebugLib
> +
> +[Protocols]
> +  gEdkiiDeviceSecurityPolicyProtocolGuid  ## PRODUCES
> +  gEdkiiDeviceIdentifierTypePciGuid       ## COMSUMES
> +
> +[Depex]
> +  TRUE
> --
> 2.19.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [edk2-devel] [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity.
       [not found] ` <15D2BB3F2A1C2156.31603@groups.io>
@ 2019-11-06  6:48   ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-06  6:48 UTC (permalink / raw)
  To: devel@edk2.groups.io, Yao, Jiewen; +Cc: Ni, Ray, Chaganty, Rangasai V, Lou, Yun

Hi Ray/Sai
Would you please review this patch?

We need this feature in next stable tag as planned.

Thank you
Yao Jiewen

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao, Jiewen
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [edk2-devel] [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe:
> Add PciSecurity.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> This driver is to do the PCI device authentication
> based upon Intel PCIe Security Specification.
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> Signed-off-by: Yun Lou <yun.lou@intel.com>
> ---
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/Int
> elPciDeviceSecurityDxe.c   | 701 ++++++++++++++++++++
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/Int
> elPciDeviceSecurityDxe.inf |  45 ++
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/Tcg
> DeviceEvent.h              | 193 ++++++
>  3 files changed, 939 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/I
> ntelPciDeviceSecurityDxe.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/I
> ntelPciDeviceSecurityDxe.c
> new file mode 100644
> index 0000000000..f1859c2715
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/I
> ntelPciDeviceSecurityDxe.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.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <IndustryStandard/Spdm.h>
> +#include <IndustryStandard/IntelPciSecurity.h>
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/Tpm20.h>
> +#include <IndustryStandard/UefiTcgPlatform.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/TpmMeasurementLib.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/DeviceSecurity.h>
> +#include <Protocol/PlatformDeviceSecurityPolicy.h>
> +#include "TcgDeviceEvent.h"
> +
> +typedef struct {
> +  UINT8                                             Measurement[SHA512_DIGEST_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 =
> 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 = PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice,
> &PciFunction);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  NewPciDevice = AllocateZeroPool(sizeof(*NewPciDevice));
> +  ASSERT_EFI_ERROR(NewPciDevice != NULL);
> +
> +  NewPciDevice->Signature   = PCI_DEVICE_INSTANCE_SIGNATURE;
> +  NewPciDevice->PciSegment  = PciSegment;
> +  NewPciDevice->PciBus      = PciBus;
> +  NewPciDevice->PciDevice   = PciDevice;
> +  NewPciDevice->PciFunction = 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 = PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice,
> &PciFunction);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Link = GetFirstNode(PciDeviceList);
> +  while (!IsNull(PciDeviceList, Link)) {
> +    CurrentPciDevice = PCI_DEVICE_INSTANCE_FROM_LINK(Link);
> +
> +    if (CurrentPciDevice->PciSegment == PciSegment && CurrentPciDevice-
> >PciBus == PciBus &&
> +        CurrentPciDevice->PciDevice == PciDevice && CurrentPciDevice-
> >PciFunction == PciFunction) {
> +      DEBUG((DEBUG_INFO, "PCI device duplicated (Loc -
>  %04x:%02x:%02x:%02x)\n", PciSegment, PciBus, PciDevice, PciFunction));
> +      return TRUE;
> +    }
> +
> +    Link = 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 = ~CapId;
> +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8,
> PCI_CAPBILITY_POINTER_OFFSET, 1, &PciCapIdHdr.NextItemPtr);
> +  ASSERT_EFI_ERROR(Status);
> +  if (PciCapIdHdr.NextItemPtr == 0 || PciCapIdHdr.NextItemPtr == 0xFF) {
> +    return 0;
> +  }
> +  PciCapIdOffset = 0;
> +  do {
> +    if (PciCapIdHdr.CapabilityID == CapId) {
> +      break;
> +    }
> +    PciCapIdOffset = PciCapIdHdr.NextItemPtr;
> +    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PciCapIdOffset, 1,
> &PciCapIdHdr);
> +    ASSERT_EFI_ERROR(Status);
> +  } while (PciCapIdHdr.NextItemPtr != 0 && PciCapIdHdr.NextItemPtr != 0xFF);
> +
> +  if (PciCapIdHdr.CapabilityID == 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 = GetPciCapId (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP);
> +  if (PcieCapIdOffset == 0) {
> +    return 0;
> +  }
> +
> +  PciExpressExtCapIdHdr.CapabilityId = ~CapId;
> +  PciExpressExtCapIdHdr.CapabilityVersion = 0xF;
> +  PciExpressExtCapIdHdr.NextCapabilityOffset = 0x100;
> +  PcieCapIdOffset = 0;
> +  do {
> +    if (PciExpressExtCapIdHdr.CapabilityId == CapId) {
> +      break;
> +    }
> +    PcieCapIdOffset = PciExpressExtCapIdHdr.NextCapabilityOffset;
> +    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, PcieCapIdOffset, 1,
> &PciExpressExtCapIdHdr);
> +    ASSERT_EFI_ERROR(Status);
> +  } while (PciExpressExtCapIdHdr.NextCapabilityOffset != 0 &&
> PciExpressExtCapIdHdr.NextCapabilityOffset != 0xFFF);
> +
> +  if (PciExpressExtCapIdHdr.CapabilityId == 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 space
> +
> +  @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 = 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 space
> +  @param Data             Byte value of the PCI device configuration space.
> +**/
> +VOID
> +DvSecPciWrite8 (
> +  IN EFI_PCI_IO_PROTOCOL *PciIo,
> +  IN UINT32              Offset,
> +  IN UINT8               Data
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = 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 associated 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 associated 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 = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof(PciData),
> &PciData);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  PcrIndex = EDKII_DEVICE_MEASUREMENT_COMPONENT_PCR_INDEX;
> +  EventType = EDKII_DEVICE_MEASUREMENT_COMPONENT_EVENT_TYPE;
> +
> +  CopyMem (EventLog.EventData.Signature,
> EDKII_DEVICE_SECURITY_EVENT_DATA_SIGNATURE,
> sizeof(EventLog.EventData.Signature));
> +  EventLog.EventData.Version                  =
> EDKII_DEVICE_SECURITY_EVENT_DATA_VERSION;
> +  EventLog.EventData.Length                   =
> sizeof(EDKII_DEVICE_SECURITY_PCI_EVENT_DATA);
> +  EventLog.EventData.SpdmMeasurementBlock.Index                    = DigestSel;
> +  EventLog.EventData.SpdmMeasurementBlock.MeasurementType          =
> SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWARE;
> +  EventLog.EventData.SpdmMeasurementBlock.MeasurementSpecification =
> 0xFF;
> +  EventLog.EventData.SpdmMeasurementBlock.Reserved                 = 0;
> +  EventLog.EventData.SpdmHashAlgo       = TcgAlgIdToSpdmHashAlgo
> (TcgAlgId);
> +  EventLog.EventData.DeviceType         =
> EDKII_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI;
> +  ZeroMem (EventLog.EventData.Reserved,
> sizeof(EventLog.EventData.Reserved));
> +  EventLog.PciContext.Version           =
> EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION;
> +  EventLog.PciContext.Length            =
> sizeof(EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT);
> +  EventLog.PciContext.VendorId          = PciData.Hdr.VendorId;
> +  EventLog.PciContext.DeviceId          = PciData.Hdr.DeviceId;
> +  EventLog.PciContext.RevisionID        = PciData.Hdr.RevisionID;
> +  EventLog.PciContext.ClassCode[0]      = PciData.Hdr.ClassCode[0];
> +  EventLog.PciContext.ClassCode[1]      = PciData.Hdr.ClassCode[1];
> +  EventLog.PciContext.ClassCode[2]      = PciData.Hdr.ClassCode[2];
> +  if ((PciData.Hdr.HeaderType & HEADER_LAYOUT_CODE) ==
> HEADER_TYPE_DEVICE) {
> +    EventLog.PciContext.SubsystemVendorID =
> PciData.Device.SubsystemVendorID;
> +    EventLog.PciContext.SubsystemID       = PciData.Device.SubsystemID;
> +  } else {
> +    EventLog.PciContext.SubsystemVendorID = 0;
> +    EventLog.PciContext.SubsystemID       = 0;
> +  }
> +
> +  DigestSize = DigestSizeFromTcgAlgId (TcgAlgId);
> +  CopyMem (&HashData.Measurement, Digest, DigestSize);
> +
> +  HashDataLen = DigestSize;
> +  Status = TpmMeasureAndLogData (
> +             PcrIndex,
> +             EventType,
> +             &EventLog,
> +             EventLog.EventData.Length,
> +             &HashData,
> +             HashDataLen
> +             );
> +  DEBUG((DEBUG_INFO, "TpmMeasureAndLogData - %r\n", Status));
> +  if (EFI_ERROR(Status)) {
> +    DeviceSecurityState->MeasurementState =
> 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 device.
> +  @param[in]  DeviceSecurityPolicy   The Device Security Policy associated with
> the device.
> +  @param[out] DeviceSecurityState    The Device Security state associated 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 = 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 = DigestSizeFromTcgAlgId (TcgAlgId);
> +  if (DigestSize == 0) {
> +    DEBUG((DEBUG_INFO, "Unsupported Algorithm - 0x%04x\n", TcgAlgId));
> +    DeviceSecurityState->MeasurementState =
> EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES;
> +    return ;
> +  }
> +  DEBUG((DEBUG_INFO, "  (DigestSize: 0x%x)\n", DigestSize));
> +
> +  DeviceSecurityState->MeasurementState =
> EDKII_DEVICE_SECURITY_STATE_SUCCESS;
> +
> +  NumDigest = 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 = 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 = 2;
> +  }
> +
> +  for (DigestSel = 0; DigestSel < NumDigest; DigestSel++) {
> +    DEBUG((DEBUG_INFO, "  DigestSel     - 0x%02x\n", DigestSel));
> +    if ((DigestSel == 0) && ((Valid & INTEL_PCI_DIGEST_0_VALID) == 0)) {
> +      continue;
> +    }
> +    if ((DigestSel == 1) && ((Valid & INTEL_PCI_DIGEST_1_VALID) == 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 = 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 = DvSecPciRead8 (
> +                   PciIo,
> +                   DvSecOffset + sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEADER) +
> OFFSET_OF(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE, Modified)
> +                   );
> +      if ((Modified & INTEL_PCI_DIGEST_MODIFIED) == 0) {
> +        break;
> +      }
> +    }
> +
> +    //
> +    // Dump Digest
> +    //
> +    {
> +      UINTN  Index;
> +      DEBUG((DEBUG_INFO, "  Digest        - "));
> +      for (Index = 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 associated with
> the device.
> +  @param[out] DeviceSecurityState    The Device Security state associated 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 =
> EDKII_DEVICE_SECURITY_STATE_SUCCESS;
> +    return ;
> +  }
> +
> +  DvSecOffset = GetPciExpressExtCapId (PciIo, INTEL_PCI_CAPID_DVSEC);
> +  DEBUG((DEBUG_INFO, "DvSecOffset - 0x%x\n", DvSecOffset));
> +  if (DvSecOffset == 0) {
> +    DeviceSecurityState->MeasurementState =
> EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES;
> +    return ;
> +  }
> +  Status = 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 != INTEL_PCI_DVSEC_VENDORID_INTEL) &&
> +      (DvSecHdr.DvSecId != INTEL_PCI_DVSEC_DVSECID_MEASUREMENT)) {
> +    DeviceSecurityState->MeasurementState =
> 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 associated with
> the device.
> +  @param[out] DeviceSecurityState    The Device Security state associated 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 =
> 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 installs 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 measurement 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 == NULL) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (!CompareGuid (&DeviceId->DeviceType,
> &gEdkiiDeviceIdentifierTypePciGuid)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = gBS->HandleProtocol (
> +                  DeviceId->DeviceHandle,
> +                  &gEdkiiDeviceIdentifierTypePciGuid,
> +                  (VOID **)&PciIo
> +                  );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n", Status));
> +    return EFI_SUCCESS;
> +  }
> +
> +  DeviceSecurityState.Version = 0x1;
> +  DeviceSecurityState.MeasurementState = 0x0;
> +  DeviceSecurityState.AuthenticationState = 0x0;
> +
> +  Status = mDeviceSecurityPolicy->GetDevicePolicy (mDeviceSecurityPolicy,
> DeviceId, &DeviceSecurityPolicy);
> +  if (EFI_ERROR(Status)) {
> +    DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->GetDevicePolicy - %r\n",
> Status));
> +    DeviceSecurityState.MeasurementState =
> EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL;
> +    DeviceSecurityState.AuthenticationState =
> EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL;
> +  } else {
> +    if ((DeviceSecurityPolicy->MeasurementPolicy &
> EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED) != 0) {
> +      DoDeviceMeasurement (PciIo, DeviceSecurityPolicy, &DeviceSecurityState);
> +      DEBUG((DEBUG_ERROR, "MeasurementState - 0x%08x\n",
> DeviceSecurityState.MeasurementState));
> +    }
> +    if ((DeviceSecurityPolicy->AuthenticationPolicy &
> EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED) != 0) {
> +      DoDeviceAuthentication (PciIo, DeviceSecurityPolicy, &DeviceSecurityState);
> +      DEBUG((DEBUG_ERROR, "AuthenticationState - 0x%08x\n",
> DeviceSecurityState.AuthenticationState));
> +    }
> +  }
> +
> +  Status = mDeviceSecurityPolicy->SetDeviceState (mDeviceSecurityPolicy,
> DeviceId, &DeviceSecurityState);
> +  if (EFI_ERROR(Status)) {
> +    DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->SetDeviceState - %r\n",
> Status));
> +  }
> +
> +  if ((DeviceSecurityState.MeasurementState == 0) &&
> +      (DeviceSecurityState.AuthenticationState == 0)) {
> +    return EFI_SUCCESS;
> +  } else {
> +    return EFI_SECURITY_VIOLATION;
> +  }
> +}
> +
> +EDKII_DEVICE_SECURITY_PROTOCOL mDeviceSecurity = {
> +  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 = gBS->LocateProtocol (&gEdkiiDeviceSecurityPolicyProtocolGuid,
> NULL, (VOID **)&mDeviceSecurityPolicy);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Handle = NULL;
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gEdkiiDeviceSecurityProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  (VOID **)&mDeviceSecurity
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/I
> ntelPciDeviceSecurityDxe.inf
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/I
> ntelPciDeviceSecurityDxe.inf
> new file mode 100644
> index 0000000000..89a4c8fadd
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/I
> ntelPciDeviceSecurityDxe.inf
> @@ -0,0 +1,45 @@
> +## @file
> +#  EDKII Device Security library for PCI device
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = IntelPciDeviceSecurityDxe
> +  FILE_GUID                      = D9569195-ED94-47D2-9523-38BF2D201371
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = 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/IntelPciDeviceSecurityDxe/T
> cgDeviceEvent.h
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/T
> cgDeviceEvent.h
> new file mode 100644
> index 0000000000..8b1227dace
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/T
> cgDeviceEvent.h
> @@ -0,0 +1,193 @@
> +/** @file
> +  TCG Device Event data structure
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +
> +#ifndef __TCG_EVENT_DATA_H__
> +#define __TCG_EVENT_DATA_H__
> +
> +#include <IndustryStandard/Spdm.h>
> +
> +#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_VARA
> IBLE_NAME variable.
> +// 2. The content of the
> EDKII_DEVICE_SIGNATURE_DATABASE_GUID/EDKII_DEVICE_ROOT_CERT_VARA
> IBLE2_NAME variable.
> +// 3. Entries in the
> EDKII_DEVICE_SIGNATURE_DATABASE_GUID/EDKII_DEVICE_ROOT_CERT_VARA
> IBLE_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 platform 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 to
> 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 the 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 been, 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 value of
> UEFI_IMAGE_SECURITY_DATABASE.
> +//            The value MUST NOT include the terminating NUL.
> +//
> +
> +#pragma pack()
> +
> +#endif
> --
> 2.19.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [edk2-devel] [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition.
       [not found] ` <15D2BB3E9D627794.4494@groups.io>
@ 2019-11-06  6:48   ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-06  6:48 UTC (permalink / raw)
  To: devel@edk2.groups.io, Yao, Jiewen; +Cc: Ni, Ray, Chaganty, Rangasai V, Lou, Yun

Hi Ray/Sai
Would you please review this patch?

We need this feature in next stable tag as planned.

Thank you
Yao Jiewen

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao, Jiewen
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [edk2-devel] [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid
> definition.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> index 3079fc2869..8c8cd9f49d 100644
> --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> @@ -53,6 +53,7 @@
> 
>  [Protocols]
>    gEdkiiPlatformVTdPolicyProtocolGuid = { 0x3d17e448, 0x466, 0x4e20, { 0x99,
> 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 }}
> +  gEdkiiDeviceSecurityPolicyProtocolGuid = {0x7ea41a99, 0x5e32, 0x4c97,
> {0x88, 0xc4, 0xd6, 0xe7, 0x46, 0x84, 0x9, 0xd4}}
> 
>  [PcdsFixedAtBuild, PcdsPatchableInModule]
>    ## Error code for VTd error.<BR><BR>
> --
> 2.19.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [edk2-devel] [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition.
       [not found] ` <15D2BB3E0A913641.22120@groups.io>
@ 2019-11-06  6:48   ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-06  6:48 UTC (permalink / raw)
  To: devel@edk2.groups.io, Yao, Jiewen; +Cc: Ni, Ray, Chaganty, Rangasai V, Lou, Yun

Hi Ray/Sai
Would you please review this patch?

We need this feature in next stable tag as planned.

Thank you
Yao Jiewen

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao, Jiewen
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [edk2-devel] [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel
> PciSecurity definition.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h | 66
> ++++++++++++++++++++
>  1 file changed, 66 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> new file mode 100644
> index 0000000000..a8c5483165
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> @@ -0,0 +1,66 @@
> +/** @file
> +  Intel PCI security data structure
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __INTEL_PCI_SECURITY_H__
> +#define __INTEL_PCI_SECURITY_H__
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT16  CapId;           // 0x23: DVSEC
> +  UINT16  CapVersion:4;    // 1
> +  UINT16  NextOffset:12;
> +  UINT16  DvSecVendorId;   // 0x8086
> +  UINT16  DvSecRevision:4; // 1
> +  UINT16  DvSecLength:12;
> +  UINT16  DvSecId;         // 0x3E: Measure
> +} INTEL_PCI_DIGEST_CAPABILITY_HEADER;
> +
> +#define INTEL_PCI_CAPID_DVSEC                0x23
> +#define INTEL_PCI_DVSEC_VENDORID_INTEL       0x8086
> +#define INTEL_PCI_DVSEC_DVSECID_MEASUREMENT  0x3E
> +
> +typedef union {
> +  struct {
> +    UINT8   DigestModified:1;         // RW1C
> +    UINT8   Reserved0:7;
> +  } Bits;
> +  UINT8 Data;
> +} INTEL_PCI_DIGEST_DATA_MODIFIED;
> +
> +#define INTEL_PCI_DIGEST_MODIFIED        BIT0
> +
> +typedef union {
> +  struct {
> +    UINT8   Digest0Valid:1;          // RO
> +    UINT8   Digest0Locked:1;         // RO
> +    UINT8   Digest1Valid:1;          // RO
> +    UINT8   Digest1Locked:1;         // RO
> +    UINT8   Reserved1:4;
> +  } Bits;
> +  UINT8 Data;
> +} INTEL_PCI_DIGEST_DATA_VALID;
> +
> +#define INTEL_PCI_DIGEST_0_VALID         BIT0
> +#define INTEL_PCI_DIGEST_0_LOCKED        BIT1
> +#define INTEL_PCI_DIGEST_1_VALID         BIT2
> +#define INTEL_PCI_DIGEST_1_LOCKED        BIT3
> +
> +typedef struct {
> +  INTEL_PCI_DIGEST_DATA_MODIFIED   Modified;   // RW1C
> +  INTEL_PCI_DIGEST_DATA_VALID      Valid;      // RO
> +  UINT16                           TcgAlgId;   // RO
> +  UINT8                            FirmwareID; // RO
> +  UINT8                            Reserved;
> +//UINT8                            Digest[];
> +} INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE;
> +
> +#pragma pack()
> +
> +#endif
> +
> --
> 2.19.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [edk2-devel] [PATCH V2 6/6] IntelSiliconPkg/dsc: Add Device Security component.
       [not found] ` <15D2BB3FAC504840.31603@groups.io>
@ 2019-11-06  6:48   ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-06  6:48 UTC (permalink / raw)
  To: devel@edk2.groups.io, Yao, Jiewen; +Cc: Ni, Ray, Chaganty, Rangasai V, Lou, Yun

Hi Ray/Sai
Would you please review this patch?

We need this feature in next stable tag as planned.

Thank you
Yao Jiewen

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao, Jiewen
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [edk2-devel] [PATCH V2 6/6] IntelSiliconPkg/dsc: Add Device Security
> component.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
> b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
> index df8984a606..0a6509d8b3 100644
> --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
> +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
> @@ -35,6 +35,7 @@
> 
> CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCache
> MaintenanceLib.inf
> 
> MicrocodeFlashAccessLib|IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFl
> ashAccessLibNull/MicrocodeFlashAccessLibNull.inf
> 
> PeiGetVtdPmrAlignmentLib|IntelSiliconPkg/Library/PeiGetVtdPmrAlignmentLib/P
> eiGetVtdPmrAlignmentLib.inf
> +
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmM
> easurementLibNull.inf
> 
>  [LibraryClasses.common.PEIM]
>    PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> @@ -75,6 +76,8 @@
> 
>  [Components]
>    IntelSiliconPkg/Library/DxeSmbiosDataHobLib/DxeSmbiosDataHobLib.inf
> +
> IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDeviceSe
> curityDxe.inf
> +
> IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/SamplePl
> atformDevicePolicyDxe.inf
>    IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
>    IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> 
> IntelSiliconPkg/Feature/VTd/PlatformVTdSampleDxe/PlatformVTdSampleDxe.inf
> --
> 2.19.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition.
  2019-10-31 12:31 ` [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition Yao, Jiewen
@ 2019-11-06 20:00   ` Chaganty, Rangasai V
  2019-11-07  3:22     ` Yao, Jiewen
  2019-11-07  4:46   ` Ni, Ray
  1 sibling, 1 reply; 28+ messages in thread
From: Chaganty, Rangasai V @ 2019-11-06 20:00 UTC (permalink / raw)
  To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Ni, Ray, Lou, Yun

Hi Jiewen, 
Few comments:
1. Can we put a reference to the spec at the file header?
2. Can we group all the macros at the top followed by structure definitions?
3. Is it possible to add some high level description above the structure definition that describes the structure?
4. I see line 80 is commented out. Can we remove that line?
5. Please add some description about the change after line 5.

Thanks,
Sai

-----Original Message-----
From: Yao, Jiewen 
Sent: Thursday, October 31, 2019 5:31 AM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
Subject: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h | 66 ++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
new file mode 100644
index 0000000000..a8c5483165
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
@@ -0,0 +1,66 @@
+/** @file
+  Intel PCI security data structure
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __INTEL_PCI_SECURITY_H__
+#define __INTEL_PCI_SECURITY_H__
+
+#pragma pack(1)
+
+typedef struct {
+  UINT16  CapId;           // 0x23: DVSEC
+  UINT16  CapVersion:4;    // 1
+  UINT16  NextOffset:12;
+  UINT16  DvSecVendorId;   // 0x8086
+  UINT16  DvSecRevision:4; // 1
+  UINT16  DvSecLength:12;
+  UINT16  DvSecId;         // 0x3E: Measure
+} INTEL_PCI_DIGEST_CAPABILITY_HEADER;
+
+#define INTEL_PCI_CAPID_DVSEC                0x23
+#define INTEL_PCI_DVSEC_VENDORID_INTEL       0x8086
+#define INTEL_PCI_DVSEC_DVSECID_MEASUREMENT  0x3E
+
+typedef union {
+  struct {
+    UINT8   DigestModified:1;         // RW1C
+    UINT8   Reserved0:7;
+  } Bits;
+  UINT8 Data;
+} INTEL_PCI_DIGEST_DATA_MODIFIED;
+
+#define INTEL_PCI_DIGEST_MODIFIED        BIT0
+
+typedef union {
+  struct {
+    UINT8   Digest0Valid:1;          // RO
+    UINT8   Digest0Locked:1;         // RO
+    UINT8   Digest1Valid:1;          // RO
+    UINT8   Digest1Locked:1;         // RO
+    UINT8   Reserved1:4;
+  } Bits;
+  UINT8 Data;
+} INTEL_PCI_DIGEST_DATA_VALID;
+
+#define INTEL_PCI_DIGEST_0_VALID         BIT0
+#define INTEL_PCI_DIGEST_0_LOCKED        BIT1
+#define INTEL_PCI_DIGEST_1_VALID         BIT2
+#define INTEL_PCI_DIGEST_1_LOCKED        BIT3
+
+typedef struct {
+  INTEL_PCI_DIGEST_DATA_MODIFIED   Modified;   // RW1C
+  INTEL_PCI_DIGEST_DATA_VALID      Valid;      // RO
+  UINT16                           TcgAlgId;   // RO
+  UINT8                            FirmwareID; // RO
+  UINT8                            Reserved;
+//UINT8                            Digest[];
+} INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE;
+
+#pragma pack()
+
+#endif
+
-- 
2.19.2.windows.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol
  2019-10-31 12:31 ` [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol Yao, Jiewen
@ 2019-11-06 21:50   ` Chaganty, Rangasai V
  2019-11-07  3:40     ` Yao, Jiewen
  2019-11-07  4:55   ` Ni, Ray
  1 sibling, 1 reply; 28+ messages in thread
From: Chaganty, Rangasai V @ 2019-11-06 21:50 UTC (permalink / raw)
  To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Ni, Ray, Lou, Yun

Same feedback as provided in patch1/6. 
In addition, is there a reason to add "EDKII" as prefix in the internal data structure names? E.g.
+typedef struct {
+  UINT32     Version; // 0x1
+  UINT32     MeasurementPolicy;
+  UINT32     AuthenticationPolicy;
+} EDKII_DEVICE_SECURITY_POLICY; // this can be named simply as "DEVICE_SECURITY_POLICY" right?

Also, on the services "GetDevicePolicy" and "SetDeviceState", is it possible to have any other return states than EFI_SUCCESS?

Regards,
Sai


-----Original Message-----
From: Yao, Jiewen 
Sent: Thursday, October 31, 2019 5:31 AM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
Subject: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h | 84 ++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
new file mode 100644
index 0000000000..cb5a71ad41
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
@@ -0,0 +1,84 @@
+/** @file
+  Device Security Policy Protocol definition
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
+#define __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
+
+#include <Uefi.h>
+#include <Protocol/DeviceSecurity.h>
+
+typedef struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL EDKII_DEVICE_SECURITY_POLICY_PROTOCOL;
+
+typedef struct {
+  UINT32     Version; // 0x1
+  UINT32     MeasurementPolicy;
+  UINT32     AuthenticationPolicy;
+} EDKII_DEVICE_SECURITY_POLICY;
+
+// BIT0 means if the action is needed or NOT
+#define EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED                 BIT0
+#define EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED              BIT0
+
+typedef struct {
+  UINT32     Version; // 0x1
+  UINT32     MeasurementState;
+  UINT32     AuthenticationState;
+} EDKII_DEVICE_SECURITY_STATE;
+
+// All zero means success
+#define EDKII_DEVICE_SECURITY_STATE_SUCCESS                          0
+#define EDKII_DEVICE_SECURITY_STATE_ERROR                            BIT31
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED           (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x0)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL   (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x1)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES        (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x10)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR         (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x20)
+
+/**
+  This function returns the device security policy associated with the device.
+
+  @param[in]  This                   The protocol instance pointer.
+  @param[in]  DeviceId               The Identifier for the device.
+  @param[out] DeviceSecurityPolicy   The Device Security Policy associated with the device.
+
+  @retval EFI_SUCCESS                The device security policy is returned
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY) (
+  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
+  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
+  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
+  );
+
+/**
+  This function sets the device state based upon the authentication result.
+
+  @param[in]  This                   The protocol instance pointer.
+  @param[in]  DeviceId               The Identifier for the device.
+  @param[in]  DeviceSecurityState    The Device Security state associated with the device.
+
+  @retval EFI_SUCCESS                The device state is set
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_DEVICE_SECURITY_SET_DEVICE_STATE) (
+  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
+  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
+  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
+  );
+
+struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL {
+  UINT32                                   Version; // 0x1
+  EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY  GetDevicePolicy;
+  EDKII_DEVICE_SECURITY_SET_DEVICE_STATE   SetDeviceState;
+};
+
+extern EFI_GUID gEdkiiDeviceSecurityPolicyProtocolGuid;
+
+#endif
-- 
2.19.2.windows.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition.
  2019-10-31 12:31 ` [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition Yao, Jiewen
@ 2019-11-06 22:09   ` Chaganty, Rangasai V
  2019-11-07  6:11   ` Ni, Ray
  1 sibling, 0 replies; 28+ messages in thread
From: Chaganty, Rangasai V @ 2019-11-06 22:09 UTC (permalink / raw)
  To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Ni, Ray, Lou, Yun

Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>

-----Original Message-----
From: Yao, Jiewen 
Sent: Thursday, October 31, 2019 5:31 AM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
Subject: [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
index 3079fc2869..8c8cd9f49d 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -53,6 +53,7 @@
 
 [Protocols]
   gEdkiiPlatformVTdPolicyProtocolGuid = { 0x3d17e448, 0x466, 0x4e20, { 0x99, 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 }}
+  gEdkiiDeviceSecurityPolicyProtocolGuid = {0x7ea41a99, 0x5e32, 0x4c97, {0x88, 0xc4, 0xd6, 0xe7, 0x46, 0x84, 0x9, 0xd4}}
 
 [PcdsFixedAtBuild, PcdsPatchableInModule]
   ## Error code for VTd error.<BR><BR>
-- 
2.19.2.windows.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition.
  2019-11-06 20:00   ` Chaganty, Rangasai V
@ 2019-11-07  3:22     ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-07  3:22 UTC (permalink / raw)
  To: Chaganty, Rangasai V, devel@edk2.groups.io; +Cc: Ni, Ray, Lou, Yun

Thanks.
Comments below:

> -----Original Message-----
> From: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>
> Sent: Thursday, November 7, 2019 4:00 AM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: RE: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity
> definition.
> 
> Hi Jiewen,
> Few comments:
> 1. Can we put a reference to the spec at the file header?
[Jiewen] Agree. Will add in V3.

> 2. Can we group all the macros at the top followed by structure definitions?
[Jiewen] I believe we had better to keep macro close to the data structure definition.

Take UefiSpec.h as example.
EFI_MEMORY_xxx is close to EFI_MEMORY_DESCRIPTOR
EVT_xxx is close to EFI_EVENT_NOTIFY
TPL_xxx is close to EFI_RAISE_TPL

Same example in Acpi.h
We put definition close to the structure, instead of put all definition together on the top.



> 3. Is it possible to add some high level description above the structure definition
> that describes the structure?
[Jiewen] Agree. Will add in V3.


> 4. I see line 80 is commented out. Can we remove that line?
[Jiewen] This is a typical way to define a variable length field.

You may find similar examples in EDKII. Just search [];
  C:\home\edkii\edk2\MdePkg\Include\Guid\CapsuleReport.h(84):  /// CHAR16 CapsuleFileName[];
  C:\home\edkii\edk2\MdePkg\Include\Guid\CapsuleReport.h(92):  /// CHAR16 CapsuleTarget[];
  C:\home\edkii\edk2\MdePkg\Include\Guid\FmpCapsule.h(46):  // UINT64 ItemOffsetList[];
  C:\home\edkii\edk2\MdePkg\Include\Guid\ImageAuthentication.h(300):  /// CHAR16                    Name[];
  C:\home\edkii\edk2\MdePkg\Include\Guid\StatusCodeDataTypeId.h(230):  //  UINT8                          ReqRes[];
  C:\home\edkii\edk2\MdePkg\Include\Guid\StatusCodeDataTypeId.h(235):  //  UINT8                          AllocRes[];
  C:\home\edkii\edk2\MdePkg\Include\Guid\SystemResourceTable.h(114):  //EFI_SYSTEM_RESOURCE_ENTRY  Entries[];
  C:\home\edkii\edk2\MdePkg\Include\Guid\WinCertificate.h(116):  /// UINT8 Signature[];


> 5. Please add some description about the change after line 5.
[Jiewen] Line 5 ? It is about license.
Would you please clarify what description is required there?



> 
> Thanks,
> Sai
> 
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Thursday, October 31, 2019 5:31 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h | 66
> ++++++++++++++++++++
>  1 file changed, 66 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> new file mode 100644
> index 0000000000..a8c5483165
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> @@ -0,0 +1,66 @@
> +/** @file
> +  Intel PCI security data structure
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __INTEL_PCI_SECURITY_H__
> +#define __INTEL_PCI_SECURITY_H__
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT16  CapId;           // 0x23: DVSEC
> +  UINT16  CapVersion:4;    // 1
> +  UINT16  NextOffset:12;
> +  UINT16  DvSecVendorId;   // 0x8086
> +  UINT16  DvSecRevision:4; // 1
> +  UINT16  DvSecLength:12;
> +  UINT16  DvSecId;         // 0x3E: Measure
> +} INTEL_PCI_DIGEST_CAPABILITY_HEADER;
> +
> +#define INTEL_PCI_CAPID_DVSEC                0x23
> +#define INTEL_PCI_DVSEC_VENDORID_INTEL       0x8086
> +#define INTEL_PCI_DVSEC_DVSECID_MEASUREMENT  0x3E
> +
> +typedef union {
> +  struct {
> +    UINT8   DigestModified:1;         // RW1C
> +    UINT8   Reserved0:7;
> +  } Bits;
> +  UINT8 Data;
> +} INTEL_PCI_DIGEST_DATA_MODIFIED;
> +
> +#define INTEL_PCI_DIGEST_MODIFIED        BIT0
> +
> +typedef union {
> +  struct {
> +    UINT8   Digest0Valid:1;          // RO
> +    UINT8   Digest0Locked:1;         // RO
> +    UINT8   Digest1Valid:1;          // RO
> +    UINT8   Digest1Locked:1;         // RO
> +    UINT8   Reserved1:4;
> +  } Bits;
> +  UINT8 Data;
> +} INTEL_PCI_DIGEST_DATA_VALID;
> +
> +#define INTEL_PCI_DIGEST_0_VALID         BIT0
> +#define INTEL_PCI_DIGEST_0_LOCKED        BIT1
> +#define INTEL_PCI_DIGEST_1_VALID         BIT2
> +#define INTEL_PCI_DIGEST_1_LOCKED        BIT3
> +
> +typedef struct {
> +  INTEL_PCI_DIGEST_DATA_MODIFIED   Modified;   // RW1C
> +  INTEL_PCI_DIGEST_DATA_VALID      Valid;      // RO
> +  UINT16                           TcgAlgId;   // RO
> +  UINT8                            FirmwareID; // RO
> +  UINT8                            Reserved;
> +//UINT8                            Digest[];
> +} INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE;
> +
> +#pragma pack()
> +
> +#endif
> +
> --
> 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol
  2019-11-06 21:50   ` Chaganty, Rangasai V
@ 2019-11-07  3:40     ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-07  3:40 UTC (permalink / raw)
  To: Chaganty, Rangasai V, devel@edk2.groups.io; +Cc: Ni, Ray, Lou, Yun

Thanks. Comment below:

> -----Original Message-----
> From: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>
> Sent: Thursday, November 7, 2019 5:51 AM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: RE: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device
> Security Policy protocol
> 
> Same feedback as provided in patch1/6.
[Jiewen] Agree. See response in previous email.
I will add structure description in V3.

> In addition, is there a reason to add "EDKII" as prefix in the internal data
> structure names? E.g.
> +typedef struct {
> +  UINT32     Version; // 0x1
> +  UINT32     MeasurementPolicy;
> +  UINT32     AuthenticationPolicy;
> +} EDKII_DEVICE_SECURITY_POLICY; // this can be named simply as
> "DEVICE_SECURITY_POLICY" right?
[Jiewen] I believe it is common practice to add EDKII_ prefix to all data structure.

I did a search in MdeModulePkg.
I do see some EDKII protocol adds EDKII_ prefix for the data structure.
But some of them does not.

I feel better if we add it to avoid namespace confusing.
I am open for discussion.


> 
> Also, on the services "GetDevicePolicy" and "SetDeviceState", is it possible to
> have any other return states than EFI_SUCCESS?
[Jiewen] Good question. I can add something in V3.


> 
> Regards,
> Sai
> 
> 
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Thursday, October 31, 2019 5:31 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security
> Policy protocol
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h |
> 84 ++++++++++++++++++++
>  1 file changed, 84 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
> new file mode 100644
> index 0000000000..cb5a71ad41
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
> @@ -0,0 +1,84 @@
> +/** @file
> +  Device Security Policy Protocol definition
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +
> +#ifndef __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
> +#define __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
> +
> +#include <Uefi.h>
> +#include <Protocol/DeviceSecurity.h>
> +
> +typedef struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL
> EDKII_DEVICE_SECURITY_POLICY_PROTOCOL;
> +
> +typedef struct {
> +  UINT32     Version; // 0x1
> +  UINT32     MeasurementPolicy;
> +  UINT32     AuthenticationPolicy;
> +} EDKII_DEVICE_SECURITY_POLICY;
> +
> +// BIT0 means if the action is needed or NOT
> +#define EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED                 BIT0
> +#define EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED              BIT0
> +
> +typedef struct {
> +  UINT32     Version; // 0x1
> +  UINT32     MeasurementState;
> +  UINT32     AuthenticationState;
> +} EDKII_DEVICE_SECURITY_STATE;
> +
> +// All zero means success
> +#define EDKII_DEVICE_SECURITY_STATE_SUCCESS                          0
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR                            BIT31
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x0)
> +#define
> EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x1)
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x10)
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x20)
> +
> +/**
> +  This function returns the device security policy associated with the device.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[out] DeviceSecurityPolicy   The Device Security Policy associated
> with the device.
> +
> +  @retval EFI_SUCCESS                The device security policy is returned
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY) (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
> +  );
> +
> +/**
> +  This function sets the device state based upon the authentication result.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[in]  DeviceSecurityState    The Device Security state associated with
> the device.
> +
> +  @retval EFI_SUCCESS                The device state is set
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_DEVICE_SECURITY_SET_DEVICE_STATE) (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
> +  );
> +
> +struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL {
> +  UINT32                                   Version; // 0x1
> +  EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY  GetDevicePolicy;
> +  EDKII_DEVICE_SECURITY_SET_DEVICE_STATE   SetDeviceState;
> +};
> +
> +extern EFI_GUID gEdkiiDeviceSecurityPolicyProtocolGuid;
> +
> +#endif
> --
> 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition.
  2019-10-31 12:31 ` [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition Yao, Jiewen
  2019-11-06 20:00   ` Chaganty, Rangasai V
@ 2019-11-07  4:46   ` Ni, Ray
  2019-11-07  7:13     ` Yao, Jiewen
  1 sibling, 1 reply; 28+ messages in thread
From: Ni, Ray @ 2019-11-07  4:46 UTC (permalink / raw)
  To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V, Lou, Yun

Jiewen,
You could use "UINT8 Digest[0];" in structure INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE.

Same comments as what Sai raised, better to have the referenced spec in the file header.

Thanks,
Ray

> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity
> definition.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h |
> 66 ++++++++++++++++++++
>  1 file changed, 66 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> new file mode 100644
> index 0000000000..a8c5483165
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> @@ -0,0 +1,66 @@
> +/** @file
> +  Intel PCI security data structure
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __INTEL_PCI_SECURITY_H__
> +#define __INTEL_PCI_SECURITY_H__
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT16  CapId;           // 0x23: DVSEC
> +  UINT16  CapVersion:4;    // 1
> +  UINT16  NextOffset:12;
> +  UINT16  DvSecVendorId;   // 0x8086
> +  UINT16  DvSecRevision:4; // 1
> +  UINT16  DvSecLength:12;
> +  UINT16  DvSecId;         // 0x3E: Measure
> +} INTEL_PCI_DIGEST_CAPABILITY_HEADER;
> +
> +#define INTEL_PCI_CAPID_DVSEC                0x23
> +#define INTEL_PCI_DVSEC_VENDORID_INTEL       0x8086
> +#define INTEL_PCI_DVSEC_DVSECID_MEASUREMENT  0x3E
> +
> +typedef union {
> +  struct {
> +    UINT8   DigestModified:1;         // RW1C
> +    UINT8   Reserved0:7;
> +  } Bits;
> +  UINT8 Data;
> +} INTEL_PCI_DIGEST_DATA_MODIFIED;
> +
> +#define INTEL_PCI_DIGEST_MODIFIED        BIT0
> +
> +typedef union {
> +  struct {
> +    UINT8   Digest0Valid:1;          // RO
> +    UINT8   Digest0Locked:1;         // RO
> +    UINT8   Digest1Valid:1;          // RO
> +    UINT8   Digest1Locked:1;         // RO
> +    UINT8   Reserved1:4;
> +  } Bits;
> +  UINT8 Data;
> +} INTEL_PCI_DIGEST_DATA_VALID;
> +
> +#define INTEL_PCI_DIGEST_0_VALID         BIT0
> +#define INTEL_PCI_DIGEST_0_LOCKED        BIT1
> +#define INTEL_PCI_DIGEST_1_VALID         BIT2
> +#define INTEL_PCI_DIGEST_1_LOCKED        BIT3
> +
> +typedef struct {
> +  INTEL_PCI_DIGEST_DATA_MODIFIED   Modified;   // RW1C
> +  INTEL_PCI_DIGEST_DATA_VALID      Valid;      // RO
> +  UINT16                           TcgAlgId;   // RO
> +  UINT8                            FirmwareID; // RO
> +  UINT8                            Reserved;
> +//UINT8                            Digest[];
> +} INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE;
> +
> +#pragma pack()
> +
> +#endif
> +
> --
> 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol
  2019-10-31 12:31 ` [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol Yao, Jiewen
  2019-11-06 21:50   ` Chaganty, Rangasai V
@ 2019-11-07  4:55   ` Ni, Ray
  2019-11-07  7:45     ` Yao, Jiewen
  1 sibling, 1 reply; 28+ messages in thread
From: Ni, Ray @ 2019-11-07  4:55 UTC (permalink / raw)
  To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V, Lou, Yun

Jiewen,
I am fine with the 1/6 patch that doesn't contain enough comments to describe the meaning
of each field in each structure because I can reach out to the referenced spec to understand them.

This 2/6 patch introduces a new protocol but contains very few comments (almost none) for each
structure each field and I cannot reach out to any spec to understand them.

So can you please add comments to each field of structures like EDKII_DEVICE_SECURITY_POLICY and
EDKII_DEVICE_SECURITY_STATE?
Also can you please add comments to all the macros defined in this patch to explain the meaning and
more important how they are going to impact the logic.

In general, can you please add enough comments so that a PCI/USB BUS driver developer can understand
the whole flow how this protocol supports the device security?

Thanks,
Ray

> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device
> Security Policy protocol
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
> 
> Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
> | 84 ++++++++++++++++++++
>  1 file changed, 84 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolic
> y.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolic
> y.h
> new file mode 100644
> index 0000000000..cb5a71ad41
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolic
> y.h
> @@ -0,0 +1,84 @@
> +/** @file
> +  Device Security Policy Protocol definition
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +
> +#ifndef __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
> +#define __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
> +
> +#include <Uefi.h>
> +#include <Protocol/DeviceSecurity.h>
> +
> +typedef struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL
> EDKII_DEVICE_SECURITY_POLICY_PROTOCOL;
> +
> +typedef struct {
> +  UINT32     Version; // 0x1
> +  UINT32     MeasurementPolicy;
> +  UINT32     AuthenticationPolicy;
> +} EDKII_DEVICE_SECURITY_POLICY;
> +
> +// BIT0 means if the action is needed or NOT
> +#define EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED                 BIT0
> +#define EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED              BIT0
> +
> +typedef struct {
> +  UINT32     Version; // 0x1
> +  UINT32     MeasurementState;
> +  UINT32     AuthenticationState;
> +} EDKII_DEVICE_SECURITY_STATE;
> +
> +// All zero means success
> +#define EDKII_DEVICE_SECURITY_STATE_SUCCESS                          0
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR                            BIT31
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x0)
> +#define
> EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x1)
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x10)
> +#define EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR
> (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x20)
> +
> +/**
> +  This function returns the device security policy associated with the device.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[out] DeviceSecurityPolicy   The Device Security Policy associated
> with the device.
> +
> +  @retval EFI_SUCCESS                The device security policy is returned
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY) (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
> +  );
> +
> +/**
> +  This function sets the device state based upon the authentication result.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[in]  DeviceSecurityState    The Device Security state associated
> with the device.
> +
> +  @retval EFI_SUCCESS                The device state is set
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_DEVICE_SECURITY_SET_DEVICE_STATE) (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
> +  );
> +
> +struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL {
> +  UINT32                                   Version; // 0x1
> +  EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY  GetDevicePolicy;
> +  EDKII_DEVICE_SECURITY_SET_DEVICE_STATE   SetDeviceState;
> +};
> +
> +extern EFI_GUID gEdkiiDeviceSecurityPolicyProtocolGuid;
> +
> +#endif
> --
> 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition.
  2019-10-31 12:31 ` [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition Yao, Jiewen
  2019-11-06 22:09   ` Chaganty, Rangasai V
@ 2019-11-07  6:11   ` Ni, Ray
  2019-11-07  7:17     ` Yao, Jiewen
  1 sibling, 1 reply; 28+ messages in thread
From: Ni, Ray @ 2019-11-07  6:11 UTC (permalink / raw)
  To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V, Lou, Yun

Jiewen,
Can you add comments to explain the protocol and the associated header file path?
Like:
  ## Guid for EDKII implementation extension, used to indaicate there are bit fields in the varstore.
  #  Include/Guid/MdeModuleHii.h
  gEdkiiIfrBitVarstoreGuid  = {0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20, 0xA8, 0xFD, 0x60,0xA7, 0x1D}}

> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> index 3079fc2869..8c8cd9f49d 100644
> --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> @@ -53,6 +53,7 @@
> 
>  [Protocols]
>    gEdkiiPlatformVTdPolicyProtocolGuid = { 0x3d17e448, 0x466, 0x4e20, { 0x99,
> 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 }}
> +  gEdkiiDeviceSecurityPolicyProtocolGuid = {0x7ea41a99, 0x5e32, 0x4c97,
> {0x88, 0xc4, 0xd6, 0xe7, 0x46, 0x84, 0x9, 0xd4}}
> 
>  [PcdsFixedAtBuild, PcdsPatchableInModule]
>    ## Error code for VTd error.<BR><BR>
> --
> 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity.
  2019-10-31 12:31 ` [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity Yao, Jiewen
@ 2019-11-07  6:38   ` Ni, Ray
  2019-11-07  8:41     ` Yao, Jiewen
  0 siblings, 1 reply; 28+ messages in thread
From: Ni, Ray @ 2019-11-07  6:38 UTC (permalink / raw)
  To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V, Lou, Yun

1. Can you make the macro short?
    EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED -> EDKII_DEVICE_MEASUREMENT_REQUIRED
    EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED -> EDKII_DEVICE_AUTHENTICATION_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. "Security 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 into 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_SECURITY_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 SetDeviceState() 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 combine them into one line and with "DeviceSecurity"
    keyword in the beginning of the message. "one line" is just a recommendation 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 <jiewen.yao@intel.com>
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add
> PciSecurity.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> This driver is to do the PCI device authentication based upon Intel PCIe
> Security Specification.
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> Signed-off-by: Yun Lou <yun.lou@intel.com>
> ---
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe
> /IntelPciDeviceSecurityDxe.c   | 701 ++++++++++++++++++++
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe
> /IntelPciDeviceSecurityDxe.inf |  45 ++
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe
> /TcgDeviceEvent.h              | 193 ++++++
>  3 files changed, 939 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDx
> e/IntelPciDeviceSecurityDxe.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityD
> 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.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <IndustryStandard/Spdm.h>
> +#include <IndustryStandard/IntelPciSecurity.h>
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/Tpm20.h>
> +#include <IndustryStandard/UefiTcgPlatform.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h> #include
> +<Library/TpmMeasurementLib.h> #include <Protocol/PciIo.h> #include
> +<Protocol/DeviceSecurity.h> #include
> +<Protocol/PlatformDeviceSecurityPolicy.h>
> +#include "TcgDeviceEvent.h"
> +
> +typedef struct {
> +  UINT8                                             Measurement[SHA512_DIGEST_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 =
> +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 = PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice,
> + &PciFunction);  ASSERT_EFI_ERROR(Status);
> +
> +  NewPciDevice = AllocateZeroPool(sizeof(*NewPciDevice));
> +  ASSERT_EFI_ERROR(NewPciDevice != NULL);
> +
> +  NewPciDevice->Signature   = PCI_DEVICE_INSTANCE_SIGNATURE;
> +  NewPciDevice->PciSegment  = PciSegment;
> +  NewPciDevice->PciBus      = PciBus;
> +  NewPciDevice->PciDevice   = PciDevice;
> +  NewPciDevice->PciFunction = 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 = PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice,
> + &PciFunction);  ASSERT_EFI_ERROR(Status);
> +
> +  Link = GetFirstNode(PciDeviceList);
> +  while (!IsNull(PciDeviceList, Link)) {
> +    CurrentPciDevice = PCI_DEVICE_INSTANCE_FROM_LINK(Link);
> +
> +    if (CurrentPciDevice->PciSegment == PciSegment && CurrentPciDevice-
> >PciBus == PciBus &&
> +        CurrentPciDevice->PciDevice == PciDevice && CurrentPciDevice-
> >PciFunction == PciFunction) {
> +      DEBUG((DEBUG_INFO, "PCI device duplicated (Loc -
>  %04x:%02x:%02x:%02x)\n", PciSegment, PciBus, PciDevice, PciFunction));
> +      return TRUE;
> +    }
> +
> +    Link = 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 = ~CapId;
> +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8,
> + PCI_CAPBILITY_POINTER_OFFSET, 1, &PciCapIdHdr.NextItemPtr);
> + ASSERT_EFI_ERROR(Status);  if (PciCapIdHdr.NextItemPtr == 0 ||
> PciCapIdHdr.NextItemPtr == 0xFF) {
> +    return 0;
> +  }
> +  PciCapIdOffset = 0;
> +  do {
> +    if (PciCapIdHdr.CapabilityID == CapId) {
> +      break;
> +    }
> +    PciCapIdOffset = PciCapIdHdr.NextItemPtr;
> +    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PciCapIdOffset, 1,
> &PciCapIdHdr);
> +    ASSERT_EFI_ERROR(Status);
> +  } while (PciCapIdHdr.NextItemPtr != 0 && PciCapIdHdr.NextItemPtr !=
> + 0xFF);
> +
> +  if (PciCapIdHdr.CapabilityID == 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 = GetPciCapId (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP);
> + if (PcieCapIdOffset == 0) {
> +    return 0;
> +  }
> +
> +  PciExpressExtCapIdHdr.CapabilityId = ~CapId;
> + PciExpressExtCapIdHdr.CapabilityVersion = 0xF;
> + PciExpressExtCapIdHdr.NextCapabilityOffset = 0x100;  PcieCapIdOffset =
> + 0;  do {
> +    if (PciExpressExtCapIdHdr.CapabilityId == CapId) {
> +      break;
> +    }
> +    PcieCapIdOffset = PciExpressExtCapIdHdr.NextCapabilityOffset;
> +    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, PcieCapIdOffset, 1,
> &PciExpressExtCapIdHdr);
> +    ASSERT_EFI_ERROR(Status);
> +  } while (PciExpressExtCapIdHdr.NextCapabilityOffset != 0 &&
> + PciExpressExtCapIdHdr.NextCapabilityOffset != 0xFFF);
> +
> +  if (PciExpressExtCapIdHdr.CapabilityId == 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 space
> +
> +  @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 = 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 space
> +  @param Data             Byte value of the PCI device configuration space.
> +**/
> +VOID
> +DvSecPciWrite8 (
> +  IN EFI_PCI_IO_PROTOCOL *PciIo,
> +  IN UINT32              Offset,
> +  IN UINT8               Data
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = 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 associated
> 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 associated
> 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 = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0,
> + sizeof(PciData), &PciData);  ASSERT_EFI_ERROR(Status);
> +
> +  PcrIndex = EDKII_DEVICE_MEASUREMENT_COMPONENT_PCR_INDEX;
> +  EventType = EDKII_DEVICE_MEASUREMENT_COMPONENT_EVENT_TYPE;
> +
> +  CopyMem (EventLog.EventData.Signature,
> EDKII_DEVICE_SECURITY_EVENT_DATA_SIGNATURE,
> sizeof(EventLog.EventData.Signature));
> +  EventLog.EventData.Version                  =
> EDKII_DEVICE_SECURITY_EVENT_DATA_VERSION;
> +  EventLog.EventData.Length                   =
> sizeof(EDKII_DEVICE_SECURITY_PCI_EVENT_DATA);
> +  EventLog.EventData.SpdmMeasurementBlock.Index                    = DigestSel;
> +  EventLog.EventData.SpdmMeasurementBlock.MeasurementType          =
> SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWA
> RE;
> +  EventLog.EventData.SpdmMeasurementBlock.MeasurementSpecification
> = 0xFF;
> +  EventLog.EventData.SpdmMeasurementBlock.Reserved                 = 0;
> +  EventLog.EventData.SpdmHashAlgo       = TcgAlgIdToSpdmHashAlgo
> (TcgAlgId);
> +  EventLog.EventData.DeviceType         =
> EDKII_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI;
> +  ZeroMem (EventLog.EventData.Reserved,
> sizeof(EventLog.EventData.Reserved));
> +  EventLog.PciContext.Version           =
> EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION;
> +  EventLog.PciContext.Length            =
> sizeof(EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT);
> +  EventLog.PciContext.VendorId          = PciData.Hdr.VendorId;
> +  EventLog.PciContext.DeviceId          = PciData.Hdr.DeviceId;
> +  EventLog.PciContext.RevisionID        = PciData.Hdr.RevisionID;
> +  EventLog.PciContext.ClassCode[0]      = PciData.Hdr.ClassCode[0];
> +  EventLog.PciContext.ClassCode[1]      = PciData.Hdr.ClassCode[1];
> +  EventLog.PciContext.ClassCode[2]      = PciData.Hdr.ClassCode[2];
> +  if ((PciData.Hdr.HeaderType & HEADER_LAYOUT_CODE) ==
> HEADER_TYPE_DEVICE) {
> +    EventLog.PciContext.SubsystemVendorID =
> PciData.Device.SubsystemVendorID;
> +    EventLog.PciContext.SubsystemID       = PciData.Device.SubsystemID;
> +  } else {
> +    EventLog.PciContext.SubsystemVendorID = 0;
> +    EventLog.PciContext.SubsystemID       = 0;
> +  }
> +
> +  DigestSize = DigestSizeFromTcgAlgId (TcgAlgId);  CopyMem
> + (&HashData.Measurement, Digest, DigestSize);
> +
> +  HashDataLen = DigestSize;
> +  Status = TpmMeasureAndLogData (
> +             PcrIndex,
> +             EventType,
> +             &EventLog,
> +             EventLog.EventData.Length,
> +             &HashData,
> +             HashDataLen
> +             );
> +  DEBUG((DEBUG_INFO, "TpmMeasureAndLogData - %r\n", Status));
> +  if (EFI_ERROR(Status)) {
> +    DeviceSecurityState->MeasurementState =
> +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 device.
> +  @param[in]  DeviceSecurityPolicy   The Device Security Policy associated
> with the device.
> +  @param[out] DeviceSecurityState    The Device Security state associated
> 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 = 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 = DigestSizeFromTcgAlgId (TcgAlgId);  if (DigestSize == 0)
> + {
> +    DEBUG((DEBUG_INFO, "Unsupported Algorithm - 0x%04x\n", TcgAlgId));
> +    DeviceSecurityState->MeasurementState =
> EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES;
> +    return ;
> +  }
> +  DEBUG((DEBUG_INFO, "  (DigestSize: 0x%x)\n", DigestSize));
> +
> +  DeviceSecurityState->MeasurementState =
> + EDKII_DEVICE_SECURITY_STATE_SUCCESS;
> +
> +  NumDigest = 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 = 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 = 2;
> +  }
> +
> +  for (DigestSel = 0; DigestSel < NumDigest; DigestSel++) {
> +    DEBUG((DEBUG_INFO, "  DigestSel     - 0x%02x\n", DigestSel));
> +    if ((DigestSel == 0) && ((Valid & INTEL_PCI_DIGEST_0_VALID) == 0)) {
> +      continue;
> +    }
> +    if ((DigestSel == 1) && ((Valid & INTEL_PCI_DIGEST_1_VALID) == 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 = 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 = DvSecPciRead8 (
> +                   PciIo,
> +                   DvSecOffset + sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEADER) +
> OFFSET_OF(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE, Modified)
> +                   );
> +      if ((Modified & INTEL_PCI_DIGEST_MODIFIED) == 0) {
> +        break;
> +      }
> +    }
> +
> +    //
> +    // Dump Digest
> +    //
> +    {
> +      UINTN  Index;
> +      DEBUG((DEBUG_INFO, "  Digest        - "));
> +      for (Index = 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 associated
> with the device.
> +  @param[out] DeviceSecurityState    The Device Security state associated
> 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 =
> EDKII_DEVICE_SECURITY_STATE_SUCCESS;
> +    return ;
> +  }
> +
> +  DvSecOffset = GetPciExpressExtCapId (PciIo, INTEL_PCI_CAPID_DVSEC);
> + DEBUG((DEBUG_INFO, "DvSecOffset - 0x%x\n", DvSecOffset));  if
> + (DvSecOffset == 0) {
> +    DeviceSecurityState->MeasurementState =
> EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES;
> +    return ;
> +  }
> +  Status = 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 != INTEL_PCI_DVSEC_VENDORID_INTEL) &&
> +      (DvSecHdr.DvSecId != INTEL_PCI_DVSEC_DVSECID_MEASUREMENT)) {
> +    DeviceSecurityState->MeasurementState =
> 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 associated
> with the device.
> +  @param[out] DeviceSecurityState    The Device Security state associated
> 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 =
> +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 installs
> 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 measurement 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 == NULL) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (!CompareGuid (&DeviceId->DeviceType,
> &gEdkiiDeviceIdentifierTypePciGuid)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = gBS->HandleProtocol (
> +                  DeviceId->DeviceHandle,
> +                  &gEdkiiDeviceIdentifierTypePciGuid,
> +                  (VOID **)&PciIo
> +                  );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n",
> Status));
> +    return EFI_SUCCESS;
> +  }
> +
> +  DeviceSecurityState.Version = 0x1;
> +  DeviceSecurityState.MeasurementState = 0x0;
> + DeviceSecurityState.AuthenticationState = 0x0;
> +
> +  Status = mDeviceSecurityPolicy->GetDevicePolicy
> + (mDeviceSecurityPolicy, DeviceId, &DeviceSecurityPolicy);  if
> (EFI_ERROR(Status)) {
> +    DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->GetDevicePolicy -
>  %r\n", Status));
> +    DeviceSecurityState.MeasurementState =
> EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL;
> +    DeviceSecurityState.AuthenticationState =
> + EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL;
> +  } else {
> +    if ((DeviceSecurityPolicy->MeasurementPolicy &
> EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED) != 0) {
> +      DoDeviceMeasurement (PciIo, DeviceSecurityPolicy,
> &DeviceSecurityState);
> +      DEBUG((DEBUG_ERROR, "MeasurementState - 0x%08x\n",
> DeviceSecurityState.MeasurementState));
> +    }
> +    if ((DeviceSecurityPolicy->AuthenticationPolicy &
> EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED) != 0) {
> +      DoDeviceAuthentication (PciIo, DeviceSecurityPolicy,
> &DeviceSecurityState);
> +      DEBUG((DEBUG_ERROR, "AuthenticationState - 0x%08x\n",
> DeviceSecurityState.AuthenticationState));
> +    }
> +  }
> +
> +  Status = mDeviceSecurityPolicy->SetDeviceState
> + (mDeviceSecurityPolicy, DeviceId, &DeviceSecurityState);  if
> (EFI_ERROR(Status)) {
> +    DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->SetDeviceState - %r\n",
> + Status));  }
> +
> +  if ((DeviceSecurityState.MeasurementState == 0) &&
> +      (DeviceSecurityState.AuthenticationState == 0)) {
> +    return EFI_SUCCESS;
> +  } else {
> +    return EFI_SECURITY_VIOLATION;
> +  }
> +}
> +
> +EDKII_DEVICE_SECURITY_PROTOCOL mDeviceSecurity = {
> +  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 = gBS->LocateProtocol
> + (&gEdkiiDeviceSecurityPolicyProtocolGuid, NULL, (VOID
> + **)&mDeviceSecurityPolicy);  ASSERT_EFI_ERROR(Status);
> +
> +  Handle = NULL;
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gEdkiiDeviceSecurityProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  (VOID **)&mDeviceSecurity
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDx
> e/IntelPciDeviceSecurityDxe.inf
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityD
> 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.<BR> # SPDX-License-Identifier:
> +BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = IntelPciDeviceSecurityDxe
> +  FILE_GUID                      = D9569195-ED94-47D2-9523-38BF2D201371
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = 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/IntelPciDeviceSecurityDx
> e/TcgDeviceEvent.h
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityD
> 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.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +
> +#ifndef __TCG_EVENT_DATA_H__
> +#define __TCG_EVENT_DATA_H__
> +
> +#include <IndustryStandard/Spdm.h>
> +
> +#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 platform
> 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 to
> 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 the
> 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 been, 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 value
> of UEFI_IMAGE_SECURITY_DATABASE.
> +//            The value MUST NOT include the terminating NUL.
> +//
> +
> +#pragma pack()
> +
> +#endif
> --
> 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [edk2-devel] [PATCH V2 5/6] IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy.
  2019-10-31 12:31 ` [PATCH V2 5/6] IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy Yao, Jiewen
@ 2019-11-07  6:55   ` Ni, Ray
  2019-11-07  8:42     ` Yao, Jiewen
  0 siblings, 1 reply; 28+ messages in thread
From: Ni, Ray @ 2019-11-07  6:55 UTC (permalink / raw)
  To: devel@edk2.groups.io, Yao, Jiewen; +Cc: Chaganty, Rangasai V, Lou, Yun

1. I am sorry but I just realized GetDevicePolicy() returns a pointer of policy to caller,
    instead of copying the policy data to caller's buffer. It's a bit strange to me. Can you
    please change the prototype so that caller needs to pass in a policy structure and
    GetDevicePolicy() fills the structure buffer using CopyMem from mDeviceSecurityPolicyNone?
    "*DeviceSecurityPolicy = &mDeviceSecurityPolicyNone;"
    "DeviceSecurityPolicy = &mDeviceSecurityPolicyMeasurement;"

2. I thought SetDeviceState() in your sample will reset the EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED
    to 0. Why didn't the sample do that?

3. I just realized you didn't define the version macro for EDKII_DEVICE_SECURITY_POLICY_PROTOCOL.Version.
    I suggest you define a macro for the version instead of let producer/consumer use hard-code number (0x1).
    And I am not sure if you will use the same version macro for the protocol.version, securitypolicy.version and
    securitystate.version. I assume you will. No matter yes or no, can you please state that through comments
    in the policy protocol header file clearly?



> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao,
> Jiewen
> Sent: Thursday, October 31, 2019 8:31 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> Subject: [edk2-devel] [PATCH V2 5/6]
> IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> 
> This driver provides the platform sample policy to measure a NVMe card.
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Yun Lou <yun.lou@intel.com>
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePoli
> cyDxe/SamplePlatformDevicePolicyDxe.c   | 189 ++++++++++++++++++++
> 
> Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePoli
> cyDxe/SamplePlatformDevicePolicyDxe.inf |  40 +++++
>  2 files changed, 229 insertions(+)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDeviceP
> olicyDxe/SamplePlatformDevicePolicyDxe.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDeviceP
> olicyDxe/SamplePlatformDevicePolicyDxe.c
> new file mode 100644
> index 0000000000..1f01b961a8
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformD
> +++ evicePolicyDxe/SamplePlatformDevicePolicyDxe.c
> @@ -0,0 +1,189 @@
> +/** @file
> +  EDKII Device Security library for PCI device
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <IndustryStandard/Spdm.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/DeviceSecurity.h>
> +#include <Protocol/PlatformDeviceSecurityPolicy.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +EDKII_DEVICE_SECURITY_POLICY           mDeviceSecurityPolicyNone = {
> +  0x1,
> +  0,
> +  0,
> +};
> +EDKII_DEVICE_SECURITY_POLICY           mDeviceSecurityPolicyMeasurement
> = {
> +  0x1,
> +  EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED,
> +  0,
> +};
> +
> +/**
> +  This function returns the device security policy associated with the device.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[out] DeviceSecurityPolicy   The Device Security Policy associated
> with the device.
> +
> +  @retval EFI_SUCCESS                The device security policy is returned
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDevicePolicy (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PCI_IO_PROTOCOL         *PciIo;
> +  UINT16                      PciVendorId;
> +  UINT16                      PciDeviceId;
> +
> +  *DeviceSecurityPolicy = &mDeviceSecurityPolicyNone;
> +
> +  DEBUG ((DEBUG_INFO, "GetDevicePolicy - 0x%g\n",
> + &DeviceId->DeviceType));
> +
> +  if (!CompareGuid (&DeviceId->DeviceType,
> &gEdkiiDeviceIdentifierTypePciGuid)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = gBS->HandleProtocol (
> +                  DeviceId->DeviceHandle,
> +                  &gEdkiiDeviceIdentifierTypePciGuid,
> +                  (VOID **)&PciIo
> +                  );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n",
> Status));
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> + PCI_VENDOR_ID_OFFSET, 1, &PciVendorId);  ASSERT_EFI_ERROR(Status);
> + Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> + PCI_DEVICE_ID_OFFSET, 1, &PciDeviceId);  ASSERT_EFI_ERROR(Status);
> + DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId,
> + PciDeviceId));
> +
> +  if ((PciVendorId == 0x8086) && (PciDeviceId == 0x0B60)) {
> +    *DeviceSecurityPolicy = &mDeviceSecurityPolicyMeasurement;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets the device state based upon the authentication result.
> +
> +  @param[in]  This                   The protocol instance pointer.
> +  @param[in]  DeviceId               The Identifier for the device.
> +  @param[in]  DeviceSecurityState    The Device Security state associated
> with the device.
> +
> +  @retval EFI_SUCCESS                The device state is set
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetDeviceState (
> +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> +  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PCI_IO_PROTOCOL         *PciIo;
> +  UINT16                      PciVendorId;
> +  UINT16                      PciDeviceId;
> +  UINTN                       Segment;
> +  UINTN                       Bus;
> +  UINTN                       Device;
> +  UINTN                       Function;
> +
> +  DEBUG ((DEBUG_INFO, "SetDeviceState - 0x%g\n",
> + &DeviceId->DeviceType));
> +
> +  if (!CompareGuid (&DeviceId->DeviceType,
> &gEdkiiDeviceIdentifierTypePciGuid)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = gBS->HandleProtocol (
> +                  DeviceId->DeviceHandle,
> +                  &gEdkiiDeviceIdentifierTypePciGuid,
> +                  (VOID **)&PciIo
> +                  );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n",
> Status));
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> + PCI_VENDOR_ID_OFFSET, 1, &PciVendorId);  ASSERT_EFI_ERROR(Status);
> + Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> + PCI_DEVICE_ID_OFFSET, 1, &PciDeviceId);  ASSERT_EFI_ERROR(Status);
> + DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId,
> + PciDeviceId));
> +
> +  Status = PciIo->GetLocation (
> +                    PciIo,
> +                    &Segment,
> +                    &Bus,
> +                    &Device,
> +                    &Function
> +                    );
> +  if (!EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_INFO, "PCI Loc - %04x:%02x:%02x:%02x\n",
> +      Segment, Bus, Device, Function));  }
> +
> +  DEBUG ((DEBUG_INFO, "State - Measurement - 0x%08x, Authentication -
> 0x%08x\n",
> +    DeviceSecurityState->MeasurementState,
> +    DeviceSecurityState->AuthenticationState
> +    ));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  mDeviceSecurityPolicy = {
> +  0x1,
> +  GetDevicePolicy,
> +  SetDeviceState,
> +};
> +
> +/**
> +  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;
> +
> +  Handle = NULL;
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gEdkiiDeviceSecurityPolicyProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mDeviceSecurityPolicy
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDeviceP
> olicyDxe/SamplePlatformDevicePolicyDxe.inf
> b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDeviceP
> olicyDxe/SamplePlatformDevicePolicyDxe.inf
> new file mode 100644
> index 0000000000..a9b77d8371
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformD
> +++ evicePolicyDxe/SamplePlatformDevicePolicyDxe.inf
> @@ -0,0 +1,40 @@
> +## @file
> +#  EDKII Device Security library for PCI device # # Copyright (c) 2019,
> +Intel Corporation. All rights reserved.<BR> # SPDX-License-Identifier:
> +BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SamplePlatformDevicePolicyDxe
> +  FILE_GUID                      = 7EA7AACF-7ED3-4166-8271-B21156523620
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = MainEntryPoint
> +
> +[Sources]
> +  SamplePlatformDevicePolicyDxe.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +[LibraryClasses]
> +  UefiRuntimeServicesTableLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  MemoryAllocationLib
> +  DevicePathLib
> +  BaseMemoryLib
> +  PrintLib
> +  DebugLib
> +
> +[Protocols]
> +  gEdkiiDeviceSecurityPolicyProtocolGuid  ## PRODUCES
> +  gEdkiiDeviceIdentifierTypePciGuid       ## COMSUMES
> +
> +[Depex]
> +  TRUE
> --
> 2.19.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition.
  2019-11-07  4:46   ` Ni, Ray
@ 2019-11-07  7:13     ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-07  7:13 UTC (permalink / raw)
  To: Ni, Ray, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V, Lou, Yun

Yes, I will add the reference spec in the header in V3.

> -----Original Message-----
> From: Ni, Ray <ray.ni@intel.com>
> Sent: Thursday, November 7, 2019 12:47 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Lou, Yun
> <yun.lou@intel.com>
> Subject: RE: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity
> definition.
> 
> Jiewen,
> You could use "UINT8 Digest[0];" in structure
> INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE.
> 
> Same comments as what Sai raised, better to have the referenced spec in the
> file header.
> 
> Thanks,
> Ray
> 
> > -----Original Message-----
> > From: Yao, Jiewen <jiewen.yao@intel.com>
> > Sent: Thursday, October 31, 2019 8:31 PM
> > To: devel@edk2.groups.io
> > Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> > <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> > Subject: [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity
> > definition.
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> >
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> > Cc: Yun Lou <yun.lou@intel.com>
> > Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> > ---
> >  Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h |
> > 66 ++++++++++++++++++++
> >  1 file changed, 66 insertions(+)
> >
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> > b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> > new file mode 100644
> > index 0000000000..a8c5483165
> > --- /dev/null
> > +++
> > b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IntelPciSecurity.h
> > @@ -0,0 +1,66 @@
> > +/** @file
> > +  Intel PCI security data structure
> > +
> > +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef __INTEL_PCI_SECURITY_H__
> > +#define __INTEL_PCI_SECURITY_H__
> > +
> > +#pragma pack(1)
> > +
> > +typedef struct {
> > +  UINT16  CapId;           // 0x23: DVSEC
> > +  UINT16  CapVersion:4;    // 1
> > +  UINT16  NextOffset:12;
> > +  UINT16  DvSecVendorId;   // 0x8086
> > +  UINT16  DvSecRevision:4; // 1
> > +  UINT16  DvSecLength:12;
> > +  UINT16  DvSecId;         // 0x3E: Measure
> > +} INTEL_PCI_DIGEST_CAPABILITY_HEADER;
> > +
> > +#define INTEL_PCI_CAPID_DVSEC                0x23
> > +#define INTEL_PCI_DVSEC_VENDORID_INTEL       0x8086
> > +#define INTEL_PCI_DVSEC_DVSECID_MEASUREMENT  0x3E
> > +
> > +typedef union {
> > +  struct {
> > +    UINT8   DigestModified:1;         // RW1C
> > +    UINT8   Reserved0:7;
> > +  } Bits;
> > +  UINT8 Data;
> > +} INTEL_PCI_DIGEST_DATA_MODIFIED;
> > +
> > +#define INTEL_PCI_DIGEST_MODIFIED        BIT0
> > +
> > +typedef union {
> > +  struct {
> > +    UINT8   Digest0Valid:1;          // RO
> > +    UINT8   Digest0Locked:1;         // RO
> > +    UINT8   Digest1Valid:1;          // RO
> > +    UINT8   Digest1Locked:1;         // RO
> > +    UINT8   Reserved1:4;
> > +  } Bits;
> > +  UINT8 Data;
> > +} INTEL_PCI_DIGEST_DATA_VALID;
> > +
> > +#define INTEL_PCI_DIGEST_0_VALID         BIT0
> > +#define INTEL_PCI_DIGEST_0_LOCKED        BIT1
> > +#define INTEL_PCI_DIGEST_1_VALID         BIT2
> > +#define INTEL_PCI_DIGEST_1_LOCKED        BIT3
> > +
> > +typedef struct {
> > +  INTEL_PCI_DIGEST_DATA_MODIFIED   Modified;   // RW1C
> > +  INTEL_PCI_DIGEST_DATA_VALID      Valid;      // RO
> > +  UINT16                           TcgAlgId;   // RO
> > +  UINT8                            FirmwareID; // RO
> > +  UINT8                            Reserved;
> > +//UINT8                            Digest[];
> > +} INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE;
> > +
> > +#pragma pack()
> > +
> > +#endif
> > +
> > --
> > 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition.
  2019-11-07  6:11   ` Ni, Ray
@ 2019-11-07  7:17     ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-07  7:17 UTC (permalink / raw)
  To: Ni, Ray, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V, Lou, Yun

I do not see other protocol add such information in DEC file.

But I am OK to add. Will do that in V3.

> -----Original Message-----
> From: Ni, Ray <ray.ni@intel.com>
> Sent: Thursday, November 7, 2019 2:12 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Lou, Yun
> <yun.lou@intel.com>
> Subject: RE: [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition.
> 
> Jiewen,
> Can you add comments to explain the protocol and the associated header file
> path?
> Like:
>   ## Guid for EDKII implementation extension, used to indaicate there are bit
> fields in the varstore.
>   #  Include/Guid/MdeModuleHii.h
>   gEdkiiIfrBitVarstoreGuid  = {0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20,
> 0xA8, 0xFD, 0x60,0xA7, 0x1D}}
> 
> > -----Original Message-----
> > From: Yao, Jiewen <jiewen.yao@intel.com>
> > Sent: Thursday, October 31, 2019 8:31 PM
> > To: devel@edk2.groups.io
> > Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> > <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> > Subject: [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition.
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> >
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> > Cc: Yun Lou <yun.lou@intel.com>
> > Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> > ---
> >  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> > b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> > index 3079fc2869..8c8cd9f49d 100644
> > --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> > +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> > @@ -53,6 +53,7 @@
> >
> >  [Protocols]
> >    gEdkiiPlatformVTdPolicyProtocolGuid = { 0x3d17e448, 0x466, 0x4e20, { 0x99,
> > 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 }}
> > +  gEdkiiDeviceSecurityPolicyProtocolGuid = {0x7ea41a99, 0x5e32, 0x4c97,
> > {0x88, 0xc4, 0xd6, 0xe7, 0x46, 0x84, 0x9, 0xd4}}
> >
> >  [PcdsFixedAtBuild, PcdsPatchableInModule]
> >    ## Error code for VTd error.<BR><BR>
> > --
> > 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol
  2019-11-07  4:55   ` Ni, Ray
@ 2019-11-07  7:45     ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-07  7:45 UTC (permalink / raw)
  To: Ni, Ray, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V, Lou, Yun

Sure.
1. add comments to each field of structures like EDKII_DEVICE_SECURITY_POLICY and EDKII_DEVICE_SECURITY_STATE.
2. add comments to all the macros defined in this patch to explain the meaning and more important how they are going to impact the logic.


I don't believe a PCI/USB BUS driver developer need understand this protocol.
The PCI/USB only need to understand MdeModulePkg/DEVICE_SECURITY_PROTOCOL.

The IntelSiliconPkg/DEVICE_SECURITY_POLICY_PROTOCOL is for the internal implementation of a device security driver. It should be unknown by device driver writer.

Thank you
Yao Jiewen


> -----Original Message-----
> From: Ni, Ray <ray.ni@intel.com>
> Sent: Thursday, November 7, 2019 12:55 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Lou, Yun
> <yun.lou@intel.com>
> Subject: RE: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device
> Security Policy protocol
> 
> Jiewen,
> I am fine with the 1/6 patch that doesn't contain enough comments to describe
> the meaning
> of each field in each structure because I can reach out to the referenced spec to
> understand them.
> 
> This 2/6 patch introduces a new protocol but contains very few comments
> (almost none) for each
> structure each field and I cannot reach out to any spec to understand them.
> 
> So can you please add comments to each field of structures like
> EDKII_DEVICE_SECURITY_POLICY and
> EDKII_DEVICE_SECURITY_STATE?
> Also can you please add comments to all the macros defined in this patch to
> explain the meaning and
> more important how they are going to impact the logic.
> 
> In general, can you please add enough comments so that a PCI/USB BUS driver
> developer can understand
> the whole flow how this protocol supports the device security?
> 
> Thanks,
> Ray
> 
> > -----Original Message-----
> > From: Yao, Jiewen <jiewen.yao@intel.com>
> > Sent: Thursday, October 31, 2019 8:31 PM
> > To: devel@edk2.groups.io
> > Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> > <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> > Subject: [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device
> > Security Policy protocol
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> >
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> > Cc: Yun Lou <yun.lou@intel.com>
> > Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> > ---
> >
> > Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolicy.h
> > | 84 ++++++++++++++++++++
> >  1 file changed, 84 insertions(+)
> >
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolic
> > y.h
> > b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolic
> > y.h
> > new file mode 100644
> > index 0000000000..cb5a71ad41
> > --- /dev/null
> > +++
> > b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/PlatformDeviceSecurityPolic
> > y.h
> > @@ -0,0 +1,84 @@
> > +/** @file
> > +  Device Security Policy Protocol definition
> > +
> > +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +
> > +#ifndef __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
> > +#define __EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H__
> > +
> > +#include <Uefi.h>
> > +#include <Protocol/DeviceSecurity.h>
> > +
> > +typedef struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL
> > EDKII_DEVICE_SECURITY_POLICY_PROTOCOL;
> > +
> > +typedef struct {
> > +  UINT32     Version; // 0x1
> > +  UINT32     MeasurementPolicy;
> > +  UINT32     AuthenticationPolicy;
> > +} EDKII_DEVICE_SECURITY_POLICY;
> > +
> > +// BIT0 means if the action is needed or NOT
> > +#define EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED                 BIT0
> > +#define EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED              BIT0
> > +
> > +typedef struct {
> > +  UINT32     Version; // 0x1
> > +  UINT32     MeasurementState;
> > +  UINT32     AuthenticationState;
> > +} EDKII_DEVICE_SECURITY_STATE;
> > +
> > +// All zero means success
> > +#define EDKII_DEVICE_SECURITY_STATE_SUCCESS                          0
> > +#define EDKII_DEVICE_SECURITY_STATE_ERROR                            BIT31
> > +#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED
> > (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x0)
> > +#define
> > EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL
> > (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x1)
> > +#define EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES
> > (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x10)
> > +#define EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR
> > (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x20)
> > +
> > +/**
> > +  This function returns the device security policy associated with the device.
> > +
> > +  @param[in]  This                   The protocol instance pointer.
> > +  @param[in]  DeviceId               The Identifier for the device.
> > +  @param[out] DeviceSecurityPolicy   The Device Security Policy associated
> > with the device.
> > +
> > +  @retval EFI_SUCCESS                The device security policy is returned
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY) (
> > +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> > +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> > +  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
> > +  );
> > +
> > +/**
> > +  This function sets the device state based upon the authentication result.
> > +
> > +  @param[in]  This                   The protocol instance pointer.
> > +  @param[in]  DeviceId               The Identifier for the device.
> > +  @param[in]  DeviceSecurityState    The Device Security state associated
> > with the device.
> > +
> > +  @retval EFI_SUCCESS                The device state is set
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EDKII_DEVICE_SECURITY_SET_DEVICE_STATE) (
> > +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> > +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> > +  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
> > +  );
> > +
> > +struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL {
> > +  UINT32                                   Version; // 0x1
> > +  EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY  GetDevicePolicy;
> > +  EDKII_DEVICE_SECURITY_SET_DEVICE_STATE   SetDeviceState;
> > +};
> > +
> > +extern EFI_GUID gEdkiiDeviceSecurityPolicyProtocolGuid;
> > +
> > +#endif
> > --
> > 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity.
  2019-11-07  6:38   ` Ni, Ray
@ 2019-11-07  8:41     ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-07  8:41 UTC (permalink / raw)
  To: Ni, Ray, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V, Lou, Yun

Good feedback.
Comment below:

> -----Original Message-----
> From: Ni, Ray <ray.ni@intel.com>
> Sent: Thursday, November 7, 2019 2:38 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Lou, Yun
> <yun.lou@intel.com>
> Subject: RE: [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add
> PciSecurity.
> 
> 1. Can you make the macro short?
>     EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED ->
> EDKII_DEVICE_MEASUREMENT_REQUIRED
>     EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED ->
> EDKII_DEVICE_AUTHENTICATION_REQUIRED
[Jiewen] Agree. Will do in V3.

> 
> 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. "Security
> 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?
[Jiewen] Agree. Will do in V3.

> 
>     But I still don't understand why the device state needs to be passed into 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_SECURITY_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
> SetDeviceState() needs to do?
[Jiewen] Agree. Will do in V3.

> 
> 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 combine
> them into one line and with "DeviceSecurity"
>     keyword in the beginning of the message. "one line" is just a recommendation
> 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));
[Jiewen] OK. I will add "DvSec Capability - 0x%x\n" as title in V3.


> 
> > -----Original Message-----
> > From: Yao, Jiewen <jiewen.yao@intel.com>
> > Sent: Thursday, October 31, 2019 8:31 PM
> > To: devel@edk2.groups.io
> > Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> > <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> > Subject: [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add
> > PciSecurity.
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> >
> > This driver is to do the PCI device authentication based upon Intel PCIe
> > Security Specification.
> >
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> > Cc: Yun Lou <yun.lou@intel.com>
> > Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> > Signed-off-by: Yun Lou <yun.lou@intel.com>
> > ---
> >
> > Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe
> > /IntelPciDeviceSecurityDxe.c   | 701 ++++++++++++++++++++
> >
> > Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe
> > /IntelPciDeviceSecurityDxe.inf |  45 ++
> >
> > Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe
> > /TcgDeviceEvent.h              | 193 ++++++
> >  3 files changed, 939 insertions(+)
> >
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDx
> > e/IntelPciDeviceSecurityDxe.c
> > b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityD
> > 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.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <IndustryStandard/Spdm.h>
> > +#include <IndustryStandard/IntelPciSecurity.h>
> > +#include <IndustryStandard/Pci.h>
> > +#include <IndustryStandard/Tpm20.h>
> > +#include <IndustryStandard/UefiTcgPlatform.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/MemoryAllocationLib.h> #include
> > +<Library/TpmMeasurementLib.h> #include <Protocol/PciIo.h> #include
> > +<Protocol/DeviceSecurity.h> #include
> > +<Protocol/PlatformDeviceSecurityPolicy.h>
> > +#include "TcgDeviceEvent.h"
> > +
> > +typedef struct {
> > +  UINT8                                             Measurement[SHA512_DIGEST_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 =
> > +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 = PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice,
> > + &PciFunction);  ASSERT_EFI_ERROR(Status);
> > +
> > +  NewPciDevice = AllocateZeroPool(sizeof(*NewPciDevice));
> > +  ASSERT_EFI_ERROR(NewPciDevice != NULL);
> > +
> > +  NewPciDevice->Signature   = PCI_DEVICE_INSTANCE_SIGNATURE;
> > +  NewPciDevice->PciSegment  = PciSegment;
> > +  NewPciDevice->PciBus      = PciBus;
> > +  NewPciDevice->PciDevice   = PciDevice;
> > +  NewPciDevice->PciFunction = 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 = PciIo->GetLocation (PciIo, &PciSegment, &PciBus, &PciDevice,
> > + &PciFunction);  ASSERT_EFI_ERROR(Status);
> > +
> > +  Link = GetFirstNode(PciDeviceList);
> > +  while (!IsNull(PciDeviceList, Link)) {
> > +    CurrentPciDevice = PCI_DEVICE_INSTANCE_FROM_LINK(Link);
> > +
> > +    if (CurrentPciDevice->PciSegment == PciSegment && CurrentPciDevice-
> > >PciBus == PciBus &&
> > +        CurrentPciDevice->PciDevice == PciDevice && CurrentPciDevice-
> > >PciFunction == PciFunction) {
> > +      DEBUG((DEBUG_INFO, "PCI device duplicated (Loc -
> >  %04x:%02x:%02x:%02x)\n", PciSegment, PciBus, PciDevice, PciFunction));
> > +      return TRUE;
> > +    }
> > +
> > +    Link = 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 = ~CapId;
> > +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8,
> > + PCI_CAPBILITY_POINTER_OFFSET, 1, &PciCapIdHdr.NextItemPtr);
> > + ASSERT_EFI_ERROR(Status);  if (PciCapIdHdr.NextItemPtr == 0 ||
> > PciCapIdHdr.NextItemPtr == 0xFF) {
> > +    return 0;
> > +  }
> > +  PciCapIdOffset = 0;
> > +  do {
> > +    if (PciCapIdHdr.CapabilityID == CapId) {
> > +      break;
> > +    }
> > +    PciCapIdOffset = PciCapIdHdr.NextItemPtr;
> > +    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PciCapIdOffset, 1,
> > &PciCapIdHdr);
> > +    ASSERT_EFI_ERROR(Status);
> > +  } while (PciCapIdHdr.NextItemPtr != 0 && PciCapIdHdr.NextItemPtr !=
> > + 0xFF);
> > +
> > +  if (PciCapIdHdr.CapabilityID == 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 = GetPciCapId (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP);
> > + if (PcieCapIdOffset == 0) {
> > +    return 0;
> > +  }
> > +
> > +  PciExpressExtCapIdHdr.CapabilityId = ~CapId;
> > + PciExpressExtCapIdHdr.CapabilityVersion = 0xF;
> > + PciExpressExtCapIdHdr.NextCapabilityOffset = 0x100;  PcieCapIdOffset =
> > + 0;  do {
> > +    if (PciExpressExtCapIdHdr.CapabilityId == CapId) {
> > +      break;
> > +    }
> > +    PcieCapIdOffset = PciExpressExtCapIdHdr.NextCapabilityOffset;
> > +    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, PcieCapIdOffset, 1,
> > &PciExpressExtCapIdHdr);
> > +    ASSERT_EFI_ERROR(Status);
> > +  } while (PciExpressExtCapIdHdr.NextCapabilityOffset != 0 &&
> > + PciExpressExtCapIdHdr.NextCapabilityOffset != 0xFFF);
> > +
> > +  if (PciExpressExtCapIdHdr.CapabilityId == 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 space
> > +
> > +  @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 = 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 space
> > +  @param Data             Byte value of the PCI device configuration space.
> > +**/
> > +VOID
> > +DvSecPciWrite8 (
> > +  IN EFI_PCI_IO_PROTOCOL *PciIo,
> > +  IN UINT32              Offset,
> > +  IN UINT8               Data
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  Status = 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 associated
> > 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 associated
> > 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 = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0,
> > + sizeof(PciData), &PciData);  ASSERT_EFI_ERROR(Status);
> > +
> > +  PcrIndex = EDKII_DEVICE_MEASUREMENT_COMPONENT_PCR_INDEX;
> > +  EventType = EDKII_DEVICE_MEASUREMENT_COMPONENT_EVENT_TYPE;
> > +
> > +  CopyMem (EventLog.EventData.Signature,
> > EDKII_DEVICE_SECURITY_EVENT_DATA_SIGNATURE,
> > sizeof(EventLog.EventData.Signature));
> > +  EventLog.EventData.Version                  =
> > EDKII_DEVICE_SECURITY_EVENT_DATA_VERSION;
> > +  EventLog.EventData.Length                   =
> > sizeof(EDKII_DEVICE_SECURITY_PCI_EVENT_DATA);
> > +  EventLog.EventData.SpdmMeasurementBlock.Index                    = DigestSel;
> > +  EventLog.EventData.SpdmMeasurementBlock.MeasurementType          =
> > SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWA
> > RE;
> > +  EventLog.EventData.SpdmMeasurementBlock.MeasurementSpecification
> > = 0xFF;
> > +  EventLog.EventData.SpdmMeasurementBlock.Reserved                 = 0;
> > +  EventLog.EventData.SpdmHashAlgo       = TcgAlgIdToSpdmHashAlgo
> > (TcgAlgId);
> > +  EventLog.EventData.DeviceType         =
> > EDKII_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI;
> > +  ZeroMem (EventLog.EventData.Reserved,
> > sizeof(EventLog.EventData.Reserved));
> > +  EventLog.PciContext.Version           =
> > EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION;
> > +  EventLog.PciContext.Length            =
> > sizeof(EDKII_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT);
> > +  EventLog.PciContext.VendorId          = PciData.Hdr.VendorId;
> > +  EventLog.PciContext.DeviceId          = PciData.Hdr.DeviceId;
> > +  EventLog.PciContext.RevisionID        = PciData.Hdr.RevisionID;
> > +  EventLog.PciContext.ClassCode[0]      = PciData.Hdr.ClassCode[0];
> > +  EventLog.PciContext.ClassCode[1]      = PciData.Hdr.ClassCode[1];
> > +  EventLog.PciContext.ClassCode[2]      = PciData.Hdr.ClassCode[2];
> > +  if ((PciData.Hdr.HeaderType & HEADER_LAYOUT_CODE) ==
> > HEADER_TYPE_DEVICE) {
> > +    EventLog.PciContext.SubsystemVendorID =
> > PciData.Device.SubsystemVendorID;
> > +    EventLog.PciContext.SubsystemID       = PciData.Device.SubsystemID;
> > +  } else {
> > +    EventLog.PciContext.SubsystemVendorID = 0;
> > +    EventLog.PciContext.SubsystemID       = 0;
> > +  }
> > +
> > +  DigestSize = DigestSizeFromTcgAlgId (TcgAlgId);  CopyMem
> > + (&HashData.Measurement, Digest, DigestSize);
> > +
> > +  HashDataLen = DigestSize;
> > +  Status = TpmMeasureAndLogData (
> > +             PcrIndex,
> > +             EventType,
> > +             &EventLog,
> > +             EventLog.EventData.Length,
> > +             &HashData,
> > +             HashDataLen
> > +             );
> > +  DEBUG((DEBUG_INFO, "TpmMeasureAndLogData - %r\n", Status));
> > +  if (EFI_ERROR(Status)) {
> > +    DeviceSecurityState->MeasurementState =
> > +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 device.
> > +  @param[in]  DeviceSecurityPolicy   The Device Security Policy associated
> > with the device.
> > +  @param[out] DeviceSecurityState    The Device Security state associated
> > 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 = 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 = DigestSizeFromTcgAlgId (TcgAlgId);  if (DigestSize == 0)
> > + {
> > +    DEBUG((DEBUG_INFO, "Unsupported Algorithm - 0x%04x\n", TcgAlgId));
> > +    DeviceSecurityState->MeasurementState =
> > EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES;
> > +    return ;
> > +  }
> > +  DEBUG((DEBUG_INFO, "  (DigestSize: 0x%x)\n", DigestSize));
> > +
> > +  DeviceSecurityState->MeasurementState =
> > + EDKII_DEVICE_SECURITY_STATE_SUCCESS;
> > +
> > +  NumDigest = 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 = 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 = 2;
> > +  }
> > +
> > +  for (DigestSel = 0; DigestSel < NumDigest; DigestSel++) {
> > +    DEBUG((DEBUG_INFO, "  DigestSel     - 0x%02x\n", DigestSel));
> > +    if ((DigestSel == 0) && ((Valid & INTEL_PCI_DIGEST_0_VALID) == 0)) {
> > +      continue;
> > +    }
> > +    if ((DigestSel == 1) && ((Valid & INTEL_PCI_DIGEST_1_VALID) == 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 = 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 = DvSecPciRead8 (
> > +                   PciIo,
> > +                   DvSecOffset + sizeof(INTEL_PCI_DIGEST_CAPABILITY_HEADER) +
> > OFFSET_OF(INTEL_PCI_DIGEST_CAPABILITY_STRUCTURE, Modified)
> > +                   );
> > +      if ((Modified & INTEL_PCI_DIGEST_MODIFIED) == 0) {
> > +        break;
> > +      }
> > +    }
> > +
> > +    //
> > +    // Dump Digest
> > +    //
> > +    {
> > +      UINTN  Index;
> > +      DEBUG((DEBUG_INFO, "  Digest        - "));
> > +      for (Index = 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 associated
> > with the device.
> > +  @param[out] DeviceSecurityState    The Device Security state associated
> > 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 =
> > EDKII_DEVICE_SECURITY_STATE_SUCCESS;
> > +    return ;
> > +  }
> > +
> > +  DvSecOffset = GetPciExpressExtCapId (PciIo, INTEL_PCI_CAPID_DVSEC);
> > + DEBUG((DEBUG_INFO, "DvSecOffset - 0x%x\n", DvSecOffset));  if
> > + (DvSecOffset == 0) {
> > +    DeviceSecurityState->MeasurementState =
> > EDKII_DEVICE_SECURITY_STATE_ERROR_PCI_NO_CAPABILITIES;
> > +    return ;
> > +  }
> > +  Status = 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 != INTEL_PCI_DVSEC_VENDORID_INTEL) &&
> > +      (DvSecHdr.DvSecId != INTEL_PCI_DVSEC_DVSECID_MEASUREMENT)) {
> > +    DeviceSecurityState->MeasurementState =
> > 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 associated
> > with the device.
> > +  @param[out] DeviceSecurityState    The Device Security state associated
> > 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 =
> > +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 installs
> > 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 measurement 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 == NULL) {
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  if (!CompareGuid (&DeviceId->DeviceType,
> > &gEdkiiDeviceIdentifierTypePciGuid)) {
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  Status = gBS->HandleProtocol (
> > +                  DeviceId->DeviceHandle,
> > +                  &gEdkiiDeviceIdentifierTypePciGuid,
> > +                  (VOID **)&PciIo
> > +                  );
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n",
> > Status));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  DeviceSecurityState.Version = 0x1;
> > +  DeviceSecurityState.MeasurementState = 0x0;
> > + DeviceSecurityState.AuthenticationState = 0x0;
> > +
> > +  Status = mDeviceSecurityPolicy->GetDevicePolicy
> > + (mDeviceSecurityPolicy, DeviceId, &DeviceSecurityPolicy);  if
> > (EFI_ERROR(Status)) {
> > +    DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->GetDevicePolicy -
> >  %r\n", Status));
> > +    DeviceSecurityState.MeasurementState =
> > EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL;
> > +    DeviceSecurityState.AuthenticationState =
> > + EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL;
> > +  } else {
> > +    if ((DeviceSecurityPolicy->MeasurementPolicy &
> > EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED) != 0) {
> > +      DoDeviceMeasurement (PciIo, DeviceSecurityPolicy,
> > &DeviceSecurityState);
> > +      DEBUG((DEBUG_ERROR, "MeasurementState - 0x%08x\n",
> > DeviceSecurityState.MeasurementState));
> > +    }
> > +    if ((DeviceSecurityPolicy->AuthenticationPolicy &
> > EDKII_DEVICE_AUTHENTICATION_POLICY_REQUIRED) != 0) {
> > +      DoDeviceAuthentication (PciIo, DeviceSecurityPolicy,
> > &DeviceSecurityState);
> > +      DEBUG((DEBUG_ERROR, "AuthenticationState - 0x%08x\n",
> > DeviceSecurityState.AuthenticationState));
> > +    }
> > +  }
> > +
> > +  Status = mDeviceSecurityPolicy->SetDeviceState
> > + (mDeviceSecurityPolicy, DeviceId, &DeviceSecurityState);  if
> > (EFI_ERROR(Status)) {
> > +    DEBUG((DEBUG_ERROR, "mDeviceSecurityPolicy->SetDeviceState - %r\n",
> > + Status));  }
> > +
> > +  if ((DeviceSecurityState.MeasurementState == 0) &&
> > +      (DeviceSecurityState.AuthenticationState == 0)) {
> > +    return EFI_SUCCESS;
> > +  } else {
> > +    return EFI_SECURITY_VIOLATION;
> > +  }
> > +}
> > +
> > +EDKII_DEVICE_SECURITY_PROTOCOL mDeviceSecurity = {
> > +  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 = gBS->LocateProtocol
> > + (&gEdkiiDeviceSecurityPolicyProtocolGuid, NULL, (VOID
> > + **)&mDeviceSecurityPolicy);  ASSERT_EFI_ERROR(Status);
> > +
> > +  Handle = NULL;
> > +  Status = gBS->InstallProtocolInterface (
> > +                  &Handle,
> > +                  &gEdkiiDeviceSecurityProtocolGuid,
> > +                  EFI_NATIVE_INTERFACE,
> > +                  (VOID **)&mDeviceSecurity
> > +                  );
> > +  ASSERT_EFI_ERROR(Status);
> > +
> > +  return Status;
> > +}
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDx
> > e/IntelPciDeviceSecurityDxe.inf
> > b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityD
> > 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.<BR> # SPDX-License-Identifier:
> > +BSD-2-Clause-Patent # ##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = IntelPciDeviceSecurityDxe
> > +  FILE_GUID                      = D9569195-ED94-47D2-9523-38BF2D201371
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = 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/IntelPciDeviceSecurityDx
> > e/TcgDeviceEvent.h
> > b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityD
> > 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.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent **/
> > +
> > +
> > +#ifndef __TCG_EVENT_DATA_H__
> > +#define __TCG_EVENT_DATA_H__
> > +
> > +#include <IndustryStandard/Spdm.h>
> > +
> > +#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 platform
> > 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 to
> > 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 the
> > 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 been, 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 value
> > of UEFI_IMAGE_SECURITY_DATABASE.
> > +//            The value MUST NOT include the terminating NUL.
> > +//
> > +
> > +#pragma pack()
> > +
> > +#endif
> > --
> > 2.19.2.windows.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [edk2-devel] [PATCH V2 5/6] IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy.
  2019-11-07  6:55   ` [edk2-devel] " Ni, Ray
@ 2019-11-07  8:42     ` Yao, Jiewen
  0 siblings, 0 replies; 28+ messages in thread
From: Yao, Jiewen @ 2019-11-07  8:42 UTC (permalink / raw)
  To: Ni, Ray, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V, Lou, Yun

Good feedback.
Comment below:

> -----Original Message-----
> From: Ni, Ray <ray.ni@intel.com>
> Sent: Thursday, November 7, 2019 2:56 PM
> To: devel@edk2.groups.io; Yao, Jiewen <jiewen.yao@intel.com>
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Lou, Yun
> <yun.lou@intel.com>
> Subject: RE: [edk2-devel] [PATCH V2 5/6]
> IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy.
> 
> 1. I am sorry but I just realized GetDevicePolicy() returns a pointer of policy to
> caller,
>     instead of copying the policy data to caller's buffer. It's a bit strange to me.
> Can you
>     please change the prototype so that caller needs to pass in a policy structure
> and
>     GetDevicePolicy() fills the structure buffer using CopyMem from
> mDeviceSecurityPolicyNone?
>     "*DeviceSecurityPolicy = &mDeviceSecurityPolicyNone;"
>     "DeviceSecurityPolicy = &mDeviceSecurityPolicyMeasurement;"
[Jiewen] Agree. Will update in V3.

> 
> 2. I thought SetDeviceState() in your sample will reset the
> EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED
>     to 0. Why didn't the sample do that?
[Jiewen] I rename the function to NotifyDeviceState() in V3.
I think that is clear.
Also the state parameter is IN. The caller should not change it.

> 
> 3. I just realized you didn't define the version macro for
> EDKII_DEVICE_SECURITY_POLICY_PROTOCOL.Version.
>     I suggest you define a macro for the version instead of let producer/consumer
> use hard-code number (0x1).
>     And I am not sure if you will use the same version macro for the
> protocol.version, securitypolicy.version and
>     securitystate.version. I assume you will. No matter yes or no, can you please
> state that through comments
>     in the policy protocol header file clearly?
[Jiewen] Agree. Will update in V3.

> 
> 
> 
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao,
> > Jiewen
> > Sent: Thursday, October 31, 2019 8:31 PM
> > To: devel@edk2.groups.io
> > Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> > <rangasai.v.chaganty@intel.com>; Lou, Yun <yun.lou@intel.com>
> > Subject: [edk2-devel] [PATCH V2 5/6]
> > IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy.
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303
> >
> > This driver provides the platform sample policy to measure a NVMe card.
> >
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> > Cc: Yun Lou <yun.lou@intel.com>
> > Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> > ---
> >
> > Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePoli
> > cyDxe/SamplePlatformDevicePolicyDxe.c   | 189 ++++++++++++++++++++
> >
> > Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePoli
> > cyDxe/SamplePlatformDevicePolicyDxe.inf |  40 +++++
> >  2 files changed, 229 insertions(+)
> >
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDeviceP
> > olicyDxe/SamplePlatformDevicePolicyDxe.c
> > b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDeviceP
> > olicyDxe/SamplePlatformDevicePolicyDxe.c
> > new file mode 100644
> > index 0000000000..1f01b961a8
> > --- /dev/null
> > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformD
> > +++ evicePolicyDxe/SamplePlatformDevicePolicyDxe.c
> > @@ -0,0 +1,189 @@
> > +/** @file
> > +  EDKII Device Security library for PCI device
> > +
> > +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <IndustryStandard/Spdm.h>
> > +#include <IndustryStandard/Pci.h>
> > +#include <Protocol/PciIo.h>
> > +#include <Protocol/DeviceSecurity.h>
> > +#include <Protocol/PlatformDeviceSecurityPolicy.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +
> > +EDKII_DEVICE_SECURITY_POLICY           mDeviceSecurityPolicyNone = {
> > +  0x1,
> > +  0,
> > +  0,
> > +};
> > +EDKII_DEVICE_SECURITY_POLICY           mDeviceSecurityPolicyMeasurement
> > = {
> > +  0x1,
> > +  EDKII_DEVICE_MEASUREMENT_POLICY_REQUIRED,
> > +  0,
> > +};
> > +
> > +/**
> > +  This function returns the device security policy associated with the device.
> > +
> > +  @param[in]  This                   The protocol instance pointer.
> > +  @param[in]  DeviceId               The Identifier for the device.
> > +  @param[out] DeviceSecurityPolicy   The Device Security Policy associated
> > with the device.
> > +
> > +  @retval EFI_SUCCESS                The device security policy is returned
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetDevicePolicy (
> > +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> > +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> > +  OUT EDKII_DEVICE_SECURITY_POLICY           **DeviceSecurityPolicy
> > +  )
> > +{
> > +  EFI_STATUS                  Status;
> > +  EFI_PCI_IO_PROTOCOL         *PciIo;
> > +  UINT16                      PciVendorId;
> > +  UINT16                      PciDeviceId;
> > +
> > +  *DeviceSecurityPolicy = &mDeviceSecurityPolicyNone;
> > +
> > +  DEBUG ((DEBUG_INFO, "GetDevicePolicy - 0x%g\n",
> > + &DeviceId->DeviceType));
> > +
> > +  if (!CompareGuid (&DeviceId->DeviceType,
> > &gEdkiiDeviceIdentifierTypePciGuid)) {
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  Status = gBS->HandleProtocol (
> > +                  DeviceId->DeviceHandle,
> > +                  &gEdkiiDeviceIdentifierTypePciGuid,
> > +                  (VOID **)&PciIo
> > +                  );
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n",
> > Status));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> > + PCI_VENDOR_ID_OFFSET, 1, &PciVendorId);  ASSERT_EFI_ERROR(Status);
> > + Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> > + PCI_DEVICE_ID_OFFSET, 1, &PciDeviceId);  ASSERT_EFI_ERROR(Status);
> > + DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId,
> > + PciDeviceId));
> > +
> > +  if ((PciVendorId == 0x8086) && (PciDeviceId == 0x0B60)) {
> > +    *DeviceSecurityPolicy = &mDeviceSecurityPolicyMeasurement;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  This function sets the device state based upon the authentication result.
> > +
> > +  @param[in]  This                   The protocol instance pointer.
> > +  @param[in]  DeviceId               The Identifier for the device.
> > +  @param[in]  DeviceSecurityState    The Device Security state associated
> > with the device.
> > +
> > +  @retval EFI_SUCCESS                The device state is set
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SetDeviceState (
> > +  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
> > +  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
> > +  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
> > +  )
> > +{
> > +  EFI_STATUS                  Status;
> > +  EFI_PCI_IO_PROTOCOL         *PciIo;
> > +  UINT16                      PciVendorId;
> > +  UINT16                      PciDeviceId;
> > +  UINTN                       Segment;
> > +  UINTN                       Bus;
> > +  UINTN                       Device;
> > +  UINTN                       Function;
> > +
> > +  DEBUG ((DEBUG_INFO, "SetDeviceState - 0x%g\n",
> > + &DeviceId->DeviceType));
> > +
> > +  if (!CompareGuid (&DeviceId->DeviceType,
> > &gEdkiiDeviceIdentifierTypePciGuid)) {
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  Status = gBS->HandleProtocol (
> > +                  DeviceId->DeviceHandle,
> > +                  &gEdkiiDeviceIdentifierTypePciGuid,
> > +                  (VOID **)&PciIo
> > +                  );
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n",
> > Status));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> > + PCI_VENDOR_ID_OFFSET, 1, &PciVendorId);  ASSERT_EFI_ERROR(Status);
> > + Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> > + PCI_DEVICE_ID_OFFSET, 1, &PciDeviceId);  ASSERT_EFI_ERROR(Status);
> > + DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId,
> > + PciDeviceId));
> > +
> > +  Status = PciIo->GetLocation (
> > +                    PciIo,
> > +                    &Segment,
> > +                    &Bus,
> > +                    &Device,
> > +                    &Function
> > +                    );
> > +  if (!EFI_ERROR(Status)) {
> > +    DEBUG ((DEBUG_INFO, "PCI Loc - %04x:%02x:%02x:%02x\n",
> > +      Segment, Bus, Device, Function));  }
> > +
> > +  DEBUG ((DEBUG_INFO, "State - Measurement - 0x%08x, Authentication -
> > 0x%08x\n",
> > +    DeviceSecurityState->MeasurementState,
> > +    DeviceSecurityState->AuthenticationState
> > +    ));
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  mDeviceSecurityPolicy = {
> > +  0x1,
> > +  GetDevicePolicy,
> > +  SetDeviceState,
> > +};
> > +
> > +/**
> > +  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;
> > +
> > +  Handle = NULL;
> > +  Status = gBS->InstallProtocolInterface (
> > +                  &Handle,
> > +                  &gEdkiiDeviceSecurityPolicyProtocolGuid,
> > +                  EFI_NATIVE_INTERFACE,
> > +                  &mDeviceSecurityPolicy
> > +                  );
> > +  ASSERT_EFI_ERROR(Status);
> > +
> > +  return Status;
> > +}
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDeviceP
> > olicyDxe/SamplePlatformDevicePolicyDxe.inf
> > b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDeviceP
> > olicyDxe/SamplePlatformDevicePolicyDxe.inf
> > new file mode 100644
> > index 0000000000..a9b77d8371
> > --- /dev/null
> > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformD
> > +++ evicePolicyDxe/SamplePlatformDevicePolicyDxe.inf
> > @@ -0,0 +1,40 @@
> > +## @file
> > +#  EDKII Device Security library for PCI device # # Copyright (c) 2019,
> > +Intel Corporation. All rights reserved.<BR> # SPDX-License-Identifier:
> > +BSD-2-Clause-Patent # ##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = SamplePlatformDevicePolicyDxe
> > +  FILE_GUID                      = 7EA7AACF-7ED3-4166-8271-B21156523620
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = MainEntryPoint
> > +
> > +[Sources]
> > +  SamplePlatformDevicePolicyDxe.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  IntelSiliconPkg/IntelSiliconPkg.dec
> > +
> > +[LibraryClasses]
> > +  UefiRuntimeServicesTableLib
> > +  UefiBootServicesTableLib
> > +  UefiDriverEntryPoint
> > +  MemoryAllocationLib
> > +  DevicePathLib
> > +  BaseMemoryLib
> > +  PrintLib
> > +  DebugLib
> > +
> > +[Protocols]
> > +  gEdkiiDeviceSecurityPolicyProtocolGuid  ## PRODUCES
> > +  gEdkiiDeviceIdentifierTypePciGuid       ## COMSUMES
> > +
> > +[Depex]
> > +  TRUE
> > --
> > 2.19.2.windows.1
> >
> >
> > 


^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2019-11-07  8:42 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-10-31 12:31 [PATCH V2 0/6] Add Device Security driver Yao, Jiewen
2019-10-31 12:31 ` [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition Yao, Jiewen
2019-11-06 20:00   ` Chaganty, Rangasai V
2019-11-07  3:22     ` Yao, Jiewen
2019-11-07  4:46   ` Ni, Ray
2019-11-07  7:13     ` Yao, Jiewen
2019-10-31 12:31 ` [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol Yao, Jiewen
2019-11-06 21:50   ` Chaganty, Rangasai V
2019-11-07  3:40     ` Yao, Jiewen
2019-11-07  4:55   ` Ni, Ray
2019-11-07  7:45     ` Yao, Jiewen
2019-10-31 12:31 ` [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition Yao, Jiewen
2019-11-06 22:09   ` Chaganty, Rangasai V
2019-11-07  6:11   ` Ni, Ray
2019-11-07  7:17     ` Yao, Jiewen
2019-10-31 12:31 ` [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity Yao, Jiewen
2019-11-07  6:38   ` Ni, Ray
2019-11-07  8:41     ` Yao, Jiewen
2019-10-31 12:31 ` [PATCH V2 5/6] IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy Yao, Jiewen
2019-11-07  6:55   ` [edk2-devel] " Ni, Ray
2019-11-07  8:42     ` Yao, Jiewen
2019-10-31 12:31 ` [PATCH V2 6/6] IntelSiliconPkg/dsc: Add Device Security component Yao, Jiewen
     [not found] ` <15D2BB3E562C773B.23805@groups.io>
2019-11-06  6:48   ` [edk2-devel] [PATCH V2 2/6] IntelSiliconPkg/Include: Add Platform Device Security Policy protocol Yao, Jiewen
     [not found] ` <15D2BB3F6D7204CF.23805@groups.io>
2019-11-06  6:48   ` [edk2-devel] [PATCH V2 5/6] IntelSiliconPkg/SamplePlatformDevicePolicyDxe: Add sample policy Yao, Jiewen
     [not found] ` <15D2BB3F2A1C2156.31603@groups.io>
2019-11-06  6:48   ` [edk2-devel] [PATCH V2 4/6] IntelSiliconPkg/IntelPciDeviceSecurityDxe: Add PciSecurity Yao, Jiewen
     [not found] ` <15D2BB3E9D627794.4494@groups.io>
2019-11-06  6:48   ` [edk2-devel] [PATCH V2 3/6] IntelSiliconPkg/dec: Add ProtocolGuid definition Yao, Jiewen
     [not found] ` <15D2BB3E0A913641.22120@groups.io>
2019-11-06  6:48   ` [edk2-devel] [PATCH V2 1/6] IntelSiliconPkg/Include: Add Intel PciSecurity definition Yao, Jiewen
     [not found] ` <15D2BB3FAC504840.31603@groups.io>
2019-11-06  6:48   ` [edk2-devel] [PATCH V2 6/6] IntelSiliconPkg/dsc: Add Device Security component Yao, Jiewen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox