]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
MdeModulePkg/Pci: Add DeviceSecurity support.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciEnumeratorSupport.c
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
+extern EDKII_DEVICE_SECURITY_PROTOCOL                          *mDeviceSecurityProtocol;\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
+/*\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
@@ -2156,6 +2218,21 @@ CreatePciIoDevice (
     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