]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/Pci: Add DeviceSecurity support.
authorJiewen Yao <jiewen.yao@intel.com>
Sun, 29 Sep 2019 08:37:14 +0000 (16:37 +0800)
committerJiewen Yao <jiewen.yao@intel.com>
Mon, 11 Nov 2019 11:04:05 +0000 (19:04 +0800)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303

Whenever a PCI device is discovered, PCI bus calls the
EDKII_DEVICE_SECURITY_PROTOCOL to authenticate it.
If the function returns success, the PCI bus allocates
the resource and installs the PCI_IO for the device.
If the function returns fail, the PCI bus skips the device.

It is similar to EFI_SECURITY_ARCH_PROTOCOL, which
is used to verify an EFI image.

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c

index b020ce50ce3ca5bf4b0873fd99dfedae4251984c..64284ac8251cf932a8dcff037e3895c047714c0f 100644 (file)
@@ -8,7 +8,7 @@
   PCI Root Bridges. So it means platform needs install PCI Root Bridge IO protocol for each\r
   PCI Root Bus and install PCI Host Bridge Resource Allocation Protocol.\r
 \r
   PCI Root Bridges. So it means platform needs install PCI Root Bridge IO protocol for each\r
   PCI Root Bus and install PCI Host Bridge Resource Allocation Protocol.\r
 \r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
@@ -37,7 +37,7 @@ UINT64                                        gAllZero             = 0;
 EFI_PCI_PLATFORM_PROTOCOL                     *gPciPlatformProtocol;\r
 EFI_PCI_OVERRIDE_PROTOCOL                     *gPciOverrideProtocol;\r
 EDKII_IOMMU_PROTOCOL                          *mIoMmuProtocol;\r
 EFI_PCI_PLATFORM_PROTOCOL                     *gPciPlatformProtocol;\r
 EFI_PCI_OVERRIDE_PROTOCOL                     *gPciOverrideProtocol;\r
 EDKII_IOMMU_PROTOCOL                          *mIoMmuProtocol;\r
-\r
+EDKII_DEVICE_SECURITY_PROTOCOL                *mDeviceSecurityProtocol;\r
 \r
 GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = {\r
   PciHotPlugRequestNotify\r
 \r
 GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = {\r
   PciHotPlugRequestNotify\r
@@ -293,6 +293,14 @@ PciBusDriverBindingStart (
           );\r
   }\r
 \r
           );\r
   }\r
 \r
+  if (mDeviceSecurityProtocol == NULL) {\r
+    gBS->LocateProtocol (\r
+          &gEdkiiDeviceSecurityProtocolGuid,\r
+          NULL,\r
+          (VOID **) &mDeviceSecurityProtocol\r
+          );\r
+  }\r
+\r
   if (PcdGetBool (PcdPciDisableBusEnumeration)) {\r
     gFullEnumeration = FALSE;\r
   } else {\r
   if (PcdGetBool (PcdPciDisableBusEnumeration)) {\r
     gFullEnumeration = FALSE;\r
   } else {\r
index 504a1b1c1297792a65b7e7bbffea26bdb6eb117d..d4113993c8af090d08d84e3465eb9b164354dbf6 100644 (file)
@@ -27,6 +27,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Protocol/PciOverride.h>\r
 #include <Protocol/PciEnumerationComplete.h>\r
 #include <Protocol/IoMmu.h>\r
 #include <Protocol/PciOverride.h>\r
 #include <Protocol/PciEnumerationComplete.h>\r
 #include <Protocol/IoMmu.h>\r
+#include <Protocol/DeviceSecurity.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/UefiDriverEntryPoint.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/UefiDriverEntryPoint.h>\r
index 05c22025b8671aec626bac2bd33725f06f8d866b..9284998f36153248230ffdd78c6068688cc111de 100644 (file)
@@ -2,7 +2,7 @@
 #  The PCI bus driver will probe all PCI devices and allocate MMIO and IO space for these devices.\r
 #  Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable hot plug supporting.\r
 #\r
 #  The PCI bus driver will probe all PCI devices and allocate MMIO and IO space for these devices.\r
 #  Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable hot plug supporting.\r
 #\r
-#  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
@@ -90,6 +90,8 @@
   gEfiIncompatiblePciDeviceSupportProtocolGuid    ## SOMETIMES_CONSUMES\r
   gEfiLoadFile2ProtocolGuid                       ## SOMETIMES_PRODUCES\r
   gEdkiiIoMmuProtocolGuid                         ## SOMETIMES_CONSUMES\r
   gEfiIncompatiblePciDeviceSupportProtocolGuid    ## SOMETIMES_CONSUMES\r
   gEfiLoadFile2ProtocolGuid                       ## SOMETIMES_PRODUCES\r
   gEdkiiIoMmuProtocolGuid                         ## SOMETIMES_CONSUMES\r
+  gEdkiiDeviceSecurityProtocolGuid                ## SOMETIMES_CONSUMES\r
+  gEdkiiDeviceIdentifierTypePciGuid               ## SOMETIMES_CONSUMES\r
   gEfiLoadedImageDevicePathProtocolGuid           ## CONSUMES\r
 \r
 [FeaturePcd]\r
   gEfiLoadedImageDevicePathProtocolGuid           ## CONSUMES\r
 \r
 [FeaturePcd]\r
index c7eafff5935545cfafb9b55ad8a7e744b131ce24..f8020f4e7218e93f6debfbcc5496a9518e2c1326 100644 (file)
@@ -10,6 +10,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include "PciBus.h"\r
 \r
 extern CHAR16  *mBarTypeStr[];\r
 #include "PciBus.h"\r
 \r
 extern CHAR16  *mBarTypeStr[];\r
+extern EDKII_DEVICE_SECURITY_PROTOCOL                          *mDeviceSecurityProtocol;\r
 \r
 #define OLD_ALIGN   0xFFFFFFFFFFFFFFFFULL\r
 #define EVEN_ALIGN  0xFFFFFFFFFFFFFFFEULL\r
 \r
 #define OLD_ALIGN   0xFFFFFFFFFFFFFFFFULL\r
 #define EVEN_ALIGN  0xFFFFFFFFFFFFFFFEULL\r
@@ -2070,6 +2071,67 @@ InitializeP2C (
   PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);\r
 }\r
 \r
   PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);\r
 }\r
 \r
+/*\r
+  Authenticate the PCI device by using DeviceSecurityProtocol.\r
+\r
+  @param PciIoDevice  PCI device.\r
+\r
+  @retval EFI_SUCCESS     The device passes the authentication.\r
+  @return not EFI_SUCCESS The device failes the authentication or\r
+                          unexpected error happen during authentication.\r
+*/\r
+EFI_STATUS\r
+AuthenticatePciDevice (\r
+  IN PCI_IO_DEVICE            *PciIoDevice\r
+  )\r
+{\r
+  EDKII_DEVICE_IDENTIFIER  DeviceIdentifier;\r
+  EFI_STATUS               Status;\r
+\r
+  if (mDeviceSecurityProtocol != NULL) {\r
+    //\r
+    // Prepare the parameter\r
+    //\r
+    DeviceIdentifier.Version = EDKII_DEVICE_IDENTIFIER_REVISION;\r
+    CopyGuid (&DeviceIdentifier.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid);\r
+    DeviceIdentifier.DeviceHandle = NULL;\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &DeviceIdentifier.DeviceHandle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    PciIoDevice->DevicePath,\r
+                    &gEdkiiDeviceIdentifierTypePciGuid,\r
+                    &PciIoDevice->PciIo,\r
+                    NULL\r
+                    );\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Do DeviceAuthentication\r
+    //\r
+    Status = mDeviceSecurityProtocol->DeviceAuthenticate (mDeviceSecurityProtocol, &DeviceIdentifier);\r
+    //\r
+    // Always uninstall, because they are only for Authentication.\r
+    // No need to check return Status.\r
+    //\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
+                    DeviceIdentifier.DeviceHandle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    PciIoDevice->DevicePath,\r
+                    &gEdkiiDeviceIdentifierTypePciGuid,\r
+                    &PciIoDevice->PciIo,\r
+                    NULL\r
+                    );\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Device Security Protocol is not found, just return success\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Create and initialize general PCI I/O device instance for\r
   PCI device/bridge device/hotplug bridge device.\r
 /**\r
   Create and initialize general PCI I/O device instance for\r
   PCI device/bridge device/hotplug bridge device.\r
@@ -2156,6 +2218,21 @@ CreatePciIoDevice (
     PciIoDevice->IsPciExp = TRUE;\r
   }\r
 \r
     PciIoDevice->IsPciExp = TRUE;\r
   }\r
 \r
+  //\r
+  // Now we can do the authentication check for the device.\r
+  //\r
+  Status = AuthenticatePciDevice (PciIoDevice);\r
+  //\r
+  // If authentication fails, skip this device.\r
+  //\r
+  if (EFI_ERROR(Status)) {\r
+    if (PciIoDevice->DevicePath != NULL) {\r
+      FreePool (PciIoDevice->DevicePath);\r
+    }\r
+    FreePool (PciIoDevice);\r
+    return NULL;\r
+  }\r
+\r
   if (PcdGetBool (PcdAriSupport)) {\r
     //\r
     // Check if the device is an ARI device.\r
   if (PcdGetBool (PcdAriSupport)) {\r
     //\r
     // Check if the device is an ARI device.\r
index 5b55fb5d3be4d83ebd9c8e2706e493bc80cb2667..72690ab6476acc46408e12552c0bc891bd751b9c 100644 (file)
@@ -1054,7 +1054,9 @@ PciScanBus (
                 &PciDevice\r
                 );\r
 \r
                 &PciDevice\r
                 );\r
 \r
-      ASSERT (!EFI_ERROR (Status));\r
+      if (EFI_ERROR (Status)) {\r
+        continue;\r
+      }\r
 \r
       PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);\r
 \r
 \r
       PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);\r
 \r